Add a minimal implementation of _get_comp_words_by_ref, the routine used to work around bash 4.0's COMP_WORDS semantics. Based on bash-completion 2.x (commit bf763033, 2010-10-26) but tweaked for simplicity and to allow zsh to at least parse the code. Based-on-patch-by: Peter van der Does <peter@xxxxxxxxxxxxxxxx> Signed-off-by: Jonathan Nieder <jrnieder@xxxxxxxxx> --- Peter van der Does wrote: > Jonathan Nieder <jrnieder@xxxxxxxxx> wrote: >> 2. Import the definition of _get_comp_words_by_ref from the >> bash-completion lib and use it if ZSH_VERSION is unset. >> >> 3. Further refinements, if needed. >> >> What do you think? > > I like the idea and we should go with this solution. > > If by importing you mean using : > [CODE]. /git_bash_completion-functions[/CODE] in the > contrib/completion/git-completion.bash script, which would be the best > solution imho. The question is where to place that the function file. [...] > It would have to include copying the functions file somewhere as well. > > Or we could use the method used now and include the functions in the > git-completion.bash script. Sorry for the lack of clarity. Here's what I meant. contrib/completion/git-completion.bash | 125 ++++++++++++++++++++++++++++++++ 1 files changed, 125 insertions(+), 0 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 0b0eb45..1743319 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -327,7 +327,102 @@ __gitcomp_1 () done } +# The following function is based on code from: +# +# bash_completion - programmable completion functions for bash 3.2+ +# +# Copyright  2006-2008, Ian Macdonald <ian@xxxxxxxxxxx> +#  2009-2010, Bash Completion Maintainers +# <bash-completion-devel@xxxxxxxxxxxxxxxxxxxxxxx> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The latest version of this software can be obtained here: +# +# http://bash-completion.alioth.debian.org/ +# +# RELEASE: 2.x + +# This function can be used to access a tokenized list of words +# on the command line: +# +# __reassemble_comp_words_by_ref '=:' +# if test "${words_[cword_-1]}" = -w +# then +# ... +# fi +# +# The argument should be a collection of characters from the list of +# word completion separators (COMP_WORDBREAKS) to treat as ordinary +# characters. +# +# This is roughly equivalent to locally setting COMP_WORDBREAKS to +# exclude those characters, but it does not clobber COMP_WORDBREAKS. +# The intent is for it to be used by commands like ssh that want to +# treat host:path as one token. +# +# Output: words_, cword_, cur_. + +__git_reassemble_comp_words_by_ref() +{ + local exclude i j first + # Which word separators to exclude? + exclude="${1//[^$COMP_WORDBREAKS]}" + cword_=$COMP_CWORD + if [ -z "$exclude" ]; then + words_=("${COMP_WORDS[@]}") + return + fi + # List of word completion separators has shrunk; + # re-assemble words to complete. + for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do + # Append each nonempty word consisting of just + # word separator characters to the current word. + first=t + while + [ $i -gt 0 ] && + [ -n "${COMP_WORDS[$i]}" ] && + # word consists of excluded word separators + [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ] + do + # Attach to the previous token, + # unless the previous token is the command name. + if [ $j -ge 2 ] && [ -n "$first" ]; then + ((j--)) + fi + first= + words_[$j]=${words_[j]}${COMP_WORDS[i]} + if [ $i = $COMP_CWORD ]; then + cword_=$j + fi + if (($i < ${#COMP_WORDS[@]} - 1)); then + ((i++)) + else + # Done. + return + fi + done + words_[$j]=${words_[j]}${COMP_WORDS[i]} + if [ $i = $COMP_CWORD ]; then + cword_=$j + fi + done +} + if ! type _get_comp_words_by_ref >/dev/null 2>&1; then +if [[ -n $ZSH_VERSION ]]; then _get_comp_words_by_ref () { while [ $# -gt 0 ]; do @@ -352,6 +447,36 @@ _get_comp_words_by_ref () shift done } +else +_get_comp_words_by_ref () +{ + local exclude cur_ cword_ + local words_=() + if [ "$1" = "-n" ]; then + exclude=$2 + shift 2 + fi + __git_reassemble_comp_words_by_ref "$exclude" + cur_=${words_[cword_]} + while [ $# -gt 0 ]; do + case "$1" in + cur) + cur=$cur_ + ;; + prev) + prev=${words_[$cword_-1]} + ;; + words) + words=("${words_[@]}") + ;; + cword) + cword=$cword_ + ;; + esac + shift + done +} +fi fi # __gitcomp accepts 1, 2, 3, or 4 arguments -- 1.7.2.3 -- 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