@matheusbsbs / matheus-bagliano / commits / 06f44c3cc5
Fork 0

completion: make compatible with zsh

Modify git-completion.bash so that it also works with zsh when using bashcompinit. In particular: declare -F Zsh doesn't have the same 'declare -F' as bash, but 'declare -f' is the same, and it works just as well for our purposes. ${var:2} Zsh does not implement ${var:2} to skip the first 2 characters, but ${var#??} works in both shells to replace the first 2 characters with nothing. Thanks to Jonathan Nieder for the suggestion. for (( n=1; "$n" ... )) Zsh does not allow "$var" in arithmetic loops. Instead, pre-compute the endpoint and use the variables without $'s or quotes. shopt Zsh uses 'setopt', which has a different syntax than 'shopt'. Since 'shopt' is used infrequently in git-completion, we provide a bare-bones emulation. emulate -L bash KSH_TYPESET Zsh offers bash emulation, which turns on a set of features to closely resemble bash. In particular, this enables SH_WORDSPLIT, which splits scalar variables on word boundaries in 'for' loops. We also need to set KSH_TYPESET, to fix "local var=$(echo foo bar)" issues. The last set of options are turned on only in _git and _gitk. Some of the sub-functions may not work correctly if called directly. Signed-off-by: Mark Lodato <lodatom@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Mark Lodato committed Sep 6, 2010 at 08:33 UTC 06f44c3cc5ca5eca638f300a518c65aa98d26d6d
1 file changed +46 -4
contrib/completion/git-completion.bash
+46 -4
@@ -21,6 +21,11 @@
21 # 2) Added the following line to your .bashrc:
22 # source ~/.git-completion.sh
23 #
24 +# Or, add the following lines to your .zshrc:
25 +# autoload bashcompinit
26 +# bashcompinit
27 +# source ~/.git-completion.sh
28 +#
29 # 3) Consider changing your PS1 to also show the current branch:
30 # PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
31 #
@@ -138,11 +143,12 @@ __git_ps1_show_upstream ()
143 # get the upstream from the "git-svn-id: ..." in a commit message
144 # (git-svn uses essentially the same procedure internally)
145 local svn_upstream=($(git log --first-parent -1 \
141 - --grep="^git-svn-id: \(${svn_url_pattern:2}\)" 2>/dev/null))
146 + --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null))
147 if [[ 0 -ne ${#svn_upstream[@]} ]]; then
148 svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]}
149 svn_upstream=${svn_upstream%@*}
145 - for ((n=1; "$n" <= "${#svn_remote[@]}"; ++n)); do
150 + local n_stop="${#svn_remote[@]}"
151 + for ((n=1; n <= n_stop; ++n)); do
152 svn_upstream=${svn_upstream#${svn_remote[$n]}}
153 done
154
@@ -2339,6 +2345,11 @@ _git ()
2345 {
2346 local i c=1 command __git_dir
2347
2348 + if [[ -n $ZSH_VERSION ]]; then
2349 + emulate -L bash
2350 + setopt KSH_TYPESET
2351 + fi
2352 +
2353 while [ $c -lt $COMP_CWORD ]; do
2354 i="${COMP_WORDS[c]}"
2355 case "$i" in
@@ -2372,17 +2383,22 @@ _git ()
2383 fi
2384
2385 local completion_func="_git_${command//-/_}"
2375 - declare -F $completion_func >/dev/null && $completion_func && return
2386 + declare -f $completion_func >/dev/null && $completion_func && return
2387
2388 local expansion=$(__git_aliased_command "$command")
2389 if [ -n "$expansion" ]; then
2390 completion_func="_git_${expansion//-/_}"
2380 - declare -F $completion_func >/dev/null && $completion_func
2391 + declare -f $completion_func >/dev/null && $completion_func
2392 fi
2393 }
2394
2395 _gitk ()
2396 {
2397 + if [[ -n $ZSH_VERSION ]]; then
2398 + emulate -L bash
2399 + setopt KSH_TYPESET
2400 + fi
2401 +
2402 __git_has_doubledash && return
2403
2404 local cur="${COMP_WORDS[COMP_CWORD]}"
@@ -2417,3 +2433,29 @@ if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
2433 complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \
2434 || complete -o default -o nospace -F _git git.exe
2435 fi
2436 +
2437 +if [[ -n $ZSH_VERSION ]]; then
2438 + shopt () {
2439 + local option
2440 + if [ $# -ne 2 ]; then
2441 + echo "USAGE: $0 (-q|-s|-u) <option>" >&2
2442 + return 1
2443 + fi
2444 + case "$2" in
2445 + nullglob)
2446 + option="$2"
2447 + ;;
2448 + *)
2449 + echo "$0: invalid option: $2" >&2
2450 + return 1
2451 + esac
2452 + case "$1" in
2453 + -q) setopt | grep -q "$option" ;;
2454 + -u) unsetopt "$option" ;;
2455 + -s) setopt "$option" ;;
2456 + *)
2457 + echo "$0: invalid flag: $1" >&2
2458 + return 1
2459 + esac
2460 + }
2461 +fi