From: "SZEDER Gábor" <szeder@ira.uka.de>
To: Peter van der Does <peter@avirtualhome.com>
Cc: Jonathan Nieder <jrnieder@gmail.com>,
"Shawn O. Pearce" <spearce@spearce.org>,
git@vger.kernel.org, Marc Branchaud <marcnarc@xiplink.com>,
Brian Gernhardt <brian@gernhardtsoftware.com>,
Kevin Ballard <kevin@sb.org>,
Mathias Lafeldt <misfire@debugon.org>
Subject: Re: [completion] Request: Include remote heads as push targets
Date: Sun, 24 Oct 2010 13:23:26 +0200 [thread overview]
Message-ID: <20101024112325.GB29386@neumann> (raw)
In-Reply-To: <20101023200739.28b6eb1e@montecarlo.grandprix.int>
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@ira.uka.de> 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@vger.kernel.org
> #
> +# 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@gnu.org/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.
>
next prev parent reply other threads:[~2010-10-24 11:23 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-21 15:37 [completion] Request: Include remote heads as push targets Marc Branchaud
2010-10-21 16:03 ` Marc Branchaud
2010-10-21 19:10 ` Jonathan Nieder
2010-10-22 1:08 ` Peter van der Does
2010-10-22 1:11 ` Kevin Ballard
2010-10-22 14:50 ` Marc Branchaud
2010-10-23 13:04 ` SZEDER Gábor
2010-10-24 0:07 ` Peter van der Does
2010-10-24 11:23 ` SZEDER Gábor [this message]
2010-10-24 16:28 ` Peter van der Does
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20101024112325.GB29386@neumann \
--to=szeder@ira.uka.de \
--cc=brian@gernhardtsoftware.com \
--cc=git@vger.kernel.org \
--cc=jrnieder@gmail.com \
--cc=kevin@sb.org \
--cc=marcnarc@xiplink.com \
--cc=misfire@debugon.org \
--cc=peter@avirtualhome.com \
--cc=spearce@spearce.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).