Conversation
| local i | ||
| for i in "${!dirs[@]}"; do | ||
| dir=${dirs[i]}/completions | ||
| for dir in "${dirs[@]}"; do |
There was a problem hiding this comment.
The result of this is that we end up loading completions without the .bash suffix from more dirs we did before this change. We may want to tighten that up some.
Could check if the dir ends with -core or -fallback and load only .bash for them. That isn't 100% correct in the case if someone has for whatever reason configured their BASH_COMPLETION_USER_DIR to have one of those suffixes (we'd want to load both with and without .bash from there for backwards compatibility).
There was a problem hiding this comment.
I agree to check the suffix -{core,fallback} (probably inside _comp_load__visit_file).
There was a problem hiding this comment.
Thank you for creating the PR! This is exactly the issue that I described in #1557 (comment).
When using the new version, I also noticed a search-order problem of
_comp_loadwhen the systembash-completion < 2.18and the user'sbash-completion >= 2.18coexist. I'll later describe it. I would like to discuss it and fix issues of_comp_loadincluding it.
I was naively thinking of swapping the directory precedence of 2) and 3), and inserting the search for completions-core before 4), but I haven't yet considered it deeply enough.
| @@ -3478,15 +3478,15 @@ _comp_load() | |||
| if [[ ${BASH_COMPLETION_USER_DIR-} ]]; then | |||
| _comp_split -F : dirs "$BASH_COMPLETION_USER_DIR" | |||
There was a problem hiding this comment.
BASH_COMPLETION_USER_DIR is supposed to contain a path like ~/.local/share/bash-completion, so we need to suffix /completion to them too. I think we can use _comp_compgen. For example, something like this: _comp_compgen -Rv dirs -F : -- -W '$BASH_COMPLETION_USER_DIR' -S /completions, though I haven't tested this carefully.
There was a problem hiding this comment.
I haven't thought of this too deeply, but I think we do not need to do that. This dir is a single directory to load completions from, solely under the user's control, I don't think we need to add any more structure or segments to it. Adding would also be a breaking change.
There was a problem hiding this comment.
Hm README.md seems to disagree with me, I misremembered. $BASH_COMPLETION_USER_DIR is by the way not documented in doc/configuration.md, only its $XDG_CONFIG_HOME/bash_completion fallback is. We should fix that.
| # Completions in the system data dirs. | ||
| _comp_split -F : paths "${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" && | ||
| dirs+=("${paths[@]/%//bash-completion}") | ||
| dirs+=("${paths[@]/%//bash-completion}"/completions{,-core,-fallback}) |
There was a problem hiding this comment.
Should we search the system completions-{core,fallback} after none were found in the in-tree completions-{core,fallback} (i.e., $_comp__base_directory/completions-{core,fallback} in the tree of the current bash_completion)? I think all default/fallback completions should already be found in the in-tree completions-{core,fallback}. Are there cases where the completion file is not found in the in-tree completions-{core,fallback} but found in the system completions-{core,fallback}?
I also think loading external completions-{core,fallback} would cause the compatibility problem with the internal API. We've been assuming that we can use the latest internal APIs defined in bash_completion inside the in-tree completions of the same version. When the in-tree completions-{core,fallback} doesn't contain the completion for a command while the system completions-{core,fallback} contains one, I think that implies the system bash-completion is newer than the current bash-completion. In this case, we should avoid loading the system completions-{core,fallback} because it is likely to contain uses of new internal APIs.
In short, I think the completions in completions-{core,fallback} are tightly bound, in the sense of internal API, to the exact version of bash_completion in the same tree. It's not safe to load completions-{core,fallback} outside the tree.
| for dir in "${paths[@]%/}"; do | ||
| [[ $dir == ?*/@(bin|sbin) ]] && | ||
| dirs+=("${dir%/*}/share/bash-completion") | ||
| dirs+=("${dir%/*}/share/bash-completion"/completions{,-core,-fallback}) |
There was a problem hiding this comment.
For the same reason, I think we don't want to load completions-{core,fallback} in the bin directories.
Also, as I mentioned above, I would like to suggest exchanging the ordering of 2) and 3).
|
Another issue is that when, the current
|
Or, maybe we can keep the current Or, another possibility is to search i) |
Currently, I like this idea, though I need to think about it more later. It seems to solve the main issues cleanly with the minimum change. diff --git a/bash_completion b/bash_completion
index e67cc3d51..d9c1d1cce 100644
--- a/bash_completion
+++ b/bash_completion
@@ -3508,15 +3508,17 @@ _comp_load()
shift
local -a source_args=("$@")
- local i
- for i in "${!dirs[@]}"; do
- dir=${dirs[i]}/completions
- [[ -d $dir ]] || continue
- for compfile in "$cmdname.bash" "$cmdname"; do
- _comp_load__visit_file "$dir/$compfile" && return 0
- done
+ local dir
+ for dir in "${dirs[@]}"; do
+ _comp_load__visit_file "$dir/completions/$cmdname.bash" && return 0
done
+
_comp_load__visit_file "$_comp__base_directory/completions-core/$cmdname.bash" && return 0
+
+ for dir in "${dirs[@]}"; do
+ _comp_load__visit_file "$dir/completions/$cmdname" && return 0
+ done
+
_comp_load__visit_file "$_comp__base_directory/completions-fallback/$cmdname.bash" && return 0
# Look up simple "xspec" completions |
I like how it looks too, but it contains a behavioral change: |
That is a good point. Then, how about using different rules for the user-specified completion files and the package-provided completion files?
Example Implementation: bc5dfff...4366ead Rationale for checking
|
This might not be spot on off the bat, but it restores some of the way we used to load completions from.
In particular, before this, completions-core and completions-fallback from the bash_completion location were not attempted, which is a regression at least for my workflow: I rely on being able to modify files in my bash-completion working dir and have them take precendence over any system installed ones.