bash: simple reimplementation of _get_comp_words_by_ref
Add a minimal implementation of _get_comp_words_by_ref so $ git show head:g <tab><tab> on bash 4 can complete paths within the head commit without requiring the bash_completion functions to be loaded. This is a follow-up to the previous patch (bash: get --pretty=m<tab> completion to work with bash v4). Based on bash-completion 2.x (commit bf763033, 2010-10-26) but tweaked for simplicity and to allow zsh to parse the code. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Improved-by: SZEDER Gábor <szeder@ira.uka.de>maint
parent
da48616f1d
commit
dbda3b1090
|
@ -321,26 +321,128 @@ __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@caliban.org>
|
||||
# © 2009-2010, Bash Completion Maintainers
|
||||
# <bash-completion-devel@lists.alioth.debian.org>
|
||||
#
|
||||
# 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:
|
||||
#
|
||||
# __git_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 going back in time and setting
|
||||
# COMP_WORDBREAKS to exclude those characters. The intent is to
|
||||
# make option types like --date=<type> and <rev>:<path> easy to
|
||||
# recognize by treating each shell word as a single token.
|
||||
#
|
||||
# It is best not to set COMP_WORDBREAKS directly because the value is
|
||||
# shared with other completion scripts. By the time the completion
|
||||
# function gets called, COMP_WORDS has already been populated so local
|
||||
# changes to COMP_WORDBREAKS have no effect.
|
||||
#
|
||||
# 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
|
||||
_get_comp_words_by_ref ()
|
||||
{
|
||||
local exclude cur_ words_ cword_
|
||||
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=${COMP_WORDS[COMP_CWORD]}
|
||||
cur=$cur_
|
||||
;;
|
||||
prev)
|
||||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
prev=${words_[$cword_-1]}
|
||||
;;
|
||||
words)
|
||||
words=("${COMP_WORDS[@]}")
|
||||
words=("${words_[@]}")
|
||||
;;
|
||||
cword)
|
||||
cword=$COMP_CWORD
|
||||
;;
|
||||
-n)
|
||||
# assume COMP_WORDBREAKS is already set sanely
|
||||
shift
|
||||
cword=$cword_
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
|
|
Loading…
Reference in New Issue