completion: exclude previous file arguments in Zsh
PATCH 1/1 completion: exclude previous file arguments in Zsh
From: Fionn Fitzmaurice <[email protected]>
When using the _git completion function bundled with Zsh
(https://sf.net/p/zsh/code/ci/master/tree/Completion/Unix/Command/_git),
duplicate files in an argument list will not be offered as completion candidates.
For example, suppose we have untracked files aa and ab (only). Then with the Zsh completion,
git add aa a<tab>
would not offer both aa and ab as completion candidates, rather it would complete ab only.
This behaviour is not present in git-completion.zsh shipped with Git, which does not deduplicate arguments.
We can get this with minor changes, however. Here we introduce an array __git_file_exclude which we populate with existing arguments and then tell compadd to exclude them, which closely matches the Zsh _git completion behaviour (as well as common programs such as rm).
---
completion: exclude previous file arguments in Zsh
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2216%2Ffionn%2Fzsh-completion-exclude-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2216/fionn/zsh-completion-exclude-v1
Pull-Request: https://github.com/git/git/pull/2216
contrib/completion/git-completion.zsh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
contrib/completion/git-completion.zsh +4 -1
@@ -117,7 +117,7 @@ __gitcomp_file () emulate -L zsh compset -P '*[=:]' - compadd -f -p "${2-}" -- ${(f)1} && _ret=0 + compadd -f -p "${2-}" -F __git_file_exclude -- ${(f)1} && _ret=0 } __gitcomp_direct_append ()
@@ -284,6 +284,8 @@ __git_zsh_main () (( $+opt_args[--help] )) && command='help' + __git_file_exclude=(${words[2,-1]:#${words[CURRENT]}}) + words=( ${orig_words[@]} ) __git_zsh_bash_func $command
@@ -296,6 +298,7 @@ _git () local _ret=1 local cur cword prev local __git_repo_path + local -a __git_file_exclude cur=${words[CURRENT]} prev=${words[CURRENT-1]}
base-commit: c46c1e37724f0478939de636ab8ea5a89086d532
Signature · 1 line
gitgitgadget
Quoted 2 lines · Fionn via GitGitGadget
We can get this with minor changes, however. Here we introduce an array
__git_file_excludewhich we populate with existing arguments and then
"existing arguments" of what?
contrib/completion/git-completion.zsh __git_zsh_main () · line 287
Quoted 9 lines
tell compadd to exclude them, which closely matches the Zsh
_gitcompletion behaviour (as well as common programs such as rm).contrib/completion/git-completion.zsh +1
-0@@ -284,6 +284,8 @@ __git_zsh_main () (( $+opt_args[--help] )) && command='help' + __git_file_exclude=(${words[2,-1]:#${words[CURRENT]}})
I don't do Zsh, but that 2 as index looks suspicious.
What will be excluded in the following command line:
git -C dir -C subdir -c foo.bar=baz add file1 file2 <TAB>
I think we should exclude only those arguments that come after the git command, in this case after "add", i.e. "file1" and "file2", but I suspect that everything starting with "dir" will get excluded.
Quoted 4 lines
contrib/completion/git-completion.zsh +1
-0+ words=( ${orig_words[@]} ) __git_zsh_bash_func $command
Quoted 1 line
"existing arguments" of what?
Of a subcommand that takes paths.
Quoted 1 line
I don't do Zsh, but that 2 as index looks suspicious.
Fair to be suspicious. word[1] is the subcommand (e.g. "add"), so we index from 2 on in order to skip it. This is independent of where the subcommand appears in the entire command line.
Quoted 7 lines
What will be excluded in the following command line:
git -C dir -C subdir -c foo.bar=baz add file1 file2 <TAB>
I think we should exclude only those arguments that come after the git command, in this case after "add", i.e. "file1" and "file2", but I suspect that everything starting with "dir" will get excluded.
In my testing this works correctly (i.e. file1 and file2 are not offered as completion candidates any more, but if e.g. dir or foo exist in the subdirectory, they would be offered).
I've been dogfooding this for about 8 months on and off. Occasionally completion candidates I'd hope would be excluded are present, but this is because the fallback completion bypasses __gitcomp_file, which is a separate issue. I have not yet encountered completion candidates being unexpectedly excluded.
An easy way to test this is to link git-completion.zsh to _git and then add
fpath=(/path/to/directory/containing/_git/file $fpath[@])
to ~/.zshrc, or similar.
Quoted 7 lines · SZEDER Gábor
What will be excluded in the following command line:
git -C dir -C subdir -c foo.bar=baz add file1 file2 <TAB>
I think we should exclude only those arguments that come after the git command, in this case after "add", i.e. "file1" and "file2", but I suspect that everything starting with "dir" will get excluded.
I was writing the same message when I saw yours.
If you had a file called 'add' in the working tree and then typed "a<TAB>" to complete, is 'add' offered together with other files whose name begins with 'a'?
Quoted 3 lines
If you had a file called 'add' in the working tree and then typed "a<TAB>" to complete, is 'add' offered together with other files whose name begins with 'a'?
It is indeed.