Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Completing possible elements of a comma-separated list

Malte Starostik wrote:
> Thanks, these both work, the latter a little better as it accepts -M to get
> case-insensitivity.

With _values, you can use:

  args=( -M 'm:{a-zA-Z}={A-Za-z}' )
and then
  _values -O args -s , ...

_values will have the advantage that the same value will not be
completed twice in the list. Though you can do that manually with
something like:  attrs=( ${attrs:#(${~words[CURRENT]/,/|})} )

> for _multi_parts I'd need to add all possible permutations I gather? Anyway,

Yes. Not ideal if there are more than a few.

> this Works For Me (TM):
>     local -a attrs
>     local parts
>     attrs=($(slptool findattrs $words[2] | \
>                perl -pi -e 's#\(([^()]+)=[^()]*\),?#$1\n#g'))
>     parts="_sep_parts -M 'm:{a-zA-Z}={A-Za-z}'"
>     repeat $[${#attrs}*5] do
>         parts="$parts attrs ,";
>     done
>     eval $parts
> *5 is an arbitrary value that allows for listing attributes multiple times.

Surely $#attrs*5 will be far higher than necessary. You could instead
count the number of commas in the current word and add one to it:
  $(( 1 + ${#words[CURRENT]//[^,]/} ))

> I only wonder why it seems to ignore -M ...

Looks to me like _sep_parts is broken. I should first point out that
_sep_parts isn't used anywhere in the distributed completion functions
so it has probably had little real testing. It is also quite old.

_sep_parts tries to use both of compadd's -U and -M options together
yet they are in effect mutually exclusive: -U renders -M irrelevant. I
would have thought it should be using the matcher earlier when it does
compadd -O.

I was initially a bit mystified by this: why does _sep_parts go to all
the trouble of building an r: matcher for the suffix only to use
compadd -U thus making it irrelevant? However, looking at the history
of _sep_parts (or _comp_parts as it used to be called), it seems that
the original implementation predated the -O and -A options to compadd,
didn't use -U and will have needed the matcher where it was.

Would be good if you can try the patch though as you might spot a
problem (probably better to send any reply about it to zsh-workers


--- /usr/local/share/zsh/4.1.1-dev-1/functions/Completion/Base/_sep_parts	2003-09-10 21:01:11.000000000 +0200
+++ /home/opk/.zfunc/_sep_parts	2003-09-20 18:21:55.000000000 +0200
@@ -17,7 +17,7 @@
 # This function understands the `-J group', `-V group', and
 # `-X explanation' options.
-local str arr sep test testarr tmparr prefix suffixes matchers autosuffix
+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.
@@ -25,12 +25,6 @@
 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]}"
-  matcher=''
 # Get the string from the line.
@@ -58,9 +52,9 @@
   # Get the matching array elements.
-  builtin compadd -O testarr -a "$arr"
+  builtin compadd -O testarr "$matcher[@]" -a "$arr"
   [[ $#testarr -eq 0 && -n "$_comp_correct" ]] &&
-    compadd -O testarr -a "$arr"
+    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.
@@ -88,9 +82,9 @@
   # No more separators, build the matches.
-  builtin compadd -O testarr -a "$arr"
+  builtin compadd -O testarr "$matcher[@]" -a "$arr"
   [[ $#testarr -eq 0 && -n "$_comp_correct" ]] &&
-    compadd -O testarr -a "$arr"
+    compadd -O testarr "$matcher[@]" -a "$arr"
 [[ $#testarr -eq 0 || ${#testarr[1]} -eq 0 ]] && return 1
@@ -98,7 +92,6 @@
 # Now we build the suffixes to give to the completion code.
@@ -125,17 +118,12 @@
-  builtin compadd -O tmparr -a "$arr"
+  builtin compadd -O tmparr "$matcher[@]" -a "$arr"
   [[ $#tmparr -eq 0 && -n "$_comp_correct" ]] &&
-    compadd -O tmparr - "$arr"
+    compadd -O tmparr "$matcher[@]" - "$arr"
-  # 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
@@ -144,17 +132,12 @@
 (( $# )) && 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.
 for i in "$suffixes[@]"; do
-  compadd -U "$group[@]" "$expl[@]" "$matchers[@]" "$autosuffix[@]" "$opts[@]" \
+  compadd -U "$group[@]" "$expl[@]" "$autosuffix[@]" "$opts[@]" \
           -i "$IPREFIX" -I "$ISUFFIX" -p "$prefix" -s "$i" -a testarr

Messages sorted by: Reverse Date, Date, Thread, Author