'git config' expects a configuration variable's name and value in separate arguments, so we let the __gitcomp() helper append a space character to each variable name by default, like we do for most other things (--options, refs, paths, etc.). 'git -c', however, expects them in a single option joined by a '=' character, i.e. 'section.name=value', so we should append a '=' character to each fully completed variable name, but no space, so the user can continue typing the value right away. Add an option to the __git_complete_config_variable_name() function to allow callers to specify an alternate suffix to add, and use it to append that '=' character to configuration variables. Update the __gitcomp() helper function to not append a trailing space to any completion words ending with a '=', not just to those option with a stuck argument. Signed-off-by: SZEDER Gábor <szeder.dev@xxxxxxxxx> --- contrib/completion/git-completion.bash | 59 ++++++++++++++++++++------ t/t9902-completion.sh | 14 ++++++ 2 files changed, 60 insertions(+), 13 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 3e9c5b6b71..367b1c50f4 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -360,7 +360,7 @@ __gitcomp () c="$c${4-}" if [[ $c == "$cur_"* ]]; then case $c in - --*=|*.) ;; + *=|*.) ;; *) c="$c " ;; esac COMPREPLY[i++]="${2-}$c" @@ -2328,18 +2328,33 @@ __git_complete_config_variable_value () } # Completes configuration sections, subsections, variable names. +# +# Usage: __git_complete_config_variable_name [<option>]... +# --sfx=<suffix>: A suffix to be appended to each fully completed +# configuration variable name (but not to sections or +# subsections) instead of the default space. __git_complete_config_variable_name () { + local sfx + + while test $# != 0; do + case "$1" in + --sfx=*) sfx="${1##--sfx=}" ;; + *) return 1 ;; + esac + shift + done + case "$cur" in branch.*.*) local pfx="${cur%.*}." cur_="${cur##*.}" - __gitcomp "remote pushRemote merge mergeOptions rebase" "$pfx" "$cur_" + __gitcomp "remote pushRemote merge mergeOptions rebase" "$pfx" "$cur_" "$sfx" return ;; branch.*) local pfx="${cur%.*}." cur_="${cur#*.}" __gitcomp_direct "$(__git_heads "$pfx" "$cur_" ".")" - __gitcomp_nl_append $'autoSetupMerge\nautoSetupRebase\n' "$pfx" "$cur_" + __gitcomp_nl_append $'autoSetupMerge\nautoSetupRebase\n' "$pfx" "$cur_" "$sfx" return ;; guitool.*.*) @@ -2347,28 +2362,28 @@ __git_complete_config_variable_name () __gitcomp " argPrompt cmd confirm needsFile noConsole noRescan prompt revPrompt revUnmerged title - " "$pfx" "$cur_" + " "$pfx" "$cur_" "$sfx" return ;; difftool.*.*) local pfx="${cur%.*}." cur_="${cur##*.}" - __gitcomp "cmd path" "$pfx" "$cur_" + __gitcomp "cmd path" "$pfx" "$cur_" "$sfx" return ;; man.*.*) local pfx="${cur%.*}." cur_="${cur##*.}" - __gitcomp "cmd path" "$pfx" "$cur_" + __gitcomp "cmd path" "$pfx" "$cur_" "$sfx" return ;; mergetool.*.*) local pfx="${cur%.*}." cur_="${cur##*.}" - __gitcomp "cmd path trustExitCode" "$pfx" "$cur_" + __gitcomp "cmd path trustExitCode" "$pfx" "$cur_" "$sfx" return ;; pager.*) local pfx="${cur%.*}." cur_="${cur#*.}" __git_compute_all_commands - __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_" + __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_" "$sfx" return ;; remote.*.*) @@ -2376,23 +2391,23 @@ __git_complete_config_variable_name () __gitcomp " url proxy fetch push mirror skipDefaultUpdate receivepack uploadpack tagOpt pushurl - " "$pfx" "$cur_" + " "$pfx" "$cur_" "$sfx" return ;; remote.*) local pfx="${cur%.*}." cur_="${cur#*.}" __gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "." - __gitcomp_nl_append "pushDefault" "$pfx" "$cur_" + __gitcomp_nl_append "pushDefault" "$pfx" "$cur_" "$sfx" return ;; url.*.*) local pfx="${cur%.*}." cur_="${cur##*.}" - __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_" + __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_" "$sfx" return ;; *.*) __git_compute_config_vars - __gitcomp "$__git_config_vars" + __gitcomp "$__git_config_vars" "" "$cur" "$sfx" ;; *) __git_compute_config_vars @@ -2409,6 +2424,20 @@ __git_complete_config_variable_name () esac } +# Completes '='-separated configuration sections/variable names and values +# for 'git -c section.name=value'. +__git_complete_config_variable_name_and_value () +{ + case "$cur" in + *=*) + # in the next patch... + ;; + *) + __git_complete_config_variable_name --sfx='=' + ;; + esac +} + _git_config () { case "$prev" in @@ -2984,7 +3013,11 @@ __git_main () # Bash filename completion return ;; - -c|--namespace) + -c) + __git_complete_config_variable_name_and_value + return + ;; + --namespace) # we don't support completing these options' arguments return ;; diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 008fba7c89..bf60a11fa8 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -1719,6 +1719,20 @@ test_expect_success 'git config - value' ' EOF ' +test_expect_success 'git -c - section' ' + test_completion "git -c br" <<-\EOF + branch.Z + browser.Z + EOF +' + +test_expect_success 'git -c - variable name' ' + test_completion "git -c log.d" <<-\EOF + log.date=Z + log.decorate=Z + EOF +' + test_expect_success 'sourcing the completion script clears cached commands' ' __git_compute_all_commands && verbose test -n "$__git_all_commands" && -- 2.23.0.rc2.350.gf4fdc32db7