Browse Source

bash: Support unique completion when possible.

Because our use of -o nospace prevents bash from adding a trailing space
when a completion is unique and has been fully completed, we need to
perform this addition on our own.  This (large) change converts all
existing uses of compgen to our wrapper __gitcomp which attempts to
handle this by tacking a trailing space onto the end of each offered
option.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
maint
Shawn O. Pearce 18 years ago committed by Junio C Hamano
parent
commit
b3391775e8
  1. 190
      contrib/completion/git-completion.bash

190
contrib/completion/git-completion.bash

@ -65,7 +65,7 @@ __gitcomp ()
{ {
local all c s=$'\n' IFS=' '$'\t'$'\n' local all c s=$'\n' IFS=' '$'\t'$'\n'
local cur="${COMP_WORDS[COMP_CWORD]}" local cur="${COMP_WORDS[COMP_CWORD]}"
if [ -n "$2" ]; then if [ $# -gt 2 ]; then
cur="$3" cur="$3"
fi fi
for c in $1; do for c in $1; do
@ -219,7 +219,7 @@ __git_complete_file ()
-- "$cur")) -- "$cur"))
;; ;;
*) *)
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) __gitcomp "$(__git_refs)"
;; ;;
esac esac
} }
@ -231,15 +231,18 @@ __git_complete_revlist ()
*...*) *...*)
pfx="${cur%...*}..." pfx="${cur%...*}..."
cur="${cur#*...}" cur="${cur#*...}"
COMPREPLY=($(compgen -P "$pfx" -W "$(__git_refs)" -- "$cur")) __gitcomp "$(__git_refs)" "$pfx" "$cur"
;; ;;
*..*) *..*)
pfx="${cur%..*}.." pfx="${cur%..*}.."
cur="${cur#*..}" cur="${cur#*..}"
COMPREPLY=($(compgen -P "$pfx" -W "$(__git_refs)" -- "$cur")) __gitcomp "$(__git_refs)" "$pfx" "$cur"
;;
*.)
__gitcomp "$cur."
;; ;;
*) *)
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) __gitcomp "$(__git_refs)"
;; ;;
esac esac
} }
@ -353,22 +356,19 @@ _git_am ()
{ {
local cur="${COMP_WORDS[COMP_CWORD]}" local cur="${COMP_WORDS[COMP_CWORD]}"
if [ -d .dotest ]; then if [ -d .dotest ]; then
COMPREPLY=($(compgen -W " __gitcomp "--skip --resolved"
--skip --resolved
" -- "$cur"))
return return
fi fi
case "$cur" in case "$cur" in
--whitespace=*) --whitespace=*)
COMPREPLY=($(compgen -W "$__git_whitespacelist" \ __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
-- "${cur##--whitespace=}"))
return return
;; ;;
--*) --*)
COMPREPLY=($(compgen -W " __gitcomp "
--signoff --utf8 --binary --3way --interactive --signoff --utf8 --binary --3way --interactive
--whitespace= --whitespace=
" -- "$cur")) "
return return
esac esac
COMPREPLY=() COMPREPLY=()
@ -379,17 +379,16 @@ _git_apply ()
local cur="${COMP_WORDS[COMP_CWORD]}" local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in case "$cur" in
--whitespace=*) --whitespace=*)
COMPREPLY=($(compgen -W "$__git_whitespacelist" \ __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
-- "${cur##--whitespace=}"))
return return
;; ;;
--*) --*)
COMPREPLY=($(compgen -W " __gitcomp "
--stat --numstat --summary --check --index --stat --numstat --summary --check --index
--cached --index-info --reverse --reject --unidiff-zero --cached --index-info --reverse --reject --unidiff-zero
--apply --no-add --exclude= --apply --no-add --exclude=
--whitespace= --inaccurate-eof --verbose --whitespace= --inaccurate-eof --verbose
" -- "$cur")) "
return return
esac esac
COMPREPLY=() COMPREPLY=()
@ -400,9 +399,7 @@ _git_add ()
local cur="${COMP_WORDS[COMP_CWORD]}" local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in case "$cur" in
--*) --*)
COMPREPLY=($(compgen -W " __gitcomp "--interactive"
--interactive
" -- "$cur"))
return return
esac esac
COMPREPLY=() COMPREPLY=()
@ -410,14 +407,12 @@ _git_add ()


_git_branch () _git_branch ()
{ {
local cur="${COMP_WORDS[COMP_CWORD]}" __gitcomp "$(__git_refs)"
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
} }


_git_checkout () _git_checkout ()
{ {
local cur="${COMP_WORDS[COMP_CWORD]}" __gitcomp "$(__git_refs)"
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
} }


_git_cherry_pick () _git_cherry_pick ()
@ -425,12 +420,10 @@ _git_cherry_pick ()
local cur="${COMP_WORDS[COMP_CWORD]}" local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in case "$cur" in
--*) --*)
COMPREPLY=($(compgen -W " __gitcomp "--edit --no-commit"
--edit --no-commit
" -- "$cur"))
;; ;;
*) *)
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) __gitcomp "$(__git_refs)"
;; ;;
esac esac
} }
@ -440,10 +433,10 @@ _git_commit ()
local cur="${COMP_WORDS[COMP_CWORD]}" local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in case "$cur" in
--*) --*)
COMPREPLY=($(compgen -W " __gitcomp "
--all --author= --signoff --verify --no-verify --all --author= --signoff --verify --no-verify
--edit --amend --include --only --edit --amend --include --only
" -- "$cur")) "
return return
esac esac
COMPREPLY=() COMPREPLY=()
@ -456,8 +449,7 @@ _git_diff ()


_git_diff_tree () _git_diff_tree ()
{ {
local cur="${COMP_WORDS[COMP_CWORD]}" __gitcomp "$(__git_refs)"
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
} }


_git_fetch () _git_fetch ()
@ -466,16 +458,15 @@ _git_fetch ()


case "${COMP_WORDS[0]},$COMP_CWORD" in case "${COMP_WORDS[0]},$COMP_CWORD" in
git-fetch*,1) git-fetch*,1)
COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur")) __gitcomp "$(__git_remotes)"
;; ;;
git,2) git,2)
COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur")) __gitcomp "$(__git_remotes)"
;; ;;
*) *)
case "$cur" in case "$cur" in
*:*) *:*)
cur="${cur#*:}" __gitcomp "$(__git_refs)" "" "${cur#*:}"
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
;; ;;
*) *)
local remote local remote
@ -483,7 +474,7 @@ _git_fetch ()
git-fetch) remote="${COMP_WORDS[1]}" ;; git-fetch) remote="${COMP_WORDS[1]}" ;;
git) remote="${COMP_WORDS[2]}" ;; git) remote="${COMP_WORDS[2]}" ;;
esac esac
COMPREPLY=($(compgen -W "$(__git_refs2 "$remote")" -- "$cur")) __gitcomp "$(__git_refs2 "$remote")"
;; ;;
esac esac
;; ;;
@ -495,7 +486,7 @@ _git_format_patch ()
local cur="${COMP_WORDS[COMP_CWORD]}" local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in case "$cur" in
--*) --*)
COMPREPLY=($(compgen -W " __gitcomp "
--stdout --attach --thread --stdout --attach --thread
--output-directory --output-directory
--numbered --start-number --numbered --start-number
@ -503,7 +494,7 @@ _git_format_patch ()
--signoff --signoff
--in-reply-to= --in-reply-to=
--full-index --binary --full-index --binary
" -- "$cur")) "
return return
;; ;;
esac esac
@ -512,8 +503,7 @@ _git_format_patch ()


_git_ls_remote () _git_ls_remote ()
{ {
local cur="${COMP_WORDS[COMP_CWORD]}" __gitcomp "$(__git_remotes)"
COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
} }


_git_ls_tree () _git_ls_tree ()
@ -526,13 +516,13 @@ _git_log ()
local cur="${COMP_WORDS[COMP_CWORD]}" local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in case "$cur" in
--pretty=*) --pretty=*)
COMPREPLY=($(compgen -W " __gitcomp "
oneline short medium full fuller email raw oneline short medium full fuller email raw
" -- "${cur##--pretty=}")) " "" "${cur##--pretty=}"
return return
;; ;;
--*) --*)
COMPREPLY=($(compgen -W " __gitcomp "
--max-count= --max-age= --since= --after= --max-count= --max-age= --since= --after=
--min-age= --before= --until= --min-age= --before= --until=
--root --not --topo-order --date-order --root --not --topo-order --date-order
@ -542,7 +532,7 @@ _git_log ()
--author= --committer= --grep= --author= --committer= --grep=
--all-match --all-match
--pretty= --name-status --name-only --pretty= --name-status --name-only
" -- "$cur")) "
return return
;; ;;
esac esac
@ -554,34 +544,31 @@ _git_merge ()
local cur="${COMP_WORDS[COMP_CWORD]}" local cur="${COMP_WORDS[COMP_CWORD]}"
case "${COMP_WORDS[COMP_CWORD-1]}" in case "${COMP_WORDS[COMP_CWORD-1]}" in
-s|--strategy) -s|--strategy)
COMPREPLY=($(compgen -W "$(__git_merge_strategies)" -- "$cur")) __gitcomp "$(__git_merge_strategies)"
return return
esac esac
case "$cur" in case "$cur" in
--strategy=*) --strategy=*)
COMPREPLY=($(compgen -W "$(__git_merge_strategies)" \ __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
-- "${cur##--strategy=}"))
return return
;; ;;
--*) --*)
COMPREPLY=($(compgen -W " __gitcomp "
--no-commit --no-summary --squash --strategy --no-commit --no-summary --squash --strategy
" -- "$cur")) "
return return
esac esac
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) __gitcomp "$(__git_refs)"
} }


_git_merge_base () _git_merge_base ()
{ {
local cur="${COMP_WORDS[COMP_CWORD]}" __gitcomp "$(__git_refs)"
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
} }


_git_name_rev () _git_name_rev ()
{ {
local cur="${COMP_WORDS[COMP_CWORD]}" __gitcomp "--tags --all --stdin"
COMPREPLY=($(compgen -W "--tags --all --stdin" -- "$cur"))
} }


_git_pull () _git_pull ()
@ -590,10 +577,10 @@ _git_pull ()


case "${COMP_WORDS[0]},$COMP_CWORD" in case "${COMP_WORDS[0]},$COMP_CWORD" in
git-pull*,1) git-pull*,1)
COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur")) __gitcomp "$(__git_remotes)"
;; ;;
git,2) git,2)
COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur")) __gitcomp "$(__git_remotes)"
;; ;;
*) *)
local remote local remote
@ -601,7 +588,7 @@ _git_pull ()
git-pull) remote="${COMP_WORDS[1]}" ;; git-pull) remote="${COMP_WORDS[1]}" ;;
git) remote="${COMP_WORDS[2]}" ;; git) remote="${COMP_WORDS[2]}" ;;
esac esac
COMPREPLY=($(compgen -W "$(__git_refs "$remote")" -- "$cur")) __gitcomp "$(__git_refs "$remote")"
;; ;;
esac esac
} }
@ -612,10 +599,10 @@ _git_push ()


case "${COMP_WORDS[0]},$COMP_CWORD" in case "${COMP_WORDS[0]},$COMP_CWORD" in
git-push*,1) git-push*,1)
COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur")) __gitcomp "$(__git_remotes)"
;; ;;
git,2) git,2)
COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur")) __gitcomp "$(__git_remotes)"
;; ;;
*) *)
case "$cur" in case "$cur" in
@ -625,11 +612,10 @@ _git_push ()
git-push) remote="${COMP_WORDS[1]}" ;; git-push) remote="${COMP_WORDS[1]}" ;;
git) remote="${COMP_WORDS[2]}" ;; git) remote="${COMP_WORDS[2]}" ;;
esac esac
cur="${cur#*:}" __gitcomp "$(__git_refs "$remote")" "" "${cur#*:}"
COMPREPLY=($(compgen -W "$(__git_refs "$remote")" -- "$cur"))
;; ;;
*) *)
COMPREPLY=($(compgen -W "$(__git_refs2)" -- "$cur")) __gitcomp "$(__git_refs2)"
;; ;;
esac esac
;; ;;
@ -640,29 +626,24 @@ _git_rebase ()
{ {
local cur="${COMP_WORDS[COMP_CWORD]}" local cur="${COMP_WORDS[COMP_CWORD]}"
if [ -d .dotest ]; then if [ -d .dotest ]; then
COMPREPLY=($(compgen -W " __gitcomp "--continue --skip --abort"
--continue --skip --abort
" -- "$cur"))
return return
fi fi
case "${COMP_WORDS[COMP_CWORD-1]}" in case "${COMP_WORDS[COMP_CWORD-1]}" in
-s|--strategy) -s|--strategy)
COMPREPLY=($(compgen -W "$(__git_merge_strategies)" -- "$cur")) __gitcomp "$(__git_merge_strategies)"
return return
esac esac
case "$cur" in case "$cur" in
--strategy=*) --strategy=*)
COMPREPLY=($(compgen -W "$(__git_merge_strategies)" \ __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
-- "${cur##--strategy=}"))
return return
;; ;;
--*) --*)
COMPREPLY=($(compgen -W " __gitcomp "--onto --merge --strategy"
--onto --merge --strategy
" -- "$cur"))
return return
esac esac
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) __gitcomp "$(__git_refs)"
} }


_git_config () _git_config ()
@ -824,8 +805,13 @@ _git_config ()
_git_reset () _git_reset ()
{ {
local cur="${COMP_WORDS[COMP_CWORD]}" local cur="${COMP_WORDS[COMP_CWORD]}"
local opt="--mixed --hard --soft" case "$cur" in
COMPREPLY=($(compgen -W "$opt $(__git_refs)" -- "$cur")) --*)
__gitcomp "--mixed --hard --soft"
return
;;
esac
__gitcomp "$(__git_refs)"
} }


_git_show () _git_show ()
@ -833,13 +819,13 @@ _git_show ()
local cur="${COMP_WORDS[COMP_CWORD]}" local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in case "$cur" in
--pretty=*) --pretty=*)
COMPREPLY=($(compgen -W " __gitcomp "
oneline short medium full fuller email raw oneline short medium full fuller email raw
" -- "${cur##--pretty=}")) " "" "${cur##--pretty=}"
return return
;; ;;
--*) --*)
COMPREPLY=($(compgen -W "--pretty=" -- "$cur")) __gitcomp "--pretty="
return return
;; ;;
esac esac
@ -906,32 +892,38 @@ _git ()
_gitk () _gitk ()
{ {
local cur="${COMP_WORDS[COMP_CWORD]}" local cur="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY=($(compgen -W "--all $(__git_refs)" -- "$cur")) case "$cur" in
--*)
__gitcomp "--not --all"
return
;;
esac
__gitcomp "$(__git_refs)"
} }


complete -o default -o nospace -F _git git complete -o default -o nospace -F _git git
complete -o default -F _gitk gitk complete -o default -o nospace -F _gitk gitk
complete -o default -F _git_am git-am complete -o default -o nospace -F _git_am git-am
complete -o default -F _git_apply git-apply complete -o default -o nospace -F _git_apply git-apply
complete -o default -F _git_branch git-branch complete -o default -o nospace -F _git_branch git-branch
complete -o default -F _git_checkout git-checkout complete -o default -o nospace -F _git_checkout git-checkout
complete -o default -F _git_cherry_pick git-cherry-pick complete -o default -o nospace -F _git_cherry_pick git-cherry-pick
complete -o default -F _git_commit git-commit complete -o default -o nospace -F _git_commit git-commit
complete -o default -o nospace -F _git_diff git-diff complete -o default -o nospace -F _git_diff git-diff
complete -o default -F _git_diff_tree git-diff-tree complete -o default -o nospace -F _git_diff_tree git-diff-tree
complete -o default -o nospace -F _git_fetch git-fetch complete -o default -o nospace -F _git_fetch git-fetch
complete -o default -o nospace -F _git_format_patch git-format-patch complete -o default -o nospace -F _git_format_patch git-format-patch
complete -o default -o nospace -F _git_log git-log complete -o default -o nospace -F _git_log git-log
complete -o default -F _git_ls_remote git-ls-remote complete -o default -o nospace -F _git_ls_remote git-ls-remote
complete -o default -o nospace -F _git_ls_tree git-ls-tree complete -o default -o nospace -F _git_ls_tree git-ls-tree
complete -o default -F _git_merge git-merge complete -o default -o nospace -F _git_merge git-merge
complete -o default -F _git_merge_base git-merge-base complete -o default -o nospace -F _git_merge_base git-merge-base
complete -o default -F _git_name_rev git-name-rev complete -o default -o nospace -F _git_name_rev git-name-rev
complete -o default -o nospace -F _git_pull git-pull complete -o default -o nospace -F _git_pull git-pull
complete -o default -o nospace -F _git_push git-push complete -o default -o nospace -F _git_push git-push
complete -o default -F _git_rebase git-rebase complete -o default -o nospace -F _git_rebase git-rebase
complete -o default -F _git_config git-config complete -o default -o nospace -F _git_config git-config
complete -o default -F _git_reset git-reset complete -o default -o nospace -F _git_reset git-reset
complete -o default -o nospace -F _git_show git-show complete -o default -o nospace -F _git_show git-show
complete -o default -o nospace -F _git_log git-show-branch complete -o default -o nospace -F _git_log git-show-branch
complete -o default -o nospace -F _git_log git-whatchanged complete -o default -o nospace -F _git_log git-whatchanged
@ -941,19 +933,19 @@ complete -o default -o nospace -F _git_log git-whatchanged
# included the '.exe' suffix. # included the '.exe' suffix.
# #
if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
complete -o default -F _git_add git-add.exe complete -o default -o nospace -F _git_add git-add.exe
complete -o default -F _git_apply git-apply.exe complete -o default -o nospace -F _git_apply git-apply.exe
complete -o default -o nospace -F _git git.exe complete -o default -o nospace -F _git git.exe
complete -o default -F _git_branch git-branch.exe complete -o default -o nospace -F _git_branch git-branch.exe
complete -o default -o nospace -F _git_diff git-diff.exe complete -o default -o nospace -F _git_diff git-diff.exe
complete -o default -o nospace -F _git_diff_tree git-diff-tree.exe complete -o default -o nospace -F _git_diff_tree git-diff-tree.exe
complete -o default -o nospace -F _git_format_patch git-format-patch.exe complete -o default -o nospace -F _git_format_patch git-format-patch.exe
complete -o default -o nospace -F _git_log git-log.exe complete -o default -o nospace -F _git_log git-log.exe
complete -o default -o nospace -F _git_ls_tree git-ls-tree.exe complete -o default -o nospace -F _git_ls_tree git-ls-tree.exe
complete -o default -F _git_merge_base git-merge-base.exe complete -o default -o nospace -F _git_merge_base git-merge-base.exe
complete -o default -F _git_name_rev git-name-rev.exe complete -o default -o nospace -F _git_name_rev git-name-rev.exe
complete -o default -o nospace -F _git_push git-push.exe complete -o default -o nospace -F _git_push git-push.exe
complete -o default -F _git_config git-config complete -o default -o nospace -F _git_config git-config
complete -o default -o nospace -F _git_show git-show.exe complete -o default -o nospace -F _git_show git-show.exe
complete -o default -o nospace -F _git_log git-show-branch.exe complete -o default -o nospace -F _git_log git-show-branch.exe
complete -o default -o nospace -F _git_log git-whatchanged.exe complete -o default -o nospace -F _git_log git-whatchanged.exe

Loading…
Cancel
Save