* [PATCH] completion: zsh: support completion after "git -C <path>"
@ 2026-06-17 15:30 Lutz Lengemann via GitGitGadget
2026-06-17 17:17 ` Ben Knoble
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Lutz Lengemann via GitGitGadget @ 2026-06-17 15:30 UTC (permalink / raw)
To: git; +Cc: Lutz Lengemann, Lutz Lengemann
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(+)
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
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH] completion: zsh: support completion after "git -C <path>" 2026-06-17 15:30 [PATCH] completion: zsh: support completion after "git -C <path>" Lutz Lengemann via GitGitGadget @ 2026-06-17 17:17 ` Ben Knoble 2026-06-17 17:21 ` Junio C Hamano 2026-06-18 17:43 ` D. Ben Knoble 2 siblings, 0 replies; 6+ messages in thread From: Ben Knoble @ 2026-06-17 17:17 UTC (permalink / raw) To: Lutz Lengemann via GitGitGadget; +Cc: git, Lutz Lengemann I’d like to take a deeper look at this, but I’m not sure when I can. > Le 17 juin 2026 à 11:37, Lutz Lengemann via GitGitGadget <gitgitgadget@gmail.com> a écrit : > > 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. One easy note, though: our commit style prefers describing the code base before the patch in question in the present tense (« does not handle », « offers nothing »). The below imperative mood looks appropriate to me. > > 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(+) > > 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 > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] completion: zsh: support completion after "git -C <path>" 2026-06-17 15:30 [PATCH] completion: zsh: support completion after "git -C <path>" Lutz Lengemann via GitGitGadget 2026-06-17 17:17 ` Ben Knoble @ 2026-06-17 17:21 ` Junio C Hamano 2026-06-18 17:43 ` D. Ben Knoble 2 siblings, 0 replies; 6+ messages in thread From: Junio C Hamano @ 2026-06-17 17:21 UTC (permalink / raw) To: Lutz Lengemann via GitGitGadget; +Cc: git, Lutz Lengemann "Lutz Lengemann via GitGitGadget" <gitgitgadget@gmail.com> writes: > 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. I do not write, use, or customize zsh, so please take my comments with huge grains of salt, or just ignore them completely (your choice) ;-), but one thng I noticed was that ... > 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' \ ... this part talks about not just "-C<dir>" but knows about all the other options that the "git" potty itself takes, while ... > @@ -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 ... this only knows about "-C<dir>" and nothing else. Doesn't it want to do something similar to what __git_main in git-completion.bash does at the beginning, namely, this part? __git_main () { local i c=1 command __git_dir __git_repo_path local __git_C_args C_args_count=0 local __git_cmd_idx while [ $c -lt $cword ]; do i="${words[c]}" case "$i" in --git-dir=*) __git_dir="${i#--git-dir=}" ;; --git-dir) ((c++)) __git_dir="${words[c]}" ;; --bare) __git_dir="." ;; --help) command="help" break ;; -c|--work-tree|--namespace) ((c++)) ;; -C) __git_C_args[C_args_count++]=-C ((c++)) __git_C_args[C_args_count++]="${words[c]}" ;; -*) ;; *) command="$i" __git_cmd_idx="$c" break ;; esac ((c++)) done ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] completion: zsh: support completion after "git -C <path>" 2026-06-17 15:30 [PATCH] completion: zsh: support completion after "git -C <path>" Lutz Lengemann via GitGitGadget 2026-06-17 17:17 ` Ben Knoble 2026-06-17 17:21 ` Junio C Hamano @ 2026-06-18 17:43 ` D. Ben Knoble 2026-07-14 22:34 ` D. Ben Knoble 2 siblings, 1 reply; 6+ messages in thread From: D. Ben Knoble @ 2026-06-18 17:43 UTC (permalink / raw) To: Lutz Lengemann via GitGitGadget; +Cc: git, Lutz Lengemann, Junio C Hamano [apologies in advance for the strange format below] On Wed, Jun 17, 2026 at 11:37 AM Lutz Lengemann via GitGitGadget <gitgitgadget@gmail.com> wrote: > > 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. See Junio's review for whether we should expand in this patch or a follow-up. In reply to Junio: > [the new handling only knows about -C] > Doesn't it want to do something similar to what __git_main in > git-completion.bash does at the beginning, namely, this part? Yeah, we probably do want to skip over -c, etc. (I see some support for --bare and --git-dir, but not skipping over it.) Still, this patch makes things no worse in that regard, and improves the situation for -C AFAICT. In reply to Lutz: > + 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 I don't see either of these 2 local variables used anywhere else… …well, except the Bash completion helpers, I suppose. But we mark these local, so how do they propagate to the other functions? Still, I was able to try this out with the somewhat hacky zsh # new shell :) # absolute path important autoload -Uz $PWD/contrib/completion/git-completion.zsh compdef git-completion.zsh git git -C <tab> and it does prioritize directories there (though I still get a listing of files afterwards, so the screen is taken up by that gigantic listing in git.git, for example). By the way, I've realized that "git -<tab>" has the same problem (a giant list of files after the other option completions), and worse has some _funky_ output! git -<tab> # without patch (option) --bare --exec-path --git-dir --help --html-path --info-path --man-path --namespace --no-pager --no-replace-objects --paginate --version --work-tree -p # treat the repository as a bare repository # path to where your core git programs are installed # set the path to the repository # prints the synopsis and a list of the most commonly used commands # print the path where gits HTML documentation is installed # print the path where the Info files are installed # print the manpath (see `man(1)`) for the man pages # set the git namespace # do not pipe git output into a pager # do not use replacement refs to replace git objects # pipe all output into less # prints the git suite version # set the path to the working tree [ed: the above block repeats twice more before the (file) listing below] (file) […] Here's the output of _complete_help (^Xh by default) in both situations, in case that helps to understand either the extra files listing (1) in the example further back or the issue with single letter options (2) just mentioned: 1: tags in context :completion::complete:git:: option-C-1 (_arguments __git_zsh_main _git git-completion.zsh) use-compctl (_default _git git-completion.zsh) globbed-files (_files _default _git git-completion.zsh) tags in context :completion::complete:git:option-C-1: directories (_directories _arguments __git_zsh_main _git git-completion.zsh) globbed-files (_files _directories _arguments __git_zsh_main _git git-completion.zsh) all-files (_files _directories _arguments __git_zsh_main _git git-completion.zsh) 2: tags in context :completion::complete:git:: argument-1 options (_arguments __git_zsh_main _git) use-compctl (_default _git) globbed-files (_files _default _git) tags in context :completion::complete:git:argument-1: common-commands alias-commands all-commands (__git_zsh_main _git) common-commands (__git_zsh_cmd_common __git_zsh_main _git) alias-commands (__git_zsh_cmd_alias __git_zsh_main _git) all-commands (__git_zsh_cmd_all __git_zsh_main _git) tags in context :completion::complete:git:options: options (_arguments __git_zsh_main _git) > + '*-C[run as if git was started in <path>]: :_directories' \ We should probably note in the log message that the _directories completion will not account for previous -C; that is, after typing git -C dir -C <tab> we will complete directories in ".", not "dir". That's probably a reasonable limitation for now, but I think we could do _slightly_ better by using a state "->dir" or something, accumulating the current prefix, and passing that to _directories as a prefix with -W (see _path_files in zshcompsys, which _directories delegates to via _files, IIUC). -- D. Ben Knoble ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] completion: zsh: support completion after "git -C <path>" 2026-06-18 17:43 ` D. Ben Knoble @ 2026-07-14 22:34 ` D. Ben Knoble 2026-08-17 19:29 ` Lutz Lengemann 0 siblings, 1 reply; 6+ messages in thread From: D. Ben Knoble @ 2026-07-14 22:34 UTC (permalink / raw) To: Lutz Lengemann via GitGitGadget; +Cc: git, Lutz Lengemann, Junio C Hamano Hi Lutz, On Thu, Jun 18, 2026 at 1:43 PM D. Ben Knoble <ben.knoble@gmail.com> wrote: > > [apologies in advance for the strange format below] > > On Wed, Jun 17, 2026 at 11:37 AM Lutz Lengemann via GitGitGadget > <gitgitgadget@gmail.com> wrote: > > > > 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. > > See Junio's review for whether we should expand in this patch or a follow-up. > > In reply to Junio: > > > [the new handling only knows about -C] > > Doesn't it want to do something similar to what __git_main in > > git-completion.bash does at the beginning, namely, this part? > > Yeah, we probably do want to skip over -c, etc. (I see some support for > --bare and --git-dir, but not skipping over it.) Still, this patch makes > things no worse in that regard, and improves the situation for -C > AFAICT. > > In reply to Lutz: > > > + 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 > > I don't see either of these 2 local variables used anywhere else… > > …well, except the Bash completion helpers, I suppose. But we mark these > local, so how do they propagate to the other functions? > > Still, I was able to try this out with the somewhat hacky > > zsh # new shell :) > # absolute path important > autoload -Uz $PWD/contrib/completion/git-completion.zsh > compdef git-completion.zsh git > > git -C <tab> > > and it does prioritize directories there (though I still get a listing > of files afterwards, so the screen is taken up by that gigantic listing > in git.git, for example). > > By the way, I've realized that "git -<tab>" has the same problem (a > giant list of files after the other option completions), and worse has > some _funky_ output! > > git -<tab> # without patch > (option) > --bare > --exec-path > --git-dir > --help > --html-path > --info-path > --man-path > --namespace > --no-pager > --no-replace-objects > --paginate > --version > --work-tree > > -p > > # treat the repository as a bare repository > # path to where your core git programs are installed > # set the path to the repository > # prints the synopsis and a list of the most commonly used commands > # print the path where gits HTML documentation is installed > # print the path where the Info files are installed > # print the manpath (see `man(1)`) for the man pages > # set the git namespace > # do not pipe git output into a pager > # do not use replacement refs to replace git objects > # pipe all output into less > # prints the git suite version > # set the path to the working tree > [ed: the above block repeats twice more before the (file) listing below] > (file) > […] > > Here's the output of _complete_help (^Xh by default) in both situations, > in case that helps to understand either the extra files listing (1) in > the example further back or the issue with single letter options (2) > just mentioned: > > 1: tags in context :completion::complete:git:: > option-C-1 (_arguments __git_zsh_main _git git-completion.zsh) > use-compctl (_default _git git-completion.zsh) > globbed-files (_files _default _git git-completion.zsh) > tags in context :completion::complete:git:option-C-1: > directories (_directories _arguments __git_zsh_main _git > git-completion.zsh) > globbed-files (_files _directories _arguments __git_zsh_main _git > git-completion.zsh) > all-files (_files _directories _arguments __git_zsh_main _git > git-completion.zsh) > > 2: tags in context :completion::complete:git:: > argument-1 options (_arguments __git_zsh_main _git) > use-compctl (_default _git) > globbed-files (_files _default _git) > tags in context :completion::complete:git:argument-1: > common-commands alias-commands all-commands (__git_zsh_main _git) > common-commands (__git_zsh_cmd_common > __git_zsh_main _git) > alias-commands (__git_zsh_cmd_alias > __git_zsh_main _git) > all-commands (__git_zsh_cmd_all > __git_zsh_main _git) > tags in context :completion::complete:git:options: > options (_arguments __git_zsh_main _git) > > > + '*-C[run as if git was started in <path>]: :_directories' \ > > We should probably note in the log message that the _directories > completion will not account for previous -C; that is, after typing > > git -C dir -C <tab> > > we will complete directories in ".", not "dir". That's probably a > reasonable limitation for now, but I think we could do _slightly_ better > by using a state "->dir" or something, accumulating the current prefix, > and passing that to _directories as a prefix with -W (see _path_files in > zshcompsys, which _directories delegates to via _files, IIUC). > > -- > D. Ben Knoble Any progress here? I just found my local copy of this patch and was briefly surprised to see it hadn't graduated anywhere (until I realized conversation had stalled at this point). -- D. Ben Knoble ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] completion: zsh: support completion after "git -C <path>" 2026-07-14 22:34 ` D. Ben Knoble @ 2026-08-17 19:29 ` Lutz Lengemann 0 siblings, 0 replies; 6+ messages in thread From: Lutz Lengemann @ 2026-08-17 19:29 UTC (permalink / raw) To: D. Ben Knoble, Lutz Lengemann; +Cc: git, Junio C Hamano Hi Ben (Resending, my earlier reply was rejected by the list for being HTML.) On Wed, Jul 15, 2026, at 00:34, D. Ben Knoble wrote: > Any progress here? I just found my local copy of this patch and was > briefly surprised to see it hadn't graduated anywhere (until I > realized conversation had stalled at this point). Sorry for the very late reply, I was on holiday and then other life things got in the way of answering :( I do have a v2 ready, which I have just pushed to my fork, and which follows this message. Junio C Hamano <gitster@pobox.com> writes: > Doesn't it want to do something similar to what __git_main in > git-completion.bash does at the beginning, namely, this part? It does, thanks. v2 no longer skips only leading -C options, but walks the words in front of the command and skips over the global options and, where they take one, their arguments, like __git_main does. That also makes "git -p checkout <TAB>" and "git --git-dir=<path> checkout <TAB>" complete the arguments of the command, which they did not before. Two related gaps are left alone, as they are bugs in the _arguments specification rather than in the command lookup: -c is not listed there at all, and --git-dir and friends are spelled "--git-dir=-", which accepts only "--git-dir=<path>", not the "--git-dir <path>" form. I can send patches for those separately. "D. Ben Knoble" <ben.knoble@gmail.com> writes: > But we mark these local, so how do they propagate to the other > functions? zsh scoping is dynamic, not lexical, so a variable declared "local" in __git_zsh_main is visible in the functions that are called from it, the bash helpers included. That is how __git_dir and __git_cmd_idx are handed down already, and __git_C_args works the same way. > We should probably note in the log message that the _directories > completion will not account for previous -C I added a note about this in the log message. > I think we could do _slightly_ better by using a state "->dir" or > something, accumulating the current prefix, and passing that to > _directories as a prefix with -W I tried that and it works, but it changes what -C offers, which is more than fixing the completion after -C, so I left it out; happy to send it on top. Two things to watch out for there: the accumulated path has to be made absolute, as -W with ".." gave me the directories of "/", and the accumulation has to stop before the word that is being completed. > By the way, I've realized that "git -<tab>" has the same problem (a > giant list of files after the other option completions) That one is older than this patch: the file listing comes from the fallback at the end of _git, let _ret && _default && _ret=0 which is where the "use-compctl" and "globbed-files" tags in your _complete_help dump come from. I could not reproduce the repeated description block with "zsh -f" and only the _complete completer, so something in my setup or yours may differ there. Either way it wants its own topic. I hope that the change now looks good, and if there is anything I should still look at just tell me. Thank you very much Lutz ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-08-17 19:29 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-06-17 15:30 [PATCH] completion: zsh: support completion after "git -C <path>" Lutz Lengemann via GitGitGadget 2026-06-17 17:17 ` Ben Knoble 2026-06-17 17:21 ` Junio C Hamano 2026-06-18 17:43 ` D. Ben Knoble 2026-07-14 22:34 ` D. Ben Knoble 2026-08-17 19:29 ` Lutz Lengemann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox