git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 4/8] bash: Add space after unique command name is completed.
@ 2007-02-04  7:38 Shawn O. Pearce
  2007-02-04  8:08 ` Junio C Hamano
  0 siblings, 1 reply; 3+ messages in thread
From: Shawn O. Pearce @ 2007-02-04  7:38 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Because we use the nospace option for our completion function for
the main 'git' wrapper bash won't automatically add a space after a
unique completion has been made by the user.  This has been pointed
out in the past by Linus Torvalds as an undesired behavior.  I agree.

We have to use the nospace option to ensure path completion for
a command such as `git show` works properly, but that breaks the
common case of getting the space for a unique completion.  So now we
set IFS=$'\n' (linefeed) and add a trailing space to every possible
completion option.  This causes bash to insert the space when the
completion is unique.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 contrib/completion/git-completion.bash |   26 ++++++++++++++++++++------
 1 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 93f2af5..1cf576e 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -61,6 +61,20 @@ __git_ps1 ()
 	fi
 }
 
+__gitcomp ()
+{
+	local all c s=$'\n' IFS=' '$'\t'$'\n'
+	for c in $1; do
+		case "$c" in
+		--*=*) all="$all$c$s" ;;
+		*)     all="$all$c $s" ;;
+		esac
+	done
+	IFS=$s
+	COMPREPLY=($(compgen -W "$all" -- "${COMP_WORDS[COMP_CWORD]}"))
+	return
+}
+
 __git_heads ()
 {
 	local cmd i is_hash=y dir="$(__gitdir "$1")"
@@ -787,12 +801,12 @@ _git ()
 	done
 
 	if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
-		COMPREPLY=($(compgen -W "
-			--git-dir= --version --exec-path
-			$(__git_commands)
-			$(__git_aliases)
-			" -- "${COMP_WORDS[COMP_CWORD]}"))
-		return;
+		case "${COMP_WORDS[COMP_CWORD]}" in
+		--*=*) COMPREPLY=() ;;
+		--*)   __gitcomp "--git-dir= --bare --version --exec-path" ;;
+		*)     __gitcomp "$(__git_commands) $(__git_aliases)" ;;
+		esac
+		return
 	fi
 
 	local expansion=$(__git_aliased_command "$command")
-- 
1.5.0.rc3.22.g5057

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 4/8] bash: Add space after unique command name is completed.
  2007-02-04  7:38 [PATCH 4/8] bash: Add space after unique command name is completed Shawn O. Pearce
@ 2007-02-04  8:08 ` Junio C Hamano
  2007-02-04  8:13   ` Shawn O. Pearce
  0 siblings, 1 reply; 3+ messages in thread
From: Junio C Hamano @ 2007-02-04  8:08 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: git

"Shawn O. Pearce" <spearce@spearce.org> writes:

> +__gitcomp ()
> +{
> +	local all c s=$'\n' IFS=' '$'\t'$'\n'
> +	for c in $1; do
> +		case "$c" in
> +		--*=*) all="$all$c$s" ;;
> +		*)     all="$all$c $s" ;;
> +		esac
> +	done
> +	IFS=$s
> +	COMPREPLY=($(compgen -W "$all" -- "${COMP_WORDS[COMP_CWORD]}"))
> +	return
> +}
> +

I do not understand what is going on here.  Care to explain?

 (1) "for c in $1": because $1 is not dquoted, it is split into
     word with IFS -- which IFS applies to this splitting?  The
     local one you hand-define to the typical " \t\n" value?

 (2) when this function returns, what IFS value does the caller
     would have?  Is the "local" used to avoid screwing up the
     caller?

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 4/8] bash: Add space after unique command name is completed.
  2007-02-04  8:08 ` Junio C Hamano
@ 2007-02-04  8:13   ` Shawn O. Pearce
  0 siblings, 0 replies; 3+ messages in thread
From: Shawn O. Pearce @ 2007-02-04  8:13 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Junio C Hamano <junkio@cox.net> wrote:
> "Shawn O. Pearce" <spearce@spearce.org> writes:
> 
> > +__gitcomp ()
> > +{
> > +	local all c s=$'\n' IFS=' '$'\t'$'\n'
> > +	for c in $1; do
> > +		case "$c" in
> > +		--*=*) all="$all$c$s" ;;
> > +		*)     all="$all$c $s" ;;
> > +		esac
> > +	done
> > +	IFS=$s
> > +	COMPREPLY=($(compgen -W "$all" -- "${COMP_WORDS[COMP_CWORD]}"))
> > +	return
> > +}
> > +
> 
> I do not understand what is going on here.  Care to explain?
> 
>  (1) "for c in $1": because $1 is not dquoted, it is split into
>      word with IFS -- which IFS applies to this splitting?  The
>      local one you hand-define to the typical " \t\n" value?

Correct.
 
>  (2) when this function returns, what IFS value does the caller
>      would have?  Is the "local" used to avoid screwing up the
>      caller?
> 

Correct.


Basically at the time I'm forming 'all' I want $1 split based on
normal splitting rules, as I'm using space, tag and LF within the
script in some places for the first parameter to __gitcomp.

But when I run compgen I need IFS to be just LF ($s) so that $all
is split only on LF and not on spaces, as spaces were added to $all
after each unique option.  This way the trailing space is part of
the unique option, and bash will tack in the trailing space for me,
despite having -o nospace enabled.

-- 
Shawn.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-02-04  8:13 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-02-04  7:38 [PATCH 4/8] bash: Add space after unique command name is completed Shawn O. Pearce
2007-02-04  8:08 ` Junio C Hamano
2007-02-04  8:13   ` Shawn O. Pearce

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).