completion: complete configuration sections and variable names for 'git -c'

'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>

SZEDER Gábor committed Aug 13, 2019 at 14:26 UTC e1e00089da9f616d23f0ca3bb183258e9013c469
2 files changed +60 -13
contrib/completion/git-completion.bash
+46 -13
@@ -360,7 +360,7 @@ __gitcomp ()
360 c="$c${4-}"
361 if [[ $c == "$cur_"* ]]; then
362 case $c in
363 - --*=|*.) ;;
363 + *=|*.) ;;
364 *) c="$c " ;;
365 esac
366 COMPREPLY[i++]="${2-}$c"
@@ -2328,18 +2328,33 @@ __git_complete_config_variable_value ()
2328 }
2329
2330 # Completes configuration sections, subsections, variable names.
2331 +#
2332 +# Usage: __git_complete_config_variable_name [<option>]...
2333 +# --sfx=<suffix>: A suffix to be appended to each fully completed
2334 +# configuration variable name (but not to sections or
2335 +# subsections) instead of the default space.
2336 __git_complete_config_variable_name ()
2337 {
2338 + local sfx
2339 +
2340 + while test $# != 0; do
2341 + case "$1" in
2342 + --sfx=*) sfx="${1##--sfx=}" ;;
2343 + *) return 1 ;;
2344 + esac
2345 + shift
2346 + done
2347 +
2348 case "$cur" in
2349 branch.*.*)
2350 local pfx="${cur%.*}." cur_="${cur##*.}"
2336 - __gitcomp "remote pushRemote merge mergeOptions rebase" "$pfx" "$cur_"
2351 + __gitcomp "remote pushRemote merge mergeOptions rebase" "$pfx" "$cur_" "$sfx"
2352 return
2353 ;;
2354 branch.*)
2355 local pfx="${cur%.*}." cur_="${cur#*.}"
2356 __gitcomp_direct "$(__git_heads "$pfx" "$cur_" ".")"
2342 - __gitcomp_nl_append $'autoSetupMerge\nautoSetupRebase\n' "$pfx" "$cur_"
2357 + __gitcomp_nl_append $'autoSetupMerge\nautoSetupRebase\n' "$pfx" "$cur_" "$sfx"
2358 return
2359 ;;
2360 guitool.*.*)
@@ -2347,28 +2362,28 @@ __git_complete_config_variable_name ()
2362 __gitcomp "
2363 argPrompt cmd confirm needsFile noConsole noRescan
2364 prompt revPrompt revUnmerged title
2350 - " "$pfx" "$cur_"
2365 + " "$pfx" "$cur_" "$sfx"
2366 return
2367 ;;
2368 difftool.*.*)
2369 local pfx="${cur%.*}." cur_="${cur##*.}"
2355 - __gitcomp "cmd path" "$pfx" "$cur_"
2370 + __gitcomp "cmd path" "$pfx" "$cur_" "$sfx"
2371 return
2372 ;;
2373 man.*.*)
2374 local pfx="${cur%.*}." cur_="${cur##*.}"
2360 - __gitcomp "cmd path" "$pfx" "$cur_"
2375 + __gitcomp "cmd path" "$pfx" "$cur_" "$sfx"
2376 return
2377 ;;
2378 mergetool.*.*)
2379 local pfx="${cur%.*}." cur_="${cur##*.}"
2365 - __gitcomp "cmd path trustExitCode" "$pfx" "$cur_"
2380 + __gitcomp "cmd path trustExitCode" "$pfx" "$cur_" "$sfx"
2381 return
2382 ;;
2383 pager.*)
2384 local pfx="${cur%.*}." cur_="${cur#*.}"
2385 __git_compute_all_commands
2371 - __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_"
2386 + __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_" "$sfx"
2387 return
2388 ;;
2389 remote.*.*)
@@ -2376,23 +2391,23 @@ __git_complete_config_variable_name ()
2391 __gitcomp "
2392 url proxy fetch push mirror skipDefaultUpdate
2393 receivepack uploadpack tagOpt pushurl
2379 - " "$pfx" "$cur_"
2394 + " "$pfx" "$cur_" "$sfx"
2395 return
2396 ;;
2397 remote.*)
2398 local pfx="${cur%.*}." cur_="${cur#*.}"
2399 __gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
2385 - __gitcomp_nl_append "pushDefault" "$pfx" "$cur_"
2400 + __gitcomp_nl_append "pushDefault" "$pfx" "$cur_" "$sfx"
2401 return
2402 ;;
2403 url.*.*)
2404 local pfx="${cur%.*}." cur_="${cur##*.}"
2390 - __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_"
2405 + __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_" "$sfx"
2406 return
2407 ;;
2408 *.*)
2409 __git_compute_config_vars
2395 - __gitcomp "$__git_config_vars"
2410 + __gitcomp "$__git_config_vars" "" "$cur" "$sfx"
2411 ;;
2412 *)
2413 __git_compute_config_vars
@@ -2409,6 +2424,20 @@ __git_complete_config_variable_name ()
2424 esac
2425 }
2426
2427 +# Completes '='-separated configuration sections/variable names and values
2428 +# for 'git -c section.name=value'.
2429 +__git_complete_config_variable_name_and_value ()
2430 +{
2431 + case "$cur" in
2432 + *=*)
2433 + # in the next patch...
2434 + ;;
2435 + *)
2436 + __git_complete_config_variable_name --sfx='='
2437 + ;;
2438 + esac
2439 +}
2440 +
2441 _git_config ()
2442 {
2443 case "$prev" in
@@ -2984,7 +3013,11 @@ __git_main ()
3013 # Bash filename completion
3014 return
3015 ;;
2987 - -c|--namespace)
3016 + -c)
3017 + __git_complete_config_variable_name_and_value
3018 + return
3019 + ;;
3020 + --namespace)
3021 # we don't support completing these options' arguments
3022 return
3023 ;;
t/t9902-completion.sh
+14
@@ -1719,6 +1719,20 @@ test_expect_success 'git config - value' '
1719 EOF
1720 '
1721
1722 +test_expect_success 'git -c - section' '
1723 + test_completion "git -c br" <<-\EOF
1724 + branch.Z
1725 + browser.Z
1726 + EOF
1727 +'
1728 +
1729 +test_expect_success 'git -c - variable name' '
1730 + test_completion "git -c log.d" <<-\EOF
1731 + log.date=Z
1732 + log.decorate=Z
1733 + EOF
1734 +'
1735 +
1736 test_expect_success 'sourcing the completion script clears cached commands' '
1737 __git_compute_all_commands &&
1738 verbose test -n "$__git_all_commands" &&