Merge branch 'fc/completion'

In addition to a user visible change to offer more options to cherry-pick,
generally cleans up and simplifies the code.

* fc/completion:
  completion: small optimization
  completion: inline __gitcomp_1 to its sole callsite
  completion: get rid of compgen
  completion: add __gitcomp_nl tests
  completion: add new __gitcompadd helper
  completion: get rid of empty COMPREPLY assignments
  completion: trivial test improvement
  completion: add more cherry-pick options
This commit is contained in:
Junio C Hamano 2013-04-18 11:46:41 -07:00
commit 5734fa4608
2 changed files with 96 additions and 47 deletions

View File

@ -53,19 +53,6 @@ __gitdir ()
fi fi
} }
__gitcomp_1 ()
{
local c IFS=$' \t\n'
for c in $1; do
c="$c$2"
case $c in
--*=*|*.) ;;
*) c="$c " ;;
esac
printf '%s\n' "$c"
done
}
# The following function is based on code from: # The following function is based on code from:
# #
# bash_completion - programmable completion functions for bash 3.2+ # bash_completion - programmable completion functions for bash 3.2+
@ -195,8 +182,18 @@ _get_comp_words_by_ref ()
} }
fi fi
# Generates completion reply with compgen, appending a space to possible __gitcompadd ()
# completion words, if necessary. {
local i=0
for x in $1; do
if [[ "$x" == "$3"* ]]; then
COMPREPLY[i++]="$2$x$4"
fi
done
}
# Generates completion reply, appending a space to possible completion words,
# if necessary.
# It accepts 1 to 4 arguments: # It accepts 1 to 4 arguments:
# 1: List of possible completion words. # 1: List of possible completion words.
# 2: A prefix to be added to each possible completion word (optional). # 2: A prefix to be added to each possible completion word (optional).
@ -208,19 +205,25 @@ __gitcomp ()
case "$cur_" in case "$cur_" in
--*=) --*=)
COMPREPLY=()
;; ;;
*) *)
local IFS=$'\n' local c i=0 IFS=$' \t\n'
COMPREPLY=($(compgen -P "${2-}" \ for c in $1; do
-W "$(__gitcomp_1 "${1-}" "${4-}")" \ c="$c${4-}"
-- "$cur_")) if [[ $c == "$cur_"* ]]; then
case $c in
--*=*|*.) ;;
*) c="$c " ;;
esac
COMPREPLY[i++]="${2-}$c"
fi
done
;; ;;
esac esac
} }
# Generates completion reply with compgen from newline-separated possible # Generates completion reply from newline-separated possible completion words
# completion words by appending a space to all of them. # by appending a space to all of them.
# It accepts 1 to 4 arguments: # It accepts 1 to 4 arguments:
# 1: List of possible completion words, separated by a single newline. # 1: List of possible completion words, separated by a single newline.
# 2: A prefix to be added to each possible completion word (optional). # 2: A prefix to be added to each possible completion word (optional).
@ -231,7 +234,7 @@ __gitcomp ()
__gitcomp_nl () __gitcomp_nl ()
{ {
local IFS=$'\n' local IFS=$'\n'
COMPREPLY=($(compgen -P "${2-}" -S "${4- }" -W "$1" -- "${3-$cur}")) __gitcompadd "$1" "${2-}" "${3-$cur}" "${4- }"
} }
# Generates completion reply with compgen from newline-separated possible # Generates completion reply with compgen from newline-separated possible
@ -614,7 +617,6 @@ __git_complete_remote_or_refspec ()
case "$cmd" in case "$cmd" in
push) no_complete_refspec=1 ;; push) no_complete_refspec=1 ;;
fetch) fetch)
COMPREPLY=()
return return
;; ;;
*) ;; *) ;;
@ -630,7 +632,6 @@ __git_complete_remote_or_refspec ()
return return
fi fi
if [ $no_complete_refspec = 1 ]; then if [ $no_complete_refspec = 1 ]; then
COMPREPLY=()
return return
fi fi
[ "$remote" = "." ] && remote= [ "$remote" = "." ] && remote=
@ -951,7 +952,6 @@ _git_am ()
" "
return return
esac esac
COMPREPLY=()
} }
_git_apply () _git_apply ()
@ -971,7 +971,6 @@ _git_apply ()
" "
return return
esac esac
COMPREPLY=()
} }
_git_add () _git_add ()
@ -1031,7 +1030,6 @@ _git_bisect ()
__gitcomp_nl "$(__git_refs)" __gitcomp_nl "$(__git_refs)"
;; ;;
*) *)
COMPREPLY=()
;; ;;
esac esac
} }
@ -1124,9 +1122,14 @@ _git_cherry ()
_git_cherry_pick () _git_cherry_pick ()
{ {
local dir="$(__gitdir)"
if [ -f "$dir"/CHERRY_PICK_HEAD ]; then
__gitcomp "--continue --quit --abort"
return
fi
case "$cur" in case "$cur" in
--*) --*)
__gitcomp "--edit --no-commit" __gitcomp "--edit --no-commit --signoff --strategy= --mainline"
;; ;;
*) *)
__gitcomp_nl "$(__git_refs)" __gitcomp_nl "$(__git_refs)"
@ -1170,7 +1173,6 @@ _git_clone ()
return return
;; ;;
esac esac
COMPREPLY=()
} }
_git_commit () _git_commit ()
@ -1354,7 +1356,6 @@ _git_fsck ()
return return
;; ;;
esac esac
COMPREPLY=()
} }
_git_gc () _git_gc ()
@ -1365,7 +1366,6 @@ _git_gc ()
return return
;; ;;
esac esac
COMPREPLY=()
} }
_git_gitk () _git_gitk ()
@ -1442,7 +1442,6 @@ _git_init ()
return return
;; ;;
esac esac
COMPREPLY=()
} }
_git_ls_files () _git_ls_files ()
@ -1578,7 +1577,6 @@ _git_mergetool ()
return return
;; ;;
esac esac
COMPREPLY=()
} }
_git_merge_base () _git_merge_base ()
@ -1831,7 +1829,7 @@ _git_config ()
local remote="${prev#remote.}" local remote="${prev#remote.}"
remote="${remote%.fetch}" remote="${remote%.fetch}"
if [ -z "$cur" ]; then if [ -z "$cur" ]; then
COMPREPLY=("refs/heads/") __gitcompadd "refs/heads/" "" "" ""
return return
fi fi
__gitcomp_nl "$(__git_refs_remotes "$remote")" __gitcomp_nl "$(__git_refs_remotes "$remote")"
@ -1891,7 +1889,6 @@ _git_config ()
return return
;; ;;
*.*) *.*)
COMPREPLY=()
return return
;; ;;
esac esac
@ -2272,7 +2269,6 @@ _git_remote ()
__gitcomp "$c" __gitcomp "$c"
;; ;;
*) *)
COMPREPLY=()
;; ;;
esac esac
} }
@ -2388,8 +2384,6 @@ _git_stash ()
*) *)
if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then
__gitcomp "$subcommands" __gitcomp "$subcommands"
else
COMPREPLY=()
fi fi
;; ;;
esac esac
@ -2402,14 +2396,12 @@ _git_stash ()
__gitcomp "--index --quiet" __gitcomp "--index --quiet"
;; ;;
show,--*|drop,--*|branch,--*) show,--*|drop,--*|branch,--*)
COMPREPLY=()
;; ;;
show,*|apply,*|drop,*|pop,*|branch,*) show,*|apply,*|drop,*|pop,*|branch,*)
__gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \ __gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \
| sed -n -e 's/:.*//p')" | sed -n -e 's/:.*//p')"
;; ;;
*) *)
COMPREPLY=()
;; ;;
esac esac
fi fi
@ -2526,7 +2518,6 @@ _git_svn ()
__gitcomp "--revision= --parent" __gitcomp "--revision= --parent"
;; ;;
*) *)
COMPREPLY=()
;; ;;
esac esac
fi fi
@ -2551,13 +2542,10 @@ _git_tag ()
case "$prev" in case "$prev" in
-m|-F) -m|-F)
COMPREPLY=()
;; ;;
-*|tag) -*|tag)
if [ $f = 1 ]; then if [ $f = 1 ]; then
__gitcomp_nl "$(__git_tags)" __gitcomp_nl "$(__git_tags)"
else
COMPREPLY=()
fi fi
;; ;;
*) *)

View File

@ -69,6 +69,7 @@ run_completion ()
local -a COMPREPLY _words local -a COMPREPLY _words
local _cword local _cword
_words=( $1 ) _words=( $1 )
test "${1: -1}" == ' ' && _words+=('')
(( _cword = ${#_words[@]} - 1 )) (( _cword = ${#_words[@]} - 1 ))
__git_wrap__git_main && print_comp __git_wrap__git_main && print_comp
} }
@ -104,6 +105,23 @@ test_gitcomp ()
test_cmp expected out test_cmp expected out
} }
# Test __gitcomp_nl
# Arguments are:
# 1: current word (cur)
# -: the rest are passed to __gitcomp_nl
test_gitcomp_nl ()
{
local -a COMPREPLY &&
sed -e 's/Z$//' >expected &&
cur="$1" &&
shift &&
__gitcomp_nl "$@" &&
print_comp &&
test_cmp expected out
}
invalid_variable_name='${foo.bar}'
test_expect_success '__gitcomp - trailing space - options' ' test_expect_success '__gitcomp - trailing space - options' '
test_gitcomp "--re" "--dry-run --reuse-message= --reedit-message= test_gitcomp "--re" "--dry-run --reuse-message= --reedit-message=
--reset-author" <<-EOF --reset-author" <<-EOF
@ -147,8 +165,51 @@ test_expect_success '__gitcomp - suffix' '
EOF EOF
' '
test_expect_success '__gitcomp - doesnt fail because of invalid variable name' '
__gitcomp "$invalid_variable_name"
'
read -r -d "" refs <<-\EOF
maint
master
next
pu
EOF
test_expect_success '__gitcomp_nl - trailing space' '
test_gitcomp_nl "m" "$refs" <<-EOF
maint Z
master Z
EOF
'
test_expect_success '__gitcomp_nl - prefix' '
test_gitcomp_nl "--fixup=m" "$refs" "--fixup=" "m" <<-EOF
--fixup=maint Z
--fixup=master Z
EOF
'
test_expect_success '__gitcomp_nl - suffix' '
test_gitcomp_nl "branch.ma" "$refs" "branch." "ma" "." <<-\EOF
branch.maint.Z
branch.master.Z
EOF
'
test_expect_success '__gitcomp_nl - no suffix' '
test_gitcomp_nl "ma" "$refs" "" "ma" "" <<-\EOF
maintZ
masterZ
EOF
'
test_expect_success '__gitcomp_nl - doesnt fail because of invalid variable name' '
__gitcomp_nl "$invalid_variable_name"
'
test_expect_success 'basic' ' test_expect_success 'basic' '
run_completion "git \"\"" && run_completion "git " &&
# built-in # built-in
grep -q "^add \$" out && grep -q "^add \$" out &&
# script # script
@ -271,7 +332,7 @@ test_expect_success 'complete tree filename with spaces' '
EOF EOF
' '
test_expect_failure 'complete tree filename with metacharacters' ' test_expect_success 'complete tree filename with metacharacters' '
echo content >"name with \${meta}" && echo content >"name with \${meta}" &&
git add . && git add . &&
git commit -m meta && git commit -m meta &&