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@xxxxxxxxx> --- I think this is now ready for inclusion. The only change from PATCHv2 is that "-z" was changed to "-n" in the final test for ZSH_VERSION. Not sure if I should put this in the actual commit message myself, but PATCHv2 was: Reviewed-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> contrib/completion/git-completion.bash | 50 +++++++++++++++++++++++++++++-- 1 files changed, 46 insertions(+), 4 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 6756990..feab651 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -21,6 +21,11 @@ # 2) Added the following line to your .bashrc: # source ~/.git-completion.sh # +# Or, add the following lines to your .zshrc: +# autoload bashcompinit +# bashcompinit +# source ~/.git-completion.sh +# # 3) Consider changing your PS1 to also show the current branch: # PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' # @@ -138,11 +143,12 @@ __git_ps1_show_upstream () # get the upstream from the "git-svn-id: ..." in a commit message # (git-svn uses essentially the same procedure internally) local svn_upstream=($(git log --first-parent -1 \ - --grep="^git-svn-id: \(${svn_url_pattern:2}\)" 2>/dev/null)) + --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null)) if [[ 0 -ne ${#svn_upstream[@]} ]]; then svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]} svn_upstream=${svn_upstream%@*} - for ((n=1; "$n" <= "${#svn_remote[@]}"; ++n)); do + local n_stop="${#svn_remote[@]}" + for ((n=1; n <= n_stop; ++n)); do svn_upstream=${svn_upstream#${svn_remote[$n]}} done @@ -2339,6 +2345,11 @@ _git () { local i c=1 command __git_dir + if [[ -n $ZSH_VERSION ]]; then + emulate -L bash + setopt KSH_TYPESET + fi + while [ $c -lt $COMP_CWORD ]; do i="${COMP_WORDS[c]}" case "$i" in @@ -2372,17 +2383,22 @@ _git () fi local completion_func="_git_${command//-/_}" - declare -F $completion_func >/dev/null && $completion_func && return + declare -f $completion_func >/dev/null && $completion_func && return local expansion=$(__git_aliased_command "$command") if [ -n "$expansion" ]; then completion_func="_git_${expansion//-/_}" - declare -F $completion_func >/dev/null && $completion_func + declare -f $completion_func >/dev/null && $completion_func fi } _gitk () { + if [[ -n $ZSH_VERSION ]]; then + emulate -L bash + setopt KSH_TYPESET + fi + __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" @@ -2417,3 +2433,29 @@ if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \ || complete -o default -o nospace -F _git git.exe fi + +if [[ -n $ZSH_VERSION ]]; then + shopt () { + local option + if [ $# -ne 2 ]; then + echo "USAGE: $0 (-q|-s|-u) <option>" >&2 + return 1 + fi + case "$2" in + nullglob) + option="$2" + ;; + *) + echo "$0: invalid option: $2" >&2 + return 1 + esac + case "$1" in + -q) setopt | grep -q "$option" ;; + -u) unsetopt "$option" ;; + -s) setopt "$option" ;; + *) + echo "$0: invalid flag: $1" >&2 + return 1 + esac + } +fi -- 1.7.2.3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html