Re: [completion] Request: Include remote heads as push targets

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Oct 23, 2010 at 08:07:39PM -0400, Peter van der Does wrote:
> On Sat, 23 Oct 2010 15:04:34 +0200
> SZEDER Gábor <szeder@xxxxxxxxxx> wrote:
>
> > This patch assumes that you use fairly recent bash-completion, because
> > _get_comp_words_by_ref() was first included in bash-completion v1.2,
> > which was released just this summer.
> > 
> > However, git completion is currently a standalone completion script,
> > i.e. to use it you need only bash, git-completion.bash, and nothing
> > else.  If we start to use _get_comp_words_by_ref() directly, as in the
> > PoC patch above, then git completion will inherently depend on
> > bash-completion, too.  This could be considered as a regression.
> > 
> > Alternatively, we could just copy the necessary functions from
> > bash-completion to git-completion.bash (with the name changed, of
> > course, e.g. to __git_get_comp_words_by_ref()), keeping git completion
> > standalone but still getting the benefits of this function, and
> > getting these bash 4 vs. 3 issues fixed.
> > 
> > Thoughts?
> > 
> 
> Instead of using [code]_get_comp_words_by_ref -n '=' cur[/code] you can
> use [code]local cur=`_get_cword "="`[/code].
> 
> To keep git completion standalone we need to, like Gábor mentioned, add
> the necessary functions, but we don't have to rename them. There is
> an option to check if a function exists. I've changed the entire git
> completion script and hopefully covered all options. From my tests it
> works on bash 4.

Checking for the function first, and declaring it if it doesn't exists
could be a viewable alternative, but not with _get_cword().  The
_get_cword() implementation you are adding below is outdated.  It is
from bash-completion 1.1, changed quite a bit after that, and in the
end became deprecated in 1.2 in favor of _get_comp_words_by_ref().


> To give an idea of what the change is, here's part of the entire diff.
> 
> diff --git a/contrib/completion/git-completion.bash
> b/contrib/completion/git-completion.bash index f83f019..a2c0589 100755
> --- a/contrib/completion/git-completion.bash
> +++ b/contrib/completion/git-completion.bash
> @@ -71,12 +71,159 @@
>  #
>  #       git@xxxxxxxxxxxxxxx
>  #
> +# Updated for Bash 4.0
>  
>  case "$COMP_WORDBREAKS" in
>  *:*) : great ;;
>  *)   COMP_WORDBREAKS="$COMP_WORDBREAKS:"
>  esac
>  
> +# If the function _get_cword does not exists, we can assume the
> +# bash_completion script isn't loaded and therefor we're defining the
> +# necessary functions ourselves.
> +if ! type _get_cword &> /dev/null ; then
> +	# features supported by bash 4.0 and higher
> +	if [ ${BASH_VERSINFO[0]} -gt 3 ]; then
> +	    declare -r git_bash4=$BASH_VERSION 2>/dev/null || :
> +	fi
> +
> +	# Get the word to complete.
> +	# This is nicer than ${COMP_WORDS[$COMP_CWORD]}, since it
> handles cases
> +	# where the user is completing in the middle of a word.
> +	# (For example, if the line is "ls foobar",
> +	# and the cursor is here -------->   ^
> +	# it will complete just "foo", not "foobar", which is what the
> user wants.)
> +	# @param $1 string  (optional) Characters out of
> $COMP_WORDBREAKS which should
> +	#     NOT be considered word breaks. This is useful for things
> like scp where
> +	#     we want to return host:path and not only path.
> +	#     NOTE: This parameter only applies to bash-4.
> +	_get_cword()
> +	{
> +    	if [ -n "$git_bash4" ] ; then
> +        	__get_cword4 "$@"
> +    	else
> +        	__get_cword3
> +    	fi
> +	} # _get_cword()
> +
> +
> +	# Get the word to complete on bash-3, where words are not
> broken by
> +	# COMP_WORDBREAKS characters and the COMP_CWORD variables look
> like this, for
> +	# example:
> +	#
> +	#     $ a b:c<TAB>
> +	#     COMP_CWORD: 1
> +	#     COMP_CWORDS:
> +	#     0: a
> +	#     1: b:c
> +	#
> +	# See also:
> +	# _get_cword, main routine
> +	# __get_cword4, bash-4 variant
> +	#
> +	__get_cword3()
> +	{
> +	    if [[ "${#COMP_WORDS[COMP_CWORD]}" -eq 0 ]] ||
> [[ "$COMP_POINT" == "${#COMP_LINE}" ]]; then
> +        	printf "%s" "${COMP_WORDS[COMP_CWORD]}"
> +    	else
> +	        local i
> +        	local cur="$COMP_LINE"
> +        	local index="$COMP_POINT"
> +        	for (( i = 0; i <= COMP_CWORD; ++i )); do
> +	            while [[
> +                	# Current COMP_WORD fits in $cur?
> +                	"${#cur}" -ge ${#COMP_WORDS[i]} &&
> +                	# $cur doesn't match COMP_WORD?
> +                	"${cur:0:${#COMP_WORDS[i]}}" !=
> "${COMP_WORDS[i]}"
> +                	]]; do
> +                	# Strip first character
> +                	cur="${cur:1}"
> +                	# Decrease cursor position
> +                	index="$(( index - 1 ))"
> +            	done
> +	
> +            	# Does found COMP_WORD matches COMP_CWORD?
> +            	if [[ "$i" -lt "$COMP_CWORD" ]]; then
> +	                # No, COMP_CWORD lies further;
> +                	local old_size="${#cur}"
> +                	cur="${cur#${COMP_WORDS[i]}}"
> +                	local new_size="${#cur}"
> +                	index="$(( index - old_size + new_size ))"
> +            	fi
> +        	done
> +
> +	        if [[ "${COMP_WORDS[COMP_CWORD]:0:${#cur}}" !=
> "$cur" ]]; then
> +            	# We messed up! At least return the whole word so
> things
> +            	# keep working
> +            	printf "%s" "${COMP_WORDS[COMP_CWORD]}"
> +        	else
> +	            printf "%s" "${cur:0:$index}"
> +        	fi
> +    	fi
> +	} # __get_cword3()
> +
> +
> +	# Get the word to complete on bash-4, where words are splitted
> by
> +	# COMP_WORDBREAKS characters (default is " \t\n\"'><=;|&(:")
> and the COMP_CWORD
> +	# variables look like this, for example:
> +	#
> +	#     $ a b:c<TAB>
> +	#     COMP_CWORD: 3
> +	#     COMP_CWORDS:
> +	#     0: a
> +	#     1: b
> +	#     2: :
> +	#     3: c
> +	#
> +	# @oaram $1 string
> +	# $1 string  (optional) Characters out of $COMP_WORDBREAKS
> which should
> +	#     NOT be considered word breaks. This is useful for things
> like scp where
> +	#     we want to return host:path and not only path.
> +	# See also:
> +	# _get_cword, main routine
> +	# __get_cword3, bash-3 variant
> +	#
> +	__get_cword4()
> +	{
> +	    local i
> +	    local LC_CTYPE=C
> +	    local WORDBREAKS=$COMP_WORDBREAKS
> +	    # Strip single quote (') and double quote (") from
> WORDBREAKS to
> +	    # workaround a bug in bash-4.0, where quoted words are
> split
> +	    # unintended, see:
> +	    #
> http://www.mail-archive.com/bug-bash@xxxxxxx/msg06095.html
> +	    # This fixes simple quoting (e.g. $ a "b<TAB> returns "b
> instead of b)
> +	    # but still fails quoted spaces (e.g. $ a "b c<TAB>
> returns c instead
> +	    # of "b c).
> +	    WORDBREAKS=${WORDBREAKS//\"/}
> +	    WORDBREAKS=${WORDBREAKS//\'/}
> +	    if [ -n "$1" ]; then
> +        	for (( i=0; i<${#1}; ++i )); do
> +	            local char=${1:$i:1}
> +            	WORDBREAKS=${WORDBREAKS//$char/}
> +        	done
> +    	fi
> +    	local cur=${COMP_LINE:0:$COMP_POINT}
> +    	local tmp=$cur
> +    	local word_start=`expr "$tmp" : '.*['"$WORDBREAKS"']'`
> +    	while [ "$word_start" -ge 2 ]; do
> +	        # Get character before $word_start
> +        	local char=${cur:$(( $word_start - 2 )):1}
> +        	# If the WORDBREAK character isn't escaped, exit loop
> +        	if [ "$char" != "\\" ]; then
> +	            break
> +        	fi
> +        	# The WORDBREAK character is escaped;
> +        	# Recalculate $word_start
> +        	tmp=${COMP_LINE:0:$(( $word_start - 2 ))}
> +        	word_start=`expr "$tmp" : '.*['"$WORDBREAKS"']'`
> +    	done
> +
> +	    cur=${cur:$word_start}
> +	    printf "%s" "$cur"
> +	} # __get_cword4()
> +fi
> +
> @@ -551,7 +698,7 @@ __git_complete_revlist ()
>  __git_complete_remote_or_refspec ()
>  {
>  	local cmd="${COMP_WORDS[1]}"
> -	local cur="${COMP_WORDS[COMP_CWORD]}"
> +	local cur=`_get_cword ":"`
>  	local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0
>  	while [ $c -lt $COMP_CWORD ]; do
>  		i="${COMP_WORDS[c]}"
> @@ -1360,7 +1508,7 @@ _git_log ()
>  {
>  	__git_has_doubledash && return
>  
> -	local cur="${COMP_WORDS[COMP_CWORD]}"
> +	local cur=`_get_cword "="`
>  	local g="$(git rev-parse --git-dir 2>/dev/null)"
>  	local merge=""
>  	if [ -f "$g/MERGE_HEAD" ]; then
> @@ -1419,7 +1567,7 @@ _git_merge ()
>  {
>  	__git_complete_strategy && return
>  
> -	local cur="${COMP_WORDS[COMP_CWORD]}"
> +	local cur=`_get_cword`
>  	case "$cur" in
>  	--*)
>  		__gitcomp "$__git_merge_options"
> 
> 
> I just need someone to test the new script on Bash 3. If somebody is
> willing to test, drop me an private email and I can send the new script.
> 
--
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


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]