about summary refs log tree commit diff
path: root/Completion
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>2000-03-23 04:19:26 +0000
committerTanaka Akira <akr@users.sourceforge.net>2000-03-23 04:19:26 +0000
commit626e2aeb1657f112feb6d03c34bb9e9f44764c75 (patch)
tree9e4a306df7b5826a796b99f0b6ffa3423ee9f5f9 /Completion
parent766fcd5ee2ef632cd982a1ec118dbdfde17c03a8 (diff)
downloadzsh-626e2aeb1657f112feb6d03c34bb9e9f44764c75.tar.gz
zsh-626e2aeb1657f112feb6d03c34bb9e9f44764c75.tar.xz
zsh-626e2aeb1657f112feb6d03c34bb9e9f44764c75.zip
zsh-workers/10195
Diffstat (limited to 'Completion')
-rw-r--r--Completion/Base/_arguments22
-rw-r--r--Completion/Base/_brace_parameter2
-rw-r--r--Completion/Base/_condition4
-rw-r--r--Completion/Base/_default2
-rw-r--r--Completion/Base/_describe47
-rw-r--r--Completion/Base/_first2
-rw-r--r--Completion/Base/_jobs14
-rw-r--r--Completion/Base/_math2
-rw-r--r--Completion/Base/_parameter2
-rw-r--r--Completion/Base/_subscript26
-rw-r--r--Completion/Base/_tilde9
-rw-r--r--Completion/Base/_values11
-rw-r--r--Completion/Builtins/_arrays3
-rw-r--r--Completion/Builtins/_autoload3
-rw-r--r--Completion/Builtins/_bindkey6
-rw-r--r--Completion/Builtins/_builtin3
-rw-r--r--Completion/Builtins/_cd3
-rw-r--r--Completion/Builtins/_command3
-rw-r--r--Completion/Builtins/_compdef20
-rw-r--r--Completion/Builtins/_echotc5
-rw-r--r--Completion/Builtins/_functions3
-rw-r--r--Completion/Builtins/_hash9
-rw-r--r--Completion/Builtins/_limits3
-rw-r--r--Completion/Builtins/_pids7
-rw-r--r--Completion/Builtins/_popd5
-rw-r--r--Completion/Builtins/_sched6
-rw-r--r--Completion/Builtins/_signals7
-rw-r--r--Completion/Builtins/_stat8
-rw-r--r--Completion/Builtins/_vars6
-rw-r--r--Completion/Builtins/_zftp29
-rw-r--r--Completion/Builtins/_zle6
-rw-r--r--Completion/Builtins/_zmodload8
-rw-r--r--Completion/Builtins/_zpty6
-rw-r--r--Completion/Builtins/_zstyle61
-rw-r--r--Completion/Commands/_next_tags9
-rw-r--r--Completion/Core/_alternative10
-rw-r--r--Completion/Core/_files126
-rw-r--r--Completion/Core/_main_complete5
-rw-r--r--Completion/Core/_multi_parts2
-rw-r--r--Completion/Core/_options5
-rw-r--r--Completion/Core/_parameters8
-rw-r--r--Completion/Core/_path_files18
-rw-r--r--Completion/Core/_requested25
-rw-r--r--Completion/Core/_sep_parts2
-rw-r--r--Completion/Core/_set_options5
-rw-r--r--Completion/Core/_setup40
-rw-r--r--Completion/Core/_tags28
-rw-r--r--Completion/Core/_unset_options5
-rw-r--r--Completion/Core/_wanted25
-rw-r--r--Completion/Debian/_apt14
-rw-r--r--Completion/Debian/_deb_packages2
-rw-r--r--Completion/Linux/_rpm12
-rw-r--r--Completion/User/_archie2
-rw-r--r--Completion/User/_cvs27
-rw-r--r--Completion/User/_dd9
-rw-r--r--Completion/User/_domains4
-rw-r--r--Completion/User/_gcc4
-rw-r--r--Completion/User/_gdb22
-rw-r--r--Completion/User/_getconf37
-rw-r--r--Completion/User/_gprof2
-rw-r--r--Completion/User/_groups4
-rw-r--r--Completion/User/_gs13
-rw-r--r--Completion/User/_hosts4
-rw-r--r--Completion/User/_lp14
-rw-r--r--Completion/User/_mailboxes15
-rw-r--r--Completion/User/_make14
-rw-r--r--Completion/User/_man4
-rw-r--r--Completion/User/_mh31
-rw-r--r--Completion/User/_mount4
-rw-r--r--Completion/User/_mutt2
-rw-r--r--Completion/User/_mysql_utils20
-rw-r--r--Completion/User/_netscape33
-rw-r--r--Completion/User/_nslookup6
-rw-r--r--Completion/User/_pbm13
-rw-r--r--Completion/User/_perl_basepods3
-rw-r--r--Completion/User/_perl_builtin_funcs3
-rw-r--r--Completion/User/_perl_modules2
-rw-r--r--Completion/User/_ports2
-rw-r--r--Completion/User/_rcs2
-rw-r--r--Completion/User/_rlogin6
-rw-r--r--Completion/User/_socket9
-rw-r--r--Completion/User/_ssh28
-rw-r--r--Completion/User/_stty21
-rw-r--r--Completion/User/_tar3
-rw-r--r--Completion/User/_telnet12
-rw-r--r--Completion/User/_tiff9
-rw-r--r--Completion/User/_urls85
-rw-r--r--Completion/User/_user_at_host8
-rw-r--r--Completion/User/_users6
-rw-r--r--Completion/User/_users_on6
-rw-r--r--Completion/User/_whois8
-rw-r--r--Completion/User/_yp11
-rw-r--r--Completion/X/_x_color4
-rw-r--r--Completion/X/_x_cursor4
-rw-r--r--Completion/X/_x_display2
-rw-r--r--Completion/X/_x_extension8
-rw-r--r--Completion/X/_x_font4
-rw-r--r--Completion/X/_x_keysym5
-rw-r--r--Completion/X/_x_modifier4
-rw-r--r--Completion/X/_x_window9
-rw-r--r--Completion/X/_xmodmap9
-rw-r--r--Completion/X/_xutils19
102 files changed, 626 insertions, 644 deletions
diff --git a/Completion/Base/_arguments b/Completion/Base/_arguments
index 472f085d5..9a133617c 100644
--- a/Completion/Base/_arguments
+++ b/Completion/Base/_arguments
@@ -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,35 +230,39 @@ if (( $# )) && comparguments -i "$autod" "$@"; then
 
             # 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 --git a/Completion/Base/_brace_parameter b/Completion/Base/_brace_parameter
index a6892d944..819ee24be 100644
--- a/Completion/Base/_brace_parameter
+++ b/Completion/Base/_brace_parameter
@@ -1,3 +1,3 @@
 #compdef -brace-parameter-
 
-_tags parameters && _parameters -e
+_wanted parameters && _parameters -e
diff --git a/Completion/Base/_condition b/Completion/Base/_condition
index b6a4eff7a..7ddfd9783 100644
--- a/Completion/Base/_condition
+++ b/Completion/Base/_condition
@@ -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 --git a/Completion/Base/_default b/Completion/Base/_default
index b84cbff6a..a237ae47d 100644
--- a/Completion/Base/_default
+++ b/Completion/Base/_default
@@ -12,7 +12,7 @@ if { zstyle -s ':completion:${curcontext}:' use-compctl ctl ||
   compcall "$opt[@]" || return 0
 fi
 
-_tags files || return 1
+_wanted files || return 1
 
 _files && return 0
 
diff --git a/Completion/Base/_describe b/Completion/Base/_describe
index 986d27c4e..95016fcd1 100644
--- a/Completion/Base/_describe
+++ b/Completion/Base/_describe
@@ -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 @@ fi
 
 # 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 --git a/Completion/Base/_first b/Completion/Base/_first
index 566cfc785..386f67fa0 100644
--- a/Completion/Base/_first
+++ b/Completion/Base/_first
@@ -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 --git a/Completion/Base/_jobs b/Completion/Base/_jobs
index 6c4154d6f..52674497e 100644
--- a/Completion/Base/_jobs
+++ b/Completion/Base/_jobs
@@ -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 @@ zstyle -T ":completion:${curcontext}:jobs" verbose       && desc=yes
 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 @@ else
 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 --git a/Completion/Base/_math b/Completion/Base/_math
index 821121c33..b9743d6b4 100644
--- a/Completion/Base/_math
+++ b/Completion/Base/_math
@@ -9,4 +9,4 @@ if [[ "$SUFFIX" = *[^a-zA-Z0-9_]* ]]; then
   SUFFIX="${SUFFIX%%[^a-zA-Z0-9_]*}"
 fi
 
-_tags parameters && _parameters
+_parameters
diff --git a/Completion/Base/_parameter b/Completion/Base/_parameter
index 7a761dea9..7e7788535 100644
--- a/Completion/Base/_parameter
+++ b/Completion/Base/_parameter
@@ -1,3 +1,3 @@
 #compdef -parameter-
 
-_tags parameters && _parameters -e
+_parameters -e
diff --git a/Completion/Base/_subscript b/Completion/Base/_subscript
index c0c0b790d..aa31bd297 100644
--- a/Completion/Base/_subscript
+++ b/Completion/Base/_subscript
@@ -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 @@ elif [[ ${(Pt)${compstate[parameter]}} = array* ]]; then
       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 --git a/Completion/Base/_tilde b/Completion/Base/_tilde
index 98e9d2c00..2edc2ca24 100644
--- a/Completion/Base/_tilde
+++ b/Completion/Base/_tilde
@@ -18,10 +18,10 @@ _tags users named-directories directory-stack
 
 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 @@ while _tags; do
       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 --git a/Completion/Base/_values b/Completion/Base/_values
index e8004ba6f..754147e05 100644
--- a/Completion/Base/_values
+++ b/Completion/Base/_values
@@ -18,7 +18,7 @@ if compvalues -i "$@"; then
 
   if ! compvalues -D descr action; then
 
-    _tags values || return 1
+    _wanted values || return 1
 
     curcontext="${oldcontext%:*}:values"
 
@@ -119,25 +119,26 @@ if compvalues -i "$@"; then
 
       # 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 --git a/Completion/Builtins/_arrays b/Completion/Builtins/_arrays
index 4f67ff08d..138b14091 100644
--- a/Completion/Builtins/_arrays
+++ b/Completion/Builtins/_arrays
@@ -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 --git a/Completion/Builtins/_autoload b/Completion/Builtins/_autoload
index de5a6045d..f1d49c3e3 100644
--- a/Completion/Builtins/_autoload
+++ b/Completion/Builtins/_autoload
@@ -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 --git a/Completion/Builtins/_bindkey b/Completion/Builtins/_bindkey
index 98459916b..d96c2289b 100644
--- a/Completion/Builtins/_bindkey
+++ b/Completion/Builtins/_bindkey
@@ -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 --git a/Completion/Builtins/_builtin b/Completion/Builtins/_builtin
index 8d682420a..1ca5e346c 100644
--- a/Completion/Builtins/_builtin
+++ b/Completion/Builtins/_builtin
@@ -7,6 +7,5 @@ if (( $CURRENT > 2 )); then
 else
   local expl
 
-  _wanted commands expl 'builtin command' &&
-      compadd "$expl[@]" "$@" - "${(k@)builtins}"
+  _wanted commands expl 'builtin command' compadd "$@" - "${(k@)builtins}"
 fi
diff --git a/Completion/Builtins/_cd b/Completion/Builtins/_cd
index 4cb070811..bea6ffbc6 100644
--- a/Completion/Builtins/_cd
+++ b/Completion/Builtins/_cd
@@ -22,8 +22,7 @@ if [[ CURRENT -eq 3 ]]; then
   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 --git a/Completion/Builtins/_command b/Completion/Builtins/_command
index 1cfa6add9..6631b9b6b 100644
--- a/Completion/Builtins/_command
+++ b/Completion/Builtins/_command
@@ -6,6 +6,5 @@ if [[ CURRENT -ge 3 ]]; then
 else
   local expl
 
-  _wanted commands expl 'external command' &&
-      compadd "$expl[@]" "$@" - "${(k@)commands}"
+  _wanted commands expl 'external command' compadd "$@" - "${(k@)commands}"
 fi
diff --git a/Completion/Builtins/_compdef b/Completion/Builtins/_compdef
index 772c6b90d..13711e865 100644
--- a/Completion/Builtins/_compdef
+++ b/Completion/Builtins/_compdef
@@ -16,24 +16,24 @@ _arguments -C -s \
 
 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 --git a/Completion/Builtins/_echotc b/Completion/Builtins/_echotc
index 4051c1945..cc07b9cd0 100644
--- a/Completion/Builtins/_echotc
+++ b/Completion/Builtins/_echotc
@@ -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 --git a/Completion/Builtins/_functions b/Completion/Builtins/_functions
index 98b21da68..de49d96ed 100644
--- a/Completion/Builtins/_functions
+++ b/Completion/Builtins/_functions
@@ -2,5 +2,4 @@
 
 local expl
 
-_wanted functions expl 'shell function' &&
-    compadd "$expl[@]" "$@" - "${(k@)functions}"
+_wanted functions expl 'shell function' compadd "$@" - "${(k@)functions}"
diff --git a/Completion/Builtins/_hash b/Completion/Builtins/_hash
index c8a51a38a..b7e777a05 100644
--- a/Completion/Builtins/_hash
+++ b/Completion/Builtins/_hash
@@ -4,15 +4,14 @@ local expl
 
 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 --git a/Completion/Builtins/_limits b/Completion/Builtins/_limits
index dae573e03..5dd2bffe5 100644
--- a/Completion/Builtins/_limits
+++ b/Completion/Builtins/_limits
@@ -2,5 +2,4 @@
 
 local expl
 
-_wanted limits expl 'process limits' &&
-    compadd "$expl[@]" ${${(f)"$(limit)"}%% *}
+_wanted limits expl 'process limits' compadd ${${(f)"$(limit)"}%% *}
diff --git a/Completion/Builtins/_pids b/Completion/Builtins/_pids
index 92fc9bac7..ff65cef31 100644
--- a/Completion/Builtins/_pids
+++ b/Completion/Builtins/_pids
@@ -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 @@ else
   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 --git a/Completion/Builtins/_popd b/Completion/Builtins/_popd
index b79121139..ba12bb3f3 100644
--- a/Completion/Builtins/_popd
+++ b/Completion/Builtins/_popd
@@ -12,7 +12,7 @@ local expl list lines revlines disp
 ! 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 @@ else
   disp=()
 fi
 
-compadd "$expl[@]" "$@" "$disp[@]" -Q - "$list[@]"
+_loop -V directory-stack expl 'directory stack' \
+    compadd "$@" "$disp[@]" -Q - "$list[@]"
diff --git a/Completion/Builtins/_sched b/Completion/Builtins/_sched
index 783113c45..97d8830b8 100644
--- a/Completion/Builtins/_sched
+++ b/Completion/Builtins/_sched
@@ -4,7 +4,7 @@ local expl lines disp
 
 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 @@ if [[ CURRENT -eq 2 ]]; then
     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 --git a/Completion/Builtins/_signals b/Completion/Builtins/_signals
index 910502165..041b6eb6b 100644
--- a/Completion/Builtins/_signals
+++ b/Completion/Builtins/_signals
@@ -20,7 +20,7 @@ done
 
 [[ "$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 @@ if _wanted signals expl signal &&
   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 --git a/Completion/Builtins/_stat b/Completion/Builtins/_stat
index c03b1590c..5f291d49b 100644
--- a/Completion/Builtins/_stat
+++ b/Completion/Builtins/_stat
@@ -9,10 +9,12 @@ else
 
   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 --git a/Completion/Builtins/_vars b/Completion/Builtins/_vars
index 2758f3de2..7d8c20f52 100644
--- a/Completion/Builtins/_vars
+++ b/Completion/Builtins/_vars
@@ -16,9 +16,9 @@ if [[ $PREFIX = *\[* ]]; then
   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 --git a/Completion/Builtins/_zftp b/Completion/Builtins/_zftp
index 6246015ec..c0b19a796 100644
--- a/Completion/Builtins/_zftp
+++ b/Completion/Builtins/_zftp
@@ -13,8 +13,8 @@ local subcom expl curcontext="${curcontext}"
 
 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 @@ fi
 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 @@ case $subcom in
       [[ -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 --git a/Completion/Builtins/_zle b/Completion/Builtins/_zle
index 8e8017817..46765bc5e 100644
--- a/Completion/Builtins/_zle
+++ b/Completion/Builtins/_zle
@@ -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 --git a/Completion/Builtins/_zmodload b/Completion/Builtins/_zmodload
index c167df445..7e893c860 100644
--- a/Completion/Builtins/_zmodload
+++ b/Completion/Builtins/_zmodload
@@ -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 --git a/Completion/Builtins/_zpty b/Completion/Builtins/_zpty
index b197b4128..4090bde69 100644
--- a/Completion/Builtins/_zpty
+++ b/Completion/Builtins/_zpty
@@ -11,13 +11,13 @@ _arguments -C -s \
   '(-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 --git a/Completion/Builtins/_zstyle b/Completion/Builtins/_zstyle
index 328e2d7d2..6cb369cfd 100644
--- a/Completion/Builtins/_zstyle
+++ b/Completion/Builtins/_zstyle
@@ -41,7 +41,6 @@ styles=(
   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 @@ while [[ -n $state ]]; do
 
   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 @@ while [[ -n $state ]]; do
       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 @@ while [[ -n $state ]]; do
       ;;
 
     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 @@ while [[ -n $state ]]; do
       ;;
 
     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 @@ while [[ -n $state ]]; do
       ;;
 
     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 --git a/Completion/Commands/_next_tags b/Completion/Commands/_next_tags
index 5cda547e8..818b73fe0 100644
--- a/Completion/Commands/_next_tags
+++ b/Completion/Commands/_next_tags
@@ -52,8 +52,13 @@ _next_tags() {
 _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 --git a/Completion/Core/_alternative b/Completion/Core/_alternative
index 73292cb52..482e9db51 100644
--- a/Completion/Core/_alternative
+++ b/Completion/Core/_alternative
@@ -44,24 +44,26 @@ while _tags; do
 
         # 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 --git a/Completion/Core/_files b/Completion/Core/_files
index 75cabda81..d4eb2b7db 100644
--- a/Completion/Core/_files
+++ b/Completion/Core/_files
@@ -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=()
-
-ign=()
-
-zstyle -s ":completion:${curcontext}:all-files" file-patterns tmp &&
-    [[ -n "$tmp" ]] &&
-        aopts=(-g "$tmp")
+(( $tmp[(I)-g*] )) && glob="${(j: :)${(M)tmp:#-g*}#-g}"
 
-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 --git a/Completion/Core/_main_complete b/Completion/Core/_main_complete
index 63d785686..fedea9b51 100644
--- a/Completion/Core/_main_complete
+++ b/Completion/Core/_main_complete
@@ -20,7 +20,7 @@ setopt localoptions nullglob rcexpandparam extendedglob
 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 \
@@ -31,6 +31,9 @@ local ctxt post ret=1 tmp _compskip format _comp_ignore \
 
 typeset -U _lastdescr
 
+_comp_opts=()
+_comp_tries=()
+
 [[ -z "$curcontext" ]] && curcontext=:::
 
 # Special completion contexts after `~' and `='.
diff --git a/Completion/Core/_multi_parts b/Completion/Core/_multi_parts
index 9e5906ac2..1c02e7e39 100644
--- a/Completion/Core/_multi_parts
+++ b/Completion/Core/_multi_parts
@@ -14,7 +14,7 @@ typeset -U tmp2
 # 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 --git a/Completion/Core/_options b/Completion/Core/_options
index 8664e239e..70e106247 100644
--- a/Completion/Core/_options
+++ b/Completion/Core/_options
@@ -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 --git a/Completion/Core/_parameters b/Completion/Core/_parameters
index c7875abcf..1e430dfc1 100644
--- a/Completion/Core/_parameters
+++ b/Completion/Core/_parameters
@@ -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 --git a/Completion/Core/_path_files b/Completion/Core/_path_files
index ad956bb72..21ca05529 100644
--- a/Completion/Core/_path_files
+++ b/Completion/Core/_path_files
@@ -20,7 +20,7 @@ exppaths=()
 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 @@ if (( $#ignore )); then
   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 @@ eorig="$orig"
 
 # 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 --git a/Completion/Core/_requested b/Completion/Core/_requested
index b5efb5a9e..41122819a 100644
--- a/Completion/Core/_requested
+++ b/Completion/Core/_requested
@@ -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 --git a/Completion/Core/_sep_parts b/Completion/Core/_sep_parts
index 11fb20ab6..2ea0e6c68 100644
--- a/Completion/Core/_sep_parts
+++ b/Completion/Core/_sep_parts
@@ -23,7 +23,7 @@ local matchflags opt group expl nm=$compstate[nmatches] opre osuf opts match
 # 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 --git a/Completion/Core/_set_options b/Completion/Core/_set_options
index ae4d3784e..ea851d64a 100644
--- a/Completion/Core/_set_options
+++ b/Completion/Core/_set_options
@@ -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 --git a/Completion/Core/_setup b/Completion/Core/_setup
index 5d63b97ce..0b9e5d0a9 100644
--- a/Completion/Core/_setup
+++ b/Completion/Core/_setup
@@ -18,42 +18,34 @@ if zstyle -a ":completion:${curcontext}:$1" list-colors val; then
 
 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 --git a/Completion/Core/_tags b/Completion/Core/_tags
index 6e3966074..b74e70264 100644
--- a/Completion/Core/_tags
+++ b/Completion/Core/_tags
@@ -50,21 +50,31 @@ if (( $# )); then
              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 --git a/Completion/Core/_unset_options b/Completion/Core/_unset_options
index 8c8ed780d..d06866517 100644
--- a/Completion/Core/_unset_options
+++ b/Completion/Core/_unset_options
@@ -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 --git a/Completion/Core/_wanted b/Completion/Core/_wanted
index 400daa701..1d6dcdb59 100644
--- a/Completion/Core/_wanted
+++ b/Completion/Core/_wanted
@@ -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 @@ else
   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 --git a/Completion/Debian/_apt b/Completion/Debian/_apt
index be7973c34..7ed7b8974 100644
--- a/Completion/Debian/_apt
+++ b/Completion/Debian/_apt
@@ -75,7 +75,7 @@ _apt_arguments () {
   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 @@ _apt-get () {
     /$'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 @@ _apt-cache () {
     /$'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 @@ _apt-cdrom () {
     -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 @@ _apt-config () {
     -- \
     /$'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 --git a/Completion/Debian/_deb_packages b/Completion/Debian/_deb_packages
index 7973d9868..3d742aa2c 100644
--- a/Completion/Debian/_deb_packages
+++ b/Completion/Debian/_deb_packages
@@ -51,7 +51,7 @@ _deb_packages () {
 
   _deb_packages_update_$pkgset
 
-  _tags packages && compadd "$expl[@]" - "${(@P)cachevar}"
+  _wanted packages && compadd "$expl[@]" - "${(@P)cachevar}"
 }
 
 _deb_packages "$@"
diff --git a/Completion/Linux/_rpm b/Completion/Linux/_rpm
index d5978eb0b..e23768185 100644
--- a/Completion/Linux/_rpm
+++ b/Completion/Linux/_rpm
@@ -189,12 +189,12 @@ while [[ -n "$state" ]]; do
     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 @@ while [[ -n "$state" ]]; do
     ;;
   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'
@@ -220,8 +220,6 @@ while [[ -n "$state" ]]; do
       _description directories expl 'old path'
     fi
 
-    _tags directories || return 1
-
     _files "$expl[@]" -/ && ret=0
     ;;
   esac
diff --git a/Completion/User/_archie b/Completion/User/_archie
index 57a5db494..cddd7680d 100644
--- a/Completion/User/_archie
+++ b/Completion/User/_archie
@@ -26,6 +26,6 @@ case "$state" in
 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 --git a/Completion/User/_cvs b/Completion/User/_cvs
index 7d55a7635..41a1b8a97 100644
--- a/Completion/User/_cvs
+++ b/Completion/User/_cvs
@@ -34,7 +34,7 @@ _cvs_command () {
 	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 @@ _cvs_watch () {
   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 @@ _cvs_root () {
     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 @@ _cvs_user_variable () {
 
 (( $+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 @@ _cvs_modules () {
   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_modules () {
 _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 @@ _cvs_files_removed () {
     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 --git a/Completion/User/_dd b/Completion/User/_dd
index fa322d791..419fc1a7a 100644
--- a/Completion/User/_dd
+++ b/Completion/User/_dd
@@ -6,9 +6,8 @@ if compset -P 1 'conv='; then
   # 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 @@ elif compset -P 1 'of='; then
   _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 --git a/Completion/User/_domains b/Completion/User/_domains
index cf7e9befe..3cc64db07 100644
--- a/Completion/User/_domains
+++ b/Completion/User/_domains
@@ -16,5 +16,5 @@ if ! zstyle -a ":completion:${curcontext}:domains" domains domains; then
   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 --git a/Completion/User/_gcc b/Completion/User/_gcc
index 7292a933c..f826f9793 100644
--- a/Completion/User/_gcc
+++ b/Completion/User/_gcc
@@ -273,8 +273,8 @@ dump)
     '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 --git a/Completion/User/_gdb b/Completion/User/_gdb
index 283aff631..2fd09cbc5 100644
--- a/Completion/User/_gdb
+++ b/Completion/User/_gdb
@@ -10,18 +10,21 @@ local cur="$words[CURRENT]" prev w list ret=1 expl
 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 @@ else
   (-[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 --git a/Completion/User/_getconf b/Completion/User/_getconf
index 7ce709588..3a635368f 100644
--- a/Completion/User/_getconf
+++ b/Completion/User/_getconf
@@ -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 @@ if [[ CURRENT -eq 2 ]]; then
 	  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 --git a/Completion/User/_gprof b/Completion/User/_gprof
index 80de70bb4..67fbb99eb 100644
--- a/Completion/User/_gprof
+++ b/Completion/User/_gprof
@@ -17,7 +17,7 @@ _arguments -C -s -{a,b,c,D,h,i,l,L,s,T,v,w,x,y,z} \
 if [[ -n "$state" ]]; then
   local cmd pair expl
 
-  _tags functions || return 1
+  _wanted functions || return 1
 
   [[ "$state" = pair ]] && pair=yes
 
diff --git a/Completion/User/_groups b/Completion/User/_groups
index 185b06549..748536f3b 100644
--- a/Completion/User/_groups
+++ b/Completion/User/_groups
@@ -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 @@ if ! zstyle -a ":completion:${curcontext}:" groups groups; then
   groups=( "$_cache_groups[@]" )
 fi
 
-compadd "$@" "$expl[@]" - "$groups[@]"
+_loop groups expl group compadd "$@" - "$groups[@]"
diff --git a/Completion/User/_gs b/Completion/User/_gs
index 8ae5a65f9..52345cdbb 100644
--- a/Completion/User/_gs
+++ b/Completion/User/_gs
@@ -25,8 +25,8 @@ else
     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 @@ else
     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 @@ else
         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 --git a/Completion/User/_hosts b/Completion/User/_hosts
index cab65329c..c90493d21 100644
--- a/Completion/User/_hosts
+++ b/Completion/User/_hosts
@@ -9,5 +9,5 @@ if ! zstyle -a ":completion:${curcontext}:hosts" hosts hosts; then
   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 --git a/Completion/User/_lp b/Completion/User/_lp
index 51fbb1616..3ff814cbb 100644
--- a/Completion/User/_lp
+++ b/Completion/User/_lp
@@ -36,14 +36,15 @@ if (( ! $+_lp_cache )); then
 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 @@ else
       _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
           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
           else
   	  disp=()
           fi
-          compadd "$expl[@]" "$disp[@]" - "$strs[@]" && ret=0
+          _loop jobs expl job compadd "$disp[@]" - "$strs[@]" && ret=0
         fi
         (( ret )) || return 0
       done
diff --git a/Completion/User/_mailboxes b/Completion/User/_mailboxes
index 3f798c2d7..784bc4e6e 100644
--- a/Completion/User/_mailboxes
+++ b/Completion/User/_mailboxes
@@ -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 @@ _mailboxes() {
   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 @@ _mua_mailboxes() {
 
   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 @@ _mua_mailboxes() {
       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 @@ _mua_mailboxes() {
        ;;
   esac
 
-  local ret=1
   (( $#mbox_names )) && _multi_parts "$@" / mbox_names && ret=0
   (( $#mbox_short )) && compadd "$@" - "$mbox_short[@]" && ret=0
   return ret
diff --git a/Completion/User/_make b/Completion/User/_make
index aaae444a8..dc08d4e26 100644
--- a/Completion/User/_make
+++ b/Completion/User/_make
@@ -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 @@ else
     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 --git a/Completion/User/_man b/Completion/User/_man
index 6f62501ee..8ae97962c 100644
--- a/Completion/User/_man
+++ b/Completion/User/_man
@@ -33,5 +33,5 @@ else
   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 --git a/Completion/User/_mh b/Completion/User/_mh
index f02aee9b5..aacde38a1 100644
--- a/Completion/User/_mh
+++ b/Completion/User/_mh
@@ -17,13 +17,16 @@ if compset -P 1 -; then
   # 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 @@ elif compset -P 1 '[+@]' || [[ "$prev" = -draftfolder ]]; then
     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 @@ elif [[ "$prev" = -(form|audit|filter) ]]; then
   [[ -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 @@ else
     # 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 --git a/Completion/User/_mount b/Completion/User/_mount
index 23b2a6378..00fb00fb5 100644
--- a/Completion/User/_mount
+++ b/Completion/User/_mount
@@ -539,11 +539,11 @@ case "$state" in
 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 --git a/Completion/User/_mutt b/Completion/User/_mutt
index 90e7dec08..8df7799ee 100644
--- a/Completion/User/_mutt
+++ b/Completion/User/_mutt
@@ -25,8 +25,6 @@ local curcontext="$curcontext" state line ret=1
  '-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 --git a/Completion/User/_mysql_utils b/Completion/User/_mysql_utils
index 6d777112d..77ed7a36e 100644
--- a/Completion/User/_mysql_utils
+++ b/Completion/User/_mysql_utils
@@ -24,33 +24,33 @@ _mysql_hosts () {
   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 @@ _mysqladmin_commands () {
        )
 
   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 --git a/Completion/User/_netscape b/Completion/User/_netscape
index 23601de12..715ca408a 100644
--- a/Completion/User/_netscape
+++ b/Completion/User/_netscape
@@ -40,30 +40,31 @@ if [[ "$state" = "remote" ]]; then
     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 @@ fi
 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 --git a/Completion/User/_nslookup b/Completion/User/_nslookup
index 7c67cb256..fc14df18c 100644
--- a/Completion/User/_nslookup
+++ b/Completion/User/_nslookup
@@ -60,7 +60,7 @@ if [[ -n "$compcontext" ]]; then
 
     _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 @@ if [[ -n "$compcontext" ]]; then
 
   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 @@ if [[ -n "$compcontext" ]]; then
     [[ -z "$state" ]] && return ret
     ;;
   *)
-    _wanted hosts expl 'server' && _hosts "$expl[@]"
+    _wanted hosts expl 'server' _hosts
     return
   esac
 fi
diff --git a/Completion/User/_pbm b/Completion/User/_pbm
index 2c12505ee..1f740ad31 100644
--- a/Completion/User/_pbm
+++ b/Completion/User/_pbm
@@ -254,7 +254,7 @@ pgmtoppm)
     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 @@ ppmquant)
   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 --git a/Completion/User/_perl_basepods b/Completion/User/_perl_basepods
index 7f257aed3..f5b2216c1 100644
--- a/Completion/User/_perl_basepods
+++ b/Completion/User/_perl_basepods
@@ -29,5 +29,4 @@ fi
 
 local expl
 
-_wanted pods expl 'Perl base pods' &&
-    compadd "$expl[@]" - $_perl_basepods
+_wanted pods expl 'Perl base pods' compadd - $_perl_basepods
diff --git a/Completion/User/_perl_builtin_funcs b/Completion/User/_perl_builtin_funcs
index 7ac69828d..8c221f5a6 100644
--- a/Completion/User/_perl_builtin_funcs
+++ b/Completion/User/_perl_builtin_funcs
@@ -28,5 +28,4 @@ fi
 
 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 --git a/Completion/User/_perl_modules b/Completion/User/_perl_modules
index 8f6a5b882..d1701f57a 100644
--- a/Completion/User/_perl_modules
+++ b/Completion/User/_perl_modules
@@ -49,4 +49,4 @@ fi
 
 local expl
 
-_wanted modules expl 'Perl modules' && compadd "$expl[@]" "$opts[@]" - $_perl_modules
+_wanted modules expl 'Perl modules' compadd "$opts[@]" - $_perl_modules
diff --git a/Completion/User/_ports b/Completion/User/_ports
index 6780067b3..e2db41960 100644
--- a/Completion/User/_ports
+++ b/Completion/User/_ports
@@ -9,4 +9,4 @@ if ! zstyle -a ":completion:${curcontext}:" ports ports; then
   ports=( "$_cache_ports[@]" )
 fi
 
-_wanted ports expl port && compadd "$@" "$expl[@]" - "$ports[@]"
+_wanted ports expl port compadd "$@" - "$ports[@]"
diff --git a/Completion/User/_rcs b/Completion/User/_rcs
index 0831b1d0b..6c4a1d9d6 100644
--- a/Completion/User/_rcs
+++ b/Completion/User/_rcs
@@ -8,5 +8,5 @@ if [[ $compstate[nmatches] -eq nm && -d RCS && $words[1] != ci ]]; then
   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 --git a/Completion/User/_rlogin b/Completion/User/_rlogin
index df78bd447..2c5e9bfc0 100644
--- a/Completion/User/_rlogin
+++ b/Completion/User/_rlogin
@@ -40,7 +40,7 @@ _rlogin () {
       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 () {
 }
 
 _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 --git a/Completion/User/_socket b/Completion/User/_socket
index dfe8f4844..fecd3e6c0 100644
--- a/Completion/User/_socket
+++ b/Completion/User/_socket
@@ -39,17 +39,16 @@ command)
 
 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 --git a/Completion/User/_ssh b/Completion/User/_ssh
index ddfe6de63..6748a270e 100644
--- a/Completion/User/_ssh
+++ b/Completion/User/_ssh
@@ -54,21 +54,18 @@ _ssh () {
         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 @@ _ssh () {
             _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 @@ _ssh () {
             ;;
           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 @@ _ssh () {
           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 @@ _ssh () {
         ;;
       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 @@ _ssh () {
       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 --git a/Completion/User/_stty b/Completion/User/_stty
index 06d0bf851..f40cd856e 100644
--- a/Completion/User/_stty
+++ b/Completion/User/_stty
@@ -4,18 +4,15 @@ local expl
 
 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 --git a/Completion/User/_tar b/Completion/User/_tar
index ac23e94f3..6ca1c27bf 100644
--- a/Completion/User/_tar
+++ b/Completion/User/_tar
@@ -142,8 +142,7 @@ elif [[ ( "$_tar_cmd" = *[xt]* || -n $del ) && -n "$tf" ]]; then
     _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 --git a/Completion/User/_telnet b/Completion/User/_telnet
index 2542ff34d..02a30f138 100644
--- a/Completion/User/_telnet
+++ b/Completion/User/_telnet
@@ -46,25 +46,25 @@ _arguments -C -s \
 
 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 --git a/Completion/User/_tiff b/Completion/User/_tiff
index a0fb0d4b4..5f7cc7edb 100644
--- a/Completion/User/_tiff
+++ b/Completion/User/_tiff
@@ -194,9 +194,12 @@ if [[ -n "$state" ]]; then
       ;;
     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 --git a/Completion/User/_urls b/Completion/User/_urls
index 3f2cab789..369017677 100644
--- a/Completion/User/_urls
+++ b/Completion/User/_urls
@@ -49,16 +49,18 @@ local localhttp_userdir="$localhttp[3]"
 
 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 @@ scheme="$match[1]"
 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 @@ case "$scheme" in
 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 @@ if [[ "$localhttp_servername" = "$host" ]]; then
       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 --git a/Completion/User/_user_at_host b/Completion/User/_user_at_host
index c7b86d385..785d79932 100644
--- a/Completion/User/_user_at_host
+++ b/Completion/User/_user_at_host
@@ -22,9 +22,9 @@ if [[ -prefix 1 *@ ]]; then
 
   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 --git a/Completion/User/_users b/Completion/User/_users
index da5539556..0457ecabf 100644
--- a/Completion/User/_users
+++ b/Completion/User/_users
@@ -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 --git a/Completion/User/_users_on b/Completion/User/_users_on
index f620f83c7..04a834d53 100644
--- a/Completion/User/_users_on
+++ b/Completion/User/_users_on
@@ -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 --git a/Completion/User/_whois b/Completion/User/_whois
index 0d2675d47..ffdbc13f9 100644
--- a/Completion/User/_whois
+++ b/Completion/User/_whois
@@ -189,14 +189,14 @@ _whois_fwhois () {
 }
 
 _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 @@ _whois:whois.internic.net () {
   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 @@ _whois:whois.nic.ad.jp () {
   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 --git a/Completion/User/_yp b/Completion/User/_yp
index fe3c0a482..4b1b031b3 100644
--- a/Completion/User/_yp
+++ b/Completion/User/_yp
@@ -95,15 +95,16 @@ if [[ "$state" = map* ]]; then
 
   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 --git a/Completion/X/_x_color b/Completion/X/_x_color
index 43f8ad5cd..d58afcb74 100644
--- a/Completion/X/_x_color
+++ b/Completion/X/_x_color
@@ -30,6 +30,6 @@ if (( ! $+_color_cache )); then
   (( $#_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 --git a/Completion/X/_x_cursor b/Completion/X/_x_cursor
index 8b057a537..416ff49a5 100644
--- a/Completion/X/_x_cursor
+++ b/Completion/X/_x_cursor
@@ -14,5 +14,5 @@ if (( ! $+_cursor_cache )); then
   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 --git a/Completion/X/_x_display b/Completion/X/_x_display
index f547a64fa..0f0ebf9ae 100644
--- a/Completion/X/_x_display
+++ b/Completion/X/_x_display
@@ -1,3 +1,3 @@
 #autoload
 
-_tags displays && _hosts -S ':0 ' -r :
+_wnated displays && _hosts -S ':0 ' -r :
diff --git a/Completion/X/_x_extension b/Completion/X/_x_extension
index 9321f4951..61b8ea2d8 100644
--- a/Completion/X/_x_extension
+++ b/Completion/X/_x_extension
@@ -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 --git a/Completion/X/_x_font b/Completion/X/_x_font
index 1be2d3312..43c7846c5 100644
--- a/Completion/X/_x_font
+++ b/Completion/X/_x_font
@@ -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 @@ if (( ! $+_font_cache )); then
  _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 --git a/Completion/X/_x_keysym b/Completion/X/_x_keysym
index 2e8f037b1..790571350 100644
--- a/Completion/X/_x_keysym
+++ b/Completion/X/_x_keysym
@@ -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 @@ if (( ! $+_keysym_cache )); then
   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 --git a/Completion/X/_x_modifier b/Completion/X/_x_modifier
index 01052da65..490d12ef3 100644
--- a/Completion/X/_x_modifier
+++ b/Completion/X/_x_modifier
@@ -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 --git a/Completion/X/_x_window b/Completion/X/_x_window
index a79f7fd62..2ca31e1bd 100644
--- a/Completion/X/_x_window
+++ b/Completion/X/_x_window
@@ -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 --git a/Completion/X/_xmodmap b/Completion/X/_xmodmap
index da0029a16..01358b0d4 100644
--- a/Completion/X/_xmodmap
+++ b/Completion/X/_xmodmap
@@ -82,9 +82,12 @@ if [[ -n "$state" ]]; then
     [[ "$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 --git a/Completion/X/_xutils b/Completion/X/_xutils
index 1fe6ce468..fe01a5d30 100644
--- a/Completion/X/_xutils
+++ b/Completion/X/_xutils
@@ -55,20 +55,23 @@ xhost)
     if [[ "$tmp" = *:* ]]; then
       if compset -P '(#b)(*):'; then
 	type="$match[1]"
-	_wanted displays expl 'disallow access' &&
-	    {
-	      compadd "$expl[@]" -M 'm:{a-z}={A-Z} r:|[:.]=* r:|=*' - \
-		      ${${(M)tmp:#(#i)$type:*}#(#i)$type:} ||
-	      _hosts "$expl[@]"
-	    }
+	_wanted displays &&
+            while _try displays expl 'disallow access'; do
+	      { compadd "$expl[@]" -M 'm:{a-z}={A-Z} r:|[:.]=* r:|=*' - \
+		        ${${(M)tmp:#(#i)$type:*}#(#i)$type:} ||
+	            _hosts "$expl[@]" } && return 0
+	    done
       else
 	_alternative \
 	    'types:name family:compadd -S: ${(L)tmp%%:*}' \
 	    'hosts:host:compadd ${(@)tmp#*:}' && ret=0
       fi
     else
-      _wanted displays expl 'disallow access' &&
-	  { compadd "$expl[@]" -M 'm:{a-z}={A-Z} r:|[:.]=* r:|=*' - $tmp || _hosts "$expl[@]" }
+      _wanted displays &&
+          while _try displays expl 'disallow access'; do
+	    { compadd "$expl[@]" -M 'm:{a-z}={A-Z} r:|[:.]=* r:|=*' - $tmp ||
+              _hosts "$expl[@]" } && return 0
+          done
     fi
   else
     compset -P +