# [PATCH v6 0/2] New zsh wrapper

5 messages from 2012-11-18 to 2012-11-19. Participants: Felipe Contreras, Junio C Hamano.
Thread: https://gitlist.dev/t/32141

## Felipe Contreras, 2012-11-18 11:08

Subject: [PATCH v6 0/2] New zsh wrapper
Message-ID: <1353236889-15052-1-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1353236889-15052-1-git-send-email-felipe.contreras%40gmail.com

```
Hi,

It looks like there's some resistance with the other patches this series was
depending upon, so lets get rid of them, they are not really needed.

This version should be ready to merge.

The second patch is new, in order for users to get the same features when
sourcing the bash script (they don't need to change anything). They'll get a
warning suggesting to check the new script git-completion.zsh. Eventually, that
support would be dropped from the bash script.

Some people were suggesting something like this, so here it is.

Can we merge the zsh wrapper now?

Felipe Contreras (2):
  completion: add new zsh completion
  completion: start moving to the new zsh completion

 contrib/completion/git-completion.bash | 104 +++++++++++++++++++--------------
 contrib/completion/git-completion.zsh  |  78 +++++++++++++++++++++++++
 2 files changed, 139 insertions(+), 43 deletions(-)
 create mode 100644 contrib/completion/git-completion.zsh

-- 
1.8.0

```

## Felipe Contreras, 2012-11-18 11:08

Subject: [PATCH v6 1/2] completion: add new zsh completion
Message-ID: <1353236889-15052-2-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1353236889-15052-2-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1353236889-15052-1-git-send-email-felipe.contreras@gmail.com>

```
It seems there's always issues with zsh's bash completion emulation.
I've tried to fix as many as I could[1], and most of the fixes are already
in the latest version of zsh, but still, there are issues.

There is no point going through all that pain; the emulation is easy to
achieve, and this patch works better than zsh's bash completion
emulation.

[1] http://zsh.git.sourceforge.net/git/gitweb.cgi?p=zsh/zsh;a=commitdiff;h=23907bb840c80eef99eabba17e086e44c9b2d3fc

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/completion/git-completion.zsh | 78 +++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)
 create mode 100644 contrib/completion/git-completion.zsh

diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh
new file mode 100644
index 0000000..4577502
--- /dev/null
+++ b/contrib/completion/git-completion.zsh
@@ -0,0 +1,78 @@
+#compdef git gitk
+
+# zsh completion wrapper for git
+#
+# You need git's bash completion script installed somewhere, by default on the
+# same directory as this script.
+#
+# If your script is on ~/.git-completion.sh instead, you can configure it on
+# your ~/.zshrc:
+#
+#  zstyle ':completion:*:*:git:*' script ~/.git-completion.sh
+#
+# The recommended way to install this script is to copy to
+# '~/.zsh/completion/_git', and then add the following to your ~/.zshrc file:
+#
+#  fpath=(~/.zsh/completion $fpath)
+
+complete ()
+{
+	# do nothing
+	return 0
+}
+
+zstyle -s ":completion:*:*:git:*" script script
+test -z "$script" && script="$(dirname ${funcsourcetrace[1]%:*})"/git-completion.bash
+ZSH_VERSION='' . "$script"
+
+__gitcomp ()
+{
+	emulate -L zsh
+
+	local cur_="${3-$cur}"
+
+	case "$cur_" in
+	--*=)
+		;;
+	*)
+		local c IFS=$' \t\n'
+		local -a array
+		for c in ${=1}; do
+			c="$c${4-}"
+			case $c in
+			--*=*|*.) ;;
+			*) c="$c " ;;
+			esac
+			array+=("$c")
+		done
+		compset -P '*[=:]'
+		compadd -Q -S '' -p "${2-}" -a -- array && _ret=0
+		;;
+	esac
+}
+
+__gitcomp_nl ()
+{
+	emulate -L zsh
+
+	local IFS=$'\n'
+	compset -P '*[=:]'
+	compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
+}
+
+_git ()
+{
+	local _ret=1
+	() {
+		emulate -L ksh
+		local cur cword prev
+		cur=${words[CURRENT-1]}
+		prev=${words[CURRENT-2]}
+		let cword=CURRENT-1
+		__${service}_main
+	}
+	let _ret && _default -S '' && _ret=0
+	return _ret
+}
+
+_git
-- 
1.8.0

```

## Felipe Contreras, 2012-11-18 11:08

Subject: [PATCH v6 2/2] completion: start moving to the new zsh completion
Message-ID: <1353236889-15052-3-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1353236889-15052-3-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1353236889-15052-1-git-send-email-felipe.contreras@gmail.com>

```
Zsh's bash completion emulation is buggy, not properly maintained, and
we have some workarounds in place for different bugs that appeared in
various versions.

Since I'm the only one that has worked on that code lately[1], it might make
snese to use the code I wrote specifically for git.

The advantages are:

 1) Less workarounds

   * No need to hack __get_comp_words_by_ref
   * No need to hack IFS or words

 2) Improved features

   * 'git show master' now properly adds a space at the end (IFS bug)
   * 'git checkout --conflict=' now properly returns the sub-items
     (missing feature)

 3) Consolidated code

   * It's all now in a single chunk, and it's basically the same as
     git-completion.zsh

Since there's some interest in moving the zsh-specific code out of this
script, lets go ahead and warn the users that they should be using
git-completion.zsh.

[1] http://zsh.git.sourceforge.net/git/gitweb.cgi?p=zsh/zsh;a=history;f=Completion/bashcompinit

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/completion/git-completion.bash | 104 +++++++++++++++++++--------------
 1 file changed, 61 insertions(+), 43 deletions(-)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index bc0657a..9cd58ca 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -23,10 +23,6 @@
 #    3) Consider changing your PS1 to also show the current branch,
 #       see git-prompt.sh for details.
 
-if [[ -n ${ZSH_VERSION-} ]]; then
-	autoload -U +X bashcompinit && bashcompinit
-fi
-
 case "$COMP_WORDBREAKS" in
 *:*) : great ;;
 *)   COMP_WORDBREAKS="$COMP_WORDBREAKS:"
@@ -169,7 +165,6 @@ __git_reassemble_comp_words_by_ref()
 }
 
 if ! type _get_comp_words_by_ref >/dev/null 2>&1; then
-if [[ -z ${ZSH_VERSION:+set} ]]; then
 _get_comp_words_by_ref ()
 {
 	local exclude cur_ words_ cword_
@@ -197,32 +192,6 @@ _get_comp_words_by_ref ()
 		shift
 	done
 }
-else
-_get_comp_words_by_ref ()
-{
-	while [ $# -gt 0 ]; do
-		case "$1" in
-		cur)
-			cur=${COMP_WORDS[COMP_CWORD]}
-			;;
-		prev)
-			prev=${COMP_WORDS[COMP_CWORD-1]}
-			;;
-		words)
-			words=("${COMP_WORDS[@]}")
-			;;
-		cword)
-			cword=$COMP_CWORD
-			;;
-		-n)
-			# assume COMP_WORDBREAKS is already set sanely
-			shift
-			;;
-		esac
-		shift
-	done
-}
-fi
 fi
 
 # Generates completion reply with compgen, appending a space to possible
@@ -2430,20 +2399,69 @@ __gitk_main ()
 	__git_complete_revlist
 }
 
-__git_func_wrap ()
-{
-	if [[ -n ${ZSH_VERSION-} ]]; then
-		emulate -L bash
-		setopt KSH_TYPESET
+if [[ -n ${ZSH_VERSION-} ]]; then
+	echo "WARNING: this script is deprecated, please see git-completion.zsh" 1>&2
 
-		# workaround zsh's bug that leaves 'words' as a special
-		# variable in versions < 4.3.12
-		typeset -h words
+	__gitcomp ()
+	{
+		emulate -L zsh
 
-		# workaround zsh's bug that quotes spaces in the COMPREPLY
-		# array if IFS doesn't contain spaces.
-		typeset -h IFS
-	fi
+		local cur_="${3-$cur}"
+
+		case "$cur_" in
+		--*=)
+			;;
+		*)
+			local c IFS=$' \t\n'
+			local -a array
+			for c in ${=1}; do
+				c="$c${4-}"
+				case $c in
+				--*=*|*.) ;;
+				*) c="$c " ;;
+				esac
+				array+=("$c")
+			done
+			compset -P '*[=:]'
+			compadd -Q -S '' -p "${2-}" -a -- array && _ret=0
+			;;
+		esac
+	}
+
+	__gitcomp_nl ()
+	{
+		emulate -L zsh
+
+		local IFS=$'\n'
+		compset -P '*[=:]'
+		compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
+	}
+
+	__git_zsh_helper ()
+	{
+		emulate -L ksh
+		local cur cword prev
+		cur=${words[CURRENT-1]}
+		prev=${words[CURRENT-2]}
+		let cword=CURRENT-1
+		__${service}_main
+	}
+
+	_git ()
+	{
+		emulate -L zsh
+		local _ret=1
+		__git_zsh_helper
+		let _ret && _default -S '' && _ret=0
+		return _ret
+	}
+
+	compdef _git git gitk
+	return
+fi
+
+__git_func_wrap ()
+{
 	local cur words cword prev
 	_get_comp_words_by_ref -n =: cur words cword prev
 	$1
-- 
1.8.0

```

## Junio C Hamano, 2012-11-19 18:55

Subject: Re: [PATCH v6 0/2] New zsh wrapper
Message-ID: <7vpq39xw01.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vpq39xw01.fsf%40alter.siamese.dyndns.org
In-Reply-To: <1353236889-15052-1-git-send-email-felipe.contreras@gmail.com>

```
Felipe Contreras <felipe.contreras@gmail.com> writes:

> The second patch is new, in order for users to get the same features when
> sourcing the bash script (they don't need to change anything). They'll get a
> warning suggesting to check the new script git-completion.zsh. Eventually, that
> support would be dropped from the bash script.
>
> Some people were suggesting something like this, so here it is.
>
> Can we merge the zsh wrapper now?
>
> Felipe Contreras (2):
>   completion: add new zsh completion
>   completion: start moving to the new zsh completion
>
>  contrib/completion/git-completion.bash | 104 +++++++++++++++++++--------------
>  contrib/completion/git-completion.zsh  |  78 +++++++++++++++++++++++++
>  2 files changed, 139 insertions(+), 43 deletions(-)
>  create mode 100644 contrib/completion/git-completion.zsh

Thanks; I am a bit puzzled as to the progression of this series, as
it spanned many months.  I *think* the following are the previous
ones, but I may be mixing up v$n patches for other series, so just
to make sure (please correct if I am mistaken):

 * (v1) http://thread.gmane.org/gmane.comp.version-control.git/189310
   with only git-completion.zsh without any changes to the bash
   side;

 * (v2) http://thread.gmane.org/gmane.comp.version-control.git/189381
   without bash side changes;

 * (v3) http://thread.gmane.org/gmane.comp.version-control.git/196720
   without bash side changes;

 * (v6) http://thread.gmane.org/gmane.comp.version-control.git/208170
   with COMPREPLY changes;

 * This one, with removal of zsh specific workarounds from bash
   completion script.

I do not care too much about how v4 and v5 looked like; I primarily
am interested in knowing if I can discard 208170 from my inbox
safely ;-).

Thanks.

```

## Felipe Contreras, 2012-11-19 21:56

Subject: Re: [PATCH v6 0/2] New zsh wrapper
Message-ID: <CAMP44s0K2bzDDJQcC-KRnY50sZ4zNPSaujH5Gj7v5y6=ZYM90Q@mail.gmail.com>
URL: https://gitlist.dev/e/CAMP44s0K2bzDDJQcC-KRnY50sZ4zNPSaujH5Gj7v5y6%3DZYM90Q%40mail.gmail.com
In-Reply-To: <7vpq39xw01.fsf@alter.siamese.dyndns.org>

```
On Mon, Nov 19, 2012 at 7:55 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Felipe Contreras <felipe.contreras@gmail.com> writes:
>
>> The second patch is new, in order for users to get the same features when
>> sourcing the bash script (they don't need to change anything). They'll get a
>> warning suggesting to check the new script git-completion.zsh. Eventually, that
>> support would be dropped from the bash script.
>>
>> Some people were suggesting something like this, so here it is.
>>
>> Can we merge the zsh wrapper now?
>>
>> Felipe Contreras (2):
>>   completion: add new zsh completion
>>   completion: start moving to the new zsh completion
>>
>>  contrib/completion/git-completion.bash | 104 +++++++++++++++++++--------------
>>  contrib/completion/git-completion.zsh  |  78 +++++++++++++++++++++++++
>>  2 files changed, 139 insertions(+), 43 deletions(-)
>>  create mode 100644 contrib/completion/git-completion.zsh
>
> Thanks; I am a bit puzzled as to the progression of this series, as
> it spanned many months.  I *think* the following are the previous
> ones, but I may be mixing up v$n patches for other series, so just
> to make sure (please correct if I am mistaken):
>
>  * (v1) http://thread.gmane.org/gmane.comp.version-control.git/189310
>    with only git-completion.zsh without any changes to the bash
>    side;

Yes, and with a lot of code that is not strictly needed.

>  * (v2) http://thread.gmane.org/gmane.comp.version-control.git/189381
>    without bash side changes;

Yes, also with more code.

>  * (v3) http://thread.gmane.org/gmane.comp.version-control.git/196720
>    without bash side changes;

Yes, now it's simpler due to changes in bash side already in.

>  * (v6) http://thread.gmane.org/gmane.comp.version-control.git/208170
>    with COMPREPLY changes;

Yeap.

>  * This one, with removal of zsh specific workarounds from bash
>    completion script.

Yes, although that is a separate patch.

> I do not care too much about how v4 and v5 looked like; I primarily
> am interested in knowing if I can discard 208170 from my inbox
> safely ;-).

Yes you can. The rest of the patches I sent in a different series.

Cheers.

-- 
Felipe Contreras

```
