Added _get_pword() helper function.
Thanks to Sung Pae (Alioth #312030): "This patch extends both __get_cword3() and __get_cword4() to accept an additional integer argument that specifies how many places previous to the current word the desired word resides, respecting any user exceptions to COMP_WORDBREAKS."
This commit is contained in:
parent
a55d311ae2
commit
545750eb2c
3
CHANGES
3
CHANGES
@ -28,6 +28,9 @@ bash-completion (2.x)
|
||||
* Drop support for bash < 3.
|
||||
* Fix sed error in qdbus completions containing slashes (Debian: 552631).
|
||||
|
||||
[ Freddy Vulto ]
|
||||
* Added _get_pword() helper function, thanks to Sung Pae (Alioth: #312030)
|
||||
|
||||
-- David Paleino <d.paleino@gmail.com> Sun, 11 Oct 2009 11:11:57 +0200
|
||||
|
||||
bash-completion (1.1)
|
||||
|
@ -243,10 +243,17 @@ _get_cword()
|
||||
if [ ${BASH_VERSINFO[0]} -ge 4 ] ; then
|
||||
__get_cword4 "$@"
|
||||
else
|
||||
__get_cword3
|
||||
__get_cword3 "$2"
|
||||
fi
|
||||
} # _get_cword()
|
||||
|
||||
# Get word previous to the current word;
|
||||
# Accepts the same arguments as _get_cword()
|
||||
#
|
||||
# This is a good alternative to `prev=${COMP_WORDS[COMP_CWORD-1]}' because bash4
|
||||
# will properly return the previous word with respect to any given exclusions to
|
||||
# COMP_WORDBREAKS.
|
||||
_get_pword() { _get_cword "${@:-}" 1; }
|
||||
|
||||
# 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
|
||||
@ -265,7 +272,10 @@ _get_cword()
|
||||
[ ${BASH_VERSINFO[0]} -lt 4 ] &&
|
||||
__get_cword3()
|
||||
{
|
||||
if [[ "${#COMP_WORDS[COMP_CWORD]}" -eq 0 ]] || [[ "$COMP_POINT" == "${#COMP_LINE}" ]]; then
|
||||
# return previous word offset by $1
|
||||
if [[ ${1//[^0-9]/} ]]; then
|
||||
printf "%s" "${COMP_WORDS[COMP_CWORD-$1]}"
|
||||
elif [[ "${#COMP_WORDS[COMP_CWORD]}" -eq 0 ]] || [[ "$COMP_POINT" == "${#COMP_LINE}" ]]; then
|
||||
printf "%s" "${COMP_WORDS[COMP_CWORD]}"
|
||||
else
|
||||
local i
|
||||
@ -317,10 +327,14 @@ __get_cword3()
|
||||
# 2: :
|
||||
# 3: c
|
||||
#
|
||||
# @oaram $1 string
|
||||
# @param $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.
|
||||
# @param $2 integer
|
||||
# $2 integer (optional) Return word according to $COMP_WORDBREAKS, negatively
|
||||
# offset by the value. For example, `__get_cword4 "=:" -1' returns the word
|
||||
# left of the current word, respecting the exclusions given at $1
|
||||
# See also:
|
||||
# _get_cword, main routine
|
||||
# __get_cword3, bash-3 variant
|
||||
@ -328,9 +342,10 @@ __get_cword3()
|
||||
[ ${BASH_VERSINFO[0]} -ge 4 ] &&
|
||||
__get_cword4()
|
||||
{
|
||||
local exclude="$1" n_idx="${2:-0}"
|
||||
local i
|
||||
local LC_CTYPE=C
|
||||
local WORDBREAKS=$COMP_WORDBREAKS
|
||||
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:
|
||||
@ -338,32 +353,50 @@ __get_cword4()
|
||||
# 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/}
|
||||
WORDBREAKS="${WORDBREAKS//[\"\']/}"
|
||||
if [[ $exclude ]]; then
|
||||
for (( i=0; i<${#exclude}; ++i )); do
|
||||
local char="${exclude:$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
|
||||
local cur="${COMP_LINE:0:$COMP_POINT}"
|
||||
local tmp="$cur"
|
||||
|
||||
cur=${cur:$word_start}
|
||||
printf "%s" "$cur"
|
||||
local break_index word_start
|
||||
# return index of first occuring break character in $1; return 0 if none
|
||||
break_index() {
|
||||
if [[ $1 == *[$WORDBREAKS]* ]]; then
|
||||
local w="${1%[$WORDBREAKS]*}"
|
||||
echo $((${#w}+1))
|
||||
else
|
||||
echo 0
|
||||
fi
|
||||
}
|
||||
# return the index of the start of the last word in $@
|
||||
word_start() {
|
||||
local buf="$@"
|
||||
local start="$(break_index "$buf")"
|
||||
while [[ $start -ge 2 ]]; do
|
||||
# Get character before $start
|
||||
local char="${cur:$(( start - 2 )):1}"
|
||||
# If the WORDBREAK character isn't escaped, exit loop
|
||||
[[ $char != \\ ]] && break
|
||||
# The WORDBREAK character is escaped; recalculate $start
|
||||
buf="${COMP_LINE:0:$(( start - 2 ))}"
|
||||
start=$(break_index "$buf")
|
||||
done
|
||||
echo $start
|
||||
}
|
||||
|
||||
# calculate current word, negatively offset by n_idx
|
||||
cur="${tmp:$(word_start "$tmp")}"
|
||||
while [[ $n_idx -gt 0 ]]; do
|
||||
local tmp="${tmp%[$WORDBREAKS]$cur}" # truncate passed string
|
||||
local cur="${tmp:$(word_start "$tmp")}" # then recalculate
|
||||
((--n_idx))
|
||||
done
|
||||
echo -n "$cur"
|
||||
} # __get_cword4()
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user