# [PATCH v3 0/4] Fix branch.autosetup(merge|rebase) completion

8 messages from 2014-01-03 to 2014-01-05. Participants: Ramkumar Ramachandra, Junio C Hamano.
Thread: https://gitlist.dev/t/35604

## Ramkumar Ramachandra, 2014-01-03 19:56

Subject: [PATCH v3 0/4] Fix branch.autosetup(merge|rebase) completion
Message-ID: <1388779022-14536-1-git-send-email-artagnon@gmail.com>
URL: https://gitlist.dev/e/1388779022-14536-1-git-send-email-artagnon%40gmail.com

```
Hi Junio et al,

In v3, I've implemented __gitcomp_nl_append (), like you
suggested. After implementing it, I feel foolish about having gone
around my head to do __gitcomp_2 ().

Thanks.

Ramkumar Ramachandra (4):
  completion: prioritize ./git-completion.bash
  completion: introduce __gitcomp_nl_append ()
  completion: fix branch.autosetup(merge|rebase)
  completion: fix remote.pushdefault

 contrib/completion/git-completion.bash | 15 +++++++++++++++
 contrib/completion/git-completion.zsh  | 10 +++++++++-
 2 files changed, 24 insertions(+), 1 deletion(-)

-- 
1.8.5.2.227.g53f3478

```

## Ramkumar Ramachandra, 2014-01-03 19:56

Subject: [PATCH v3 1/4] completion: prioritize ./git-completion.bash
Message-ID: <1388779022-14536-2-git-send-email-artagnon@gmail.com>
URL: https://gitlist.dev/e/1388779022-14536-2-git-send-email-artagnon%40gmail.com
In-Reply-To: <1388779022-14536-1-git-send-email-artagnon@gmail.com>

```
To ease development, prioritize ./git-completion.bash over other
standard system paths.

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
 contrib/completion/git-completion.zsh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh
index fac5e71..6fca145 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -30,10 +30,10 @@ if [ -z "$script" ]; then
 	local -a locations
 	local e
 	locations=(
+		$(dirname ${funcsourcetrace[1]%:*})/git-completion.bash
 		'/etc/bash_completion.d/git' # fedora, old debian
 		'/usr/share/bash-completion/completions/git' # arch, ubuntu, new debian
 		'/usr/share/bash-completion/git' # gentoo
-		$(dirname ${funcsourcetrace[1]%:*})/git-completion.bash
 		)
 	for e in $locations; do
 		test -f $e && script="$e" && break
-- 
1.8.5.2.227.g53f3478

```

## Ramkumar Ramachandra, 2014-01-03 19:57

Subject: [PATCH v3 2/4] completion: introduce __gitcomp_nl_append ()
Message-ID: <1388779022-14536-3-git-send-email-artagnon@gmail.com>
URL: https://gitlist.dev/e/1388779022-14536-3-git-send-email-artagnon%40gmail.com
In-Reply-To: <1388779022-14536-1-git-send-email-artagnon@gmail.com>

```
There are situations where multiple classes of completions possible. For
example

  branch.<TAB>

should try to complete

  branch.master.
  branch.autosetupmerge
  branch.autosetuprebase

The first candidate has the suffix ".", and the second/ third candidates
have the suffix " ". To facilitate completions of this kind, create a
variation of __gitcomp_nl () that appends to the existing list of
completion candidates, COMPREPLY.

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
 contrib/completion/git-completion.bash | 13 +++++++++++++
 contrib/completion/git-completion.zsh  |  8 ++++++++
 2 files changed, 21 insertions(+)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 51c2dd4..bf358d6 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -233,6 +233,19 @@ __gitcomp_nl ()
 	__gitcompadd "$1" "${2-}" "${3-$cur}" "${4- }"
 }
 
+# Variation of __gitcomp_nl () that appends to the existing list of
+# completion candidates, COMPREPLY.
+__gitcomp_nl_append ()
+{
+	local IFS=$'\n'
+	local i=${#COMPREPLY[@]}
+	for x in $1; do
+		if [[ "$x" == "$3"* ]]; then
+			COMPREPLY[i++]="$2$x$4"
+		fi
+	done
+}
+
 # Generates completion reply with compgen from newline-separated possible
 # completion filenames.
 # It accepts 1 to 3 arguments:
diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh
index 6fca145..6b77968 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -76,6 +76,14 @@ __gitcomp_nl ()
 	compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
 }
 
+__gitcomp_nl_append ()
+{
+	emulate -L zsh
+
+	local IFS=$'\n'
+	compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
+}
+
 __gitcomp_file ()
 {
 	emulate -L zsh
-- 
1.8.5.2.227.g53f3478

```

## Ramkumar Ramachandra, 2014-01-03 19:57

Subject: [PATCH v3 3/4] completion: fix branch.autosetup(merge|rebase)
Message-ID: <1388779022-14536-4-git-send-email-artagnon@gmail.com>
URL: https://gitlist.dev/e/1388779022-14536-4-git-send-email-artagnon%40gmail.com
In-Reply-To: <1388779022-14536-1-git-send-email-artagnon@gmail.com>

```
When attempting to complete

  $ git config branch.auto<TAB>

'autosetupmerge' and 'autosetuprebase' don't come up. This is because
"$cur" is matched with "branch.*" and a list of branches are
completed. Add 'autosetupmerge', 'autosetuprebase' to the list of
branches using __gitcomp_nl_append ().

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
 contrib/completion/git-completion.bash | 1 +
 1 file changed, 1 insertion(+)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index bf358d6..75c7302 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1840,6 +1840,7 @@ _git_config ()
 	branch.*)
 		local pfx="${cur%.*}." cur_="${cur#*.}"
 		__gitcomp_nl "$(__git_heads)" "$pfx" "$cur_" "."
+		__gitcomp_nl_append $'autosetupmerge\nautosetuprebase\n' "$pfx" "$cur_"
 		return
 		;;
 	guitool.*.*)
-- 
1.8.5.2.227.g53f3478

```

## Ramkumar Ramachandra, 2014-01-03 19:57

Subject: [PATCH v3 4/4] completion: fix remote.pushdefault
Message-ID: <1388779022-14536-5-git-send-email-artagnon@gmail.com>
URL: https://gitlist.dev/e/1388779022-14536-5-git-send-email-artagnon%40gmail.com
In-Reply-To: <1388779022-14536-1-git-send-email-artagnon@gmail.com>

```
When attempting to complete

  $ git config remote.push<TAB>

'pushdefault' doesn't come up. This is because "$cur" is matched with
"remote.*" and a list of remotes are completed. Add 'pushdefault' to the
list of remotes using __gitcomp_nl_append ().

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
 contrib/completion/git-completion.bash | 1 +
 1 file changed, 1 insertion(+)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 75c7302..345ceff 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1883,6 +1883,7 @@ _git_config ()
 	remote.*)
 		local pfx="${cur%.*}." cur_="${cur#*.}"
 		__gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
+		__gitcomp_nl_append "pushdefault" "$pfx" "$cur_"
 		return
 		;;
 	url.*.*)
-- 
1.8.5.2.227.g53f3478

```

## Junio C Hamano, 2014-01-03 20:41

Subject: Re: [PATCH v3 2/4] completion: introduce __gitcomp_nl_append ()
Message-ID: <xmqq38l4n6h9.fsf@gitster.dls.corp.google.com>
URL: https://gitlist.dev/e/xmqq38l4n6h9.fsf%40gitster.dls.corp.google.com
In-Reply-To: <1388779022-14536-3-git-send-email-artagnon@gmail.com>

```
Ramkumar Ramachandra <artagnon@gmail.com> writes:

> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
> index 51c2dd4..bf358d6 100644
> --- a/contrib/completion/git-completion.bash
> +++ b/contrib/completion/git-completion.bash
> @@ -233,6 +233,19 @@ __gitcomp_nl ()
>  	__gitcompadd "$1" "${2-}" "${3-$cur}" "${4- }"
>  }
>  
> +# Variation of __gitcomp_nl () that appends to the existing list of
> +# completion candidates, COMPREPLY.
> +__gitcomp_nl_append ()
> +{
> +	local IFS=$'\n'
> +	local i=${#COMPREPLY[@]}
> +	for x in $1; do
> +		if [[ "$x" == "$3"* ]]; then
> +			COMPREPLY[i++]="$2$x$4"
> +		fi
> +	done
> +}

Hmph. Why so much duplication with __gitcompadd, though.

I would have expected that this "append" behaviour to be done at the
lower level by introducing __gitcompappend that does not forcibly
truncate by starting from a hard-coded i=0, i.e. a collection of
small helper functions plus a single implementation of the logic to
push elements into COMPREPLY[] in __gitcompappend, perhaps like
these:

	__gitcompappend () {
		local i=${#COMPREPLY[@]}
		for x in $1; do
                        if [[ "$x" == "$3"* ]]; then
                                COMPREPLY[i++]="$2$x$4"
                        fi
		done
        }

	__gitcompadd () {
		COMPREPLY=()
		__gitcompappend "$@"
	}

	__gitcomp_nl_append () {
		local IFS=$'\n'
                __gitcompappend "$1" "${2-}" "${3-$cur}" "${4- }"
        }

	__gitcomp_nl () {
		COMPREPLY=()
                __gitcomp_nl_append "$@"		
        }
        
Is it because going this route and doing it at such a low level
would make zsh completion (which I have no clue about ;-)
unnecessarily complex?

> +
>  # Generates completion reply with compgen from newline-separated possible
>  # completion filenames.
>  # It accepts 1 to 3 arguments:
> diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh
> index 6fca145..6b77968 100644
> --- a/contrib/completion/git-completion.zsh
> +++ b/contrib/completion/git-completion.zsh
> @@ -76,6 +76,14 @@ __gitcomp_nl ()
>  	compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
>  }
>  
> +__gitcomp_nl_append ()
> +{
> +	emulate -L zsh
> +
> +	local IFS=$'\n'
> +	compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
> +}
> +
>  __gitcomp_file ()
>  {
>  	emulate -L zsh

```

## Junio C Hamano, 2014-01-03 21:21

Subject: Re: [PATCH v3 4/4] completion: fix remote.pushdefault
Message-ID: <xmqqy52wlq2k.fsf@gitster.dls.corp.google.com>
URL: https://gitlist.dev/e/xmqqy52wlq2k.fsf%40gitster.dls.corp.google.com
In-Reply-To: <1388779022-14536-5-git-send-email-artagnon@gmail.com>

```
Ramkumar Ramachandra <artagnon@gmail.com> writes:

> When attempting to complete
>
>   $ git config remote.push<TAB>
>
> 'pushdefault' doesn't come up. This is because "$cur" is matched with
> "remote.*" and a list of remotes are completed. Add 'pushdefault' to the
> list of remotes using __gitcomp_nl_append ().

"Add ... to the list of remotes" (same for "list of branches" in
3/4) sounds somewhat funny, doesn't it?  How about

	Add remote.pushdefault as a candidate for completion, too.

or something like that instead?

>
> Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
> ---
>  contrib/completion/git-completion.bash | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
> index 75c7302..345ceff 100644
> --- a/contrib/completion/git-completion.bash
> +++ b/contrib/completion/git-completion.bash
> @@ -1883,6 +1883,7 @@ _git_config ()
>  	remote.*)
>  		local pfx="${cur%.*}." cur_="${cur#*.}"
>  		__gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
> +		__gitcomp_nl_append "pushdefault" "$pfx" "$cur_"
>  		return
>  		;;
>  	url.*.*)

```

## Ramkumar Ramachandra, 2014-01-05 10:06

Subject: Re: [PATCH v3 2/4] completion: introduce __gitcomp_nl_append ()
Message-ID: <CALkWK0=rrcTFdpymGB5QJhdLhYvm4FLMGurqugbCGvAdDKVhqA@mail.gmail.com>
URL: https://gitlist.dev/e/CALkWK0%3DrrcTFdpymGB5QJhdLhYvm4FLMGurqugbCGvAdDKVhqA%40mail.gmail.com
In-Reply-To: <xmqq38l4n6h9.fsf@gitster.dls.corp.google.com>

```
Junio C Hamano wrote:
> Is it because going this route and doing it at such a low level
> would make zsh completion (which I have no clue about ;-)
> unnecessarily complex?

The zsh completion only cares to override __gitcomp_nl () and
__gitcomp_nl_append (), without bothering to re-implement the
lower-level functions; so it's no problem at all. I wrote mine out by
thinking of a non-intrusive direct translation, while your version
focuses on eliminating duplication. I don't have a strong preference
either way, so I will resubmit with your version.

```
