From 3bee6a4733a1ff03b9cc659ea026c6dc17567d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZEDER=20G=C3=A1bor?= Date: Thu, 28 Apr 2011 18:01:53 +0200 Subject: completion: don't declare 'local words' to make zsh happy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "_get_comp_words_by_ref -n := words" command from the bash_completion library reassembles a modified version of COMP_WORDS with ':' and '=' no longer treated as word separators and stores it in the ${words[@]} array. Git's programmable tab completion script uses this to abstract away the difference between bash v3's and bash v4's definitions of COMP_WORDS (bash v3 used shell words, while bash v4 breaks at separator characters); see v1.7.4-rc0~11^2~2 (bash: get --pretty=m completion to work with bash v4, 2010-12-02). zsh has (or rather its completion functions have) another idea about what ${words[@]} should contain: the array is prepopulated with the words from the command it is completing. For reasons that are not well understood, when git-completion.bash reserves its own "words" variable with "local words", the variable becomes empty and cannot be changed from then on. So the completion script neglects the arguments it has seen, and words complete like git subcommand names. For example, typing "git log origi" gives no completions because there are no "git origi..." commands. However, when this words variable is not declared as local but is just populated by _get_comp_words_by_ref() and then read in various completion functions, then zsh seems to be happy about it and our completion script works as expected. So, to get our completion script working again under zsh and to prevent the words variable from leaking into the shell environment under bash, we will only declare words as local when using bash. Reported-by: Stefan Haller Suggested-by: Felipe Contreras Explained-by: Jonathan Nieder Signed-off-by: SZEDER Gábor Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'contrib/completion/git-completion.bash') diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 00691fcd82..10c1b83aa9 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -2608,9 +2608,11 @@ _git () if [[ -n ${ZSH_VERSION-} ]]; then emulate -L bash setopt KSH_TYPESET + else + local words fi - local cur words cword prev + local cur cword prev _get_comp_words_by_ref -n =: cur words cword prev while [ $c -lt $cword ]; do i="${words[c]}" @@ -2659,9 +2661,11 @@ _gitk () if [[ -n ${ZSH_VERSION-} ]]; then emulate -L bash setopt KSH_TYPESET + else + local words fi - local cur words cword prev + local cur cword prev _get_comp_words_by_ref -n =: cur words cword prev __git_has_doubledash && return -- cgit v1.2.3 From dad4277529b856bffe07760ac3928d06b5424fdc Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Wed, 27 Apr 2011 16:27:04 -0500 Subject: completion: move private shopt shim for zsh to __git_ namespace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most zsh users probably probably do not expect a custom shopt function to enter their environment just because they ran "source ~/.git-completion.sh". Such namespace pollution makes development of other scripts confusing (because it makes the bash-specific shopt utility seem to be available in zsh) and makes git's tab completion script brittle (since any other shell snippet implementing some other subset of shopt will break it). Rename the shopt shim to the more innocuous __git_shopt to be a good citizen (with two underscores to avoid confusion with completion rules for a hypothetical "git shopt" command). Signed-off-by: Jonathan Nieder Acked-by: SZEDER Gábor Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'contrib/completion/git-completion.bash') diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 10c1b83aa9..70897b3026 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -628,12 +628,12 @@ __git_refs_remotes () __git_remotes () { local i ngoff IFS=$'\n' d="$(__gitdir)" - shopt -q nullglob || ngoff=1 - shopt -s nullglob + __git_shopt -q nullglob || ngoff=1 + __git_shopt -s nullglob for i in "$d/remotes"/*; do echo ${i#$d/remotes/} done - [ "$ngoff" ] && shopt -u nullglob + [ "$ngoff" ] && __git_shopt -u nullglob for i in $(git --git-dir="$d" config --get-regexp 'remote\..*\.url' 2>/dev/null); do i="${i#remote.}" echo "${i/.url*/}" @@ -2703,7 +2703,7 @@ complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \ fi if [[ -n ${ZSH_VERSION-} ]]; then - shopt () { + __git_shopt () { local option if [ $# -ne 2 ]; then echo "USAGE: $0 (-q|-s|-u)