diff options
author | Junio C Hamano <gitster@pobox.com> | 2021-01-15 15:20:29 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2021-01-15 15:20:30 -0800 |
commit | f9fb9063fd792e3f50ae2cd0847c88d2df287068 (patch) | |
tree | 30890fbcdb81542309e29383230e223dd42c249d | |
parent | Merge branch 'en/stash-apply-sparse-checkout' (diff) | |
parent | completion: add proper public __git_complete (diff) | |
download | tgif-f9fb9063fd792e3f50ae2cd0847c88d2df287068.tar.xz |
Merge branch 'fc/completion-aliases-support'
Bash completion (in contrib/) update to make it easier for
end-users to add completion for their custom "git" subcommands.
* fc/completion-aliases-support:
completion: add proper public __git_complete
test: completion: add tests for __git_complete
completion: bash: improve function detection
completion: bash: add __git_have_func helper
-rw-r--r-- | contrib/completion/git-completion.bash | 50 | ||||
-rwxr-xr-x | t/t9902-completion.sh | 20 |
2 files changed, 60 insertions, 10 deletions
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 463a3124da..4b1f4264a6 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -29,6 +29,15 @@ # tell the completion to use commit completion. This also works with aliases # of form "!sh -c '...'". For example, "!sh -c ': git commit ; ... '". # +# If you have a command that is not part of git, but you would still +# like completion, you can use __git_complete: +# +# __git_complete gl git_log +# +# Or if it's a main command (i.e. git or gitk): +# +# __git_complete gk gitk +# # Compatible with bash 3.2.57. # # You can set the following environment variables to influence the behavior of @@ -3358,15 +3367,19 @@ __git_support_parseopt_helper () { esac } +__git_have_func () { + declare -f -- "$1" >/dev/null 2>&1 +} + __git_complete_command () { local command="$1" local completion_func="_git_${command//-/_}" - if ! declare -f $completion_func >/dev/null 2>/dev/null && - declare -f _completion_loader >/dev/null 2>/dev/null + if ! __git_have_func $completion_func && + __git_have_func _completion_loader then _completion_loader "git-$command" fi - if declare -f $completion_func >/dev/null 2>/dev/null + if __git_have_func $completion_func then $completion_func return 0 @@ -3493,10 +3506,7 @@ __git_func_wrap () $1 } -# Setup completion for certain functions defined above by setting common -# variables and workarounds. -# This is NOT a public function; use at your own risk. -__git_complete () +___git_complete () { local wrapper="__git_wrap${2}" eval "$wrapper () { __git_func_wrap $2 ; }" @@ -3504,13 +3514,33 @@ __git_complete () || complete -o default -o nospace -F $wrapper $1 } -__git_complete git __git_main -__git_complete gitk __gitk_main +# Setup the completion for git commands +# 1: command or alias +# 2: function to call (e.g. `git`, `gitk`, `git_fetch`) +__git_complete () +{ + local func + + if __git_have_func $2; then + func=$2 + elif __git_have_func __$2_main; then + func=__$2_main + elif __git_have_func _$2; then + func=_$2 + else + echo "ERROR: could not find function '$2'" 1>&2 + return 1 + fi + ___git_complete $1 $func +} + +___git_complete git __git_main +___git_complete gitk __gitk_main # The following are necessary only for Cygwin, and only are needed # when the user has tab-completed the executable name and consequently # included the '.exe' suffix. # if [ "$OSTYPE" = cygwin ]; then - __git_complete git.exe __git_main + ___git_complete git.exe __git_main fi diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index a1c4f1f6d4..c4a7758409 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -2380,4 +2380,24 @@ test_expect_success 'sourcing the completion script clears cached --options' ' verbose test -z "$__gitcomp_builtin_notes_edit" ' +test_expect_success '__git_complete' ' + unset -f __git_wrap__git_main && + + __git_complete foo __git_main && + __git_have_func __git_wrap__git_main && + unset -f __git_wrap__git_main && + + __git_complete gf _git_fetch && + __git_have_func __git_wrap_git_fetch && + + __git_complete foo git && + __git_have_func __git_wrap__git_main && + unset -f __git_wrap__git_main && + + __git_complete gd git_diff && + __git_have_func __git_wrap_git_diff && + + test_must_fail __git_complete ga missing +' + test_done |