Completing configuration sections and variable names for the stuck argument of 'git clone --config=<TAB>' requires a bit of extra care compared to doing the same for the unstuck argument of 'git clone --config <TAB>', because we have to deal with that '--config=' being part of the current word to be completed. Add an option to the __git_complete_config_variable_name_and_value() and in turn to the __git_complete_config_variable_name() helper functions to specify the current section/variable name to be completed, so they can be used even when completing the stuck argument of '--config='. __git_complete_config_variable_value() already has such an option, and thus no further changes were necessary to complete possible values after 'git clone --config=section.name=<TAB>'. Signed-off-by: SZEDER Gábor <szeder.dev@xxxxxxxxx> --- contrib/completion/git-completion.bash | 66 +++++++++++++++++++------- t/t9902-completion.sh | 21 ++++++++ 2 files changed, 70 insertions(+), 17 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 279f04df87..ce7ff0a96d 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1406,6 +1406,11 @@ _git_clone () ;; esac case "$cur" in + --config=*) + __git_complete_config_variable_name_and_value \ + --cur="${cur##--config=}" + return + ;; --*) __gitcomp_builtin clone return @@ -2352,35 +2357,41 @@ __git_complete_config_variable_value () # Completes configuration sections, subsections, variable names. # # Usage: __git_complete_config_variable_name [<option>]... +# --cur=<word>: The current configuration section/variable name to be +# completed. Defaults to the current word to be completed. # --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 + local cur_="$cur" sfx while test $# != 0; do case "$1" in + --cur=*) cur_="${1##--cur=}" ;; --sfx=*) sfx="${1##--sfx=}" ;; *) return 1 ;; esac shift done - case "$cur" in + case "$cur_" in branch.*.*) - local pfx="${cur%.*}." cur_="${cur##*.}" + local pfx="${cur_%.*}." + cur_="${cur_##*.}" __gitcomp "remote pushRemote merge mergeOptions rebase" "$pfx" "$cur_" "$sfx" return ;; branch.*) - local pfx="${cur%.*}." cur_="${cur#*.}" + local pfx="${cur%.*}." + cur_="${cur#*.}" __gitcomp_direct "$(__git_heads "$pfx" "$cur_" ".")" __gitcomp_nl_append $'autoSetupMerge\nautoSetupRebase\n' "$pfx" "$cur_" "$sfx" return ;; guitool.*.*) - local pfx="${cur%.*}." cur_="${cur##*.}" + local pfx="${cur_%.*}." + cur_="${cur_##*.}" __gitcomp " argPrompt cmd confirm needsFile noConsole noRescan prompt revPrompt revUnmerged title @@ -2388,28 +2399,33 @@ __git_complete_config_variable_name () return ;; difftool.*.*) - local pfx="${cur%.*}." cur_="${cur##*.}" + local pfx="${cur_%.*}." + cur_="${cur_##*.}" __gitcomp "cmd path" "$pfx" "$cur_" "$sfx" return ;; man.*.*) - local pfx="${cur%.*}." cur_="${cur##*.}" + local pfx="${cur_%.*}." + cur_="${cur_##*.}" __gitcomp "cmd path" "$pfx" "$cur_" "$sfx" return ;; mergetool.*.*) - local pfx="${cur%.*}." cur_="${cur##*.}" + local pfx="${cur_%.*}." + cur_="${cur_##*.}" __gitcomp "cmd path trustExitCode" "$pfx" "$cur_" "$sfx" return ;; pager.*) - local pfx="${cur%.*}." cur_="${cur#*.}" + local pfx="${cur_%.*}." + cur_="${cur_#*.}" __git_compute_all_commands __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_" "$sfx" return ;; remote.*.*) - local pfx="${cur%.*}." cur_="${cur##*.}" + local pfx="${cur_%.*}." + cur_="${cur_##*.}" __gitcomp " url proxy fetch push mirror skipDefaultUpdate receivepack uploadpack tagOpt pushurl @@ -2417,19 +2433,21 @@ __git_complete_config_variable_name () return ;; remote.*) - local pfx="${cur%.*}." cur_="${cur#*.}" + local pfx="${cur_%.*}." + cur_="${cur_#*.}" __gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "." __gitcomp_nl_append "pushDefault" "$pfx" "$cur_" "$sfx" return ;; url.*.*) - local pfx="${cur%.*}." cur_="${cur##*.}" + local pfx="${cur_%.*}." + cur_="${cur_##*.}" __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_" "$sfx" return ;; *.*) __git_compute_config_vars - __gitcomp "$__git_config_vars" "" "$cur" "$sfx" + __gitcomp "$__git_config_vars" "" "$cur_" "$sfx" ;; *) __git_compute_config_vars @@ -2441,22 +2459,36 @@ __git_complete_config_variable_name () for (s in sections) print s "." } - ')" + ')" "" "$cur_" ;; esac } # Completes '='-separated configuration sections/variable names and values # for 'git -c section.name=value'. +# +# Usage: __git_complete_config_variable_name_and_value [<option>]... +# --cur=<word>: The current configuration section/variable name/value to be +# completed. Defaults to the current word to be completed. __git_complete_config_variable_name_and_value () { - case "$cur" in + local cur_="$cur" + + while test $# != 0; do + case "$1" in + --cur=*) cur_="${1##--cur=}" ;; + *) return 1 ;; + esac + shift + done + + case "$cur_" in *=*) __git_complete_config_variable_value \ - --varname="${cur%%=*}" --cur="${cur#*=}" + --varname="${cur_%%=*}" --cur="${cur_#*=}" ;; *) - __git_complete_config_variable_name --sfx='=' + __git_complete_config_variable_name --cur="$cur_" --sfx='=' ;; esac } diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 9e90a64830..5d98d66dbd 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -1740,6 +1740,27 @@ test_expect_success 'git -c - value' ' EOF ' +test_expect_success 'git clone --config= - section' ' + test_completion "git clone --config=br" <<-\EOF + branch.Z + browser.Z + EOF +' + +test_expect_success 'git clone --config= - variable name' ' + test_completion "git clone --config=log.d" <<-\EOF + log.date=Z + log.decorate=Z + EOF +' + +test_expect_success 'git clone --config= - value' ' + test_completion "git clone --config=color.pager=" <<-\EOF + false Z + true 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