completion: complete configuration sections and variable names for 'git -c'
authorSZEDER Gábor <szeder.dev@gmail.com>
Tue, 13 Aug 2019 12:26:49 +0000 (14:26 +0200)
committerJunio C Hamano <gitster@pobox.com>
Tue, 13 Aug 2019 19:31:04 +0000 (12:31 -0700)
'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@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
contrib/completion/git-completion.bash
t/t9902-completion.sh
index 3e9c5b6b71a052a65ac2378c5043fd94f9a1b7ec..367b1c50f450e055ab5572f6695ffd58c05ca0df 100644 (file)
@@ -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
                        ;;
index 008fba7c8963889cdb7262509c2eddbdb63ca9c3..bf60a11fa81767836f009d659b45239ce541a47f 100755 (executable)
@@ -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" &&