aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Kiddle <opk@users.sourceforge.net>2003-11-13 17:25:59 +0000
committerOliver Kiddle <opk@users.sourceforge.net>2003-11-13 17:25:59 +0000
commit824961fd6dee35f650b5e29181d22fc71f14fd3a (patch)
tree0a16ba4db970d3f70c136cb2b86b028c3328a5d1
parent3bcec12bd0ec066cbc3d133d69823c8ae551dfff (diff)
downloadzsh-824961fd6dee35f650b5e29181d22fc71f14fd3a.tar.gz
zsh-824961fd6dee35f650b5e29181d22fc71f14fd3a.tar.xz
zsh-824961fd6dee35f650b5e29181d22fc71f14fd3a.zip
merge changes from 4.1
-rw-r--r--ChangeLog5
-rw-r--r--Completion/Base/Utility/_sep_parts146
2 files changed, 151 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index b19706b8b..aa354e62d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -34,6 +34,11 @@
permissions on directories in the fpath; also in case of symlinks,
find parent with ${^fpath:h} rather than ${^fpath}/..
+2003-09-21 Oliver Kiddle <opk@zsh.org>
+
+ * users/6606: Completion/Base/Utility/_sep_parts: handle any
+ matching control options passed down
+
2003-09-10 Wayne Davison <wayned@users.sourceforge.net>
* users/6529 + unposted: StartupFiles/zshenv: updated the comments
diff --git a/Completion/Base/Utility/_sep_parts b/Completion/Base/Utility/_sep_parts
new file mode 100644
index 000000000..6e6c1beed
--- /dev/null
+++ b/Completion/Base/Utility/_sep_parts
@@ -0,0 +1,146 @@
+#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 alternately 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 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'
+
+# 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 "$matcher[@]" -a "$arr"
+ [[ $#testarr -eq 0 && -n "$_comp_correct" ]] &&
+ compadd -O testarr "$matcher[@]" -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 "$matcher[@]" -a "$arr"
+ [[ $#testarr -eq 0 && -n "$_comp_correct" ]] &&
+ compadd -O testarr "$matcher[@]" -a "$arr"
+fi
+
+[[ $#testarr -eq 0 || ${#testarr[1]} -eq 0 ]] && return 1
+
+# Now we build the suffixes to give to the completion code.
+
+shift
+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 separators
+ # 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 "$matcher[@]" -a "$arr"
+ [[ $#tmparr -eq 0 && -n "$_comp_correct" ]] &&
+ compadd -O tmparr "$matcher[@]" - "$arr"
+
+ suffixes=("${(@)^suffixes[@]}${(q)1}${(@)^tmparr}")
+
+ 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}")
+
+# Add the matches for each of the suffixes.
+
+PREFIX="$pre"
+SUFFIX="$suf"
+for i in "$suffixes[@]"; do
+ compadd -U "$group[@]" "$expl[@]" "$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] ]]