Skip to content

Commit 56f24e8

Browse files
sprohaskagitster
authored andcommitted
completion: handle '!f() { ... }; f' and "!sh -c '...' -" aliases
'!f() { ... }; f' and "!sh -c '....' -" are recommended patterns for declaring more complex aliases (see git wiki [1]). This commit teaches the completion to handle them. When determining which completion to use for an alias, an opening brace or single quote is now skipped, and the search for a git command is continued. For example, the aliases '!f() { git commit ... }' or "!sh -c 'git commit ...'" now trigger commit completion. Previously, the search stopped on the opening brace or quote, and the completion tried it to determine how to complete, which obviously was useless. The null command ':' is now skipped, so that it can be used as a workaround to declare the desired completion style. For example, the aliases !f() { : git commit ; if ... } f !sh -c ': git commit; if ...' - now trigger commit completion. Shell function declarations now work with or without space before the parens, i.e. '!f() ...' and '!f () ...' both work. [1] https://git.wiki.kernel.org/index.php/Aliases Signed-off-by: Steffen Prohaska <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e156455 commit 56f24e8

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

contrib/completion/git-completion.bash

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121
# source ~/.git-completion.sh
2222
# 3) Consider changing your PS1 to also show the current branch,
2323
# see git-prompt.sh for details.
24+
#
25+
# If you use complex aliases of form '!f() { ... }; f', you can use the null
26+
# command ':' as the first command in the function body to declare the desired
27+
# completion style. For example '!f() { : git commit ; ... }; f' will
28+
# tell the completion to use commit completion. This also works with aliases
29+
# of form "!sh -c '...'". For example, "!sh -c ': git commit ; ... '".
2430

2531
case "$COMP_WORDBREAKS" in
2632
*:*) : great ;;
@@ -781,6 +787,10 @@ __git_aliased_command ()
781787
-*) : option ;;
782788
*=*) : setting env ;;
783789
git) : git itself ;;
790+
\(\)) : skip parens of shell function definition ;;
791+
{) : skip start of shell helper function ;;
792+
:) : skip null command ;;
793+
\'*) : skip opening quote after sh -c ;;
784794
*)
785795
echo "$word"
786796
return

t/t9902-completion.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,33 @@ test_expect_success 'complete files' '
550550
test_completion "git add mom" "momified"
551551
'
552552

553+
test_expect_success "completion uses <cmd> completion for alias: !sh -c 'git <cmd> ...'" '
554+
test_config alias.co "!sh -c '"'"'git checkout ...'"'"'" &&
555+
test_completion "git co m" <<-\EOF
556+
master Z
557+
mybranch Z
558+
mytag Z
559+
EOF
560+
'
561+
562+
test_expect_success 'completion uses <cmd> completion for alias: !f () { VAR=val git <cmd> ... }' '
563+
test_config alias.co "!f () { VAR=val git checkout ... ; } f" &&
564+
test_completion "git co m" <<-\EOF
565+
master Z
566+
mybranch Z
567+
mytag Z
568+
EOF
569+
'
570+
571+
test_expect_success 'completion used <cmd> completion for alias: !f() { : git <cmd> ; ... }' '
572+
test_config alias.co "!f() { : git checkout ; if ... } f" &&
573+
test_completion "git co m" <<-\EOF
574+
master Z
575+
mybranch Z
576+
mytag Z
577+
EOF
578+
'
579+
553580
test_expect_failure 'complete with tilde expansion' '
554581
git init tmp && cd tmp &&
555582
test_when_finished "cd .. && rm -rf tmp" &&

0 commit comments

Comments
 (0)