Steffen Prohaska [off-list ref] writes:
'!f() { ... }; f' is a recommended pattern to declare more complex
aliases (see git wiki [1]). This commit teaches the completion to
handle them.
Hmm, I've never endorsed nor recommended such a notation myself ;-)
I tend to prefer writing it like so instead:
sh -c '...' -
so that I won't clobber "f" (or any other name). I wonder if you
can help users of this other pattern as well.
When determining which completion to use for an alias, the opening brace
is now ignored in order to continue the search for a git command inside
the function body. For example, the alias '!f() { git commit ... }' now
triggers commit completion.
I suspect that "scanning" is error-prone. I like this one for its
cuteness very much, though:
Furthermore, the null command ':' is now skipped, so that it can be used
as a workaround to declare the desired completion style. For example,
the alias '!f() { : git commit ; if ... ' now triggers commit
completion.
+test_expect_success 'completion uses <cmd> completion for alias !f() { VAR=val git <cmd> ... }' '
+ test_config alias.co "!f() { VAR=val git checkout ... ; } f" &&
Is it only "f" that is completed, or can I spell it using another
arbitrary token, e.g.
test_config alias.co "!co () { git checkout ... } co"
On Jun 10, 2014, at 7:27 AM, Junio C Hamano [off-list ref] wrote:
Steffen Prohaska [off-list ref] writes:
I tend to prefer writing it like so instead:
sh -c '...' -
so that I won't clobber "f" (or any other name). I wonder if you
can help users of this other pattern as well.
I'll send an updated patch that handles it.
quoted
+test_expect_success 'completion uses <cmd> completion for alias !f() { VAR=val git <cmd> ... }' '
+ test_config alias.co "!f() { VAR=val git checkout ... ; } f" &&
Is it only "f" that is completed, or can I spell it using another
arbitrary token, e.g.
test_config alias.co "!co () { git checkout ... } co"
Any token that starts with ! already worked before.
The updated patch will also handle spaces before the parens.
Steffen
'!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 ... ' and "!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 <redacted>
---
contrib/completion/git-completion.bash | 10 ++++++++++
t/t9902-completion.sh | 27 +++++++++++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 2c59a76..575f8f7 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -21,6 +21,12 @@
# source ~/.git-completion.sh
# 3) Consider changing your PS1 to also show the current branch,
# see git-prompt.sh for details.
+#
+# If you use complex aliases of form '!f() { ... }; f', you can use the null
+# command ':' as the first command in the function body to declare the desired
+# completion style. For example '!f() { : git commit ; ... }; f' will
+# tell the completion to use commit completion. This also works with aliases
+# of form "!sh -c '...'". For example, "!sh -c ': git commit ; ... '".
case "$COMP_WORDBREAKS" in
*:*) : great ;;@@ -781,6 +787,10 @@ __git_aliased_command ()
-*) : option ;;
*=*) : setting env ;;
git) : git itself ;;
+ \(\)) : skip parens of shell function definition ;;
+ {) : skip start of shell helper function ;;
+ :) : skip null command ;;
+ \'*) : skip opening quote after sh -c ;;
*)
echo "$word"
returndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 2d4beb5..1d1c106 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -550,6 +550,33 @@ test_expect_success 'complete files' '
test_completion "git add mom" "momified"
'
+test_expect_success "completion uses <cmd> completion for alias: !sh -c 'git <cmd> ...'" '
+ test_config alias.co "!sh -c '"'"'git checkout ...'"'"'" &&
+ test_completion "git co m" <<-\EOF
+ master Z
+ mybranch Z
+ mytag Z
+ EOF
+'
+
+test_expect_success 'completion uses <cmd> completion for alias: !f () { VAR=val git <cmd> ... }' '
+ test_config alias.co "!f () { VAR=val git checkout ... ; } f" &&
+ test_completion "git co m" <<-\EOF
+ master Z
+ mybranch Z
+ mytag Z
+ EOF
+'
+
+test_expect_success 'completion used <cmd> completion for alias: !f() { : git <cmd> ; ... }' '
+ test_config alias.co "!f() { : git checkout ; if ... } f" &&
+ test_completion "git co m" <<-\EOF
+ master Z
+ mybranch Z
+ mytag Z
+ EOF
+'
+
test_expect_failure 'complete with tilde expansion' '
git init tmp && cd tmp &&
test_when_finished "cd .. && rm -rf tmp" &&--
2.0.0.244.g4e8e734