From: Lutz Lengemann <lutz@lengemann.net>
The zsh completion wrapper (__git_zsh_main) did not handle the global -C option, so "git -C <path> <command> <TAB>" offered nothing and could not complete a command's arguments.
Three things are needed to make it work, all scoped to -C:
- Add -C to the _arguments specification, so completion no longer stops
at it. - Advance __git_cmd_idx past any leading "-C <path>" options. The index
is hard-coded to 1, i.e. the command is assumed to be the first
argument; with -C present the command sits two words later for each
-C, so the bash helpers otherwise look at the wrong word and produce
nothing. - Collect the -C paths into __git_C_args, as __git_main does. The bash
helpers run git to resolve aliases and list refs; without the -C
paths they run in the current directory, so completion fails whenever
the cwd is not the target repository or the command is an alias.With these, "git -C <path> <command> <TAB>" completes the command, its options and its arguments, including outside the repository, through aliases, and with repeated -C options.
Signed-off-by: Lutz Lengemann <lutz@lengemann.net>
---
completion: zsh: support completion after "git -C "
This patch is intentionally scoped to -C, but the underlying problem is
more general. The zsh wrapper hard-codes __git_cmd_idx=1, i.e. it
assumes the command is always the first argument. That assumption breaks
argument completion after any global option that precedes the command,
not just -C — e.g. --git-dir, --work-tree, --namespace, -c, and
-p/--paginate. After those, git <opt> <command> <TAB> currently
completes the command name but not its arguments.
The same approach generalizes cleanly: instead of skipping only leading
-C options, walk all leading global options and their arguments to
locate the command and its true index (mirroring the option scan in
__git_main in git-completion.bash), while collecting -C into
__git_C_args and --git-dir into __git_dir as today.
I kept this revision narrow for reviewability and because git -C is the
case where I miss the completion, but I'm happy to extend it to cover
the other global options in a follow-up (or fold it into this patch) if
that's preferred.Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2155%2Fmobilutz%2Fzsh-complete-global-C-v1 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2155/mobilutz/zsh-complete-global-C-v1 Pull-Request: https://github.com/gitgitgadget/git/pull/2155
contrib/completion/git-completion.zsh | 9 +++++++++ 1 file changed, 9 insertions(+)
Show changes to contrib/completion/git-completion.zsh +9 −0
diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh index c32186a977..323049be8b 100644 --- a/contrib/completion/git-completion.zsh +++ b/contrib/completion/git-completion.zsh @@ -227,6 +227,7 @@ __git_zsh_main () '(-p --paginate --no-pager)'{-p,--paginate}'[pipe all output into ''less'']' \ '(-p --paginate)--no-pager[do not pipe git output into a pager]' \ '--git-dir=-[set the path to the repository]: :_directories' \ + '*-C[run as if git was started in <path>]: :_directories' \ '--bare[treat the repository as a bare repository]' \ '(- :)--version[prints the git suite version]' \ '--exec-path=-[path to where your core git programs are installed]:: :_directories' \ @@ -252,6 +253,14 @@ __git_zsh_main () ;; (arg) local command="${words[1]}" __git_dir __git_cmd_idx=1 + local -a __git_C_args + local -i i=2 + + while [[ ${orig_words[i]} == -C ]]; do + __git_C_args+=(-C ${orig_words[i+1]}) + (( __git_cmd_idx += 2 )) + (( i += 2 )) + done if (( $+opt_args[--bare] )); then __git_dir='.' base-commit: 0fae78c9d55efe705877ea537fe42c59164ccd94
-- gitgitgadget