mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-01-22 00:21:27 +01:00
moved from Completion/Core/_sep_parts
This commit is contained in:
parent
99c5c4c87a
commit
126524eab1
1 changed files with 163 additions and 0 deletions
163
Completion/Base/Utility/_sep_parts
Normal file
163
Completion/Base/Utility/_sep_parts
Normal file
|
@ -0,0 +1,163 @@
|
|||
#autoload
|
||||
|
||||
# This function can be used to separately complete parts of strings
|
||||
# where each part may be one of a set of matches and different parts
|
||||
# have different sets.
|
||||
# Arguments are alternatingly arrays and separator strings. Arrays may
|
||||
# be given by name or literally as words separated by white space in
|
||||
# parentheses, e.g.:
|
||||
#
|
||||
# _sep_parts '(foo bar)' @ hosts
|
||||
#
|
||||
# This will make this function complete the strings `foo' and `bar'.
|
||||
# If the string on the line contains a `@', the substring after it
|
||||
# will be completed from the array `hosts'. Of course more arrays
|
||||
# may be given, each preceded by another separator string.
|
||||
#
|
||||
# This function understands the `-J group', `-V group', and
|
||||
# `-X explanation' options.
|
||||
|
||||
local str arr sep test testarr tmparr prefix suffixes matchers autosuffix
|
||||
local matchflags opt group expl nm=$compstate[nmatches] opre osuf opts matcher
|
||||
|
||||
# Get the options.
|
||||
|
||||
zparseopts -D -a opts \
|
||||
'J+:=group' 'V+:=group' P: F: S: r: R: q 1 2 n 'X+:=expl' 'M+:=matcher'
|
||||
|
||||
if (( $#matcher )); then
|
||||
matcher="${matcher[2]}"
|
||||
else
|
||||
matcher=''
|
||||
fi
|
||||
|
||||
# Get the string from the line.
|
||||
|
||||
opre="$PREFIX"
|
||||
osuf="$SUFFIX"
|
||||
str="$PREFIX$SUFFIX"
|
||||
SUFFIX=""
|
||||
prefix=""
|
||||
|
||||
# Walk through the arguments to find the longest unambiguous prefix.
|
||||
|
||||
while [[ $# -gt 1 ]]; do
|
||||
# Get the next array and separator.
|
||||
arr="$1"
|
||||
sep="$2"
|
||||
|
||||
if [[ "$arr[1]" == '(' ]]; then
|
||||
tmparr=( ${=arr[2,-2]} )
|
||||
arr=tmparr
|
||||
fi
|
||||
|
||||
# Is the separator on the line?
|
||||
|
||||
[[ "$str" != *${sep}* ]] && break
|
||||
|
||||
# Get the matching array elements.
|
||||
|
||||
PREFIX="${str%%(|\\)${sep}*}"
|
||||
builtin compadd -O testarr -a "$arr"
|
||||
[[ $#testarr -eq 0 && -n "$_comp_correct" ]] &&
|
||||
compadd -O testarr -a "$arr"
|
||||
|
||||
# If there are no matches we give up. If there is more than one
|
||||
# match, this is the part we will complete.
|
||||
|
||||
(( $#testarr )) || return 1
|
||||
[[ $#testarr -gt 1 ]] && break
|
||||
|
||||
# Only one match, add it to the prefix and skip over it in `str',
|
||||
# continuing with the next array and separator.
|
||||
|
||||
prefix="${prefix}${testarr[1]}${sep}"
|
||||
str="${str#*${sep}}"
|
||||
shift 2
|
||||
done
|
||||
|
||||
# Get the array to work upon.
|
||||
|
||||
arr="$1"
|
||||
if [[ "$arr[1]" == '(' ]]; then
|
||||
tmparr=( ${=arr[2,-2]} )
|
||||
arr=tmparr
|
||||
fi
|
||||
|
||||
if [[ $# -le 1 || "$str" != *${2}* ]]; then
|
||||
# No more separators, build the matches.
|
||||
|
||||
PREFIX="$str"
|
||||
builtin compadd -O testarr -a "$arr"
|
||||
[[ $#testarr -eq 0 && -n "$_comp_correct" ]] &&
|
||||
compadd -O testarr -a "$arr"
|
||||
fi
|
||||
|
||||
[[ $#testarr -eq 0 || ${#testarr[1]} -eq 0 ]] && return 1
|
||||
|
||||
# Now we build the suffixes to give to the completion code.
|
||||
|
||||
shift
|
||||
matchers=()
|
||||
suffixes=("")
|
||||
autosuffix=()
|
||||
|
||||
while [[ $# -gt 0 && "$str" == *${1}* ]]; do
|
||||
# Remove anything up to the the suffix.
|
||||
|
||||
str="${str#*${1}}"
|
||||
|
||||
# Again, we get the string from the line up to the next separator
|
||||
# and build a pattern from it.
|
||||
|
||||
if [[ $# -gt 2 ]]; then
|
||||
PREFIX="${str%%${3}*}"
|
||||
else
|
||||
PREFIX="$str"
|
||||
fi
|
||||
|
||||
# We incrementally add suffixes by appending to them the seperators
|
||||
# and the strings from the next array that match the pattern we built.
|
||||
|
||||
arr="$2"
|
||||
if [[ "$arr[1]" == '(' ]]; then
|
||||
tmparr=( ${=arr[2,-2]} )
|
||||
arr=tmparr
|
||||
fi
|
||||
|
||||
builtin compadd -O tmparr -a "$arr"
|
||||
[[ $#tmparr -eq 0 && -n "$_comp_correct" ]] &&
|
||||
compadd -O tmparr - "$arr"
|
||||
|
||||
suffixes=("${(@)^suffixes[@]}${(q)1}${(@)^tmparr}")
|
||||
|
||||
# We want the completion code to generate the most specific suffix
|
||||
# for us, so we collect matching specifications that allow partial
|
||||
# word matching before the separators on the fly.
|
||||
|
||||
matchers=("$matchers[@]" "r:|${1:q}=*")
|
||||
shift 2
|
||||
done
|
||||
|
||||
# If we were given at least one more separator we make the completion
|
||||
# code offer it by appending it as a autoremovable suffix.
|
||||
|
||||
(( $# )) && autosuffix=(-qS "${(q)1}")
|
||||
|
||||
# If we have collected matching specifications, we build an array
|
||||
# from it that can be used as arguments to `compadd'.
|
||||
|
||||
[[ $#matchers+$#matcher -gt 0 ]] && matchers=(-M "$matchers $matcher")
|
||||
|
||||
# Add the matches for each of the suffixes.
|
||||
|
||||
PREFIX="$pre"
|
||||
SUFFIX="$suf"
|
||||
for i in "$suffixes[@]"; do
|
||||
compadd -U "$group[@]" "$expl[@]" "$matchers[@]" "$autosuffix[@]" "$opts[@]" \
|
||||
-i "$IPREFIX" -I "$ISUFFIX" -p "$prefix" -s "$i" -a testarr
|
||||
done
|
||||
|
||||
# This sets the return value to indicate that we added matches (or not).
|
||||
|
||||
[[ nm -ne compstate[nmatches] ]]
|
Loading…
Reference in a new issue