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

PATCH: tag aliases



Ok, here is the patch. Looks rather big, compared to the few changes
in the configuration stuff...


The idea is to let users invent their own tags. This is done with the
tag-order style, the syntax is currently:

  zstyle ':completion:...' tag-order 'foo:bar'

Here, `foo' is the tag offered by the completion function and `bar' is 
the alias. Completion will then proceed as if only `foo' were given,
i.e. the matches for that tag are generated. BUT: instead of using
`foo' to look up style, the function will use `bar'.

The alias may also be followed by another colon and a
description. This description will then be used for the `%d' in the
format style instead of the one given by the completion function.

This only really gets interesting when using more than one alias for
the same tag:

  zstyle ':completion:...' tag-order 'foo:bar foo:baz'

This will make the matches for the `foo' tag be generated *twice*,
once using `bar' as the tag for lookup and once with `baz'. And with
that one can set all our tag-specific styles separately, e.g.:

  zstyle ':completion:*' tag-order 'arguments values' \
      'options:-long-options:long\ options 
       options:-short-options:short\ options 
       options:-single-letter-options:single\ letter\ options'

  zstyle '*:-long-options' ignored-patterns '[-+](|-|[^-]*)'
  zstyle '*:-short-options' ignored-patterns '--*' '-?'
  zstyle '*:-single-letter-options' ignored-patterns '???*'

Can be used to separate long options, normal options and single letter 
options. Another example would be to use something like:

  zstyle ':completion:...' tag-order 'foo:-no-match' 'foo:-case-match'
  zstyle '*:-case-match' matcher 'm:{a-z}={A-Z}'

To try multiple matchers for a single type of matches.

[ This also quite clearly shows that we should try to find ways to make
  configuration easier, I'll make some suggestions below. ]

So, from a user's point of view the change is rather small, but the
fact that multiple tag aliases have to be tried everywhere is
responsible for most of the patch. I did this by adding two new
functions `_try' and `_loop' (here, too, I'd like to hear suggestions
for better names). Then I changed `_wanted' and `_requested' to allow
to do the loop over the tag aliases directly, calling a command with
arguments given to them. See the updated completion-style-guide for a
description and examples (or the manual, or the completion functions).


The other change we were discussing is file-patterns. This has been
cleaned up (as I hope you'll agree if you look at _files). You can now 
do things like:

  zstyle ':completion:*:*:rm:*' file-patterns \
      '*.o:object-files' ':all-files'

I.e., the strings in the value are of the form `<patterns>:<tag>',
again with an optional `:<description>' after it. _files will then
offer all the tags from the value (they are real tags, not aliases)
one after another (but you can change that with tag-order, as
usual). A empty pattern (as in the `:all-files' from the example) is
replaced by the pattern used by the completion function (if any).

That's it. Nicely simple?


Sooo... please note that this patch is almost only intended to provide 
the basic machinery on which we can now try to make things easier, as
I already said: especially (and probably: only; meaning that the code
may become more complicated) from the configuration side.


I think we should do this by looking at the things users might want to 
configure (I too often look at the way we can implement it, trying to
make that fast/easy, I know...).

One thing that already came up is the matcher style. It would be nice
to be able to have an easy way to say `in context ... first try this
match spec, then this, then...'. This can be done with alias tags, but 
certainly not convenient enough. It gets especially uncomfortable when 
the match specs are to be used for more than one tag. One way I can
think of to make that more comfortable is to allow patterns for the
tags in the tag-order style and allow tag aliases to be meant to be
appended to the original tag. For example:

  zstyle ... tag-order '*' '*:-case-match'
  zstyle '...:*-case-match' matcher 'm:{a-z}={A-Z}'

The '*' would be replaced by all tags offered, so they would first be
tried with no match specs (only those from matcher-list, that is).
If that produces no matches, it would be tried again with (if the
offered tags are `foo' and `bar') the tag aliases `foo-case-match' and 
`bar-case-match', so that the matcher from the second line would be
used for them. I.e. if the alias starts with a hyphen this means that
it is to be appended to the tag instead of replacing it for the
lookup. There is almost certainly a better syntax...

Aside: I can almost hear some people saying that we should just make
the matcher style try its values one after another. This would be
possible, by looking it up in _try and _loop and making them loop over 
the match specs if there are any. I actually tried that (before
implementing the tag aliases) and I don't like it. The problem is that 
we already have several loops (completers, matcher-list, offered tags, 
tag aliases; in this order) and for adding more loops we would have to 
decide how to nest them. For the ones this we have now, this is fairly 
obvious (with the probably exception of matcher-list). But for the
matcher style: should it be in the loop for the tag aliases or around
it. And then someone could say that ignored-patterns should be changed 
to try the patterns one after another -- another loop and again: how
should it be nested? Because of that I would definitely prefer to
leave the control flow as it is now and just try to find the most
convenient way to configure things.

Ok. Another thing people might want to configure is to give different
(sets of) patterns to ignore and to try them one after another. There
are two forms of this: use it to split groups of matches as in the
options example above and use it to really try first one pattern, if
that generates no matches, try the next pattern and so on. Of course
we can express that with tag-order -- its the difference between
putting it in one string and in separate strings. But both forms are
relatively complicated to configure at the moment. For the first form
the example above already shows that we had to give the `arguments values'
in the first string of the value to get the normal tag-order. I.e.
there is no easy way to express `*if* the tag foo is used, then always 
use the aliases bar and baz for it'. Of course we could easily extend
_tags (where tag-order is tested) to look up a style, say
`tag-aliases' for every tag it uses and, if the style is set, replace
the tag in its list with the values from that style. But I still hope
there is a better way (or maybe everyone likes this? it is certainly
easy to implement).

The second form is more complicated. I haven't had too many ideas
about this yet, but maybe it could be done with the patterns-for-tags
I suggested above. E.g.:

  zstyle ':completion:*:*:-command-:*' tag-order 'functions:-non-comp *' '*'
  zstyle '*:-non-comp' ignored-patterns '_*'

Would say to first try only functions not beginning with an underscore 
and all the other tags offered. I.e. the `*' would here mean `all
other tags', not `all tags', but I think this is sensible anyway,
because giving the same tag more than once in the same string doesn't
make much sense anyway.

The last thing on my list is (for now) the alternate set stuff. Of
course, this is also connected to the ignored-patterns style. The
thing I wasn't sure about is how to easily get the behaviour this
shows now when removing the alternate set altogether for the new
completion system. But its quite simple: we could just add a
completer, say `_ignored' that does normal completion (or that calls
all preceding completer in the way _prefix does it), but makes sure
that the ignored-patterns style and $fignore are not used. Since it
will only be called when no preceding completer generated matches, it
can easily be used to give the default behaviour by putting it at the
end of the completer style. It would also make the prefer-ignored syle 
superfluous because one could simply put the completer at the place
where one wants the ignored matches to be tried. In fact, I'm so
content with this, that I'd like to start write it. The only thing
that holds me back is that I don't know how religiously attached
people are to the alternate set stuff. Would anyone be against this
change? It would make completion from the alternate set somewhat
slower, because the list of matches would have to be build anew. But
with the finer control over the ignored-patterns style we have now,
one could fine-tune this anyway for the places where one wants to try
otherwise-ignored matches earlier.

And finally: Bart and I had this bit of discussion about changing the
completer field to always contain the `-<num>' suffix. And we didn't
like it. With the prefer-ignored change I just suggested I'm not sure
how important this will be in the future anyway, but I found another
possibility. We could make the completer style allow an alias-syntax
like the one from tag-order, too. I would then first change the style
so that one doesn't need to give the leading underscores (given that
people who use the completion system don't have to worry much about
function names, this change is probably overdue anyway). And then one
could do:

  zstyle ':completion:*' completer complete ... complete:foo

The first invocation of _complete would use the usual
`...:complete:...' in the context name but the second one would use
`...:foo:...' in the completer field.


Anyway... I'd like to hear your comments, suggestions and so
on. Especially about the configuration stuff, but also about the
syntax of the tag-order and file-patterns styles, about the names of
the two new functions (yes, I didn't even try to make them sensible
because I wasn't sure what I was implementing when I started it), and
so on...


Bye
 Sven

P.S.: Next to all the tags stuff the patch contains a small change for 
      the return value of `zstyle -t  ...', as `suggested' by Oliver.
      See _setup or the manual for enlightenment.

diff -ru ../z.old/Completion/Base/_arguments Completion/Base/_arguments
--- ../z.old/Completion/Base/_arguments	Wed Mar 22 09:13:13 2000
+++ Completion/Base/_arguments	Wed Mar 22 10:31:44 2000
@@ -4,7 +4,7 @@
 # descriptions given as arguments to this function.
 
 local long cmd="$words[1]" descr mesg subopts opt usecc autod
-local oldcontext="$curcontext"
+local oldcontext="$curcontext" hasopts
 
 long=$argv[(I)--]
 if (( long )); then
@@ -230,34 +230,38 @@
 
             # Anything inside `(...)' is added directly.
 
-            compadd "$subopts[@]" "$expl[@]" - ${=action[2,-2]}
+            _loop arguments expl "$descr" \
+                compadd "$subopts[@]" - ${=action[2,-2]}
           elif [[ "$action" = \{*\} ]]; then
 
             # A string in braces is evaluated.
 
-            eval "$action[2,-2]"
+            _loop arguments expl "$descr" eval "$action[2,-2]"
 
           elif [[ "$action" = \ * ]]; then
 
             # If the action starts with a space, we just call it.
 
 	    eval "action=( $action )"
-            "$action[@]"
+            _loop arguments expl "$descr" "$action[@]"
           else
 
-            # Otherwise we call it with the description-arguments built above.
+            # Otherwise we call it with the description-arguments.
 
             eval "action=( $action )"
-            "$action[1]" "$subopts[@]" "$expl[@]" "${(@)action[2,-1]}"
+            _loop arguments expl "$descr" \
+                "$action[1]" "$subopts[@]" "${(@)action[2,-1]}"
           fi
         fi
       fi
 
-      if [[ -z "$matched" ]] && _requested options &&
+      if [[ -z "$matched$hasopts" ]] && _requested options &&
           { ! zstyle -T ":completion:${curcontext}:options" prefix-needed ||
-          [[ "$origpre" = [-+]* ||
-             ( -z "$aret$mesg" && nm -eq compstate[nmatches] ) ]] } ; then
+            [[ "$origpre" = [-+]* ||
+            ( -z "$aret$mesg" && nm -eq compstate[nmatches] ) ]] } ; then
 	local prevpre="$PREFIX" previpre="$IPREFIX"
+
+	hasopts=yes
 
 	PREFIX="$origpre"
 	IPREFIX="$origipre"
diff -ru ../z.old/Completion/Base/_brace_parameter Completion/Base/_brace_parameter
--- ../z.old/Completion/Base/_brace_parameter	Wed Mar 22 09:13:13 2000
+++ Completion/Base/_brace_parameter	Wed Mar 22 09:14:05 2000
@@ -1,3 +1,3 @@
 #compdef -brace-parameter-
 
-_tags parameters && _parameters -e
+_wanted parameters && _parameters -e
diff -ru ../z.old/Completion/Base/_condition Completion/Base/_condition
--- ../z.old/Completion/Base/_condition	Wed Mar 22 09:13:13 2000
+++ Completion/Base/_condition	Wed Mar 22 09:14:05 2000
@@ -3,9 +3,9 @@
 local prev="$words[CURRENT-1]" ret=1
 
 if [[ "$prev" = -o ]]; then
-  _tags -C -o options && _options
+  _wanted -C -o options && _options
 elif [[ "$prev" = -([a-hkprsuwxLOGSN]|[no]t|ef) ]]; then
-  _tags -C "$prev" files && _files
+  _wanted -C "$prev" files && _files
 else
   if [[ "$PREFIX" = -* ]] ||
      ! zstyle -T ":completion:${curcontext}:options" prefix-needed; then
diff -ru ../z.old/Completion/Base/_default Completion/Base/_default
--- ../z.old/Completion/Base/_default	Wed Mar 22 09:13:13 2000
+++ Completion/Base/_default	Wed Mar 22 09:14:05 2000
@@ -12,7 +12,7 @@
   compcall "$opt[@]" || return 0
 fi
 
-_tags files || return 1
+_wanted files || return 1
 
 _files && return 0
 
diff -ru ../z.old/Completion/Base/_describe Completion/Base/_describe
--- ../z.old/Completion/Base/_describe	Wed Mar 22 09:13:13 2000
+++ Completion/Base/_describe	Wed Mar 22 10:32:09 2000
@@ -3,7 +3,7 @@
 # This can be used to add options or values with descriptions as matches.
 
 local _opt _expl _tmps _tmpd _tmpmd _tmpms _ret=1 _showd _nm _hide _args
-local _type=values
+local _type=values _descr
 
 # Get the option.
 
@@ -14,37 +14,40 @@
 
 # Do the tests. `showd' is set if the descriptions should be shown.
 
-_tags "$_type" || return 1
+_wanted "$_type" || return 1
 
 zstyle -T ":completion:${curcontext}:$_type" verbose && _showd=yes
 
-_description "$_type" _expl "$1"
+_descr="$1"
 shift
 
-if [[ -n "$_showd" ]]; then
-  compdescribe -I ' -- ' "$@"
-else
-  compdescribe -i "$@"
-fi
-
 [[ "$_type" = options ]] &&
     zstyle -t ":completion:${curcontext}:options" prefix-hidden && _hide=yes
 
-while compdescribe -g _args _tmpd _tmpmd _tmps _tmpms; do
+while _try "$_type" _expl "$_descr"; do
+
+  if [[ -n "$_showd" ]]; then
+    compdescribe -I ' -- ' "$@"
+  else
+    compdescribe -i "$@"
+  fi
+
+  while compdescribe -g _args _tmpd _tmpmd _tmps _tmpms; do
 
-  # See if we should remove the option prefix characters.
+    # See if we should remove the option prefix characters.
 
-  if [[ -n "$_hide" ]]; then
-    if [[ "$PREFIX" = --* ]]; then
-      _tmpd=( "${(@)_tmpd#--}" )
-      _tmps=( "${(@)_tmps#--}" )
-    elif [[ "$PREFIX" = [-+]* ]]; then
-      _tmpd=( "${(@)_tmpd#[-+]}" )
-      _tmps=( "${(@)_tmps#[-+]}" )
+    if [[ -n "$_hide" ]]; then
+      if [[ "$PREFIX" = --* ]]; then
+        _tmpd=( "${(@)_tmpd#--}" )
+        _tmps=( "${(@)_tmps#--}" )
+      elif [[ "$PREFIX" = [-+]* ]]; then
+        _tmpd=( "${(@)_tmpd#[-+]}" )
+        _tmps=( "${(@)_tmps#[-+]}" )
+      fi
     fi
-  fi
-  compadd "$_args[@]" "$_expl[@]" -ld _tmpd - "$_tmpmd[@]" && _ret=0
-  compadd "$_args[@]" "$_expl[@]" -d _tmps  - "$_tmpms[@]" && _ret=0
-done
 
+    compadd "$_args[@]" "$_expl[@]" -ld _tmpd - "$_tmpmd[@]" && _ret=0
+    compadd "$_args[@]" "$_expl[@]" -d _tmps  - "$_tmpms[@]" && _ret=0
+  done
+done
 return _ret
diff -ru ../z.old/Completion/Base/_first Completion/Base/_first
--- ../z.old/Completion/Base/_first	Wed Mar 22 09:13:13 2000
+++ Completion/Base/_first	Wed Mar 22 09:14:05 2000
@@ -34,7 +34,7 @@
 # completion of words from the history by adding two commas at the end 
 # and hitting TAB.
 #
-#     if [[ "$PREFIX" = *,, ]] && _tags history-words; then
+#     if [[ "$PREFIX" = *,, ]] && _wanted history-words; then
 #       local max i=1 expl
 #     
 #       PREFIX="$PREFIX[1,-2]"
diff -ru ../z.old/Completion/Base/_jobs Completion/Base/_jobs
--- ../z.old/Completion/Base/_jobs	Wed Mar 22 09:13:13 2000
+++ Completion/Base/_jobs	Wed Mar 22 09:14:05 2000
@@ -1,8 +1,8 @@
 #autoload
 
-local expl disp jobs job jids pfx='%' desc how
+local expl disp jobs job jids pfx='%' desc how expls
 
-_tags jobs || return 1
+_wanted jobs || return 1
 
 if [[ "$1" = -t ]]; then
   zstyle -T ":completion:${curcontext}:jobs" prefix-needed &&
@@ -15,15 +15,15 @@
 if [[ "$1" = -r ]]; then
   jids=( "${(@k)jobstates[(R)running*]}" )
   shift
-  _description jobs expl 'running job'
+  expls='running job'
 elif [[ "$1" = -s ]]; then
   jids=( "${(@k)jobstates[(R)running*]}" )
   shift
-  _description jobs expl 'suspended job'
+  expls='suspended job'
 else
   [[ "$1" = - ]] && shift
   jids=( "${(@k)jobtexts}" )
-  _description jobs expl job
+  expls=job
 fi
 
 if [[ -n "$desc" ]]; then
@@ -79,7 +79,7 @@
 fi
 
 if [[ -n "$desc" ]]; then
-  compadd "$@" "$expl[@]" -ld disp - "%$^jobs[@]"
+  _loop jobs expl "$expls" compadd "$@" -ld disp - "%$^jobs[@]"
 else
-  compadd "$@" "$expl[@]" - "%$^jobs[@]"
+  _loop jobs expl "$expls" compadd "$@" - "%$^jobs[@]"
 fi
diff -ru ../z.old/Completion/Base/_math Completion/Base/_math
--- ../z.old/Completion/Base/_math	Wed Mar 22 09:13:13 2000
+++ Completion/Base/_math	Wed Mar 22 09:14:06 2000
@@ -9,4 +9,4 @@
   SUFFIX="${SUFFIX%%[^a-zA-Z0-9_]*}"
 fi
 
-_tags parameters && _parameters
+_parameters
diff -ru ../z.old/Completion/Base/_parameter Completion/Base/_parameter
--- ../z.old/Completion/Base/_parameter	Wed Mar 22 09:13:13 2000
+++ Completion/Base/_parameter	Wed Mar 22 09:14:06 2000
@@ -1,3 +1,3 @@
 #compdef -parameter-
 
-_tags parameters && _parameters -e
+_parameters -e
diff -ru ../z.old/Completion/Base/_subscript Completion/Base/_subscript
--- ../z.old/Completion/Base/_subscript	Wed Mar 22 09:13:14 2000
+++ Completion/Base/_subscript	Wed Mar 22 09:14:06 2000
@@ -3,23 +3,23 @@
 local expl
 
 if [[ "$PREFIX" = :* ]]; then
-  _wanted characters expl 'character class' &&
-      compadd "$expl[@]" -p: -S ':]' alnum alpha blank cntrl digit graph \
-                                     lower print punct space upper xdigit
+  _wanted characters expl 'character class' \
+      compadd -p: -S ':]' alnum alpha blank cntrl digit graph \
+                          lower print punct space upper xdigit
 elif [[ ${(Pt)${compstate[parameter]}} = assoc* ]]; then
-  _wanted association-keys expl 'association key' &&
-      if [[ "$RBUFFER" = \]* ]]; then
-        compadd "$expl[@]" -S '' - "${(@kP)${compstate[parameter]}}"
-      else
-        compadd "$expl[@]" -S ']' - "${(@kP)${compstate[parameter]}}"
-      fi
+  local suf
+
+  [[ "$RBUFFER" != \]* ]] && suf=']'
+
+  _wanted association-keys expl 'association key' \
+      compadd -S "$suf" - "${(@kP)${compstate[parameter]}}"
 elif [[ ${(Pt)${compstate[parameter]}} = array* ]]; then
   local list i j ret=1 disp
 
   _tags indexes parameters
 
   while _tags; do
-    if _requested -V indexes expl 'array index'; then
+    if _requested indexes; then
       ind=( {1..${#${(P)${compstate[parameter]}}}} )
       if zstyle -T ":completion:${curcontext}:indexes" verbose; then
         list=()
@@ -38,9 +38,11 @@
       fi
 
       if [[ "$RBUFFER" = \]* ]]; then
-        compadd "$expl[@]" -S '' "$disp[@]" - "$ind[@]" && ret=0
+        _loop -V indexes expl 'array index' \
+            compadd -S '' "$disp[@]" - "$ind[@]" && ret=0
       else
-        compadd "$expl[@]" -S ']' "$disp[@]" - "$ind[@]" && ret=0
+        _loop -V indexes expl 'array index' \
+            compadd -S ']' "$disp[@]" - "$ind[@]" && ret=0
       fi
     fi
     _requested parameters && _parameters && ret=0
diff -ru ../z.old/Completion/Base/_tilde Completion/Base/_tilde
--- ../z.old/Completion/Base/_tilde	Wed Mar 22 09:13:14 2000
+++ Completion/Base/_tilde	Wed Mar 22 09:14:06 2000
@@ -18,10 +18,10 @@
 
 while _tags; do
   _requested users && _users "$suf[@]" "$@" && ret=0
-  _requested named-directories expl 'named directory' &&
-      compadd "$suf[@]" "$expl[@]" "$@" - "${(@k)nameddirs}"
+  _requested named-directories expl 'named directory' \
+      compadd "$suf[@]" "$@" - "${(@k)nameddirs}"
 
-  if _requested -V directory-stack expl 'directory stack' &&
+  if _requested directory-stack &&
      { ! zstyle -T ":completion:${curcontext}:directory-stack" prefix-needed ||
        [[ "$PREFIX" = [-+]* || nm -eq compstate[nmatches] ]] }; then
     if zstyle -T ":completion:${curcontext}:directory-stack" verbose; then
@@ -46,7 +46,8 @@
       list=( ${PREFIX[1]}{0..${#dirstack}} )
       disp=()
     fi
-    compadd "$expl[@]" "$suf[@]" "$disp[@]" -Q - "$list[@]" && ret=0
+    _loop -V directory-stack expl 'directory stack' \
+        compadd "$suf[@]" "$disp[@]" -Q - "$list[@]" && ret=0
   fi
   (( ret )) || return 0
 done
diff -ru ../z.old/Completion/Base/_values Completion/Base/_values
--- ../z.old/Completion/Base/_values	Wed Mar 22 09:13:14 2000
+++ Completion/Base/_values	Wed Mar 22 09:14:06 2000
@@ -18,7 +18,7 @@
 
   if ! compvalues -D descr action; then
 
-    _tags values || return 1
+    _wanted values || return 1
 
     curcontext="${oldcontext%:*}:values"
 
@@ -119,25 +119,26 @@
 
       # Anything inside `(...)' is added directly.
 
-      compadd "$subopts[@]" "$expl[@]" - ${=action[2,-2]}
+      _loop arguments expl "$descr" compadd "$subopts[@]" - ${=action[2,-2]}
     elif [[ "$action" = \{*\} ]]; then
 
       # A string in braces is evaluated.
 
-      eval "$action[2,-2]"
+      _loop arguments expl "$descr" eval "$action[2,-2]"
 
     elif [[ "$action" = \ * ]]; then
 
       # If the action starts with a space, we just call it.
 
       eval "action=( $action )"
-      "$action[@]"
+      _loop arguments expl "$descr" "$action[@]"
     else
 
       # Otherwise we call it with the description-arguments built above.
 
       eval "action=( $action )"
-      "$action[1]" "$subopts[@]" "$expl[@]" "${(@)action[2,-1]}"
+      _loop arguments expl "$descr" \
+          "$action[1]" "$subopts[@]" "${(@)action[2,-1]}"
     fi
   fi
 
diff -ru ../z.old/Completion/Builtins/_arrays Completion/Builtins/_arrays
--- ../z.old/Completion/Builtins/_arrays	Wed Mar 22 09:13:15 2000
+++ Completion/Builtins/_arrays	Wed Mar 22 09:14:07 2000
@@ -2,5 +2,4 @@
 
 local expl
 
-_wanted arrays expl array &&
-    compadd "$expl[@]" - "${(@k)parameters[(R)*array*]}"
+_wanted arrays expl array compadd - "${(@k)parameters[(R)*array*]}"
diff -ru ../z.old/Completion/Builtins/_autoload Completion/Builtins/_autoload
--- ../z.old/Completion/Builtins/_autoload	Wed Mar 22 09:13:15 2000
+++ Completion/Builtins/_autoload	Wed Mar 22 09:14:07 2000
@@ -2,5 +2,4 @@
 
 local expl
 
-_wanted functions expl 'shell function' &&
-    compadd "$expl[@]" - ${^fpath}/*(N:t)
+_wanted functions expl 'shell function' compadd - ${^fpath}/*(N:t)
diff -ru ../z.old/Completion/Builtins/_bindkey Completion/Builtins/_bindkey
--- ../z.old/Completion/Builtins/_bindkey	Wed Mar 22 09:13:15 2000
+++ Completion/Builtins/_bindkey	Wed Mar 22 09:14:07 2000
@@ -10,9 +10,7 @@
 local expl
 
 if [[ "$words[2]" = -*[DAN]* || "$words[CURRENT-1]" = -*M ]]; then
-  _wanted -C -M keymaps expl keymap &&
-      compadd "$expl[@]" - "$keymaps[@]"
+  _wanted -C -M keymaps expl keymap compadd - "$keymaps[@]"
 else
-  _wanted widgets expl widget &&
-      compadd "$expl[@]" -M 'r:|-=* r:|=*' - "${(@k)widgets}"
+  _wanted widgets expl widget compadd -M 'r:|-=* r:|=*' - "${(@k)widgets}"
 fi
diff -ru ../z.old/Completion/Builtins/_builtin Completion/Builtins/_builtin
--- ../z.old/Completion/Builtins/_builtin	Wed Mar 22 09:13:15 2000
+++ Completion/Builtins/_builtin	Wed Mar 22 09:14:07 2000
@@ -7,6 +7,5 @@
 else
   local expl
 
-  _wanted commands expl 'builtin command' &&
-      compadd "$expl[@]" "$@" - "${(k@)builtins}"
+  _wanted commands expl 'builtin command' compadd "$@" - "${(k@)builtins}"
 fi
diff -ru ../z.old/Completion/Builtins/_cd Completion/Builtins/_cd
--- ../z.old/Completion/Builtins/_cd	Wed Mar 22 09:13:15 2000
+++ Completion/Builtins/_cd	Wed Mar 22 09:14:07 2000
@@ -22,8 +22,7 @@
   rep=(${~PWD/$words[2]/*}~$PWD(-/N))
   # Now remove all the common parts of $PWD and the completions from this
   rep=(${${rep#${PWD%%$words[2]*}}%${PWD#*$words[2]}})
-  (( $#rep )) && _wanted -C replacement strings expl replacement &&
-      compadd "$expl[@]" $rep
+  (( $#rep )) && _wanted -C replacement strings expl replacement compadd $rep
 elif _popd || [[ $PREFIX != (\~|/|./|../)* && $#cdpath -ne 0 ]]; then
   local tdir tdir2
 
diff -ru ../z.old/Completion/Builtins/_command Completion/Builtins/_command
--- ../z.old/Completion/Builtins/_command	Wed Mar 22 09:13:15 2000
+++ Completion/Builtins/_command	Wed Mar 22 09:14:07 2000
@@ -6,6 +6,5 @@
 else
   local expl
 
-  _wanted commands expl 'external command' &&
-      compadd "$expl[@]" "$@" - "${(k@)commands}"
+  _wanted commands expl 'external command' compadd "$@" - "${(k@)commands}"
 fi
diff -ru ../z.old/Completion/Builtins/_compdef Completion/Builtins/_compdef
--- ../z.old/Completion/Builtins/_compdef	Wed Mar 22 09:13:15 2000
+++ Completion/Builtins/_compdef	Wed Mar 22 09:14:08 2000
@@ -16,24 +16,24 @@
 
 case $state in
   ccom)
-    _wanted commands expl 'completed command' &&
-        compadd "$expl[@]" - ${(k)_comps}
+    _wanted commands expl 'completed command' compadd - ${(k)_comps}
   ;;
   cfun)
-    if _wanted functions expl 'completion function'; then
+    if _wanted functions; then
       list=( ${^fpath:/.}/_(|*[^~])(N:t) )
-      if zstyle -T ":completion:${curcontext}" prefix-hidden; then
+      if zstyle -T ":completion:${curcontext}:functions" prefix-hidden; then
         disp=( ${list[@]#_} )
-        compadd "$expl[@]" -d disp - "$list[@]"
+        _loop functions expl 'completion function' compadd -d disp - "$list[@]"
       else
-        compadd "$expl[@]" - "$list[@]"
+        _loop functions expl 'completion function' compadd - "$list[@]"
       fi
     fi
   ;;
   style)
-    _wanted widgetstyle expl 'widget style' &&
-        compadd complete-word delete-char-or-list expand-or-complete \
-        expand-or-complete-prefix list-choices menu-complete \
-        menu-expand-or-complete reverse-menu-complete
+    _wanted widgetstyle expl 'widget style' \
+        compadd -M 'r:|-=* r:|=*' \
+            complete-word delete-char-or-list expand-or-complete \
+            expand-or-complete-prefix list-choices menu-complete \
+            menu-expand-or-complete reverse-menu-complete
   ;;
 esac
diff -ru ../z.old/Completion/Builtins/_echotc Completion/Builtins/_echotc
--- ../z.old/Completion/Builtins/_echotc	Wed Mar 22 09:13:15 2000
+++ Completion/Builtins/_echotc	Wed Mar 22 09:14:08 2000
@@ -2,7 +2,6 @@
 
 local expl
 
-_wanted arguments expl 'terminal capability' &&
-    compadd "$expl[@]" \
-            al dc dl do le up al bl cd ce cl cr \
+_wanted arguments expl 'terminal capability' \
+    compadd al dc dl do le up al bl cd ce cl cr \
             dc dl do ho is le ma nd nl se so up
diff -ru ../z.old/Completion/Builtins/_functions Completion/Builtins/_functions
--- ../z.old/Completion/Builtins/_functions	Wed Mar 22 09:13:16 2000
+++ Completion/Builtins/_functions	Wed Mar 22 09:14:08 2000
@@ -2,5 +2,4 @@
 
 local expl
 
-_wanted functions expl 'shell function' &&
-    compadd "$expl[@]" "$@" - "${(k@)functions}"
+_wanted functions expl 'shell function' compadd "$@" - "${(k@)functions}"
diff -ru ../z.old/Completion/Builtins/_hash Completion/Builtins/_hash
--- ../z.old/Completion/Builtins/_hash	Wed Mar 22 09:13:16 2000
+++ Completion/Builtins/_hash	Wed Mar 22 09:14:08 2000
@@ -4,15 +4,14 @@
 
 if [[ "$words[2]" = -*d* ]]; then
   if compset -P 1 '*='; then
-    _wanted -C -d-value files && _path_files -g '*(-/)'
+    _wanted -C -d-value files expl directories _path_files -/
   else
-    _wanted -C -d named-directories expl 'named directory' &&
-        compadd "$expl[@]" -q -S '=' - "${(@k)nameddirs}"
+    _wanted -C -d named-directories expl 'named directory' \
+        compadd -q -S '=' - "${(@k)nameddirs}"
   fi
 elif compset -P 1 '*='; then
   _wanted -C value values expl 'executable file' &&
       _files "$expl[@]" -g '*(-*)'
 else
-  _wanted -C name commands expl command &&
-      compadd "$expl[@]" -q -S '=' - "${(@k)commands}"
+  _wanted -C name commands expl command compadd -q -S '=' - "${(@k)commands}"
 fi
diff -ru ../z.old/Completion/Builtins/_limits Completion/Builtins/_limits
--- ../z.old/Completion/Builtins/_limits	Wed Mar 22 09:13:16 2000
+++ Completion/Builtins/_limits	Wed Mar 22 09:14:08 2000
@@ -2,5 +2,4 @@
 
 local expl
 
-_wanted limits expl 'process limits' &&
-    compadd "$expl[@]" ${${(f)"$(limit)"}%% *}
+_wanted limits expl 'process limits' compadd ${${(f)"$(limit)"}%% *}
diff -ru ../z.old/Completion/Builtins/_pids Completion/Builtins/_pids
--- ../z.old/Completion/Builtins/_pids	Wed Mar 22 09:13:16 2000
+++ Completion/Builtins/_pids	Wed Mar 22 09:14:09 2000
@@ -5,7 +5,7 @@
 
 local out list expl match desc listargs args
 
-_wanted processes expl 'process ID' || return 1
+_wanted processes || return 1
 
 if [[ "$1" = -m ]]; then
   match="${2}*"
@@ -29,5 +29,6 @@
   desc=()
 fi
 
-compadd "$expl[@]" "$@" "$desc[@]" - \
-    ${${${(M)${(f)"${out}"}[2,-1]:#[ 	]#${PREFIX}[0-9]#${SUFFIX}[ 	]#*${~match}}## #}%% *}
+_loop processes expl 'process ID' \
+    compadd "$@" "$desc[@]" - \
+        ${${${(M)${(f)"${out}"}[2,-1]:#[ 	]#${PREFIX}[0-9]#${SUFFIX}[ 	]#*${~match}}## #}%% *}
diff -ru ../z.old/Completion/Builtins/_popd Completion/Builtins/_popd
--- ../z.old/Completion/Builtins/_popd	Wed Mar 22 09:13:16 2000
+++ Completion/Builtins/_popd	Wed Mar 22 09:14:09 2000
@@ -12,7 +12,7 @@
 ! zstyle -T ":completion:${curcontext}:directory-stack" prefix-needed ||
     [[ $PREFIX = [-+]* ]] || return 1
 
-_wanted -V directory-stack expl 'directory stack' || return 1
+_wanted directory-stack || return 1
 
 if zstyle -T ":completion:${curcontext}:directory-stack" verbose; then
   # get the list of directories with their canonical number
@@ -39,4 +39,5 @@
   disp=()
 fi
 
-compadd "$expl[@]" "$@" "$disp[@]" -Q - "$list[@]"
+_loop -V directory-stack expl 'directory stack' \
+    compadd "$@" "$disp[@]" -Q - "$list[@]"
diff -ru ../z.old/Completion/Builtins/_sched Completion/Builtins/_sched
--- ../z.old/Completion/Builtins/_sched	Wed Mar 22 09:13:16 2000
+++ Completion/Builtins/_sched	Wed Mar 22 09:14:09 2000
@@ -4,7 +4,7 @@
 
 if [[ CURRENT -eq 2 ]]; then
   if compset -P -; then
-    _wanted -C - jobs expl 'scheduled jobs' || return 1
+    _wanted -C - jobs || return 1
 
     lines=(${(f)"$(sched)"})
     if zstyle -T ":completion:${curcontext}:jobs" verbose; then
@@ -12,7 +12,9 @@
     else
       disp=()
     fi
-    [[ -z $lines ]] || compadd "$expl[@]" "$disp[@]" - {1..$#lines}
+    [[ -z $lines ]] || _loop jobs expl 'scheduled jobs' \
+                           compadd "$disp[@]" - {1..$#lines}
+    return
   else
     _message 'time specification'
     return 1
diff -ru ../z.old/Completion/Builtins/_signals Completion/Builtins/_signals
--- ../z.old/Completion/Builtins/_signals	Wed Mar 22 09:13:16 2000
+++ Completion/Builtins/_signals	Wed Mar 22 09:14:09 2000
@@ -20,7 +20,7 @@
 
 [[ "$1" = -(|-) ]] && shift
 
-if _wanted signals expl signal &&
+if _wanted signals &&
        { [[ -z "$minus" ]] ||
          ! zstyle -T ":completion:${curcontext}:signals" prefix-needed ||
          [[ "$PREFIX" = -* ]] } ; then
@@ -32,6 +32,7 @@
   else
     disp=()
   fi
-  compadd "$@" "$expl[@]" "$disp[@]" -M 'm:{a-z}=${A-Z}' - \
-          "${minus}${(@)^signals[1,last]}"
+  _loop signals expl signal \
+      compadd "$@" "$disp[@]" -M 'm:{a-z}={A-Z}' - \
+              "${minus}${(@)^signals[1,last]}"
 fi
diff -ru ../z.old/Completion/Builtins/_stat Completion/Builtins/_stat
--- ../z.old/Completion/Builtins/_stat	Wed Mar 22 09:13:16 2000
+++ Completion/Builtins/_stat	Wed Mar 22 09:14:09 2000
@@ -9,10 +9,12 @@
 
   while _tags; do
     _requested files && _files && ret=0
-    _requested options expl 'inode element' &&
+    _requested options &&
         { ! zstyle -T ":completion:${curcontext}:options" prefix-needed ||
           [[ "$PREFIX[1]" = + || ret -eq 1 ]] } &&
-        compadd "$expl[@]" - +device +inode +mode +nlink +uid +gid +rdev \
-                             +size +atime +mtime +ctime +blksize +block +link
+        _loop options expl 'inode element' \
+            compadd - +device +inode +mode +nlink +uid +gid +rdev \
+                      +size +atime +mtime +ctime +blksize +block +link
+    (( ret )) || return 0
   done
 fi
diff -ru ../z.old/Completion/Builtins/_vars Completion/Builtins/_vars
--- ../z.old/Completion/Builtins/_vars	Wed Mar 22 09:13:17 2000
+++ Completion/Builtins/_vars	Wed Mar 22 09:14:10 2000
@@ -16,9 +16,9 @@
   if [[ ${(tP)var} = assoc* ]]; then
     local expl
 
-    _wanted -C subscript association-keys expl 'association key' &&
-        compadd "$expl[@]" $addclose - ${(kP)var}
+    _wanted -C subscript association-keys expl 'association key' \
+        compadd $addclose - ${(kP)var}
   fi
 else
-  _tags parameters && _parameters
+  _wanted parameters && _parameters
 fi
diff -ru ../z.old/Completion/Builtins/_zftp Completion/Builtins/_zftp
--- ../z.old/Completion/Builtins/_zftp	Wed Mar 22 09:13:17 2000
+++ Completion/Builtins/_zftp	Wed Mar 22 09:14:10 2000
@@ -13,8 +13,8 @@
 
 if [[ $words[1] = zftp ]]; then
   if [[ $CURRENT -eq 2 ]]; then
-    _wanted commands expl sub-command &&
-        compadd "$expl[@]" open params user login type ascii binary mode put \
+    _wanted commands expl sub-command \
+        compadd open params user login type ascii binary mode put \
           putat get getat append appendat ls dir local remote mkdir rmdir \
           session rmsession
     return
@@ -28,49 +28,51 @@
 case $subcom in
   *(cd|ls|dir))
     # complete remote directories
-    _tags directories && zfcd_match $PREFIX $SUFFIX
+    _wanted directories && zfcd_match $PREFIX $SUFFIX
     ;;
 
   *(get(|at)|gcp|delete|remote))
     # complete remote files
-    _tags files && zfget_match $PREFIX $SUFFIX
+    _wanted files && zfget_match $PREFIX $SUFFIX
     ;;
 
   *(put(|at)|pcp))
     # complete local files
-    _tags files && _files
+    _wanted files && _files
     ;;
 
   *(open|anon|params))
     # complete hosts:  should do cleverer stuff with user names
-    _tags hosts && _hosts
+    _wanted hosts && _hosts
     ;;
 
   *(goto|mark))
     # complete bookmarks.  First decide if ncftp mode is go.
-    _wanted bookmarks expl bookmark || return 1
+    _wanted bookmarks || return 1
     if [[ $words[2] = -*n* ]]; then
       if [[ -f ~/.ncftp/bookmarks ]]; then
-        compadd "$expl[@]" - $(awk -F, 'NR > 2 { print $1 }' ~/.ncftp/bookmarks)
+        _loop bookmarks expl bookmark \
+            compadd - $(awk -F, 'NR > 2 { print $1 }' ~/.ncftp/bookmarks)
       fi
     else
       if [[ -f ${ZFTP_BMFILE:=${ZDOTDIR:-$HOME}/.zfbkmarks} ]]; then
-        compadd "$expl[@]" - $(awk '{print $1}' $ZFTP_BMFILE)
+        _loop bookmarks expl bookmark \
+            compadd - $(awk '{print $1}' $ZFTP_BMFILE)
       fi
     fi
     ;;
 
   *session)
     # complete sessions, excluding the current one.
-    _wanted sessions expl 'another FTP session' &&
-        compadd "$expl[@]" - ${$(zftp session):#$ZFTP_SESSION}
+    _wanted sessions expl 'another FTP session' \
+        compadd - ${$(zftp session):#$ZFTP_SESSION}
     ;;
 
   *transfer)
     # complete arguments like sess1:file1 sess2:file2
     if [[ $PREFIX = *:* ]]; then
       # complete file in the given session
-      _tags files || return 1
+      _wanted files || return 1
       local sess=${PREFIX%%:*} oldsess=$ZFTP_SESSION
       compset -p $(( $#sess + 1 ))
       [[ -n $sess ]] && zftp session $sess
@@ -78,8 +80,7 @@
       [[ -n $sess && -n $oldsess ]] && zftp session $oldsess
     else
       # note here we can complete the current session
-      _wanted sessions expl 'FTP session' &&
-          compadd "$expl[@]" -S : - $(zftp session)
+      _wanted sessions expl 'FTP session' compadd -S : - $(zftp session)
     fi
     ;;
 
diff -ru ../z.old/Completion/Builtins/_zle Completion/Builtins/_zle
--- ../z.old/Completion/Builtins/_zle	Wed Mar 22 09:13:17 2000
+++ Completion/Builtins/_zle	Wed Mar 22 09:14:10 2000
@@ -3,8 +3,8 @@
 local expl
 
 if [[ "$words[2]" = -N && CURRENT -eq 3 ]]; then
-  _wanted -C -N functions expl 'widget shell function' &&
-      compadd "$expl[@]" "$@" - "${(k@)functions}" && ret=0
+  _wanted -C -N functions expl 'widget shell function' \
+      compadd "$@" - "${(k@)functions}"
 else
-  _wanted widgets expl widget && compadd "$expl[@]" - "${(@k)widgets}"
+  _wanted widgets expl widget compadd - "${(@k)widgets}"
 fi
diff -ru ../z.old/Completion/Builtins/_zmodload Completion/Builtins/_zmodload
--- ../z.old/Completion/Builtins/_zmodload	Wed Mar 22 09:13:17 2000
+++ Completion/Builtins/_zmodload	Wed Mar 22 09:14:10 2000
@@ -3,11 +3,9 @@
 local fl="$words[2]" expl
 
 if [[ "$fl" = -*(a*u|u*a)* || "$fl" = -*a* && CURRENT -ge 4 ]]; then
-  _wanted builtins expl 'builtin command' &&
-      compadd "$expl[@]" "$@" - "${(k@)builtins}"
+  _wanted builtins expl 'builtin command' compadd "$@" - "${(k@)builtins}"
 elif [[ "$fl" = -*u* ]]; then
-  _wanted modules expl module && compadd "$expl[@]" - "${(@k)modules}"
+  _wanted modules expl module compadd - "${(@k)modules}"
 else
-  _wanted files expl 'module file' &&
-      _files "$expl[@]" -W module_path -/g '*.s[ol](:r)'
+  _wanted files expl 'module file' _files -W module_path -/g '*.s[ol](:r)'
 fi
diff -ru ../z.old/Completion/Builtins/_zpty Completion/Builtins/_zpty
--- ../z.old/Completion/Builtins/_zpty	Wed Mar 22 09:13:17 2000
+++ Completion/Builtins/_zpty	Wed Mar 22 09:14:10 2000
@@ -11,13 +11,13 @@
   '(-e -b -d -w -r)-L[list defined commands as calls]' \
   '*::args:_normal'
 
-if [[ $state = name ]] && _wanted zptynames expl 'zpty command names'; then
+if [[ $state = name ]] && _wanted names; then
   list=( ${${(f)"$(zpty)"}#*\) } )
   names=( ${list%%:*} )
   if zstyle -T ":completion:${curcontext}" verbose; then
     zformat -a list ' --' ${${(f)"$(zpty)"}#*\) }
-    compadd "$expl[@]" -d list - "$names[@]"
+    _loop names expl 'zpty command names' compadd -d list - "$names[@]"
   else
-    compadd "$expl[@]" - "$names[@]"
+    _loop names expl 'zpty command names' compadd - "$names[@]"
   fi
 fi
diff -ru ../z.old/Completion/Builtins/_zstyle Completion/Builtins/_zstyle
--- ../z.old/Completion/Builtins/_zstyle	Wed Mar 22 09:13:17 2000
+++ Completion/Builtins/_zstyle	Wed Mar 22 09:14:10 2000
@@ -41,7 +41,6 @@
   list-packed		 c:bool
   list-rows-first	 c:bool
   local			 c:
-  matcher		 c:
   matcher-list		 c:
   max-errors		 c:
   menu			 c:boolauto
@@ -94,9 +93,9 @@
 
   case "$ostate" in
     contexts)
-      if _wanted contexts expl context; then
+      if _wanted contexts; then
         if [[ $PREFIX != :*: ]]; then
-	  compadd -P : -S : "$expl[@]" completion zftp
+	  _loop contexts expl context compadd -P : -S : completion zftp
         elif [[ $PREFIX = :completion:* ]]; then
           mesg=''
           case "$PREFIX" in
@@ -118,8 +117,8 @@
       else
         ctop=cz
       fi
-      _wanted styles expl style &&
-         compadd "$expl[@]" -M 'r:|-=* r:|=*' - ${(k)styles[(R)[^:]#[$ctop][^:]#:*]}
+      _wanted styles expl style \
+         compadd -M 'r:|-=* r:|=*' - ${(k)styles[(R)[^:]#[$ctop][^:]#:*]}
       ;;
       
     style-arg)
@@ -127,32 +126,28 @@
       ;;
 
     bool) 
-      _wanted values expl boolean &&
-	compadd "$expl[@]" true false
+      _wanted values expl boolean compadd true false
       ;;
 
     boolauto) 
-      _wanted values expl boolean &&
-	compadd "$expl[@]" true false auto select
+      _wanted values expl boolean compadd true false auto select
       ;;
 
     cursor)
       if [[ "$words[2]" = *:completion:inc* ]]; then
-        _wanted values expl 'cursor positioning' &&
-	  compadd "$expl[@]" complete key default
+        _wanted values expl 'cursor positioning' compadd complete key default
       elif [[ "$words[2]" = *:completion::* ]]; then
-        _wanted values expl 'cursor positioning' &&
-	  compadd "$expl[@]" true false
+        _wanted values expl 'cursor positioning' compadd true false
       else
-        _wanted values expl 'cursor positioning' &&
-	  compadd "$expl[@]" complete key default true false
+        _wanted values expl 'cursor positioning' \
+	  compadd complete key default true false
       fi
       ;;
 
     completer)
-      _wanted values expl completer &&
-	compadd "$expl[@]" _complete _approximate _correct _match \
-          _expand _list _menu _oldlist
+      _wanted values expl completer \
+	compadd _complete _approximate _correct _match \
+                _expand _list _menu _oldlist _next_tags
       ;;
 
     user-host-port)
@@ -177,32 +172,32 @@
       ;;
 
     listwhen)
-      _wanted values expl 'when to list completions' &&
-	compadd "$expl[@]" always never sometimes
+      _wanted values expl 'when to list completions' \
+	compadd always never sometimes
       ;;
 
     packageset)
-      _wanted values expl 'default package set' &&
-        compadd "$expl[@]" available installed uninstalled
+      _wanted values expl 'default package set' \
+        compadd available installed uninstalled
       ;;
 
     progress)
-      _wanted values expl 'progress meter style' &&
-        compadd "$expl[@]" none bar percent
+      _wanted values expl 'progress meter style' \
+        compadd none bar percent
       ;;
 
     sdirs)
-      _wanted values expl 'whether to complete . or ..' &&
-        compadd "$expl[@]" true false ..
+      _wanted values expl 'whether to complete . or ..' \
+        compadd true false ..
       ;;
 
     stop)
-      _wanted values expl 'when to insert matches' &&
-	compadd "$expl[@]" true false verbose
+      _wanted values expl 'when to insert matches' \
+	compadd true false verbose
       ;;
 
     tag)
-      _wanted tags expl tag && compadd "$expl[@]" - $taglist
+      _wanted tags expl tag compadd - $taglist
       ;;
 
     user-host)
@@ -215,13 +210,13 @@
       ;;
 
     ignorepar)
-      _wanted values expl 'which parents to ignore' &&
-        compadd "$expl[@]" parent pwd .. directory
+      _wanted values expl 'which parents to ignore' \
+        compadd parent pwd .. directory
       ;;
 
     single-ignored)
-      _wanted values expl 'how to handle single alternate match' &&
-          compadd "$expl[@]" - show menu
+      _wanted values expl 'how to handle single alternate match' \
+          compadd - show menu
       ;;
 
     _*)
diff -ru ../z.old/Completion/Commands/_next_tags Completion/Commands/_next_tags
--- ../z.old/Completion/Commands/_next_tags	Wed Mar 22 09:13:18 2000
+++ Completion/Commands/_next_tags	Wed Mar 22 13:23:01 2000
@@ -52,8 +52,13 @@
 _next_tags_sort() {
   local order tags tag nodef
 
-  zstyle -a ":completion:${curcontext}:" tag-order order ||
-    order=( 'arguments values' options globbed-files directories all-files )
+  if ! zstyle -a ":completion:${curcontext}:" tag-order order; then
+    if (( $+_comp_default_tags )); then
+      order=( "$_comp_default_tags[@]" )
+    else
+      order=( 'arguments values' options )
+    fi
+  fi
 
   # But we also remove the tags we've already tried...
 
diff -ru ../z.old/Completion/Core/_alternative Completion/Core/_alternative
--- ../z.old/Completion/Core/_alternative	Wed Mar 22 09:13:19 2000
+++ Completion/Core/_alternative	Wed Mar 22 09:14:11 2000
@@ -44,24 +44,26 @@
 
         # Anything inside `(...)' is added directly.
 
-        compadd "$subopts[@]" "$expl[@]" - ${=action[2,-2]}
+        _loop "${def%%:*}" expl "$descr" \
+            compadd "$subopts[@]" - ${=action[2,-2]}
       elif [[ "$action" = \{*\} ]]; then
 
         # A string in braces is evaluated.
 
-        eval "$action[2,-2]"
+        _loop "${def%%:*}" expl "$descr" eval "$action[2,-2]"
       elif [[ "$action" = \ * ]]; then
 
         # If the action starts with a space, we just call it.
 
         eval "action=( $action )"
-        "$action[@]"
+        _loop "${def%%:*}" expl "$descr" "$action[@]"
       else
 
         # Otherwise we call it with the description-arguments built above.
 
         eval "action=( $action )"
-        "$action[1]" "$subopts[@]" "$expl[@]" "${(@)action[2,-1]}"
+        _loop "${def%%:*}" expl "$descr" \
+            "$action[1]" "$subopts[@]" "${(@)action[2,-1]}"
       fi
     fi
   done
diff -ru ../z.old/Completion/Core/_files Completion/Core/_files
--- ../z.old/Completion/Core/_files	Wed Mar 22 09:13:20 2000
+++ Completion/Core/_files	Wed Mar 22 11:28:51 2000
@@ -1,105 +1,61 @@
 #autoload
 
-local opts opt type=file glob group gopts dopts aopts tmp _file_pat_checked=yes
-local hasign ign
+local opts tmp glob pats tags expl tag ret=1 i pat descr minus
+local _comp_default_tags
 
 zparseopts -a opts \
-    '/=tmp' 'f=tmp' 'g+:-=tmp' q n 1 2 P: S: r: R: W: X: M+: F: \
-    'J:=group' 'V:=group'
+    '/=tmp' 'f=tmp' 'g+:-=tmp' q n 1 2 P: S: r: R: W: X+: M+: F: J+: V+:
 
 type="${(@j::M)${(@)tmp#-}#?}"
-[[ -n "$type" ]] || type=f
-if (( $tmp[(I)-g*] )); then
-  gopts=( -g ${(j: :)${(M)tmp:#-g*}#-g} )
-else
-  gopts=()
-fi
-(( $opts[(I)-F] )) && hasign=yes
-
-[[ "$group[2]" = files ]] && opts=("$opts[@]" "$group[@]") group=()
+(( $tmp[(I)-g*] )) && glob="${(j: :)${(M)tmp:#-g*}#-g}"
 
-ign=()
-
-zstyle -s ":completion:${curcontext}:all-files" file-patterns tmp &&
-    [[ -n "$tmp" ]] &&
-        aopts=(-g "$tmp")
-
-if zstyle -s ":completion:${curcontext}:directories" file-patterns tmp &&
-   [[ -n "$tmp" ]]; then
-  dopts=(-g "$tmp")
-  if [[ "$type" = (*/*g*|*g*/*) ]]; then
-    type=g
-  elif [[ "$type" != *[/g]* ]]; then
-    type="${type}/"
-  fi
+if zstyle -a ":completion:${curcontext}:" file-patterns pats; then
+  [[ "$type" = */* ]] && glob="$glob *(-/)"
+  pats=( \ ${(M)^${pats/#:/ ${glob:-\*}:}:#*[^\\]:*} )
 else
-  dopts=(-/)
-fi
-if zstyle -s ":completion:${curcontext}:globbed-files" file-patterns tmp &&
-   [[ -n "$tmp" ]]; then
-  gopts=(-g "$tmp")
-  if [[ "$type" != (*/*g*|*g*/*) ]]; then
-    if [[ "$type" = *[g/]* ]]; then
-      type=g
+  if [[ "$type" = *g* ]]; then
+    if [[ "$type" = */* ]]; then
+      pats=( " ${glob//:/\\:} *(-/):globbed-files" '*:all-files' )
     else
-      type=ga
+      pats=( " ${glob//:/\\:}:globbed-files"
+             '*(-/):directories' '*:all-files' )
     fi
+  elif [[ "$type" = */* ]]; then
+    pats=( '*(-/):directories' '*:all-files' )
+  else
+    pats=( '*:all-files' )
   fi
 fi
 
-case "$type" in
-*/*g*|*g*/*) _tags globbed-files all-files             ;;
-*a*g*|*g*a*) _tags globbed-files all-files             ;;
-*g*)         _tags globbed-files directories all-files ;;
-*/*)         _tags directories all-files               ;;
-*)           _tags all-files                           ;;
-esac
+tags=( "${(@)${(@)pats#*[^\\]:}%%:*}" )
+_comp_default_tags=( "$tags[@]" )
+
+_tags "$tags[@]"
 
 while _tags; do
-  if _requested all-files; then
-    if (( $#group )); then
-      group[2]=all-files
-      _setup all-files
-      [[ -z "$hasign" ]] &&
-        zstyle -a ":completion:${curcontext}:all-files" ignored-patterns _comp_ignore &&
-	  ign=(-F _comp_ignore)
-    fi
-    _path_files "$opts[@]" "$ign[@]" "$aopts[@]"
-    return
-  elif _requested directories; then
-    if _requested globbed-files; then
-      if (( $#group )); then
-        group[2]=globbed-files
-	_setup globbed-files
-        [[ -z "$hasign" ]] &&
-          zstyle -a ":completion:${curcontext}:all-files" ignored-patterns _comp_ignore &&
-	    ign=(-F _comp_ignore)
-      fi
-      _path_files "$opts[@]" "$ign[@]" "$dopts[@]" "$gopts[@]" && return 0
-    else
-      if (( $#group )); then
-        group[2]=directories
-	_setup directories
-        [[ -z "$hasign" ]] &&
-          zstyle -a ":completion:${curcontext}:all-files" ignored-patterns _comp_ignore &&
-	    ign=(-F _comp_ignore)
+
+  for tag in "$tags[@]"; do
+
+    if _requested "$tag"; then
+
+      i="$pats[(I)*[^\\\\]:${tag}(|:*)]"
+      pat="${${pats[i]%%:${tag}*}//\\\\:/:}"
+
+      if [[ i -gt 0 && "$pat" != \ # ]]; then
+        if [[ "$pats[i]" = *:${tag}:* ]]; then
+          descr="${pats[i]#*:${tag}:}"
+          minus=()
+        else
+          descr=file
+	  minus=(-)
+        fi
+        _loop "$tag" expl "$descr" \
+            _path_files -g "$pat" "$opts[@]" "$minus[@]" && ret=0
       fi
-      _path_files "$opts[@]" "$ign[@]" "$dopts[@]" && return 0
-    fi
-  elif _requested globbed-files; then
-    if (( $#group )); then
-      group[2]=globbed-files
-      _setup globbed-files
-      [[ -z "$hasign" ]] &&
-        zstyle -a ":completion:${curcontext}:all-files" ignored-patterns _comp_ignore &&
-	  ign=(-F _comp_ignore)
     fi
-    if [[ "$type" = (*/*g*|*g*/*) ]]; then
-      _path_files "$opts[@]" "$ign[@]" "$dopts[@]" "$gopts[@]" && return 0
-    else
-      _path_files "$opts[@]" "$ign[@]" "$gopts[@]" && return 0
-    fi
-  fi
+  done
+
+  (( ret )) || return 0
 done
 
 return 1
diff -ru ../z.old/Completion/Core/_main_complete Completion/Core/_main_complete
--- ../z.old/Completion/Core/_main_complete	Wed Mar 22 09:13:20 2000
+++ Completion/Core/_main_complete	Wed Mar 22 09:14:11 2000
@@ -20,7 +20,7 @@
 unsetopt markdirs globsubst shwordsplit nounset ksharrays
 
 local ctxt post ret=1 tmp _compskip format _comp_ignore \
-      _completers _completer _completer_num \
+      _completers _completer _completer_num curtag \
       _matchers _matcher _matcher_num _comp_tags \
       context state line opt_args val_args curcontext="$curcontext" \
       _last_nmatches=-1 _last_menu_style _def_menu_style _menu_style sel \
@@ -30,6 +30,9 @@
       _saved_insert="${compstate[insert]}"
 
 typeset -U _lastdescr
+
+_comp_opts=()
+_comp_tries=()
 
 [[ -z "$curcontext" ]] && curcontext=:::
 
diff -ru ../z.old/Completion/Core/_multi_parts Completion/Core/_multi_parts
--- ../z.old/Completion/Core/_multi_parts	Wed Mar 22 09:13:20 2000
+++ Completion/Core/_multi_parts	Wed Mar 22 09:14:11 2000
@@ -14,7 +14,7 @@
 # Get the options.
 
 zparseopts -D -a sopts \
-    'J:=group' 'V:=group' 'X:=expl' 'P:=opts' 'F:=opts' \
+    'J+:=group' 'V+:=group' 'X+:=expl' 'P:=opts' 'F:=opts' \
     S: r: R: q 1 2 n f 'M+:=match' 'i=imm'
 
 sopts=( "$sopts[@]" "$opts[@]" )
diff -ru ../z.old/Completion/Core/_options Completion/Core/_options
--- ../z.old/Completion/Core/_options	Wed Mar 22 09:13:21 2000
+++ Completion/Core/_options	Wed Mar 22 09:14:12 2000
@@ -4,6 +4,5 @@
 
 local expl
 
-_wanted zsh-options expl 'zsh option' &&
-    compadd "$expl[@]" "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - \
-        "${(@k)options}"
+_wanted zsh-options expl 'zsh option' \
+    compadd "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - "${(@k)options}"
diff -ru ../z.old/Completion/Core/_parameters Completion/Core/_parameters
--- ../z.old/Completion/Core/_parameters	Wed Mar 22 09:13:21 2000
+++ Completion/Core/_parameters	Wed Mar 22 09:14:12 2000
@@ -3,10 +3,6 @@
 # This should be used to complete parameter names if you need some of the
 # extra options of compadd. It completes only non-local parameters.
 
-local pars expl
+local expl
 
-_wanted parameters expl parameter || return 1
-
-pars=( ${(k)parameters[(R)^*local*]} )
-
-compadd "$expl[@]" "$@" - $pars
+_wanted parameters expl parameter compadd "$@" - ${(k)parameters[(R)^*local*]}
diff -ru ../z.old/Completion/Core/_path_files Completion/Core/_path_files
--- ../z.old/Completion/Core/_path_files	Wed Mar 22 09:13:21 2000
+++ Completion/Core/_path_files	Wed Mar 22 09:14:12 2000
@@ -20,7 +20,7 @@
 zparseopts -a mopts \
     'P:=pfxsfx' 'S:=pfxsfx' 'q=pfxsfx' 'r:=pfxsfx' 'R:=pfxsfx' \
     'W:=prepaths' 'F:=ignore' 'M+:=matcher' \
-    J: V: X: 1: 2: n: 'f=tmp1' '/=tmp1' 'g+:-=tmp1'
+    J+: V+: X+: 1: 2: n: 'f=tmp1' '/=tmp1' 'g+:-=tmp1'
 
 sopt="-${(@j::M)${(@)tmp1#-}#?}"
 (( $tmp1[(I)-[/g]*] )) && haspats=yes
@@ -54,20 +54,6 @@
   fi
 fi  
 
-if [[ -z "$_file_pat_checked" ]] &&
-   zstyle -s ":completion:${curcontext}:files" file-patterns tmp1 &&
-   [[ -n "$tmp1" ]]; then
-  if [[ "$tmp1" = '*(-/)' ]]; then
-    gopt=''
-    sopt=-/
-  else
-    gopt=yes
-    sopt=-
-  fi
-  pats=( $=tmp1 )
-  haspats=yes
-fi
-
 # If we were given no file selection option, we behave as if we were given
 # a `-f'.
 
@@ -155,7 +141,7 @@
 
 # If given no `-F' option, we may want to use $fignore, turned into patterns.
 
-[[ $#ignore -eq 0 && -z $gopt && -n $FIGNORE ]] && 
+[[ $#ignore -eq 0 && ( -z $gopt || "$pats" = \ #\*\ # ) && -n $FIGNORE ]] && 
    ignore=( "?*${^fignore[@]}" )
 
 if (( $#ignore )); then
diff -ru ../z.old/Completion/Core/_requested Completion/Core/_requested
--- ../z.old/Completion/Core/_requested	Wed Mar 22 09:13:21 2000
+++ Completion/Core/_requested	Wed Mar 22 09:36:16 2000
@@ -1,15 +1,20 @@
 #autoload
 
-local tag
+local gopt=-J
 
-if [[ "$1" = -[VJ]* ]]; then
-  tag="$2"
-else
-  tag="$1"
+if [[ "$1" = -([12]|)[VJ] ]]; then
+  gopt="$1"
+  shift
 fi
 
-comptags -R "$tag" && _comp_tags="$_comp_tags $tag" &&
-    if [[ $# -gt 1 ]]; then
-      _description "$@"
-      return 0
-    fi
+if comptags -R "$1"; then
+  _comp_tags="$_comp_tags $1"
+  if [[ $# -gt 3 ]]; then
+    _loop "$gopt" "$@"
+  elif [[ $# -gt 1 ]]; then
+    _description "$gopt" "$@"
+  fi
+  return 0
+else
+  return 1
+fi
diff -ru ../z.old/Completion/Core/_sep_parts Completion/Core/_sep_parts
--- ../z.old/Completion/Core/_sep_parts	Wed Mar 22 09:13:21 2000
+++ Completion/Core/_sep_parts	Wed Mar 22 09:14:12 2000
@@ -23,7 +23,7 @@
 # Get the options.
 
 zparseopts -D -a opts \
-    'J:=group' 'V:=group' P: F: S: r: R: q 1 2 n 'X:=expl' 'M+:=match'
+    'J+:=group' 'V+:=group' P: F: S: r: R: q 1 2 n 'X+:=expl' 'M+:=match'
 
 if (( $#match )); then
   match="${match[2]}"
diff -ru ../z.old/Completion/Core/_set_options Completion/Core/_set_options
--- ../z.old/Completion/Core/_set_options	Wed Mar 22 09:13:21 2000
+++ Completion/Core/_set_options	Wed Mar 22 09:14:13 2000
@@ -6,6 +6,5 @@
 
 local expl
 
-_wanted zsh-options expl 'set zsh option' &&
-    compadd "$expl[@]" "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - \
-            $=_set_options
+_wanted zsh-options expl 'set zsh option' \
+    compadd "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - $=_set_options
diff -ru ../z.old/Completion/Core/_setup Completion/Core/_setup
--- ../z.old/Completion/Core/_setup	Wed Mar 22 09:13:21 2000
+++ Completion/Core/_setup	Wed Mar 22 09:22:56 2000
@@ -18,42 +18,34 @@
 
 fi
 
-if zstyle -s ":completion:${curcontext}:$1" list-packed val; then
-  if [[ "$val" = (yes|true|1|on) ]]; then
-    compstate[list]="${compstate[list]} packed"
-  else
-    compstate[list]="${compstate[list]:gs/packed//}"
-  fi
+if zstyle -t ":completion:${curcontext}:$1" list-packed; then
+  compstate[list]="${compstate[list]} packed"
+elif [[ $? -eq 1 ]]; then
+  compstate[list]="${compstate[list]:gs/packed//}"
 else
   compstate[list]="$_saved_list"
 fi
 
-if zstyle -s ":completion:${curcontext}:$1" list-rows-first val; then
-  if [[ "$val" = (yes|true|1|on) ]]; then
-    compstate[list]="${compstate[list]} rows"
-  else
-    compstate[list]="${compstate[list]:gs/rows//}"
-  fi
+if zstyle -t ":completion:${curcontext}:$1" list-rows-first; then
+  compstate[list]="${compstate[list]} rows"
+elif [[ $? -eq 1 ]]; then
+  compstate[list]="${compstate[list]:gs/rows//}"
 else
   compstate[list]="$_saved_list"
 fi
 
-if zstyle -s ":completion:${curcontext}:$1" last-prompt val; then
-  if [[ "$val" = (yes|true|1|on) ]]; then
-    compstate[last_prompt]=yes
-  else
-    compstate[last_prompt]=''
-  fi
+if zstyle -t ":completion:${curcontext}:$1" last-prompt; then
+  compstate[last_prompt]=yes
+elif [[ $? -eq 1 ]]; then
+  compstate[last_prompt]=''
 else
   compstate[last_prompt]="$_saved_lastprompt"
 fi
 
-if zstyle -s ":completion:${curcontext}:$1" accept-exact val; then
-  if [[ "$val" = (yes|true|1|on) ]]; then
-    compstate[exact]=accept
-  else
-    compstate[exact]=''
-  fi
+if zstyle -t ":completion:${curcontext}:$1" accept-exact; then
+  compstate[exact]=accept
+elif [[ $? -eq 1 ]]; then
+  compstate[exact]=''
 else
   compstate[exact]="$_saved_exact"
 fi
diff -ru ../z.old/Completion/Core/_tags Completion/Core/_tags
--- ../z.old/Completion/Core/_tags	Wed Mar 22 09:13:21 2000
+++ Completion/Core/_tags	Wed Mar 22 11:05:44 2000
@@ -50,21 +50,31 @@
              fi
              ;;
       \!*)   comptry "${(@)argv:#(${(j:|:)~${=tag[2,-1]}})}";;
-      ?*)    comptry ${=tag};;
+      ?*)    comptry ${${(ps: :)${tag//\\\\ /$'\0'}}//$'\0'/ };;
       esac
     done
 
-    [[ -z "$nodef" ]] && comptry "$@"
+    if [[ -z "$nodef" ]]; then
+      if (( $+_comp_default_tags )); then
+        for tag in "$_comp_default_tags[@]"; do
+          comptry "$tag"
+        done
+      else
+        comptry "$@"
+      fi
+    fi
   else
 
-    # The first ones give the default behaviour.
-
-    comptry arguments values
-    comptry options
-    comptry globbed-files
-    comptry directories
-    comptry all-files
+    # Use default tags...
 
+    if (( $+_comp_default_tags )); then
+      for tag in "$_comp_default_tags[@]"; do
+        comptry "$tag"
+      done
+    else
+      comptry arguments values
+      comptry options
+    fi
     comptry "$@"
   fi
 
diff -ru ../z.old/Completion/Core/_unset_options Completion/Core/_unset_options
--- ../z.old/Completion/Core/_unset_options	Wed Mar 22 09:13:21 2000
+++ Completion/Core/_unset_options	Wed Mar 22 09:14:13 2000
@@ -6,6 +6,5 @@
 
 local expl
 
-_wanted zsh-options expl 'unset zsh option' &&
-    compadd "$expl[@]" "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - \
-            $=_unset_options
+_wanted zsh-options expl 'unset zsh option' \
+    compadd "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - $=_unset_options
diff -ru ../z.old/Completion/Core/_wanted Completion/Core/_wanted
--- ../z.old/Completion/Core/_wanted	Wed Mar 22 09:13:21 2000
+++ Completion/Core/_wanted	Wed Mar 22 09:14:13 2000
@@ -1,6 +1,6 @@
 #autoload
 
-local targs tag
+local targs gopt=-J
 
 if [[ "$1" = -C?* ]]; then
   targs=( -C "${1[3,-1]}" )
@@ -12,15 +12,22 @@
   targs=()
 fi
 
-if [[ "$1" = -[VJ]* ]]; then
-  tag="$2"
-else
-  tag="$1"
+if [[ "$1" = -([12]|)[VJ] ]]; then
+  gopt="$1"
+  shift
 fi
 
-if [[ $# -gt 1 ]]; then
-  _tags "$targs[@]" "$tag" && _comp_tags="$_comp_tags $tag" &&
-    _description "$@"
+if [[ $# -gt 3 ]]; then
+  if _tags "$targs[@]" "$1"; then
+    _comp_tags="$_comp_tags $1"
+
+    _loop -t "$gopt" "$@"
+  else
+    return 1
+  fi
+elif [[ $# -gt 1 ]]; then
+  _tags "$targs[@]" "$1" && _comp_tags="$_comp_tags $1" &&
+    _description "$gopt" "$@"
 else
-  _tags "$targs[@]" "$tag" && _comp_tags="$_comp_tags $tag"
+  _tags "$targs[@]" "$1" && _comp_tags="$_comp_tags $1"
 fi
diff -ru ../z.old/Completion/Debian/_apt Completion/Debian/_apt
--- ../z.old/Completion/Debian/_apt	Wed Mar 22 09:13:23 2000
+++ Completion/Debian/_apt	Wed Mar 22 09:14:14 2000
@@ -75,7 +75,7 @@
   nul=$'\0'
   qnul="\$'\\0'"
 
-  comp_bool='_tags values && compadd "$expl_bool[@]" '"$bool"
+  comp_bool='_wanted values && compadd "$expl_bool[@]" '"$bool"
   comp_intlevel= #"_message 'intlevel'"
   comp_configfile='_files "$expl_configfile[@]"'
   comp_arbitem= #"_message 'Foo::Bar=bar'"
@@ -384,7 +384,7 @@
     /$'check\0'/ \| \
     /$'source\0'/ /$'[^\0]#\0'/ :'_deb_packages "$expl_packages[@]" avail' \# \| \
     /$'help\0/' \| \
-    /"[]"/	:'_tags actions && compadd "$expl_action[@]" update upgrade install remove dist-upgrade dselect-upgrade clean autoclean check source help'
+    /"[]"/	:'_wanted actions expl_action action compadd update upgrade install remove dist-upgrade dselect-upgrade clean autoclean check source help'
 
   _apt-get () {
     local expl_action expl_packages
@@ -422,7 +422,7 @@
     /$'search\0'/ /$'[^\0]#\0'/ :'_message "pattern"' \| \
     /$'show\0'/ /$'[^\0]#\0'/ :'_deb_packages "$expl_packages[@]" avail' \# \| \
     /$'depends\0'/ \| \
-    /"[]"/ :'_tags actions && compadd "$expl_action[@]" help add gencaches showpkg stats dump dumpavail unmet check search show depends'
+    /"[]"/ :'_wanted actions expl_action action compadd help add gencaches showpkg stats dump dumpavail unmet check search show depends'
 
   _apt-cache () {
     local expl_action expl_packages expl_pkg_cache expl_src_cache
@@ -451,7 +451,7 @@
     -o,--option:arbitem \
     -- \
     /$'add\0'/ \| \
-    /"[]"/	:'_tags actions && compadd "$expl_action[@]" add'
+    /"[]"/	:'_wanted actions expl_action action compadd add'
 
   _apt-cdrom () {
     local expl_action expl_mount_point
@@ -473,11 +473,11 @@
     -- \
     /$'shell\0'/ \
       \( \
-	/$'[^\0]#\0'/ :'_tags parameters && compadd "$expl_shell_var[@]" - "${(@k)parameters}"' \
-	/$'[^\0]#\0'/ :'_tags configuration-keys && compadd "$expl_config_key[@]" - ${${(f)"$(apt-config dump 2>&1)"}% *}' \
+	/$'[^\0]#\0'/ :'_wanted parameters expl_shell_var "shell variable to assign" compadd - "${(@k)parameters}"' \
+	/$'[^\0]#\0'/ :'_wanted configuration-keys expl_config_key "configuration key" compadd - ${${(f)"$(apt-config dump 2>&1)"}% *}' \
       \) \# \| \
     /$'dump\0'/ \| \
-    /"[]"/	:'_tags actions && compadd "$expl_action[@]" shell dump'
+    /"[]"/	:'_wanted actions expl_action action compadd shell dump'
 
   _apt-config () {
     local expl_action expl_shell_var expl_config_key
diff -ru ../z.old/Completion/Debian/_deb_packages Completion/Debian/_deb_packages
--- ../z.old/Completion/Debian/_deb_packages	Wed Mar 22 09:13:23 2000
+++ Completion/Debian/_deb_packages	Wed Mar 22 09:14:14 2000
@@ -51,7 +51,7 @@
 
   _deb_packages_update_$pkgset
 
-  _tags packages && compadd "$expl[@]" - "${(@P)cachevar}"
+  _wanted packages && compadd "$expl[@]" - "${(@P)cachevar}"
 }
 
 _deb_packages "$@"
diff -ru ../z.old/Completion/Linux/_rpm Completion/Linux/_rpm
--- ../z.old/Completion/Linux/_rpm	Wed Mar 22 09:13:24 2000
+++ Completion/Linux/_rpm	Wed Mar 22 09:14:14 2000
@@ -189,12 +189,12 @@
     state=package_file
     ;&
   package)
-    _wanted packages expl 'RPM package' &&
-        compadd "$expl[@]" -M 'r:|-=* r:|=*' - $(_call packages rpm -qa) && ret=0
+    _wanted packages expl 'RPM package' \
+        compadd -M 'r:|-=* r:|=*' - $(_call packages rpm -qa) && ret=0
     ;;
   package_file)
     if compset -P ftp://; then
-      _tags hosts && _hosts -S/ && ret=0
+      _hosts -S/ && ret=0
     else
       _alternative \
           'files:RPM package file:_files -g \*.\(\#i\)rpm' \
@@ -203,8 +203,8 @@
     ;;
   tags)
     if compset -P '*\{'; then
-      _wanted tags expl 'RPM tag' &&
-          compadd "$expl[@]" -M 'm:{a-z}={A-Z}' -S '\}' - \
+      _wanted tags expl 'RPM tag' \
+          compadd -M 'm:{a-z}={A-Z}' -S '\}' - \
                   "${(@)${(@f)$(_call tags rpm --querytags)}#RPMTAG_}" && ret=0
     else
       _message 'RPM format'
@@ -219,8 +219,6 @@
     else
       _description directories expl 'old path'
     fi
-
-    _tags directories || return 1
 
     _files "$expl[@]" -/ && ret=0
     ;;
diff -ru ../z.old/Completion/User/_archie Completion/User/_archie
--- ../z.old/Completion/User/_archie	Wed Mar 22 09:13:25 2000
+++ Completion/User/_archie	Wed Mar 22 09:14:14 2000
@@ -26,6 +26,6 @@
 serverhost)
   : ${(A)archie_servers:=${(M)$(_call hosts archie -L):#archie.*}}
 
-  _wanted hosts expl 'archie servers' && compadd "$expl[@]" -  $archie_servers
+  _wanted hosts expl 'archie servers' compadd -  $archie_servers
   ;;
 esac
diff -ru ../z.old/Completion/User/_cvs Completion/User/_cvs
--- ../z.old/Completion/User/_cvs	Wed Mar 22 09:13:26 2000
+++ Completion/User/_cvs	Wed Mar 22 09:14:15 2000
@@ -34,7 +34,7 @@
 	watchers "")
 
   if (( CURRENT == 1 )); then
-    _tags commands && { compadd "$@" ${(k)cmds} || compadd "$@" ${(kv)=cmds} }
+    _wanted commands && { compadd "$@" ${(k)cmds} || compadd "$@" ${(kv)=cmds} }
   else
     local curcontext="$curcontext"
 
@@ -371,7 +371,7 @@
   local expl
 
   if (( CURRENT == 2 )); then
-    _wanted values expl 'watch comamnd' && compadd on off add remove
+    _wanted values expl 'watch command' compadd on off add remove
   else
     case "$words[2]" in
       on|off) # "+lR"
@@ -427,14 +427,14 @@
     fi
   fi
 
-  _tags files && {
+  _wanted files && {
     compadd -M 'r:|[:@./]=* r:|=*' "$@" $_cvs_roots || _files "$@" -/
   }
 }
 
 (( $+functions[_cvs_tempdir] )) ||
 _cvs_tempdir () {
-  _tags directories && compadd "$@" $TMPPREFIX:h $TMPDIR /tmp
+  _wanted directories && compadd "$@" $TMPPREFIX:h $TMPDIR /tmp
 }
 
 (( $+functions[_cvs_user_variable] )) ||
@@ -450,29 +450,29 @@
 
 (( $+functions[_cvs_bindir] )) ||
 _cvs_bindir () {
-  _tags directories && { compadd "$@" /usr/local/bin || _files "$@" -/ }
+  _wanted directories && { compadd "$@" /usr/local/bin || _files "$@" -/ }
 }
 
 (( $+functions[_cvs_editor] )) ||
 _cvs_editor () {
-  _tags commands && compadd "$@" vi
+  _wanted commands && compadd "$@" vi
 }
 
 (( $+functions[_cvs_gzip_level] )) ||
 _cvs_gzip_level () {
-  _tags values && compadd "$@" 9
+  _wanted values && compadd "$@" 9
 }
 
 # define completion functions for cvs common options and arguments.
 
 (( $+functions[_cvs_D] )) ||
 _cvs_D () {
-  _tags values && compadd "$@" today yesterday week\ ago month\ ago
+  _wanted values && compadd "$@" today yesterday week\ ago month\ ago
 }
 
 (( $+functions[_cvs_k] )) ||
 _cvs_k () {
-  _tags values && compadd "$@" kv kvl k o b v
+  _wanted values && compadd "$@" kv kvl k o b v
 }
 
 (( $+functions[_cvs_m] )) ||
@@ -489,9 +489,8 @@
   if [[ $root = :* || ! -d $root ]]; then
     _message "module name"
   else
-    _wanted modules expl module &&
-        compadd "$expl[@]" - \
-            $root/^CVSROOT(:t) \
+    _wanted modules expl module \
+        compadd - $root/^CVSROOT(:t) \
             ${${(M)${(f)"$(<$root/CVSROOT/modules)"}:#[^#]*}%%[ 	]*}
   fi
 }
@@ -500,7 +499,7 @@
 _cvs_revisions () {
   local expl
 
-  _wanted values expl revision &&
+  _wanted values expl revision \
       compadd - ${${${(M)${(f)"$(cvs -q status -vl .)"}:#	*}##[ 	]##(No Tags Exist)#}%%[ 	]*}
 }
 
@@ -618,7 +617,7 @@
     local omit
     omit=(${pref}*(D:t))
     eval 'entries=(${entries:#('${(j:|:)${(@)omit:q}}')})'
-    _tags directories && compadd "$@" -P "$qpref" - ${entries:q} ||
+    _wanted directories && compadd "$@" -P "$qpref" - ${entries:q} ||
         _cvs_directories "$@"
   else
     _files "$@"
diff -ru ../z.old/Completion/User/_dd Completion/User/_dd
--- ../z.old/Completion/User/_dd	Wed Mar 22 09:13:26 2000
+++ Completion/User/_dd	Wed Mar 22 09:14:15 2000
@@ -6,9 +6,8 @@
   # If there's a comma present, ignore up to the last one.  The
   # test alone will have that effect.
   compset -p '*,'
-  _wanted values expl conversion &&
-      compadd "$expl[@]" -qS, -q \
-              ascii ebcdic ibm block unblock lcase ucase swab noerror sync
+  _wanted values expl conversion \
+      compadd -qS, ascii ebcdic ibm block unblock lcase ucase swab noerror sync
 elif compset -P 1 'if='; then
   _description files expl 'input file'
   _tilde_files "$expl[@]"
@@ -16,6 +15,6 @@
   _description files expl 'output file'
   _tilde_files "$expl[@]"
 else
-  _wanted values expl option &&
-      compadd "$expl[@]" -S '=' if of ibs obs bs cbs skip files seek count conv
+  _wanted values expl option \
+      compadd -S '=' if of ibs obs bs cbs skip files seek count conv
 fi
diff -ru ../z.old/Completion/User/_domains Completion/User/_domains
--- ../z.old/Completion/User/_domains	Wed Mar 22 09:13:26 2000
+++ Completion/User/_domains	Wed Mar 22 09:14:15 2000
@@ -16,5 +16,5 @@
   domains=( "$_cache_domains[@]" )
 fi
 
-_wanted domains expl domain &&
-    compadd -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' "$@" "$expl[@]" - "$domains[@]"
+_wanted domains expl domain \
+    compadd -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' "$@" - "$domains[@]"
diff -ru ../z.old/Completion/User/_gcc Completion/User/_gcc
--- ../z.old/Completion/User/_gcc	Wed Mar 22 09:13:27 2000
+++ Completion/User/_gcc	Wed Mar 22 09:14:15 2000
@@ -273,8 +273,8 @@
     'p[annotate assembler output]' && ret=0
   ;;
 library)
-  _wanted libraries expl library &&
-      compadd "$expl[@]" - ${^=LD_LIBRARY_PATH:-/usr/lib /usr/local/lib}/lib*.(a|so*)(:t:fr:s/lib//) && ret=0
+  _wanted libraries expl library \
+      compadd - ${^=LD_LIBRARY_PATH:-/usr/lib /usr/local/lib}/lib*.(a|so*)(:t:fr:s/lib//) && ret=0
   ;;
 esac
 
diff -ru ../z.old/Completion/User/_gdb Completion/User/_gdb
--- ../z.old/Completion/User/_gdb	Wed Mar 22 09:13:27 2000
+++ Completion/User/_gdb	Wed Mar 22 09:14:15 2000
@@ -10,18 +10,21 @@
 if compset -P '-(cd|directory)='; then
   _files -/
 elif compset -P '-tty='; then
-  _wanted devices expl 'terminal device' && compadd "$expl[@]" - /dev/tty*
+  _wanted devices expl 'terminal device' compadd - /dev/tty*
 elif compset -P '-(exec|se)='; then
   _description files expl executable
   _files "$expl[@]" -g '*(-*)'
 elif compset -P '-(symbols|core|command)='; then
   _files
 elif [[ "$PREFIX" = -* ]]; then
-  if _wanted options expl option; then
-    compadd "$expl[@]" -QS '' - -symbols\= -exec\= -se\= -core\= -command\= \
-                                -directory\= -cd\= -tty\=
-    compadd "$expl[@]"        - -help -h -s -e -c -x -d -nx -n -quiet -q \
-	  		        -batch -fullname -f -b
+  if _wanted options; then
+    while _try options expl option; do
+      compadd "$expl[@]" -QS '' - -symbols\= -exec\= -se\= -core\= -command\= \
+                                  -directory\= -cd\= -tty\= && ret=0
+      compadd "$expl[@]"        - -help -h -s -e -c -x -d -nx -n -quiet -q \
+	    		          -batch -fullname -f -b && ret=0
+      (( ret )) || return 0
+    done
   fi
 else
   prev="$words[CURRENT-1]"
@@ -31,10 +34,9 @@
   (-[csx]) _files && return 0 ;;
   (-e)     _description files expl executable
            _files "$expl[@]" -g '*(-*)' && return 0 ;;
-  (-b)     _wanted -V values expl 'baud rate' &&
-               compadd "$expl[@]" 0 50 75 110 134 150 200 300 600 1200 1800 \
-			          2400 4800 9600 19200 38400 57600 115200 \
-			          230400 && return 0 ;;
+  (-b)     _wanted -V values expl 'baud rate' \
+               compadd 0 50 75 110 134 150 200 300 600 1200 1800 2400 4800 \
+		       9600 19200 38400 57600 115200 230400 && return 0 ;;
   esac
 
   w=( "${(@)words[2,-1]}" )
diff -ru ../z.old/Completion/User/_getconf Completion/User/_getconf
--- ../z.old/Completion/User/_getconf	Wed Mar 22 09:13:24 2000
+++ Completion/User/_getconf	Wed Mar 22 09:14:15 2000
@@ -1,20 +1,19 @@
 #compdef getconf
 
-local expl
+local expl ret=1
 
 if [[ CURRENT -eq 2 ]]; then
   _tags syswideconfig pathconfig standardsconfig
 
   while _tags; do
-    if _requested -V syswideconfig expl 'systemwide configuration variables'
-    then
-      compadd "$expl[@]" -S '' ARG_MAX BC_BASE_MAX BC_DIM_MAX BC_SCALE_MAX \
+    _requested -V syswideconfig expl 'systemwide configuration variables' \
+      compadd -S '' ARG_MAX BC_BASE_MAX BC_DIM_MAX BC_SCALE_MAX \
           BC_STRING_MAX CHILD_MAX COLL_WEIGHTS_MAX EXPR_NEST_MAX LINE_MAX \
-	  NGROUPS_MAX OPEN_MAX RE_DUP_MAX STREAM_MAX TZNAME_MAX
-    fi
-    if _requested -V standardsconfig \
-        expl 'system-standards configuration variables'; then
-      compadd "$expl[@]" -S '' _POSIX_CHILD_MAX _POSIX_LINK_MAX \
+	  NGROUPS_MAX OPEN_MAX RE_DUP_MAX STREAM_MAX TZNAME_MAX && ret=0
+
+    _requested -V standardsconfig \
+        expl 'system-standards configuration variables' \
+      compadd -S '' _POSIX_CHILD_MAX _POSIX_LINK_MAX \
           _POSIX_MAX_CANON _POSIX_MAX_INPUT _POSIX_NAME_MAX _POSIX_NGROUPS_MAX \
 	  _POSIX_OPEN_MAX _POSIX_PATH_MAX _POSIX_PIPE_BUF _POSIX_SSIZE_MAX \
 	  _POSIX_STREAM_MAX _POSIX_TZNAME_MAX _POSIX_VERSION \
@@ -22,15 +21,17 @@
 	  POSIX2_BC_STRING_MAX POSIX2_COLL_WEIGHTS_MAX POSIX2_EXPR_NEST_MAX \
 	  POSIX2_LINE_MAX POSIX2_RE_DUP_MAX POSIX2_VERSION POSIX2_C_BIND \
 	  POSIX2_C_DEV POSIX2_FORT_DEV POSIX2_FORT_RUN POSIX2_LOCALEDEF \
-	  POSIX2_SW_DEV _XOPEN_VERSION
-    fi
-    if _requested -V pathconfig expl 'system path configuration variables'
-    then
-      compadd "$expl[@]" -S '' PIPE_BUF _POSIX_CHOWN_RESTRICTED \
-          _POSIX_NO_TRUNC _POSIX_VDISABLE
-      compadd "$expl[@]" -S ' ' LINK_MAX MAX_CANON MAX_INPUT NAME_MAX PATH_MAX \
-          PIPE_BUF
-    fi
+	  POSIX2_SW_DEV _XOPEN_VERSION && ret=0
+
+    _requested pathconfig &&
+        while _try -V pathconfig expl 'system path configuration variables'; do
+          compadd "$expl[@]" -S '' PIPE_BUF _POSIX_CHOWN_RESTRICTED \
+                                   _POSIX_NO_TRUNC _POSIX_VDISABLE && ret=0
+          compadd "$expl[@]" -S ' ' LINK_MAX MAX_CANON MAX_INPUT NAME_MAX \
+                                    PATH_MAX PIPE_BUF && ret=0
+          (( ret )) || break
+        done
+    (( ret )) || return 0
   done
 else
   _files -/
diff -ru ../z.old/Completion/User/_gprof Completion/User/_gprof
--- ../z.old/Completion/User/_gprof	Wed Mar 22 09:13:27 2000
+++ Completion/User/_gprof	Wed Mar 22 09:14:16 2000
@@ -17,7 +17,7 @@
 if [[ -n "$state" ]]; then
   local cmd pair expl
 
-  _tags functions || return 1
+  _wanted functions || return 1
 
   [[ "$state" = pair ]] && pair=yes
 
diff -ru ../z.old/Completion/User/_groups Completion/User/_groups
--- ../z.old/Completion/User/_groups	Wed Mar 22 09:13:27 2000
+++ Completion/User/_groups	Wed Mar 22 09:14:16 2000
@@ -2,7 +2,7 @@
 
 local expl groups tmp
 
-_wanted groups expl group || return 1
+_wanted groups || return 1
 
 if ! zstyle -a ":completion:${curcontext}:" groups groups; then
   (( $+_cache_groups )) ||
@@ -16,4 +16,4 @@
   groups=( "$_cache_groups[@]" )
 fi
 
-compadd "$@" "$expl[@]" - "$groups[@]"
+_loop groups expl group compadd "$@" - "$groups[@]"
diff -ru ../z.old/Completion/User/_gs Completion/User/_gs
--- ../z.old/Completion/User/_gs	Wed Mar 22 09:13:27 2000
+++ Completion/User/_gs	Wed Mar 22 09:14:16 2000
@@ -25,8 +25,8 @@
     if [[ "$PREFIX" = *\=* ]]; then
       _message 'systemdict definition value'
     else
-      _wanted names expl 'systemdict definition name' &&
-          compadd "$expl[@]" -M 'm:{a-z}={A-Z}' - \
+      _wanted names expl 'systemdict definition name' \
+          compadd -M 'm:{a-z}={A-Z}' - \
                   DISKFONTS NOCACHE NOBIND NODISPLAY NOPAUSE PLATFONTS SAFER \
                   WRITESYSTEMDICT && ret=0
     fi
@@ -35,8 +35,8 @@
     if compset -P '*='; then
       case "$IPREFIX" in
       *DEVICE\=)
-        _wanted devices expl 'ghostscript device' &&
-            compadd "$expl[@]" - "${(@)${=${$(_call devices gs -h)##* devices:}%%Search path:*}:#}" && ret=0
+        _wanted devices expl 'ghostscript device' \
+            compadd - "${(@)${=${$(_call devices gs -h)##* devices:}%%Search path:*}:#}" && ret=0
         ;;
       *OutputFile\=)
         _description files expl 'output file'
@@ -47,9 +47,8 @@
         return 1
       esac
     else
-      _wanted names expl 'systemdict name' &&
-          compadd "$expl[@]" -S\= -M 'm:{a-z}={A-Z}' - DEVICE OutputFile &&
-              ret=0
+      _wanted names expl 'systemdict name' \
+          compadd -S\= -M 'm:{a-z}={A-Z}' - DEVICE OutputFile && ret=0
     fi
     ;;
   esac
diff -ru ../z.old/Completion/User/_hosts Completion/User/_hosts
--- ../z.old/Completion/User/_hosts	Wed Mar 22 09:13:28 2000
+++ Completion/User/_hosts	Wed Mar 22 09:14:16 2000
@@ -9,5 +9,5 @@
   hosts=( "$_cache_hosts[@]" )
 fi
 
-_wanted hosts expl host &&
-    compadd -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' "$@" "$expl[@]" - "$hosts[@]"
+_wanted hosts expl host \
+    compadd -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' "$@" - "$hosts[@]"
diff -ru ../z.old/Completion/User/_lp Completion/User/_lp
--- ../z.old/Completion/User/_lp	Wed Mar 22 09:13:28 2000
+++ Completion/User/_lp	Wed Mar 22 09:14:16 2000
@@ -36,14 +36,15 @@
 fi
 
 if compset -P -P || [[ "$words[CURRENT-1]" = -P ]]; then
-  if _wanted printers expl printer; then
+  if _wanted printers; then
     if zstyle -T ":completion:${curcontext}:printers" verbose; then
       zformat -a list ' -- ' "$_lp_cache[@]"
       disp=(-ld list)
     else
       disp=()
     fi
-    compadd "$expl[@]" "$disp[@]" - "${(@)_lp_cache%%:*}" && return 0
+    _loop printers expl printer \
+        compadd "$disp[@]" - "${(@)_lp_cache%%:*}" && return 0
 
     (( $+_lp_alias_cache )) || return 1
 
@@ -70,7 +71,7 @@
       _tags users jobs
 
       while _tags; do
-        if _requested users expl user; then
+        if _requested users; then
           strs=( "${(@)${(@)list##[^ 	]##[ 	]##[^ 	]##[ 	]##}%%[ 	]*}" )
           if [[ -z "$shown" ]] &&
              zstyle -T ":completion:${curcontext}:users" verbose; then
@@ -79,9 +80,10 @@
           else
   	  disp=()
           fi
-          compadd "$expl[@]" "$disp[@]" - "$strs[@]" || _users && ret=0
+	  _loop users expl user compadd "$disp[@]" - "$strs[@]" ||
+              _users && ret=0
         fi
-        if _requested jobs expl job; then
+        if _requested jobs; then
           strs=( "${(@)${(@)list##[^ 	]##[ 	]##[^ 	]##[ 	]##[^ 	]##[ 	]##}%%[ 	]*}" )
           if [[ -z "$shown" ]] &&
              zstyle -T ":completion:${curcontext}:jobs" verbose; then
@@ -90,7 +92,7 @@
           else
   	  disp=()
           fi
-          compadd "$expl[@]" "$disp[@]" - "$strs[@]" && ret=0
+          _loop jobs expl job compadd "$disp[@]" - "$strs[@]" && ret=0
         fi
         (( ret )) || return 0
       done
diff -ru ../z.old/Completion/User/_mailboxes Completion/User/_mailboxes
--- ../z.old/Completion/User/_mailboxes	Wed Mar 22 09:13:28 2000
+++ Completion/User/_mailboxes	Wed Mar 22 09:14:16 2000
@@ -2,7 +2,7 @@
 
 _mailboxes() {
   #emulate -L zsh
-  local expl nm="$compstate[nmatches]"
+  local expl ret=1
   local pinedirectory="${pinedirectory:-~/mail}"
   local maildirectory="${maildirectory:-~/Mail}"
 
@@ -40,15 +40,14 @@
   esac
 
   while _tags; do
-    if _requested mailboxes expl 'mailbox specification'; then
-      _mua_mailboxes "$expl[@]"
-    fi
+    _requested mailboxes expl 'mailbox specification' _mua_mailboxes && ret=0
+
     if _requested files expl 'mailbox file'; then
       [[ "${curcontext}" != *:(mail|mush|zmail|zmlite):* ]] &&
 	compset -P -f
-      _path_files "$expl[@]"
+      _files "$expl[@]" && ret=0
     fi
-    [[ nm -ne $compstate[nmatches] ]] && return 0
+    (( ret )) || return 0
   done
 
   return 1
@@ -96,6 +95,7 @@
 
   local -a mbox_short
   local -aU mbox_names
+  local ret=1
 
   case "${curcontext}" in
     (*:elm:*) # I've probably got this wrong, or at least incomplete
@@ -111,7 +111,7 @@
       fi
       ;;
     (*:mh:*) # I've probably got this wrong, or at least incomplete
-      (( $#_mh_cache )) && _multi_parts "${expl[@]}" / _mh_cache
+      (( $#_mh_cache )) && _multi_parts "${expl[@]}" / _mh_cache && ret=0
       ;;
     (*:mush:*)
       if compset -P %; then
@@ -155,7 +155,6 @@
        ;;
   esac
 
-  local ret=1
   (( $#mbox_names )) && _multi_parts "$@" / mbox_names && ret=0
   (( $#mbox_short )) && compadd "$@" - "$mbox_short[@]" && ret=0
   return ret
diff -ru ../z.old/Completion/User/_make Completion/User/_make
--- ../z.old/Completion/User/_make	Wed Mar 22 09:13:28 2000
+++ Completion/User/_make	Wed Mar 22 09:14:17 2000
@@ -1,6 +1,6 @@
 #compdef make gmake pmake
 
-local prev="$words[CURRENT-1]" file ret=1 expl
+local prev="$words[CURRENT-1]" file expl tmp
 
 if [[ "$prev" = -[CI] ]]; then
   _files -/
@@ -18,11 +18,15 @@
     file=''
   fi
 
-  [[ -n "$file" ]] && _wanted targets expl 'make target' &&
-      compadd "$expl[@]" - \
+  if [[ -n "$file" ]] && _wanted targets; then
+    tmp=(
           $(awk '/^[a-zA-Z0-9][^\/ \t]+:/ {print $1}
  	      /^\.include  *<bsd\.port\.(subdir\.|pre\.)?mk>/ || /^\.include  *".*mk\/bsd\.pkg\.(subdir\.)?mk"/ {
  	        print "fetch fetch-list extract patch configure build install reinstall deinstall package describe checkpatch checksum makesum" }' \
- 	     FS=: $file) && ret=0
-  (( ret )) && { compset -P 1 '*='; _files }
+ 	     FS=: $file)
+         )
+    _loop targets expl 'make target' compadd "$tmp[@]" && return 0
+  fi
+  compset -P 1 '*='
+  _files
 fi
diff -ru ../z.old/Completion/User/_man Completion/User/_man
--- ../z.old/Completion/User/_man	Wed Mar 22 09:13:28 2000
+++ Completion/User/_man	Wed Mar 22 09:14:17 2000
@@ -33,5 +33,5 @@
   rep=( $manpath/(sman|man|cat)*/${~approx}$PREFIX${~star}$SUFFIX.<->*(N:t) )
 fi
 
-(( $#rep )) && _wanted manuals expl 'manual page' &&
-    compadd "$expl[@]" - ${rep%%.[^.]##(.gz|.bz2|)}
+(( $#rep )) && _wanted manuals expl 'manual page' \
+    compadd - ${rep%%.[^.]##(.gz|.bz2|)}
diff -ru ../z.old/Completion/User/_mh Completion/User/_mh
--- ../z.old/Completion/User/_mh	Wed Mar 22 09:13:28 2000
+++ Completion/User/_mh	Wed Mar 22 09:14:17 2000
@@ -17,13 +17,16 @@
   # get list of options, which MH commands can generate themselves
   # awk is just too icky to use for this, sorry.  send me one if
   # you come up with it.
-  _wanted options expl option &&
-      compadd "$expl[@]" - $($words[1] -help | perl -ne 'if (/^\s*-\(?(\S+)/) {
+  if _wanted options; then
+    _loop options expl option \
+        compadd - $($words[1] -help | perl -ne 'if (/^\s*-\(?(\S+)/) {
             $n = $1;
             $n =~ s/\)//g;
             print $n =~ s/^\[([a-z]+)\]// ? "$n\n$1$n\n" : "$n\n";
           }')
-  return
+    return
+  fi
+  return 1
 elif compset -P 1 '[+@]' || [[ "$prev" = -draftfolder ]]; then
   # Complete folder names.
   local mhpath
@@ -35,7 +38,7 @@
     mhpath=$(mhpath)
   fi
 
-  _wanted files expl 'MH folder' && _path_files "$expl[@]" -W mhpath -/
+  _wanted files expl 'MH folder' _path_files -W mhpath -/
 elif [[ "$prev" = -(editor|(whatnow|rmm|show|more)proc) ]]; then
   _command_names -e
 elif [[ "$prev" = -file ]]; then
@@ -48,14 +51,11 @@
   [[ -d $mhlib ]] || { mhlib=$(mhparam mhlproc); mhlib=$mhlib:h; }
   mhfpath=($mymhdir $mhlib)
 
-  _wanted files expl 'MH template file' &&
-    _files "$expl[@]" -W mhfpath -g '*(.)'
+  _wanted files expl 'MH template file' _files -W mhfpath -g '*(.)'
 elif [[ "$prev" = -(no|)cc ]]; then
-  _wanted -C "$prev" values expl 'CC address' &&
-      compadd "$expl[@]" all to cc me
+  _wanted -C "$prev" values expl 'CC address' compadd all to cc me
 elif [[ "$prev" = -[rw]cache ]]; then
-  _wanted -C "$prev" values expl cache &&
-      compadd "$expl[@]" public private never ask
+  _wanted -C "$prev" values expl cache compadd public private never ask
 else
   # Generate sequences.
   local foldnam folddir f ret
@@ -72,11 +72,14 @@
     # leaving foldnam empty works here
   fi
 
-  if _wanted sequences expl sequence; then
-    compadd "$expl[@]" $(mark $foldnam 2>/dev/null | awk -F: '{ print $1 }') &&
+  if _wanted sequences; then
+    while _try sequences expl sequence; do
+      compadd "$expl[@]" $(mark $foldnam 2>/dev/null | awk -F: '{ print $1 }') &&
         ret=0
-    compadd "$expl[@]" reply next cur prev first last all unseen && ret=0
-    _files "$expl[@]" -W folddir -g '<->' && ret=0
+      compadd "$expl[@]" reply next cur prev first last all unseen && ret=0
+      _files "$expl[@]" -W folddir -g '<->' && ret=0
+      (( ret )) || return 0
+    done
   fi
   return ret
 fi
diff -ru ../z.old/Completion/User/_mount Completion/User/_mount
--- ../z.old/Completion/User/_mount	Wed Mar 22 09:13:29 2000
+++ Completion/User/_mount	Wed Mar 22 09:14:17 2000
@@ -539,11 +539,11 @@
 fstype)
   compset -P '*,'
 
-  _wanted types expl 'file system type' &&
+  _wanted types expl 'file system type' \
       compadd "$expl[@]" -qS, -M 'L:|no=' - "$fss[@]" && ret=0
   ;;
 fsopt)
-  _tags options || return 1
+  _wanted options || return 1
 
   eval 'tmp=(' '"$_fs_'${(s:,:)^${opt_args[$typeops]:-${deffs}}}'[@]"' ')'
   tmp=( "$_fs_any[@]" "${(@)tmp:#}" )
diff -ru ../z.old/Completion/User/_mutt Completion/User/_mutt
--- ../z.old/Completion/User/_mutt	Wed Mar 22 09:13:29 2000
+++ Completion/User/_mutt	Wed Mar 22 09:14:17 2000
@@ -25,8 +25,6 @@
  '-Z+:open first mailbox with new mail:' && ret=0
 
 if [[ "$state" = userhost ]]; then
-  _tags hosts || return 1
-
   if compset -P '*@'; then
     _description hosts expl 'remote host name'
     _hosts "$expl[@]" -q -S, && return 0
diff -ru ../z.old/Completion/User/_mysql_utils Completion/User/_mysql_utils
--- ../z.old/Completion/User/_mysql_utils	Wed Mar 22 09:13:35 2000
+++ Completion/User/_mysql_utils	Wed Mar 22 09:14:18 2000
@@ -24,33 +24,33 @@
   local _mysql_user _mysql_port _mysql_host _mysql_params
   _mysql_get_identity
 
-  _wanted hosts expl 'server host' &&
+  _wanted hosts expl 'server host' \
     _combination -s '[:@]' '' hosts-ports-users \
       ${_mysql_user:+users=${_mysql_user:q}} \
       ${_mysql_port:+ports=${_mysql_port:q}} \
-      hosts "$expl[@]"
+      hosts -
 }
 
 _mysql_ports () {
   local _mysql_user _mysql_port _mysql_host _mysql_params
   _mysql_get_identity
 
-  _wanted ports expl 'server port' &&
+  _wanted ports expl 'server port' \
     _combination -s '[:@]' '' hosts-ports-users \
       ${_mysql_user:+users=${_mysql_user:q}} \
       ${_mysql_host:+hosts=${_mysql_host:q}} \
-      ports "$expl[@]"
+      ports -
 }
 
 _mysql_users () {
   local _mysql_user _mysql_port _mysql_host _mysql_params
   _mysql_get_identity
 
-  _wanted users expl 'server username' &&
+  _wanted users expl 'server username' \
     _combination -s '[:@]' '' hosts-ports-users \
       ${_mysql_host:+hosts=${_mysql_host:q}} \
       ${_mysql_port:+ports=${_mysql_port:q}} \
-      users "$expl[@]"
+      users -
 }
 
 _mysql_databases () {
@@ -205,15 +205,13 @@
        )
 
   if (( CURRENT == 1 )); then
-    _tags commands && compadd "$@" $cmds
+    _wanted commands expl command compadd "$@" - $cmds
   else
     local curcontext="$curcontext"
 
     case "$words[1]" in
-      (create)
-      ;&
-      (drop)
-        _wanted mysqldbs expl "MySQL databases" && _mysql_databases
+      (create|drop)
+        _wanted mysqldbs expl "MySQL databases" _mysql_databases
       ;;
       (kill)
         _message 'thread ids'
diff -ru ../z.old/Completion/User/_netscape Completion/User/_netscape
--- ../z.old/Completion/User/_netscape	Wed Mar 22 09:13:29 2000
+++ Completion/User/_netscape	Wed Mar 22 09:14:18 2000
@@ -40,30 +40,31 @@
     openFile*) _files -W ~;;
     saveAs*) 
       if compset -P "*,"; then
-        _wanted types expl 'data type' &&
+        _wanted types expl 'data type' \
             compadd -s")" -M 'm:{a-zA-Z}={A-Za-z}' HTML Text PostScript &&
                 ret=0
       else
-        _tags files && _path_files -W ~ && ret=0
+        _files -W ~ && ret=0
       fi
     ;;
     mailto*)
       compset -P "*,"
       if compset -P '*@'; then
-        _wanted hosts expl 'remote host name' &&
-            _hosts "$expl[@]" -q -S, && ret=0
+        _wanted hosts expl 'remote host name' _hosts -q -S, && ret=0
       else
-        _wanted users expl 'login name' && _users "$expl[@]" -q -S@ && ret=0
+        _wanted users expl 'login name' _users -q -S@ && ret=0
       fi
     ;;
     *)
-      if _wanted commands expl 'remote commands'; then
+      if _wanted commands; then
         if [[ -z "$QIPREFIX" ]]; then
-	  compadd "$expl[@]" -s'(' -S '' -M 'm:{a-zA-Z}={A-Za-z}' - \
-                  $remote_commands && ret=0
+	  _loop commands expl 'remote commands' \
+  	      compadd  -s'(' -S '' -M 'm:{a-zA-Z}={A-Za-z}' - \
+                      $remote_commands && ret=0
         else
-          compadd "$expl[@]" -qS '(' -M 'm:{a-zA-Z}={A-Za-z}' - \
-                  $remote_commands && ret=0
+	  _loop commands expl 'remote commands' \
+              compadd -qS '(' -M 'm:{a-zA-Z}={A-Za-z}' - \
+                      $remote_commands && ret=0
 	fi
       fi
     ;;
@@ -73,14 +74,16 @@
 if [[ "$state" = "urls" ]]; then
   # Complete netscape urls
   if compset -P about: ; then
-    _wanted values expl 'about what' &&
+    _wanted values expl 'about what' \
         compadd authors blank cache document fonts global hype image-cache \
             license logo memory-cache mozilla plugins && ret=0
   else
-    if _tags prefixes; then
-      _description prefixes expl 'URL prefix'
-      compadd "$expl[@]" -S '' about: mocha: javascript:
-      _urls "$@" && ret=0
+    if _wanted prefixes; then
+      while _try prefixes expl 'URL prefix'; do
+        compadd "$expl[@]" -S '' about: mocha: javascript: && ret=0
+        _urls "$@" && ret=0
+	(( ret )) || return 0
+      done
     fi
   fi
 fi
diff -ru ../z.old/Completion/User/_nslookup Completion/User/_nslookup
--- ../z.old/Completion/User/_nslookup	Wed Mar 22 09:13:29 2000
+++ Completion/User/_nslookup	Wed Mar 22 09:14:18 2000
@@ -60,7 +60,7 @@
 
     _funcall ret _nslookup_redirect && return ret
 
-    _tags -C redirection files || return 1
+    _wanted -C redirection files || return 1
 
     if [[ "$words[1]" != (finger|ls) ]]; then
       _message "redirection not allowed for command \`$words[1]'"
@@ -86,7 +86,7 @@
 
   case "$words[1]" in
   (|l)server)
-    _wanted hosts expl 'new default server' && _hosts "$expl[@]"
+    _wanted hosts expl 'new default server' _hosts
     return
     ;;
   root|exit|help|\?)
@@ -119,7 +119,7 @@
     [[ -z "$state" ]] && return ret
     ;;
   *)
-    _wanted hosts expl 'server' && _hosts "$expl[@]"
+    _wanted hosts expl 'server' _hosts
     return
   esac
 fi
diff -ru ../z.old/Completion/User/_pbm Completion/User/_pbm
--- ../z.old/Completion/User/_pbm	Wed Mar 22 09:13:29 2000
+++ Completion/User/_pbm	Wed Mar 22 09:14:18 2000
@@ -254,7 +254,7 @@
     fi
     _x_color && ret=0
   
-    _wanted options expl option && compadd "$expl[@]" - -map && ret=0
+    _wanted options expl option compadd - -map && ret=0
   
     return ret
   elif [[ CURRENT -eq 3 && "$words[2]" = -map ]]; then
@@ -590,12 +590,11 @@
   fi
   
   if [[ CURRENT -eq 2 ]]; then
-    _wanted options expl option &&
-        if [[ -n "$opt" ]]; then
-          compadd "$expl[@]" - -map -fs -floyd && ret=0
-        else
-          compadd "$expl[@]" - -map && ret=0
-        fi
+    if [[ -n "$opt" ]]; then
+      _wanted options expl option compadd - -map -fs -floyd && ret=0
+    else
+      _wanted options expl option compadd - -map && ret=0
+    fi
     _message 'number of colors'
   
     return ret
diff -ru ../z.old/Completion/User/_perl_basepods Completion/User/_perl_basepods
--- ../z.old/Completion/User/_perl_basepods	Wed Mar 22 09:13:30 2000
+++ Completion/User/_perl_basepods	Wed Mar 22 09:14:18 2000
@@ -29,5 +29,4 @@
 
 local expl
 
-_wanted pods expl 'Perl base pods' &&
-    compadd "$expl[@]" - $_perl_basepods
+_wanted pods expl 'Perl base pods' compadd - $_perl_basepods
diff -ru ../z.old/Completion/User/_perl_builtin_funcs Completion/User/_perl_builtin_funcs
--- ../z.old/Completion/User/_perl_builtin_funcs	Wed Mar 22 09:13:30 2000
+++ Completion/User/_perl_builtin_funcs	Wed Mar 22 09:14:18 2000
@@ -28,5 +28,4 @@
 
 local expl
 
-_wanted functions expl 'Perl built-in functions' &&
-    compadd "$expl[@]" - $_perl_builtin_funcs
+_wanted functions expl 'Perl built-in functions' compadd - $_perl_builtin_funcs
diff -ru ../z.old/Completion/User/_perl_modules Completion/User/_perl_modules
--- ../z.old/Completion/User/_perl_modules	Wed Mar 22 09:13:30 2000
+++ Completion/User/_perl_modules	Wed Mar 22 09:14:19 2000
@@ -49,4 +49,4 @@
 
 local expl
 
-_wanted modules expl 'Perl modules' && compadd "$expl[@]" "$opts[@]" - $_perl_modules
+_wanted modules expl 'Perl modules' compadd "$opts[@]" - $_perl_modules
diff -ru ../z.old/Completion/User/_ports Completion/User/_ports
--- ../z.old/Completion/User/_ports	Wed Mar 22 09:13:30 2000
+++ Completion/User/_ports	Wed Mar 22 09:14:19 2000
@@ -9,4 +9,4 @@
   ports=( "$_cache_ports[@]" )
 fi
 
-_wanted ports expl port && compadd "$@" "$expl[@]" - "$ports[@]"
+_wanted ports expl port compadd "$@" - "$ports[@]"
diff -ru ../z.old/Completion/User/_rcs Completion/User/_rcs
--- ../z.old/Completion/User/_rcs	Wed Mar 22 09:13:31 2000
+++ Completion/User/_rcs	Wed Mar 22 09:14:19 2000
@@ -8,5 +8,5 @@
   local rep expl
 
   rep=(RCS/$PREFIX*$SUFFIX,v(:t:s/\,v//))
-  (( $#rep )) && _wanted files expl 'RCS file' && compadd "$expl[@]" - $rep
+  (( $#rep )) && _wanted files expl 'RCS file' compadd - $rep
 fi
diff -ru ../z.old/Completion/User/_rlogin Completion/User/_rlogin
--- ../z.old/Completion/User/_rlogin	Wed Mar 22 09:13:31 2000
+++ Completion/User/_rlogin	Wed Mar 22 09:14:19 2000
@@ -40,7 +40,7 @@
       if compset -P '*:'; then
 	_files && ret=0
       elif compset -P '*@'; then
-        _tags hosts && _rlogin_hosts -S: -q && ret=0
+        _wanted hosts && _rlogin_hosts -S: -q && ret=0
       else
         _alternative \
 	    'files:: _files' \
@@ -54,11 +54,11 @@
 }
 
 _rlogin_users () {
-  _tags users && _combination -s '[:@]' my-accounts users-hosts users "$@"
+  _wanted users && _combination -s '[:@]' my-accounts users-hosts users "$@"
 }
 
 _rlogin_hosts () {
-  _tags hosts &&
+  _wanted hosts &&
       if [[ "$IPREFIX" == *@ ]]; then
         _combination -s '[:@]' my-accounts users-hosts "users=${IPREFIX/@}" hosts "$@"
       else
diff -ru ../z.old/Completion/User/_socket Completion/User/_socket
--- ../z.old/Completion/User/_socket	Wed Mar 22 09:13:31 2000
+++ Completion/User/_socket	Wed Mar 22 09:14:19 2000
@@ -39,17 +39,16 @@
 
 arg1)
   if (( $+opt_args[-s] )); then
-    _wanted ports expl 'port to listen' && _ports "$expl[@]"
+    _wanted ports expl 'port to listen' _ports
   else
-    _wanted hosts expl 'host' &&
-        _combination '' hosts-ports hosts "$expl[@]"
+    _wanted hosts expl 'host' _combination '' hosts-ports hosts -
   fi
   ;;
 
 arg2)
   if (( ! $+opt_args[-s] )); then
-    _wanted ports expl 'port to connect' &&
-        _combination '' hosts-ports hosts="${line[1]:q}" ports "$expl[@]"
+    _wanted ports expl 'port to connect' \
+        _combination '' hosts-ports hosts="${line[1]:q}" ports -
   fi
   ;;
 esac
diff -ru ../z.old/Completion/User/_ssh Completion/User/_ssh
--- ../z.old/Completion/User/_ssh	Wed Mar 22 09:13:31 2000
+++ Completion/User/_ssh	Wed Mar 22 09:14:20 2000
@@ -54,21 +54,18 @@
         if compset -P '*[= ]'; then
           case "$IPREFIX" in
           *(#i)(batchmode|compression|fallbacktorsh|forward(agent|x11)|keepalive|passwordauthentication|rhosts(|rsa)authentication|rsaauthentication|usersh|kerberos(authetication|tgtparsing)|usepriviledgedport)*)
-	    _wanted values expl 'truth value' && compadd "$expl[@]" yes no &&
-                ret=0
+	    _wanted values expl 'truth value' compadd yes no && ret=0
             ;;
           *(#i)cipher*)
-	    _wanted values expl 'encryption cipher' &&
-                compadd "$expl[@]" idea des 3des blowfish arcfour tss none && \
-                    ret=0
+	    _wanted values expl 'encryption cipher' \
+                compadd idea des 3des blowfish arcfour tss none && ret=0
             ;;
           *(#i)globalknownhostsfile*)
             _description files expl 'global file with known hosts'
             _files "$expl[@]" && ret=0
             ;;
           *(#i)hostname*)
-	    _wanted hosts expl 'real host name to log into' &&
-                _ssh_hosts "$expl[@]" && ret=0
+	    _wanted hosts expl 'real host name to log into' _ssh_hosts && ret=0
             ;;
           *(#i)identityfile*)
             _description files expl 'SSH identity file'
@@ -84,16 +81,14 @@
             _normal && ret=0
             ;;
           *(#i)stricthostkeychecking*)
-            _wanted values expl 'checking type' &&
-	        compadd "$expl[@]" yes no ask
+            _wanted values expl 'checking type' compadd yes no ask && ret=0
             ;;
           *(#i)userknownhostsfile*)
             _description files expl 'user file with known hosts'
             _files "$expl[@]" && ret=0
             ;;
           *(#i)user*)
-	    _wanted users expl 'user to log in as' &&
-                _ssh_users "$expl[@]" && ret=0
+	    _wanted users expl 'user to log in as' _ssh_users && ret=0
             ;;
           *(#i)xauthlocation*)
             _description files expl 'xauth program'
@@ -101,8 +96,8 @@
             ;;
           esac
         else
-          _wanted values expl 'configure file option' &&
-              compadd "$expl[@]" -M 'm:{a-z}={A-Z}' -S '=' - \
+          _wanted values expl 'configure file option' \
+              compadd -M 'm:{a-z}={A-Z}' -S '=' - \
                   BatchMode ClearAllForwardings Cipher Compression \
                   CompressionLevel Host ConnectionAttempts EscapeChar \
                   FallBackToRsh ForwardAgent ForwardX11 \
@@ -121,7 +116,7 @@
           if compset -P '*:'; then
             _message 'port number'
           else
-	    _wanted hosts expl host && _ssh_hosts -qS: "$expl[@]"
+	    _wanted hosts expl host _ssh_hosts -qS:
           fi
         else
           _message 'listen-port number'
@@ -136,8 +131,7 @@
         ;;
       userhost)
         if compset -P '*@'; then
-	  _wanted hosts expl 'remote host name' &&
-              _ssh_hosts "$expl[@]" && ret=0
+	  _wanted hosts expl 'remote host name' _ssh_hosts && ret=0
         else
           if (( $+opt_args[-l] )); then
 	    tmp=()
@@ -180,7 +174,7 @@
       if compset -P '*:'; then
         _remote_files && ret=0
       elif compset -P '*@'; then
-        _wanted hosts expl host && _ssh_hosts -S: "$expl[@]" && ret=0
+        _wanted hosts expl host _ssh_hosts -S: && ret=0
       else
         _alternative \
 	    'files:: _files' \
diff -ru ../z.old/Completion/User/_stty Completion/User/_stty
--- ../z.old/Completion/User/_stty	Wed Mar 22 09:13:31 2000
+++ Completion/User/_stty	Wed Mar 22 09:14:20 2000
@@ -4,18 +4,15 @@
 
 if [[ "$words[CURRENT-1]" = \
   (*erase|discard|status|dsusp|intr|kill|lnext|quit|reprint|start|s*p) ]]; then
-  _wanted characters expl 'control character' &&
-      compadd "$expl[@]" '^-' '^h' '^?' '^c' '^u'
+  _wanted characters expl 'control character' compadd '^-' '^h' '^?' '^c' '^u'
 else
   compset -P '[-+]'
-  _wanted values expl setting &&
-      compadd "$expl[@]" rows columns intr quit erase kill eof eol \
-                         eol2 start stop susp dsusp reprint discard \
-			 werase lnext parenb parodd cs8 cstopb hupcl \
-			 cread clocal parext ignbrk brkint ignpar \
-			 parmrk inpck istrip inlcr igncr icrnl iuclc \
-			 ixon ixany ixoff imaxbel isig icanon xcase \
-			 echo echoe echok echonl noflsh tostop echoctl \
-			 echoprt echoke flusho pending iexten opost \
-			 olcuc onlcr ocrnl onocr onlret ofill ofdel 
+  _wanted values expl setting \
+      compadd rows columns intr quit erase kill eof eol eol2 start stop \
+              susp dsusp reprint discard werase lnext parenb parodd cs8 \
+              cstopb hupcl cread clocal parext ignbrk brkint ignpar \
+	      parmrk inpck istrip inlcr igncr icrnl iuclc ixon ixany ixoff \
+              imaxbel isig icanon xcase echo echoe echok echonl noflsh \
+              tostop echoctl echoprt echoke flusho pending iexten opost \
+	      olcuc onlcr ocrnl onocr onlret ofill ofdel 
 fi
diff -ru ../z.old/Completion/User/_tar Completion/User/_tar
--- ../z.old/Completion/User/_tar	Wed Mar 22 09:13:32 2000
+++ Completion/User/_tar	Wed Mar 22 09:14:20 2000
@@ -142,8 +142,7 @@
     _tar_cache_name=$tf
   fi
 
-  _wanted files expl 'file from archive' &&
-      _multi_parts "$expl[@]" / _tar_cache_list
+  _wanted files expl 'file from archive' _multi_parts / _tar_cache_list
 else
     _files
 fi
diff -ru ../z.old/Completion/User/_telnet Completion/User/_telnet
--- ../z.old/Completion/User/_telnet	Wed Mar 22 09:13:32 2000
+++ Completion/User/_telnet	Wed Mar 22 09:14:20 2000
@@ -46,25 +46,25 @@
 
 case "$state" in
 hosts)
-  _wanted hosts expl host &&
+  _wanted hosts expl host \
       _combination -s '[@:]' '' users-hosts-ports \
           ${opt_args[-l]:+users=${opt_args[-l]:q}} \
-          hosts "$expl[@]"
+          hosts -
   ;;
 
 ports)
-  _wanted ports expl port &&
+  _wanted ports expl port \
       _combination -s '[@:]' '' users-hosts-ports \
           ${opt_args[-l]:+users=${opt_args[-l]:q}} \
           hosts="${line[1]:q}" \
-          ports "$expl[@]"
+          ports -
   ;;
 
 users)
-  _wanted users expl user &&
+  _wanted users expl user \
       _combination -s '[@:]' '' users-hosts-ports \
       ${line[2]:+hosts="${line[2]:q}"} \
       ${line[3]:+ports="${line[3]:q}"} \
-      users "$expl[@]"
+      users -
   ;;
 esac
diff -ru ../z.old/Completion/User/_tiff Completion/User/_tiff
--- ../z.old/Completion/User/_tiff	Wed Mar 22 09:13:32 2000
+++ Completion/User/_tiff	Wed Mar 22 09:14:20 2000
@@ -194,9 +194,12 @@
       ;;
     esac
   else
-    if _wanted values expl 'compression scheme'; then
-      compadd "$expl[@]" - none g4 packbits && ret=0
-      compadd "$expl[@]" -qS: - lzw zip jpeg g3 && ret=0
+    if _wanted values; then
+      while _try values expl 'compression scheme'; do
+        compadd "$expl[@]" - none g4 packbits && ret=0
+        compadd "$expl[@]" -qS: - lzw zip jpeg g3 && ret=0
+	(( ret )) || return 0
+      done
     fi
   fi
 fi
diff -ru ../z.old/Completion/User/_urls Completion/User/_urls
--- ../z.old/Completion/User/_urls	Wed Mar 22 09:13:33 2000
+++ Completion/User/_urls	Wed Mar 22 09:14:21 2000
@@ -49,16 +49,18 @@
 
 if [[ "$1" = -f ]]; then
   shift
-  _tags -C -f files && _files "$@" && return
+  _wanted -C -f files && _files "$@" && return
 fi
 
 ipre="$IPREFIX"
 
-if ! compset -P '(#b)([-+.a-z0-9]#):' &&
-   _wanted -C argument prefixes expl 'URL prefix'; then
-  [[ -d $urls_path/bookmark ]] &&
-    compadd "$@" "$expl[@]" -S '' bookmark: && ret=0
-  compadd "$@" "$expl[@]" -S '' file: ftp:// gopher:// http:// && ret=0
+if ! compset -P '(#b)([-+.a-z0-9]#):' && _wanted -C argument prefixes; then
+  while _try prefixes expl 'URL prefix' "$@"; do
+    [[ -d $urls_path/bookmark ]] &&
+      compadd "$expl[@]" -S '' bookmark: && ret=0
+    compadd "$expl[@]" -S '' file: ftp:// gopher:// http:// && ret=0
+    (( ret )) || return 0
+  done
   return ret
 fi
 scheme="$match[1]"
@@ -66,35 +68,40 @@
 case "$scheme" in
   http|ftp|gopher)
     if ! compset -P //; then
-      _wanted -C "$scheme" prefixes expl 'end of prefix' &&
-          compadd "$expl[@]" "$@" -S '' //
+      _wanted -C "$scheme" prefixes expl 'end of prefix' compadd "$@" -S '' //
       return
     fi
   ;;
   file)
     if ! compset -P //; then
-      _wanted -C file files expl 'local file' || return 1
+      _wanted -C file files || return 1
 
-      if [[ -prefix / ]]; then
-	_path_files "$expl[@]" "$@" -S '' -g '*(^/)' && ret=0
-	_path_files "$expl[@]" "$@" -S/ -r '/' -/ && ret=0
-      elif [[ -z "$PREFIX" ]]; then
-	compadd "$expl[@]" -S '/' -r '/' - "${PWD%/}" && ret=0
-      fi
+      while _try files expl 'local file' "$@"; do
+        if [[ -prefix / ]]; then
+	  _path_files "$expl[@]" -S '' -g '*(^/)' && ret=0
+	  _path_files "$expl[@]" -S/ -r '/' -/ && ret=0
+        elif [[ -z "$PREFIX" ]]; then
+	  compadd "$expl[@]" -S '/' -r '/' - "${PWD%/}" && ret=0
+        fi
+	(( ret )) || return 0
+      done
       return ret
     fi
   ;;
   bookmark)
     if [[ -f "$urls_path/$scheme/${(Q)PREFIX}${(Q)SUFFIX}" &&
 	  -s "$urls_path/$scheme/${(Q)PREFIX}${(Q)SUFFIX}" ]]; then
-      _wanted -C bookmark bookmarks expl bookmarks &&
-          compadd "$expl[@]" "$@" -U - \
+      _wanted -C bookmark bookmarks expl bookmarks \
+          compadd "$@" -U - \
               "$ipre$(<"$urls_path/$scheme/${(Q)PREFIX}${(Q)SUFFIX}")" && ret=0
     else
-      if _wanted -C bookmark files expl 'bookmark'; then
-        _path_files -W "$urls_path/$scheme" "$expl[@]" -S '' -g '*(^/)' && 
-            ret=0
-        _path_files -W "$urls_path/$scheme" -S/ -r '/' -/ && ret=0
+      if _wanted -C bookmark files; then
+        while _try files expl 'bookmark'; do
+          _path_files -W "$urls_path/$scheme" "$expl[@]" -S '' -g '*(^/)' && 
+              ret=0
+          _path_files -W "$urls_path/$scheme" -S/ -r '/' -/ && ret=0
+          (( ret )) || return 0
+        done
       fi
     fi
     return ret
@@ -102,19 +109,22 @@
 esac
 
 # Complete hosts
-if ! compset -P '(#b)([^/]#)/' &&
-   _wanted hosts expl host; then
+if ! compset -P '(#b)([^/]#)/' && _wanted hosts; then
   uhosts=($urls_path/$scheme/$PREFIX*$SUFFIX(/:t))
-  (( $#uhosts )) || _hosts -S/ && ret=0
-  [[ "$scheme" = http ]] && uhosts=($uhosts $localhttp_servername)
-  compadd "$expl[@]" "$@" -S/ - $uhosts && ret=0
+
+  while _try hosts expl host "$@"; do
+    (( $#uhosts )) || _hosts -S/ && ret=0
+    [[ "$scheme" = http ]] && uhosts=($uhosts $localhttp_servername)
+    compadd "$expl[@]" -S/ - $uhosts && ret=0
+    (( ret )) || return 0
+  done
   return ret
 fi
 host="$match[1]"
 
 # Complete part after hostname
 
-_wanted -C local files expl 'local file' || return 1
+_wanted -C local files || return 1
 
 if [[ "$localhttp_servername" = "$host" ]]; then
   if compset -P \~; then
@@ -123,14 +133,23 @@
       return
     fi
     user="$match[1]"
-    _path_files "$expl[@]" -W ~$user/$localhttp_userdir -g '*(^/)' && ret=0
-    _path_files "$expl[@]" -W ~$user/$localhttp_userdir -S/ -r '/' -/ && ret=0
+    while _try files expl 'local file'; do
+      _path_files "$expl[@]" -W ~$user/$localhttp_userdir -g '*(^/)' && ret=0
+      _path_files "$expl[@]" -W ~$user/$localhttp_userdir -S/ -r '/' -/ && ret=0
+      (( ret )) || return 0
+    done
   else
-    _path_files "$expl[@]" -W $localhttp_documentroot -g '*(^/)' && ret=0
-    _path_files "$expl[@]" -W $localhttp_documentroot -S/ -r '/' -/ && ret=0
+    while _try files expl 'local file'; do
+      _path_files "$expl[@]" -W $localhttp_documentroot -g '*(^/)' && ret=0
+      _path_files "$expl[@]" -W $localhttp_documentroot -S/ -r '/' -/ && ret=0
+      (( ret )) || return 0
+    done
   fi
 else
-  _path_files "$expl[@]" -W $urls_path/$scheme/$host -g '*(^/)' && ret=0
-  _path_files "$expl[@]" -W $urls_path/$scheme/$host -S/ -r '/' -/ && ret=0
+  while _try files expl 'local file'; do
+    _path_files "$expl[@]" -W $urls_path/$scheme/$host -g '*(^/)' && ret=0
+    _path_files "$expl[@]" -W $urls_path/$scheme/$host -S/ -r '/' -/ && ret=0
+    (( ret )) || return 0
+  done
 fi
 return $ret
diff -ru ../z.old/Completion/User/_user_at_host Completion/User/_user_at_host
--- ../z.old/Completion/User/_user_at_host	Wed Mar 22 09:13:33 2000
+++ Completion/User/_user_at_host	Wed Mar 22 09:14:21 2000
@@ -22,9 +22,9 @@
 
   compset -P 1 '*@'
 
-  _wanted -C user-at hosts expl "host for $user" &&
-      _combination -s '[:@]' "${tag}" users-hosts users="$user" hosts "$expl[@]" "$@"
+  _wanted -C user-at hosts expl "host for $user" \
+      _combination -s '[:@]' "${tag}" users-hosts users="$user" hosts "$@" -
 else
-  _wanted users expl "user" &&
-      _combination -s '[:@]' "${tag}" users-hosts users -S@ -q "$expl[@]" "$@"
+  _wanted users expl "user" \
+      _combination -s '[:@]' "${tag}" users-hosts users -S@ -q "$@" -
 fi
diff -ru ../z.old/Completion/User/_users Completion/User/_users
--- ../z.old/Completion/User/_users	Wed Mar 22 09:13:33 2000
+++ Completion/User/_users	Wed Mar 22 09:14:21 2000
@@ -2,9 +2,9 @@
 
 local expl users
 
-_wanted users expl user || return 1
+_wanted users || return 1
 
 zstyle -a ":completion:${curcontext}:" users users &&
-    compadd "$expl[@]" "$@" - "$users[@]" && return 0
+    _loop users expl user compadd "$@" - "$users[@]" && return 0
 
-compadd "$@" "$expl[@]" - "${(@k)userdirs}"
+_loop users expl user compadd "$@" - "${(@k)userdirs}"
diff -ru ../z.old/Completion/User/_users_on Completion/User/_users_on
--- ../z.old/Completion/User/_users_on	Wed Mar 22 09:13:33 2000
+++ Completion/User/_users_on	Wed Mar 22 09:14:21 2000
@@ -2,11 +2,11 @@
 
 local expl
 
-_tags users || return 1
+_wanted users || return 1
 
 if which users >/dev/null; then
-  _description users expl 'users logged on'
-  compadd "$@" "$expl[@]" - $(_call users users) && return 0
+  _loop users expl 'users logged on' \
+      compadd "$@" - $(_call users users) && return 0
 else
   # Other methods of finding out users logged on should be added here
   return 1
diff -ru ../z.old/Completion/User/_whois Completion/User/_whois
--- ../z.old/Completion/User/_whois	Wed Mar 22 09:13:34 2000
+++ Completion/User/_whois	Wed Mar 22 09:14:21 2000
@@ -189,14 +189,14 @@
 }
 
 _whois_hosts () {
-  _tags hosts &&
+  _wanted hosts &&
     compadd "$@" \
       -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' \
       - ${_whois_servers%:?} || _hosts "$@"
 }
 
 _whois_ports () {
-  _tags ports && compadd "$@" - whois || _ports "$@"
+  _wanted ports && compadd "$@" - whois || _ports "$@"
 }
 
 (( $+functions[_whois:whois.internic.net] )) ||
@@ -204,7 +204,7 @@
   if (( CURRENT == 1 )); then
     local expl
 
-    _wanted strings expl string && compadd "$expl[@]" HELP DOMAIN HOST
+    _wanted strings expl string compadd HELP DOMAIN HOST
   else
     _message 'string'
   fi
@@ -215,7 +215,7 @@
   if (( CURRENT == 1 )); then
     local expl
 
-    _wanted strings expl string && compadd HELP DOM NET HOST PERSON CONN COM
+    _wanted strings expl string compadd HELP DOM NET HOST PERSON CONN COM
   else
     _message 'string'
   fi
diff -ru ../z.old/Completion/User/_yp Completion/User/_yp
--- ../z.old/Completion/User/_yp	Wed Mar 22 09:13:34 2000
+++ Completion/User/_yp	Wed Mar 22 09:14:22 2000
@@ -95,15 +95,16 @@
 
   while _tags; do
     # The `-M ...' allows `pa.n<TAB>' to complete to `passwd.byname'.
-    _requested maps expl 'map name' &&
-        compadd "$expl[@]" -M 'l:.|by=by l:.|=by r:|.=* r:|=*' - \
+    _requested maps expl 'map name' \
+        compadd -M 'l:.|by=by l:.|=by r:|.=* r:|=*' - \
                 "$_yp_cache_maps[@]" && ret=0
-    _requested nicknames expl nicknames &&
-        compadd "$expl[@]" - "$_yp_cache_nicks[@]" && ret=0
+    _requested nicknames expl nicknames \
+        compadd - "$_yp_cache_nicks[@]" && ret=0
+    (( ret )) || return 0
   done
 elif [[ "$state" = servers ]]; then
   if compset -P '*,'; then
-    _wanted hosts expl server && _hosts -qS, && ret=0
+    _wanted hosts expl server _hosts -qS, && ret=0
   else
     _message 'domain name'
   fi
diff -ru ../z.old/Completion/X/_x_color Completion/X/_x_color
--- ../z.old/Completion/X/_x_color	Wed Mar 22 09:13:36 2000
+++ Completion/X/_x_color	Wed Mar 22 09:14:22 2000
@@ -30,6 +30,6 @@
   (( $#_color_cache )) || _color_cache=(white black gray red blue green)
 fi
 
-_wanted colors expl 'color specification' &&
-    compadd "$@" "$expl[@]" -M 'm:{a-z}={A-Z} m:-=\  r:|[ A-Z0-9]=* r:|=*' - \
+_wanted colors expl 'color specification' \
+    compadd "$@" -M 'm:{a-z}={A-Z} m:-=\  r:|[ A-Z0-9]=* r:|=*' - \
             "$_color_cache[@]"
diff -ru ../z.old/Completion/X/_x_cursor Completion/X/_x_cursor
--- ../z.old/Completion/X/_x_cursor	Wed Mar 22 09:13:36 2000
+++ Completion/X/_x_cursor	Wed Mar 22 09:14:22 2000
@@ -14,5 +14,5 @@
   fi
 fi
 
-_wanted cursors expl 'cursor name' &&
-    compadd "$@" "$expl[@]" -M 'm:-=_ r:|_=*' - "$_cursor_cache[@]"
+_wanted cursors expl 'cursor name' \
+    compadd "$@" -M 'm:-=_ r:|_=*' - "$_cursor_cache[@]"
diff -ru ../z.old/Completion/X/_x_display Completion/X/_x_display
--- ../z.old/Completion/X/_x_display	Wed Mar 22 09:13:36 2000
+++ Completion/X/_x_display	Wed Mar 22 09:14:22 2000
@@ -1,3 +1,3 @@
 #autoload
 
-_tags displays && _hosts -S ':0 ' -r :
+_wnated displays && _hosts -S ':0 ' -r :
diff -ru ../z.old/Completion/X/_x_extension Completion/X/_x_extension
--- ../z.old/Completion/X/_x_extension	Wed Mar 22 09:13:37 2000
+++ Completion/X/_x_extension	Wed Mar 22 09:14:22 2000
@@ -2,16 +2,18 @@
 
 local expl
 
-_wanted extensions expl 'X extensions' || return 1
+_wanted extensions || return 1
 
 (( $+_xe_cache )) || _xe_cache=( "${(@)${(@f)$(xdpyinfo)}[(r)number of extensions:*,-1][2,(r)default screen number:*][1,-2]//[      ]}" )
 
 if [[ "$1" = -a ]]; then
   shift
 
-  compadd "$@" "$expl[@]" -M 'm:{a-z}={A-Z} r:|-=* r:|=*' - all "$_xe_cache[@]"
+  _loop extensions expl 'X extensions' \
+      compadd "$@" -M 'm:{a-z}={A-Z} r:|-=* r:|=*' - all "$_xe_cache[@]"
 else
   [[ "$1" = - ]] && shift
 
-  compadd "$@" "$expl[@]" -M 'm:{a-z}={A-Z} r:|-=* r:|=*' - "$_xe_cache[@]"
+  _loop extensions expl 'X extensions' \
+      compadd "$@" -M 'm:{a-z}={A-Z} r:|-=* r:|=*' - "$_xe_cache[@]"
 fi
diff -ru ../z.old/Completion/X/_x_font Completion/X/_x_font
--- ../z.old/Completion/X/_x_font	Wed Mar 22 09:13:37 2000
+++ Completion/X/_x_font	Wed Mar 22 09:14:22 2000
@@ -2,7 +2,7 @@
 
 local expl
 
-_wanted fonts expl font || return 1
+_wanted fonts || return 1
 
 # This *has* to be improved some day...
 
@@ -12,4 +12,4 @@
  _font_cache=( "${(@)^${(@f)$(_call fonts xlsfonts)}%%--*}--" )
 fi
 
-compadd -M 'r:|-=* r:|=*' "$expl[@]" "$@" -S '' - "$_font_cache[@]"
+_loop fonts expl font compadd -M 'r:|-=* r:|=*' "$@" -S '' - "$_font_cache[@]"
diff -ru ../z.old/Completion/X/_x_keysym Completion/X/_x_keysym
--- ../z.old/Completion/X/_x_keysym	Wed Mar 22 09:13:37 2000
+++ Completion/X/_x_keysym	Wed Mar 22 09:14:23 2000
@@ -2,7 +2,7 @@
 
 local expl
 
-_wanted keysyms expl 'key symbol' || return 1
+_wanted keysyms || return 1
 
 if (( ! $+_keysym_cache )); then
   local file
@@ -18,4 +18,5 @@
   fi
 fi
 
-compadd "$@" "$expl[@]" -M 'm:{a-z}={A-Z} r:|-=* r:|=*' - $_keysym_cache
+_loop keysyms expl 'key symbol' \
+    compadd "$@" -M 'm:{a-z}={A-Z} r:|-=* r:|=*' - $_keysym_cache
diff -ru ../z.old/Completion/X/_x_modifier Completion/X/_x_modifier
--- ../z.old/Completion/X/_x_modifier	Wed Mar 22 09:13:37 2000
+++ Completion/X/_x_modifier	Wed Mar 22 09:14:23 2000
@@ -2,6 +2,6 @@
 
 local expl
 
-_wanted modifiers expl modifier &&
-    compadd "$@" "$expl[@]" -M 'm:{a-z}={A-Z}' - \
+_wanted modifiers expl modifier \
+    compadd "$@" -M 'm:{a-z}={A-Z}' - \
             Shift Lock Control Mod1 Mod2 Mod3 Mod4 Mod5
diff -ru ../z.old/Completion/X/_x_window Completion/X/_x_window
--- ../z.old/Completion/X/_x_window	Wed Mar 22 09:13:37 2000
+++ Completion/X/_x_window	Wed Mar 22 09:14:23 2000
@@ -2,18 +2,17 @@
 
 local list expl
 
-_tags windows || return 1
+_wanted windows || return 1
 
 list=( "${(@)${(M@)${(@f)$(_call windows xwininfo -root -tree)}:#[ 	]#0x[0-9a-f]# \"*}##[ 	]#}" )
 
 if [[ "$1" = -n ]]; then
   shift
 
-  _description windows expl 'window name'
-  compadd "$@" "$expl[@]" -d list - "${(@)${(@)list#*\"}%%\"*}"
+  _loop windows expl 'window name' \
+      compadd "$@" -d list - "${(@)${(@)list#*\"}%%\"*}"
 else
   [[ "$1" = - ]] && shift
 
-  _description windows expl 'window ID'
-  compadd "$@" "$expl[@]" -d list - "${(@)list%% *}"
+  _loop windows expl 'window ID' compadd "$@" -d list - "${(@)list%% *}"
 fi
diff -ru ../z.old/Completion/X/_xmodmap Completion/X/_xmodmap
--- ../z.old/Completion/X/_xmodmap	Wed Mar 22 09:13:37 2000
+++ Completion/X/_xmodmap	Wed Mar 22 09:14:23 2000
@@ -82,9 +82,12 @@
     [[ "$what" = *ksym* ]] && _x_keysym "$suf[@]" && ret=0
 
   else
-    if _wanted commands expl command; then
-      compadd "$expl[@]" -S ' ' keycode keysym clear add remove && ret=0
-      compadd "$expl[@]" -S ' = ' pointer && ret=0
+    if _wanted commands; then
+      while _try commands expl command; do
+        compadd "$expl[@]" -S ' ' keycode keysym clear add remove && ret=0
+        compadd "$expl[@]" -S ' = ' pointer && ret=0
+        (( ret )) || return 0
+      done
     fi
   fi
 fi
diff -ru ../z.old/Completion/X/_xutils Completion/X/_xutils
--- ../z.old/Completion/X/_xutils	Wed Mar 22 09:13:38 2000
+++ Completion/X/_xutils	Wed Mar 22 09:14:23 2000
@@ -55,20 +55,23 @@
     if [[ "$tmp" = *:* ]]; then
       if compset -P '(#b)(*):'; then
 	type="$match[1]"
-	_wanted displays expl 'disallow access' &&
-	    {
-	      compadd