about summary refs log tree commit diff
path: root/Completion
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>1999-11-15 12:01:46 +0000
committerTanaka Akira <akr@users.sourceforge.net>1999-11-15 12:01:46 +0000
commit35b2633ad941966f5fca07b625a594a5b68c0fdb (patch)
treeb54740d014e594ba5d81931cdcdb3387bcf9dfca /Completion
parentbb98460a01ce1f6c1e71f7e401f782c81b71486b (diff)
downloadzsh-35b2633ad941966f5fca07b625a594a5b68c0fdb.tar.gz
zsh-35b2633ad941966f5fca07b625a594a5b68c0fdb.tar.xz
zsh-35b2633ad941966f5fca07b625a594a5b68c0fdb.zip
manual/8639
Diffstat (limited to 'Completion')
-rw-r--r--Completion/Base/_arg_compile2
-rw-r--r--Completion/Base/_arguments51
-rw-r--r--Completion/Base/_brace_parameter2
-rw-r--r--Completion/Base/_command_names2
-rw-r--r--Completion/Base/_condition10
-rw-r--r--Completion/Base/_default5
-rw-r--r--Completion/Base/_describe42
-rw-r--r--Completion/Base/_equal2
-rw-r--r--Completion/Base/_first2
-rw-r--r--Completion/Base/_jobs8
-rw-r--r--Completion/Base/_math2
-rw-r--r--Completion/Base/_parameter2
-rw-r--r--Completion/Base/_regex_arguments4
-rw-r--r--Completion/Base/_subscript29
-rw-r--r--Completion/Base/_tilde16
-rw-r--r--Completion/Base/_values55
-rw-r--r--Completion/Builtins/_aliases2
-rw-r--r--Completion/Builtins/_arrays6
-rw-r--r--Completion/Builtins/_autoload6
-rw-r--r--Completion/Builtins/_bindkey12
-rw-r--r--Completion/Builtins/_builtin6
-rw-r--r--Completion/Builtins/_cd6
-rw-r--r--Completion/Builtins/_command6
-rw-r--r--Completion/Builtins/_compdef12
-rw-r--r--Completion/Builtins/_disable2
-rw-r--r--Completion/Builtins/_echotc9
-rw-r--r--Completion/Builtins/_enable2
-rw-r--r--Completion/Builtins/_functions6
-rw-r--r--Completion/Builtins/_hash22
-rw-r--r--Completion/Builtins/_kill9
-rw-r--r--Completion/Builtins/_limits6
-rw-r--r--Completion/Builtins/_pids14
-rw-r--r--Completion/Builtins/_popd10
-rw-r--r--Completion/Builtins/_sched5
-rw-r--r--Completion/Builtins/_stat15
-rw-r--r--Completion/Builtins/_trap5
-rw-r--r--Completion/Builtins/_unhash2
-rw-r--r--Completion/Builtins/_vars14
-rw-r--r--Completion/Builtins/_wait2
-rw-r--r--Completion/Builtins/_which2
-rw-r--r--Completion/Builtins/_zftp35
-rw-r--r--Completion/Builtins/_zle9
-rw-r--r--Completion/Builtins/_zmodload14
-rw-r--r--Completion/Commands/_complete_help35
-rw-r--r--Completion/Commands/_correct_word15
-rw-r--r--Completion/Commands/_expand_word21
-rw-r--r--Completion/Commands/_history_complete_word36
-rw-r--r--Completion/Commands/_read_comp4
-rw-r--r--Completion/Core/.distfiles2
-rw-r--r--Completion/Core/_alternative21
-rw-r--r--Completion/Core/_approximate31
-rw-r--r--Completion/Core/_complete21
-rw-r--r--Completion/Core/_correct6
-rw-r--r--Completion/Core/_description16
-rw-r--r--Completion/Core/_expand61
-rw-r--r--Completion/Core/_files6
-rw-r--r--Completion/Core/_list12
-rw-r--r--Completion/Core/_main_complete21
-rw-r--r--Completion/Core/_match20
-rw-r--r--Completion/Core/_menu8
-rw-r--r--Completion/Core/_message4
-rw-r--r--Completion/Core/_normal23
-rw-r--r--Completion/Core/_oldlist26
-rw-r--r--Completion/Core/_options8
-rw-r--r--Completion/Core/_parameters5
-rw-r--r--Completion/Core/_path_files12
-rw-r--r--Completion/Core/_requested12
-rw-r--r--Completion/Core/_set_options7
-rw-r--r--Completion/Core/_sort_tags6
-rw-r--r--Completion/Core/_style74
-rw-r--r--Completion/Core/_tags61
-rw-r--r--Completion/Core/_unset_options7
-rw-r--r--Completion/Core/_wanted21
-rw-r--r--Completion/Core/compdump2
-rw-r--r--Completion/Core/compinit253
-rw-r--r--Completion/Core/compinstall30
-rw-r--r--Completion/Debian/_apt16
-rw-r--r--Completion/Debian/_deb_packages13
-rw-r--r--Completion/Linux/_rpm33
-rw-r--r--Completion/User/_archie9
-rw-r--r--Completion/User/_cvs61
-rw-r--r--Completion/User/_dd10
-rw-r--r--Completion/User/_flex4
-rw-r--r--Completion/User/_gcc10
-rw-r--r--Completion/User/_gdb27
-rw-r--r--Completion/User/_gprof6
-rw-r--r--Completion/User/_groups7
-rw-r--r--Completion/User/_gs31
-rw-r--r--Completion/User/_hosts6
-rw-r--r--Completion/User/_killall6
-rw-r--r--Completion/User/_lynx4
-rw-r--r--Completion/User/_mailboxes44
-rw-r--r--Completion/User/_make13
-rw-r--r--Completion/User/_man6
-rw-r--r--Completion/User/_mh32
-rw-r--r--Completion/User/_mount21
-rw-r--r--Completion/User/_mutt6
-rw-r--r--Completion/User/_netscape45
-rw-r--r--Completion/User/_nslookup28
-rw-r--r--Completion/User/_pbm15
-rw-r--r--Completion/User/_perl_basepods11
-rw-r--r--Completion/User/_perl_builtin_funcs5
-rw-r--r--Completion/User/_perl_modules4
-rw-r--r--Completion/User/_ports5
-rw-r--r--Completion/User/_rcs3
-rw-r--r--Completion/User/_rlogin33
-rw-r--r--Completion/User/_socket32
-rw-r--r--Completion/User/_ssh108
-rw-r--r--Completion/User/_stty25
-rw-r--r--Completion/User/_tar10
-rw-r--r--Completion/User/_telnet46
-rw-r--r--Completion/User/_tiff27
-rw-r--r--Completion/User/_urls81
-rw-r--r--Completion/User/_use_lo4
-rw-r--r--Completion/User/_user_at_host14
-rw-r--r--Completion/User/_users4
-rw-r--r--Completion/User/_users_on2
-rw-r--r--Completion/User/_wget4
-rw-r--r--Completion/User/_whois24
-rw-r--r--Completion/User/_yp46
-rw-r--r--Completion/X/_x_arguments19
-rw-r--r--Completion/X/_x_color13
-rw-r--r--Completion/X/_x_cursor6
-rw-r--r--Completion/X/_x_display4
-rw-r--r--Completion/X/_x_extension4
-rw-r--r--Completion/X/_x_font3
-rw-r--r--Completion/X/_x_keysym3
-rw-r--r--Completion/X/_x_modifier8
-rw-r--r--Completion/X/_x_window2
-rw-r--r--Completion/X/_xmodmap7
-rw-r--r--Completion/X/_xt_arguments57
-rw-r--r--Completion/X/_xutils12
132 files changed, 1199 insertions, 1240 deletions
diff --git a/Completion/Base/_arg_compile b/Completion/Base/_arg_compile
index 8eb2e80f5..44db86abe 100644
--- a/Completion/Base/_arg_compile
+++ b/Completion/Base/_arg_compile
@@ -39,7 +39,7 @@
 #       "assign"  as loose, but must follow an "=" in the same word ("=")
 #     HOW should be suffixed with a colon if the following argument is
 #      _not_ required to appear.
-#     STR is to be displayed based on compconfig[describe_options].
+#     STR is to be displayed based on style `description'
 #     XOR is another option in combination with which OPT may not appear.
 #      It may be ":" to disable non-option completions when OPT is present.
 #     MSG is a string to be displayed above the matches in a listing.
diff --git a/Completion/Base/_arguments b/Completion/Base/_arguments
index fbc7d7875..531b11407 100644
--- a/Completion/Base/_arguments
+++ b/Completion/Base/_arguments
@@ -3,7 +3,8 @@
 # Complete the arguments of the current command according to the
 # descriptions given as arguments to this function.
 
-local long cmd="$words[1]" descr mesg subopts
+local long cmd="$words[1]" descr mesg subopts opt usecc autod
+local oldcontext="$curcontext"
 
 long=$argv[(I)--]
 if (( long )); then
@@ -151,30 +152,33 @@ if (( long )); then
   set -- "$tmpargv[@]" "${(@P)name}"
 fi
 
-if [[ "$1" = -O?* ]]; then
-  subopts=( "${(@P)1[3,-1]}" )
-  shift
-elif [[ "$1" = -O ]]; then
-  subopts=( "${(@P)1}" )
-  shift 2
-else
-  subopts=()
-fi
+subopts=()
+while getopts ':O:C' opt; do
+  if [[ "$opt" = O ]]; then
+    subopts=( "${(@P)OPTARG}" )
+  else
+    usecc=yes
+  fi
+done
 
-if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
+shift OPTIND-1
+
+_style -s options auto-description autod
+
+if comparguments -i "$autod" "$@"; then
   local nm="$compstate[nmatches]" action noargs aret expl local
   local next direct odirect equal single match matched ws tmp1 tmp2
-  local opts _sub_context oldsc="${_sub_context}"
+  local opts subc
 
   if comparguments -D descr action; then
-    comparguments -C _sub_context
-    _sub_context="${oldsc}:${oldsc:+${oldsc}-}${_sub_context}"
+    comparguments -C subc
+    curcontext="${oldcontext}:$subc"
 
     if comparguments -O next direct odirect equal; then
       opts=yes
-      _tags "${oldsc}:any" arguments options
+      _tags arguments options
     else
-      _tags "${oldsc}:any" arguments
+      _tags arguments
     fi
   else
     if comparguments -a; then
@@ -185,7 +189,7 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
     comparguments -O next direct odirect equal || return 1
 
     opts=yes
-    _tags "${oldsc}:any" options
+    _tags options
   fi
 
   while _tags; do
@@ -196,6 +200,11 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
         if [[ "$action" = -\>* ]]; then
           comparguments -W line opt_args
           state="${${action[3,-1]##[ 	]#}%%[ 	]#}"
+	  if [[ -n "$usecc" ]]; then
+	    curcontext="$subc"
+	  else
+	    context="$subc"
+	  fi
           compstate[restore]=''
           aret=yes
         else
@@ -248,7 +257,7 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
         fi
       fi
       if [[ -z "$matched" ]] && _requested options &&
-          { ! _style options prefix-needed yes ||
+          { ! _style options prefix-needed ||
             [[ "$PREFIX" = [-+]* ]] } ; then
         comparguments -M match
 
@@ -296,8 +305,8 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
 	  SUFFIX="$suffix"
 	  IPREFIX="${IPREFIX}${equal[1]%%:*}="
 	  matched=yes
-	  comparguments -L "$equal[1]" descr action _sub_context
-          _sub_context="${oldsc}:${oldsc+${oldsc}-}${_sub_context}"
+	  comparguments -L "$equal[1]" descr action subc
+	  curcontext="${oldcontext}:$subc"
 	  continue
         fi
       fi
@@ -306,6 +315,8 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
     [[ -n "$aret" || nm -ne compstate[nmatches] ]] && break
   done
 
+  [[ -z "$aret" || -z "$usecc" ]] && curcontext="$oldcontext"
+
   [[ -n "$aret" ]] && return 300
 
   [[ -n "$mesg" ]] && _message "$mesg"
diff --git a/Completion/Base/_brace_parameter b/Completion/Base/_brace_parameter
index 1d1a48c78..3502bd794 100644
--- a/Completion/Base/_brace_parameter
+++ b/Completion/Base/_brace_parameter
@@ -1,6 +1,6 @@
 #compdef -brace-parameter-
 
-_tags any parameters && _parameters -e
+_requested -t parameters && _parameters -e
 
 
 # Without the `-e' option, we would use the following (see the file
diff --git a/Completion/Base/_command_names b/Completion/Base/_command_names
index 8d8f5630f..63c8601e9 100644
--- a/Completion/Base/_command_names
+++ b/Completion/Base/_command_names
@@ -27,4 +27,4 @@ fi
 
 args=( "$@" )
 
-_alternative -O args any "$defs[@]"
+_alternative -O args "$defs[@]"
diff --git a/Completion/Base/_condition b/Completion/Base/_condition
index 93bbdc7f4..51ac6bf0d 100644
--- a/Completion/Base/_condition
+++ b/Completion/Base/_condition
@@ -3,13 +3,9 @@
 local prev="$words[CURRENT-1]"
 
 if [[ "$prev" = -o ]]; then
-  _tags - -o options || return 1
-
-  _options
+  _tags -C -o options && _options
 elif [[ "$prev" = -([no]t|ef) ]]; then
-  _tags - "$prev" files || return 1
-
-  _files
+  _tags -C "$prev" files && _files
 else
-  _alternative any 'files:: _files' 'parameters:: _parameters'
+  _alternative 'files:: _files' 'parameters:: _parameters'
 fi
diff --git a/Completion/Base/_default b/Completion/Base/_default
index cf4077d3b..920f3a959 100644
--- a/Completion/Base/_default
+++ b/Completion/Base/_default
@@ -14,10 +14,9 @@ local expl
 
 # compcall || return 0
 
-_tags any files || return 1
+_tags files || return 1
 
-_description expl file
-_files "$expl[@]" && return
+_files && return 0
 
 # magicequalsubst allows arguments like <any-old-stuff>=~/foo to do
 # file name expansion after the =.  In that case, it's natural to
diff --git a/Completion/Base/_describe b/Completion/Base/_describe
index db2011727..181ccbfcb 100644
--- a/Completion/Base/_describe
+++ b/Completion/Base/_describe
@@ -2,54 +2,54 @@
 
 # This can be used to add options or values with descriptions as matches.
 
-local cmd opt expl tmps tmpd tmpmd tmpms ret=1 showd _nm hide args
-local type=values
+local _cmd _opt _expl _tmps _tmpd _tmpmd _tmpms _ret=1 _showd _nm _hide _args
+local _type=values
 
-cmd="$words[1]"
+_cmd="$words[1]"
 
 # Get the options.
 
-while getopts 'oc:' opt; do
-  if [[ "$opt" = o ]]; then
-    type=options
+while getopts 'oc:' _opt; do
+  if [[ "$_opt" = o ]]; then
+    _type=options
   else
-    cmd="$OPTARG"
+    _cmd="$OPTARG"
   fi
 done
 shift OPTIND-1
 
 # Do the tests. `showd' is set if the descriptions should be shown.
 
-_tags -c "$cmd" any "$type" || return 1
+_tags "$_type" || return 1
 
-_style "$type" description yes && showd=yes
+_style "$_type" description && _showd=yes
 
-_description expl "$1"
+_description _expl "$1"
 shift
 
-if [[ -n "$showd" ]]; then
+if [[ -n "$_showd" ]]; then
   compdescribe -I ' -- ' "$@"
 else
   compdescribe -i "$@"
 fi
 
-[[ "$type" = options ]] && _style options prefix-hidden yes && hide=yes
+[[ "$_type" = options ]] && _style options prefix-hidden && _hide=yes
 
-while compdescribe -g args tmpd tmpmd tmps tmpms; do
+while compdescribe -g _args _tmpd _tmpmd _tmps _tmpms; do
 
   # See if we should remove the option prefix characters.
 
-  if [[ -n "$hide" ]]; then
+  if [[ -n "$_hide" ]]; then
     if [[ "$PREFIX" = --* ]]; then
-      tmpd=( "${(@)tmpd#--}" )
-      tmps=( "${(@)tmps#--}" )
+      _tmpd=( "${(@)_tmpd#--}" )
+      _tmps=( "${(@)_tmps#--}" )
     elif [[ "$PREFIX" = [-+]* ]]; then
-      tmpd=( "${(@)tmpd#[-+]}" )
-      tmps=( "${(@)tmps#[-+]}" )
+      _tmpd=( "${(@)_tmpd#[-+]}" )
+      _tmps=( "${(@)_tmps#[-+]}" )
     fi
   fi
-  compadd "$args[@]" "$expl[@]" -ld tmpd - "$tmpmd[@]" && ret=0
-  compadd "$args[@]" "$expl[@]" -d tmps - "$tmpms[@]" && ret=0
+  compadd "$_args[@]" "$_expl[@]" -ld _tmpd - "$_tmpmd[@]" && _ret=0
+  compadd "$_args[@]" "$_expl[@]" -d _tmps  - "$_tmpms[@]" && _ret=0
 done
 
-return ret
+return _ret
diff --git a/Completion/Base/_equal b/Completion/Base/_equal
index 760f85c68..b0d31f2be 100644
--- a/Completion/Base/_equal
+++ b/Completion/Base/_equal
@@ -4,6 +4,6 @@ local args
 
 args=( "$@" )
 
-_alternative -O args any \
+_alternative -O args \
     'commands:command:compadd - ${(@k)commands}' \
     'aliases:alias:compadd - ${(@k)aliases}'
diff --git a/Completion/Base/_first b/Completion/Base/_first
index fc434fca7..7c070d743 100644
--- a/Completion/Base/_first
+++ b/Completion/Base/_first
@@ -50,7 +50,7 @@
 #       # We first search in the last ten words, then in the last
 #       # twenty words, and so on...
 #       while [[ i -le max ]]; do
-#         if [[ -n "$compconfig[history_sort]" ]]; then
+#         if _style history-entries sort; then
 #           _description expl "history ($n)"
 #         else
 #           _description -V expl "history ($n)"
diff --git a/Completion/Base/_jobs b/Completion/Base/_jobs
index ba83d784e..40d6efc34 100644
--- a/Completion/Base/_jobs
+++ b/Completion/Base/_jobs
@@ -2,11 +2,11 @@
 
 local expl disp jobs job jids pfx='%' desc
 
-_tags any jobs || return 1
+_tags jobs || return 1
 
-_style jobs prefix-needed yes && [[ "$PREFIX" != %* ]] && return 1
-_style jobs prefix-hidden yes && pfx=''
-_style jobs description yes   && desc=yes
+_style jobs prefix-needed && [[ "$PREFIX" != %* ]] && return 1
+_style jobs prefix-hidden && pfx=''
+_style jobs description   && desc=yes
 
 if [[ "$1" = -r ]]; then
   jids=( "${(@k)jobstates[(R)running*]}" )
diff --git a/Completion/Base/_math b/Completion/Base/_math
index 77d97acf1..821121c33 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 any parameters && _parameters
+_tags parameters && _parameters
diff --git a/Completion/Base/_parameter b/Completion/Base/_parameter
index 3ed91d620..1c4d5e014 100644
--- a/Completion/Base/_parameter
+++ b/Completion/Base/_parameter
@@ -1,6 +1,6 @@
 #compdef -parameter-
 
-_tags any parameters && _parameters -e
+_tags parameters && _parameters -e
 
 # Without the `-e' option, we would use the following (see the file
 # Core/_parameters for more enlightenment).
diff --git a/Completion/Base/_regex_arguments b/Completion/Base/_regex_arguments
index e2858e66c..ba6d330da 100644
--- a/Completion/Base/_regex_arguments
+++ b/Completion/Base/_regex_arguments
@@ -329,7 +329,9 @@ _regex_arguments () {
   local regex index first last nullable
   local i state next
 
-  local cache_dir="${compconfig[regex_arguments_path]:-$HOME/.zsh/regex_arguments}"
+  local cache_dir
+  _style -s regex argument-path cache_dir
+  [[ -z "$cache_dir" ]] && cache_dir="$HOME/.zsh/regex_arguments"
   local cache_file="$cache_dir/$1"
   local cache_test
 
diff --git a/Completion/Base/_subscript b/Completion/Base/_subscript
index c5c6ca7e9..80a3b1720 100644
--- a/Completion/Base/_subscript
+++ b/Completion/Base/_subscript
@@ -3,30 +3,25 @@
 local expl
 
 if [[ "$PREFIX" = :* ]]; then
-  _tags any char-classes || return 1
-
-  _description expl 'character class'
-  compadd "$expl[@]" -p: -S ':]' alnum alpha blank cntrl digit graph \
-                                 lower print punct space upper xdigit
+  _wanted char-classes expl 'character class' &&
+      compadd "$expl[@]" -p: -S ':]' alnum alpha blank cntrl digit graph \
+                                     lower print punct space upper xdigit
 elif [[ ${(Pt)${compstate[parameter]}} = assoc* ]]; then
-  _tags any association-keys || return 1
-
-  _description expl 'association key'
-  if [[ "$RBUFFER" = \]* ]]; then
-    compadd "$expl[@]" -S '' - "${(@kP)${compstate[parameter]}}"
-  else
-    compadd "$expl[@]" -S ']' - "${(@kP)${compstate[parameter]}}"
-  fi
+  _wanted association-keys expl 'association key' &&
+      if [[ "$RBUFFER" = \]* ]]; then
+        compadd "$expl[@]" -S '' - "${(@kP)${compstate[parameter]}}"
+      else
+        compadd "$expl[@]" -S ']' - "${(@kP)${compstate[parameter]}}"
+      fi
 elif [[ ${(Pt)${compstate[parameter]}} = array* ]]; then
   local list i j ret=1 disp
 
-  _tags any indexes parameters
+  _tags indexes parameters
 
   while _tags; do
-    if _requested indexes; then
-      _description -V expl 'array index'
+    if _requested indexes -V expl 'array index'; then
       ind=( {1..${#${(P)${compstate[parameter]}}}} )
-      if _style indexes description yes; then
+      if _style indexes description; then
         list=()
         for i in "$ind[@]"; do
           [[ "$i" = ${PREFIX}*${SUFFIX} ]] &&
diff --git a/Completion/Base/_tilde b/Completion/Base/_tilde
index afdca1222..bd21cd044 100644
--- a/Completion/Base/_tilde
+++ b/Completion/Base/_tilde
@@ -14,19 +14,17 @@ else
   suf=(-qS/)
 fi
 
-_tags any users named-directoriess directory-stack
+_tags users named-directories directory-stack
 
 while _tags; do
   _requested users && _users "$suf[@]" "$@" && ret=0
-  if _requested named-directories; then
-    _description expl 'named directory'
-    compadd "$suf[@]" "$expl[@]" "$@" - "${(@k)nameddirs}"
-  fi
+  _requested named-directories expl 'named directory' &&
+      compadd "$suf[@]" "$expl[@]" "$@" - "${(@k)nameddirs}"
 
-  if _requested directory-stack &&
-     { ! _style directory-stack prefix-needed yes ||
+  if _requested directory-stack -V expl 'directory stack' &&
+     { ! _style directory-stack prefix-needed ||
        [[ "$PREFIX" = [-+]* ]] }; then
-    if _style directory-stack description yes; then
+    if _style directory-stack description; then
       integer i
 
       lines=("${PWD}" "${dirstack[@]}")
@@ -48,8 +46,6 @@ while _tags; do
       list=( ${PREFIX[1]}{0..${#dirstack}} )
       disp=()
     fi
-
-    _description -V expl 'directory stack'
     compadd "$expl[@]" "$suf[@]" "$disp[@]" -Q - "$list[@]" && ret=0
   fi
   (( ret )) || return 0
diff --git a/Completion/Base/_values b/Completion/Base/_values
index e4d61d288..70a461a48 100644
--- a/Completion/Base/_values
+++ b/Completion/Base/_values
@@ -1,27 +1,28 @@
 #autoload
 
-local subopts
-
-if [[ "$1" = -O?* ]]; then
-  subopts=( "${(@P)1[3,-1]}" )
-  shift
-if [[ "$1" = -O ]]; then
-  subopts=( "${(@P)1}" )
-  shift 2
-else
-  subopts=()
-fi
+local subopts opt usecc
+
+subopts=()
+while getopts ':O:C' opt; do
+  if [[ "$opt" = O ]]; then
+    subopts=( "${(@P)OPTARG}" )
+  else
+    usecc=yes
+  fi
+done
+
+shift OPTIND-1
 
 if compvalues -i "$@"; then
 
-  local noargs args opts descr action expl sep _sub_context oldsc="$_sub_context"
+  local noargs args opts descr action expl sep subc
+  local oldcontext="$curcontext"
 
   if ! compvalues -D descr action; then
 
-    compvalues -C _sub_context
-    _sub_context="${oldsc}:${oldsc+${oldsc}-}${_sub_context}"
+    _tags values || return 1
 
-    _tags "${_sub_context}" values || return 1
+    curcontext="${oldcontext}:values"
 
     compvalues -V noargs args opts
 
@@ -47,8 +48,8 @@ if compvalues -i "$@"; then
         PREFIX="$prefix"
 	SUFFIX="$suffix"
         IPREFIX="${IPREFIX}${args[1]%%:*}="
-	compvalues -L "${args[1]%%:*}" descr action _sub_context
-        _sub_context="${oldsc}:${oldsc+${oldsc}-}${_sub_context}"
+	compvalues -L "${args[1]%%:*}" descr action subc
+	curcontext="${oldcontext}:$subc"
       fi
     else
       compvalues -d descr
@@ -63,14 +64,19 @@ if compvalues -i "$@"; then
         args -S= -M 'r:|[_-]=* r:|=*' -- \
         opts -qS= -M 'r:|[_-]=* r:|=*'
 
+      curcontext="$oldcontext"
+
       return
     fi
   else
-    compvalues -C _sub_context
-    _sub_context="${oldsc}:${oldsc+${oldsc}-}${_sub_context}"
+    compvalues -C subc
+    curcontext="${oldcontext}:$subc"
   fi
 
-  _tags "${oldsc}:any" arguments || return 1
+  if ! _tags arguments; then
+    curcontext="$oldcontext"
+    return 1
+  fi
 
   _description expl "$descr"
 
@@ -83,6 +89,11 @@ if compvalues -i "$@"; then
   if [[ "$action" = -\>* ]]; then
     compvalues -v val_args
     state="${${action[3,-1]##[ 	]#}%%[ 	]#}"
+    if [[ -n "$usecc" ]]; then
+      curcontext="$subc"
+    else
+      context="$subc"
+    fi
     compstate[restore]=''
     return 1
   else
@@ -131,7 +142,11 @@ if compvalues -i "$@"; then
     fi
   fi
 
+  curcontext="$oldcontext"
+
   [[ nm -ne "$compstate[nmatches]" ]]
 else
+  curcontext="$oldcontext"
+
   return 1;
 fi
diff --git a/Completion/Builtins/_aliases b/Completion/Builtins/_aliases
index a097d020e..78ec59686 100644
--- a/Completion/Builtins/_aliases
+++ b/Completion/Builtins/_aliases
@@ -2,6 +2,6 @@
 
 local expl
 
-_alternative any:argument \
+_alternative \
   'aliases:regular alias:compadd - ${(@k)aliases}' \
   'global-aliases:global alias:compadd - ${(@k)galiases}'
diff --git a/Completion/Builtins/_arrays b/Completion/Builtins/_arrays
index 37eb20bf5..4f67ff08d 100644
--- a/Completion/Builtins/_arrays
+++ b/Completion/Builtins/_arrays
@@ -2,7 +2,5 @@
 
 local expl
 
-_tags any:argument arrays || return 1
-
-_description expl array
-compadd "$expl[@]" - "${(@k)parameters[(R)*array*]}"
+_wanted arrays expl array &&
+    compadd "$expl[@]" - "${(@k)parameters[(R)*array*]}"
diff --git a/Completion/Builtins/_autoload b/Completion/Builtins/_autoload
index 116bb7765..de5a6045d 100644
--- a/Completion/Builtins/_autoload
+++ b/Completion/Builtins/_autoload
@@ -2,7 +2,5 @@
 
 local expl
 
-_tags any:argument functions || return 1
-
-_description expl 'shell function'
-compadd "$expl[@]" - ${^fpath}/*(N:t)
+_wanted functions expl 'shell function' &&
+    compadd "$expl[@]" - ${^fpath}/*(N:t)
diff --git a/Completion/Builtins/_bindkey b/Completion/Builtins/_bindkey
index 31215a576..98459916b 100644
--- a/Completion/Builtins/_bindkey
+++ b/Completion/Builtins/_bindkey
@@ -10,13 +10,9 @@
 local expl
 
 if [[ "$words[2]" = -*[DAN]* || "$words[CURRENT-1]" = -*M ]]; then
-  _tags -M keymaps || return 1
-
-  _description expl keymap
-  compadd "$expl[@]" - "$keymaps[@]"
+  _wanted -C -M keymaps expl keymap &&
+      compadd "$expl[@]" - "$keymaps[@]"
 else
-  _tags any:argument widgets || return 1
-
-  _description expl widget
-  compadd "$expl[@]" -M 'r:|-=* r:|=*' - "${(@k)widgets}"
+  _wanted widgets expl widget &&
+      compadd "$expl[@]" -M 'r:|-=* r:|=*' - "${(@k)widgets}"
 fi
diff --git a/Completion/Builtins/_builtin b/Completion/Builtins/_builtin
index fcb20560f..8d682420a 100644
--- a/Completion/Builtins/_builtin
+++ b/Completion/Builtins/_builtin
@@ -7,8 +7,6 @@ if (( $CURRENT > 2 )); then
 else
   local expl
 
-  _tags any:command commands || return 1
-
-  _description expl 'builtin command'
-  compadd "$expl[@]" "$@" - "${(k@)builtins}"
+  _wanted commands expl 'builtin command' &&
+      compadd "$expl[@]" "$@" - "${(k@)builtins}"
 fi
diff --git a/Completion/Builtins/_cd b/Completion/Builtins/_cd
index 26846fde2..2203dcf15 100644
--- a/Completion/Builtins/_cd
+++ b/Completion/Builtins/_cd
@@ -22,10 +22,8 @@ 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]}})
-  if (( $#rep )) && _tags replacement strings; then
-    _description expl replacement
-    compadd "$expl[@]" $rep
-  fi
+  (( $#rep )) && _wanted -C replacement strings expl replacement &&
+      compadd "$expl[@]" $rep
 elif _popd || [[ $PREFIX != (\~|/|./|../)* && $#cdpath -ne 0 ]]; then
   local tdir tdir2
 
diff --git a/Completion/Builtins/_command b/Completion/Builtins/_command
index 23995dbbe..1cfa6add9 100644
--- a/Completion/Builtins/_command
+++ b/Completion/Builtins/_command
@@ -6,8 +6,6 @@ if [[ CURRENT -ge 3 ]]; then
 else
   local expl
 
-  _tags any:command commands || return 1
-
-  _description expl 'external command'
-  compadd "$expl[@]" "$@" - "${(k@)commands}"
+  _wanted commands expl 'external command' &&
+      compadd "$expl[@]" "$@" - "${(k@)commands}"
 fi
diff --git a/Completion/Builtins/_compdef b/Completion/Builtins/_compdef
index df25d44de..7b4b0cb35 100644
--- a/Completion/Builtins/_compdef
+++ b/Completion/Builtins/_compdef
@@ -12,16 +12,12 @@ while [[ $words[base] = -* ]]; do
 done
 
 if [ "$delete" ]; then
-  _tags any:argument commands || return 1
-
-  _description expl 'completed command'
-  compadd "$expl[@]" - ${(k)_comps}
+  _wanted commands expl 'completed command' &&
+      compadd "$expl[@]" - ${(k)_comps}
 else
   if [[ CURRENT -eq base ]]; then
-    _tags any:argument functions || return 1
-
-    _description expl 'completion function'
-    compadd "$expl[@]" - ${^fpath:/.}/_(|*[^~])(N:t)
+    _wanted functions expl 'completion function' &&
+        compadd "$expl[@]" - ${^fpath:/.}/_(|*[^~])(N:t)
   else
     _command_names
   fi
diff --git a/Completion/Builtins/_disable b/Completion/Builtins/_disable
index 33c202864..7c17c9939 100644
--- a/Completion/Builtins/_disable
+++ b/Completion/Builtins/_disable
@@ -12,4 +12,4 @@ args=()
 [[ "$prev" != -* ]]  &&
     tags=( 'builtins:builtin command:compadd - ${(@k)builtins} )
 
-_alternative any "$args[@]"
+_alternative "$args[@]"
diff --git a/Completion/Builtins/_echotc b/Completion/Builtins/_echotc
index 2193261a1..06b78408d 100644
--- a/Completion/Builtins/_echotc
+++ b/Completion/Builtins/_echotc
@@ -2,8 +2,7 @@
 
 local expl
 
-_tags any:argument capabilities || return 1
-
-_description expl 'terminal capability'
-compadd "$expl[@]" \
-        al dc dl do le up al bl cd ce cl cr dc dl do ho is le ma nd nl se so up
+_wanted capabilities expl 'terminal capability' &&
+    compadd "$expl[@]" \
+            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/_enable b/Completion/Builtins/_enable
index ae2bdc38c..5cb07539e 100644
--- a/Completion/Builtins/_enable
+++ b/Completion/Builtins/_enable
@@ -12,4 +12,4 @@ args=()
 [[ "$prev" != -* ]]  &&
     tags=( 'builtins:builtin command:compadd - ${(@k)dis_builtins} )
 
-_alternative any "$args[@]"
+_alternative "$args[@]"
diff --git a/Completion/Builtins/_functions b/Completion/Builtins/_functions
index 9e6925ce7..98b21da68 100644
--- a/Completion/Builtins/_functions
+++ b/Completion/Builtins/_functions
@@ -2,7 +2,5 @@
 
 local expl
 
-_tags argument:any functions || return 1
-
-_description expl 'shell function'
-compadd "$expl[@]" "$@" - "${(k@)functions}"
+_wanted functions expl 'shell function' &&
+    compadd "$expl[@]" "$@" - "${(k@)functions}"
diff --git a/Completion/Builtins/_hash b/Completion/Builtins/_hash
index 24a9964b9..e5f182528 100644
--- a/Completion/Builtins/_hash
+++ b/Completion/Builtins/_hash
@@ -4,23 +4,15 @@ local expl
 
 if [[ "$words[2]" = -*d* ]]; then
   if compset -P 1 '*\='; then
-    _tags - -d-value files || return 1
-
-    _path_files -g '*(-/)'
+    _wanted -C -d-value files && _path_files -g '*(-/)'
   else
-    _tags - -d named-directories || return 1
-
-    _description expl 'named directory'
-    compadd "$expl[@]" -q -S '=' - "${(@k)nameddirs}"
+    _wanted -C -d named-directories expl 'named directory' &&
+        compadd "$expl[@]" -q -S '=' - "${(@k)nameddirs}"
   fi
 elif compset -P 1 '*\='; then
-  _tags value executables || return 1
-
-  _description expl 'executable file'
-  _files "$expl[@]" -g '*(*)'
+  _wanted -C value values executables expl 'executable file' &&
+      _files "$expl[@]" -g '*(*)'
 else
-  _tags any:argument commands || return 1
-
-  _description expl command
-  compadd "$expl[@]" -q -S '=' - "${(@k)commands}"
+  _wanted -C name commands expl command &&
+      compadd "$expl[@]" -q -S '=' - "${(@k)commands}"
 fi
diff --git a/Completion/Builtins/_kill b/Completion/Builtins/_kill
index e2dc88dac..0fee6dee8 100644
--- a/Completion/Builtins/_kill
+++ b/Completion/Builtins/_kill
@@ -3,11 +3,8 @@
 local list expl
 
 if compset -P 1 -; then
-
-  _tags - -:signal signals || return 1
-
-  _description expl signal
-  compadd "$expl[@]" $signals[1,-3]
+  _wanted -C - expl signal &&
+      compadd "$expl[@]" $signals[1,-3]
 else
-  _alternative argument 'jobs:: _jobs' 'processes:: _pids'
+  _alternative -C argument 'jobs:: _jobs' 'processes:: _pids'
 fi
diff --git a/Completion/Builtins/_limits b/Completion/Builtins/_limits
index 12e90e96a..dae573e03 100644
--- a/Completion/Builtins/_limits
+++ b/Completion/Builtins/_limits
@@ -2,7 +2,5 @@
 
 local expl
 
-_tags any:argument limits || return 1
-
-_description expl 'process limits'
-compadd "$expl[@]" ${${(f)"$(limit)"}%% *}
+_wanted limits expl 'process limits' &&
+    compadd "$expl[@]" ${${(f)"$(limit)"}%% *}
diff --git a/Completion/Builtins/_pids b/Completion/Builtins/_pids
index f96c11e2d..597a19477 100644
--- a/Completion/Builtins/_pids
+++ b/Completion/Builtins/_pids
@@ -3,23 +3,25 @@
 # If given the `-m <pattern>' option, this tries to complete only pids
 # of processes whose command line match the `<pattern>'.
 
-local list expl match desc
+local list expl match desc listargs args
 
-_tags any processes || return 1
+_wanted processes expl 'process ID' || return 1
 
 if [[ "$1" = -m ]]; then
   match="${2}*"
   shift 2
 fi
 
-_description expl 'process ID'
+_style -a ps list-arguments listargs
+_style -a ps arguments args
+(( $#listargs )) || listargs=( "$args[@]" )
 
-if _style processes description yes; then
-  list=("${(@Mr:COLUMNS-1:)${(f@)$(ps ${=compconfig[ps_listargs]:-$=compconfig[ps_args]} 2>/dev/null)}[2,-1]:#[ 	]#${PREFIX}[0-9]#${SUFFIX}[ 	]*${~match}}")
+if _style processes description; then
+  list=("${(@Mr:COLUMNS-1:)${(f@)$(ps $listargs 2>/dev/null)}[2,-1]:#[ 	]#${PREFIX}[0-9]#${SUFFIX}[ 	]*${~match}}")
   desc=(-ld list)
 else
   desc=()
 fi
 
 compadd "$expl[@]" "$@" "$desc[@]" - \
-  ${${${(M)${(f)"$(ps $=compconfig[ps_args] 2>/dev/null)"}[2,-1]:#*${~match}}## #}%% *}
+    ${${${(M)${(f)"$(ps $args 2>/dev/null)"}[2,-1]:#*${~match}}## #}%% *}
diff --git a/Completion/Builtins/_popd b/Completion/Builtins/_popd
index 5e4910f48..9b9b0d048 100644
--- a/Completion/Builtins/_popd
+++ b/Completion/Builtins/_popd
@@ -7,14 +7,13 @@
 
 setopt extendedglob nonomatch
 
-_tags any directory-stack || return 1
+local expl list lines revlines disp
 
-! _style directory-stack prefix-needed yes ||
-    [[ $PREFIX = [-+]* ]] || return 1
+_wanted directory-stack -V expl 'directory stack' || return 1
 
-local expl list lines revlines disp
+! _style directory-stack prefix-needed || [[ $PREFIX = [-+]* ]] || return 1
 
-if _style directory-stack description yes; then
+if _style directory-stack description; then
   # get the list of directories with their canonical number
   # and turn the lines into an array, removing the current directory
   lines=("${PWD}" "${dirstack[@]}")
@@ -39,5 +38,4 @@ else
   disp=()
 fi
 
-_description -V expl 'directory stack index'
 compadd "$expl[@]" "$@" -qS/ "$disp[@]" -Q - "$list[@]"
diff --git a/Completion/Builtins/_sched b/Completion/Builtins/_sched
index d3245f7ef..6a327e891 100644
--- a/Completion/Builtins/_sched
+++ b/Completion/Builtins/_sched
@@ -4,15 +4,14 @@ local expl lines disp
 
 if [[ CURRENT -eq 2 ]]; then
   if compset -P -; then
-    _tags - - entries || return 1
+    _wanted -C - entries expl 'scheduled jobs' || return 1
 
     lines=(${(f)"$(sched)"})
-    if _style entries description yes; then
+    if _style entries description; then
       disp=( -ld lines )
     else
       disp=()
     fi
-    _description expl 'scheduled jobs'
     [[ -z $lines ]] || compadd "$expl[@]" "$disp[@]" - {1..$#lines}
   else
     _message 'time specification'
diff --git a/Completion/Builtins/_stat b/Completion/Builtins/_stat
index 3f1b62ca3..75370f991 100644
--- a/Completion/Builtins/_stat
+++ b/Completion/Builtins/_stat
@@ -5,11 +5,14 @@ local expl
 if [[ "$words[CURRENT-1]" = -[AH] ]]; then
   _arrays
 else
-  _tags any:argument elements || return 1
+  _tags elements files || return 1
 
-  _description expl 'inode element'
-  [[ "$PREFIX[1]" = + ]] &&
-      compadd "$expl[@]" - +device +inode +mode +nlink +uid +gid +rdev +size \
-                           +atime +mtime +ctime +blksize +block +link
-  _files
+  while _tags; do
+    _requested elements expl 'inode element' &&
+        { ! _style elements prefix-needed || [[ "$PREFIX[1]" = + ]] } &&
+        compadd "$expl[@]" - +device +inode +mode +nlink +uid +gid +rdev \
+                             +size +atime +mtime +ctime +blksize +block +link
+    fi
+    _requested files && _files
+  done
 fi
diff --git a/Completion/Builtins/_trap b/Completion/Builtins/_trap
index 5dbb2d284..bbbef1c55 100644
--- a/Completion/Builtins/_trap
+++ b/Completion/Builtins/_trap
@@ -6,8 +6,5 @@ if [[ CURRENT -eq 2 ]]; then
   compset -q
   _normal
 else
-  _tags any:argument signals || return 1
-
-  _description expl signal
-  compadd "$expl[@]" - "$signals[@]"
+  _wanted signals expl signal && compadd "$expl[@]" - "$signals[@]"
 fi
diff --git a/Completion/Builtins/_unhash b/Completion/Builtins/_unhash
index 6ccbc21a4..7a0d0c25a 100644
--- a/Completion/Builtins/_unhash
+++ b/Completion/Builtins/_unhash
@@ -11,4 +11,4 @@ args=()
 [[ "$fl != -* ]] &&
     args=( 'commands:: _command_names -e' )
 
-_alternative any:argument "$args[@]"
+_alternative "$args[@]"
diff --git a/Completion/Builtins/_vars b/Completion/Builtins/_vars
index 43cdf5d2c..2758f3de2 100644
--- a/Completion/Builtins/_vars
+++ b/Completion/Builtins/_vars
@@ -1,8 +1,8 @@
 #compdef getopts read unset vared
 
 # This will handle completion of keys of associative arrays, e.g. at
-# `vared compconfig[<TAB>'.  However, in this version the [ must be
-# added by hand.
+# `vared foo[<TAB>'.  However, in this version the [ must be added
+# by hand.
 
 if [[ $PREFIX = *\[* ]]; then
   local var=${PREFIX%%\[*}
@@ -16,13 +16,9 @@ if [[ $PREFIX = *\[* ]]; then
   if [[ ${(tP)var} = assoc* ]]; then
     local expl
 
-    _tags subscript association-keys || return 1
-
-    _description expl 'association key'
-    compadd "$expl[@]" $addclose - ${(kP)var}
+    _wanted -C subscript association-keys expl 'association key' &&
+        compadd "$expl[@]" $addclose - ${(kP)var}
   fi
 else
-  _tags any parameters || return 1
-
-  _parameters
+  _tags parameters && _parameters
 fi
diff --git a/Completion/Builtins/_wait b/Completion/Builtins/_wait
index 04ad5e873..28fdb7985 100644
--- a/Completion/Builtins/_wait
+++ b/Completion/Builtins/_wait
@@ -1,3 +1,3 @@
 #compdef wait
 
-_alternative argument:any 'jobs:: _jobs' 'processes:: _pids'
+_alternative 'jobs:: _jobs' 'processes:: _pids'
diff --git a/Completion/Builtins/_which b/Completion/Builtins/_which
index 6e9e0a460..5b1427962 100644
--- a/Completion/Builtins/_which
+++ b/Completion/Builtins/_which
@@ -4,7 +4,7 @@ local args
 
 args=( "$@" )
 
-_alternative -O args any:argument \
+_alternative -O args \
   'commands:external command:compadd - ${(k@)commands}' \
   'builtins:builtin command:compadd - ${(k@)builtins}' \
   'functions:shell function:compadd - ${(k@)functions}' \
diff --git a/Completion/Builtins/_zftp b/Completion/Builtins/_zftp
index 2728d1747..8407de30e 100644
--- a/Completion/Builtins/_zftp
+++ b/Completion/Builtins/_zftp
@@ -4,7 +4,7 @@
 # zfcd_match and zfget_match (also used for old-style completion)
 # need to be installed for remote file and directory completion to work.
 
-emulate -L zsh
+# emulate -L zsh
 
 # Don't try any more completion after this.
 _compskip=all
@@ -13,12 +13,10 @@ local subcom expl
 
 if [[ $words[1] = zftp ]]; then
   if [[ $CURRENT -eq 2 ]]; then
-    _tags command commands || return 1
-
-    _description expl sub-command
-    compadd "$expl[@]" open params user login type ascii binary mode put \
-      putat get getat append appendat ls dir local remote mkdir rmdir \
-      session rmsession
+    _wanted commands expl sub-command &&
+        compadd "$expl[@]" open params user login type ascii binary mode put \
+          putat get getat append appendat ls dir local remote mkdir rmdir \
+          session rmsession
     return
   fi
   subcom=$words[2]
@@ -29,28 +27,27 @@ fi
 case $subcom in
   *(cd|ls|dir))
     # complete remote directories
-    _tags "$subcom" directories && zfcd_match $PREFIX $SUFFIX
+    _tags -C "$subcom" directories && zfcd_match $PREFIX $SUFFIX
     ;;
 
   *(get(|at)|gcp|delete|remote))
     # complete remote files
-    _tags "$subcom" files && zfget_match $PREFIX $SUFFIX
+    _tags -C "$subcom" files && zfget_match $PREFIX $SUFFIX
     ;;
 
   *(put(|at)|pcp))
     # complete local files
-    _tags "$subcom" files && _files
+    _tags -C "$subcom" files && _files
     ;;
 
   *(open|anon|params))
     # complete hosts:  should do cleverer stuff with user names
-    _tags "$subcom" hosts && _hosts
+    _tags -C "$subcom" hosts && _hosts
     ;;
 
   *(goto|mark))
     # complete bookmarks.  First decide if ncftp mode is go.
-    _tags "$subcom" bookmarks || return 1
-    _description expl bookmark
+    _wanted -C "$subcom" bookmarks expl bookmark || return 1
     if [[ $words[2] = -*n* ]]; then
       if [[ -f ~/.ncftp/bookmarks ]]; then
         compadd "$expl[@]" - $(awk -F, 'NR > 2 { print $1 }' ~/.ncftp/bookmarks)
@@ -64,16 +61,15 @@ case $subcom in
 
   *session)
     # complete sessions, excluding the current one.
-    _tags "$subcom" sessions || return 1
-    _description expl 'another FTP session'
-    compadd "$expl[@]" - ${$(zftp session):#$ZFTP_SESSION}
+    _wanted -C "$subcom" sessions expl 'another FTP session' &&
+        compadd "$expl[@]" - ${$(zftp session):#$ZFTP_SESSION}
     ;;
 
   *transfer)
     # complete arguments like sess1:file1 sess2:file2
     if [[ $PREFIX = *:* ]]; then
       # complete file in the given session
-      _tags "$subcom" files || return 1
+      _tags -C "$subcom" files || return 1
       local sess=${PREFIX%%:*} oldsess=$ZFTP_SESSION
       compset -p $(( $#sess + 1 ))
       [[ -n $sess ]] && zftp session $sess
@@ -81,9 +77,8 @@ case $subcom in
       [[ -n $sess && -n $oldsess ]] && zftp session $oldsess
     else
       # note here we can complete the current session
-      _tags "$subcom" sessions || return 1
-      _description expl 'FTP session'
-      compadd "$expl[@]" -S : - $(zftp session)
+      _wanted -C "$subcom" sessions expl 'FTP session' &&
+          compadd "$expl[@]" -S : - $(zftp session)
     fi
     ;;
 
diff --git a/Completion/Builtins/_zle b/Completion/Builtins/_zle
index 21997ef62..8e8017817 100644
--- a/Completion/Builtins/_zle
+++ b/Completion/Builtins/_zle
@@ -3,11 +3,8 @@
 local expl
 
 if [[ "$words[2]" = -N && CURRENT -eq 3 ]]; then
-  _tags any:argument functions || return 1
-  _description expl 'widget shell function'
-  compadd "$expl[@]" "$@" - "${(k@)functions}" && ret=0
+  _wanted -C -N functions expl 'widget shell function' &&
+      compadd "$expl[@]" "$@" - "${(k@)functions}" && ret=0
 else
-  _tags any:argument widgets || return 1
-  _description expl widget
-  compadd "$expl[@]" - "${(@k)widgets}"
+  _wanted widgets expl widget && compadd "$expl[@]" - "${(@k)widgets}"
 fi
diff --git a/Completion/Builtins/_zmodload b/Completion/Builtins/_zmodload
index 1a1097a7a..bedc4b08f 100644
--- a/Completion/Builtins/_zmodload
+++ b/Completion/Builtins/_zmodload
@@ -3,15 +3,11 @@
 local fl="$words[2]" expl
 
 if [[ "$fl" = -*(a*u|u*a)* || "$fl" = -*a* && CURRENT -ge 4 ]]; then
-  _tags any:argument builtins || return 1
-  _description expl 'builtin command'
-  compadd "$expl[@]" "$@" - "${(k@)builtins}" && ret=0
+  _wanted builtins expl 'builtin command' &&
+      compadd "$expl[@]" "$@" - "${(k@)builtins}"
 elif [[ "$fl" = -*u* ]]; then
-  _tags any:argument modules || return 1
-  _description expl module
-  compadd "$expl[@]" - "${(@k)modules}"
+  _wanted modules expl module && compadd "$expl[@]" - "${(@k)modules}"
 else
-  _tags any:argument files || return 1
-  _description expl 'module file'
-  compadd "$expl[@]" - ${^module_path}/*.s[ol](N:t:r)
+  _wanted files expl 'module file' &&
+      compadd "$expl[@]" - ${^module_path}/*.s[ol](N:t:r)
 fi
diff --git a/Completion/Commands/_complete_help b/Completion/Commands/_complete_help
new file mode 100644
index 000000000..cfefdcf90
--- /dev/null
+++ b/Completion/Commands/_complete_help
@@ -0,0 +1,35 @@
+#compdef -k complete-word \C-xh
+
+_complete_help() {
+  local _sort_tags=_help_sort_tags text i
+  typeset -A help_tags
+  typeset -U help_contexts
+
+  help_contexts=()
+
+  compadd() { return 1 }
+
+  _main_complete
+
+  unfunction compadd
+
+  for i in "$help_contexts[@]"; do
+    text="${text}
+tags in context \`${i}': ${help_tags[$i]}"
+  done
+
+  compstate[list]=list
+  compstate[force_list]=yes
+  compstate[insert]=''
+
+  compadd -UX "$text[2,-1]" -n ''
+}
+
+_help_sort_tags() {
+  help_contexts=( "$help_contexts[@]" "$curcontext" )
+  help_tags[$curcontext]="${help_tags[$curcontext]}
+    ${argv}"
+  comptry "$@"
+}
+
+_complete_help "$@"
diff --git a/Completion/Commands/_correct_word b/Completion/Commands/_correct_word
index d0abcd4fe..e0fee1fff 100644
--- a/Completion/Commands/_correct_word
+++ b/Completion/Commands/_correct_word
@@ -7,19 +7,8 @@
 # If configurations keys with the prefix `correctword_' are
 # given they override those starting with `correct_'.
 
-local oca="$compconfig[correct_accept]"
-local oco="$compconfig[correct_original]"
-local ocp="$compconfig[correct_prompt]"
-local oci="$compconfig[correct_insert]"
+local curcontext="$curcontext"
 
-compconfig[correct_accept]="${compconfig[correctword_accept]-6n}"
-compconfig[correct_original]="${compconfig[correctword_original]-$oco}"
-compconfig[correct_prompt]="${compconfig[correctword_prompt]-$ocp}"
-compconfig[correct_insert]="${compconfig[correctword_insert]}"
+[[ -z "$curcontext" ]] && curcontext=":correct-word"
 
 _main_complete _correct
-
-compconfig[correct_accept]="$oca"
-compconfig[correct_original]="$oco"
-compconfig[correct_prompt]="$ocp"
-compconfig[correct_insert]="$oci"
diff --git a/Completion/Commands/_expand_word b/Completion/Commands/_expand_word
index d8f5f42f8..b4e22de48 100644
--- a/Completion/Commands/_expand_word
+++ b/Completion/Commands/_expand_word
@@ -5,25 +5,8 @@
 # If configurations keys with the prefix `expandword_' are
 # given they override those starting with `expand_'.
 
-local oes="$compconfig[expand_substitute]"
-local oeg="$compconfig[expand_glob]"
-local oem="$compconfig[expand_menu]"
-local oeo="$compconfig[expand_original]"
-local oep="$compconfig[expand_prompt]"
-local oec="$compconfig[expand_completions]"
+local curcontext="$curcontext"
 
-compconfig[expand_substitute]="${compconfig[expandword_substitute]}"
-compconfig[expand_glob]="${compconfig[expandword_glob]-$oeg}"
-compconfig[expand_menu]="${compconfig[expandword_menu]-$oem}"
-compconfig[expand_original]="${compconfig[expandword_original]-$oeo}"
-compconfig[expand_prompt]="${compconfig[expandword_prompt]-$oep}"
-compconfig[expand_completions]="${compconfig[expandword_completions]-$oec}"
+[[ -z "$curcontext" ]] && curcontext=":expand-word"
 
 _main_complete _expand
-
-compconfig[expand_substitute]="$oes"
-compconfig[expand_glob]="$oeg"
-compconfig[expand_menu]="$oem"
-compconfig[expand_original]="$oeo"
-compconfig[expand_prompt]="$oep"
-compconfig[expand_completions]="$oec"
diff --git a/Completion/Commands/_history_complete_word b/Completion/Commands/_history_complete_word
index 1112339af..ee6ac2de2 100644
--- a/Completion/Commands/_history_complete_word
+++ b/Completion/Commands/_history_complete_word
@@ -7,17 +7,17 @@
 #
 # Available configuration keys:
 #
-#   history_list -- display lists of available matches
-#   history_stop -- prevent looping at beginning and end of matches
-#                   during menu-completion
-#   history_sort -- sort matches lexically (default is to sort by age)
-#   history_remove_all_dups --
-#                   remove /all/ duplicate matches rather than just
-#                   consecutives
+#   :history-entries:list -- display lists of available matches
+#   :history-entries:stop -- prevent looping at beginning and end of matches
+#                            during menu-completion
+#   :history-entries:sort -- sort matches lexically (default is to sort by age)
+#   :history-entries:remove-all-dups --
+#                            remove /all/ duplicate matches rather than just
+#                            consecutives
 #
 
 _history_complete_word () {
-  local expl direction
+  local expl direction stop
 
   if [[ $WIDGET = *newer ]]; then
     direction=older
@@ -25,16 +25,19 @@ _history_complete_word () {
     direction=newer
   fi
 
-  [[ -z "$compconfig[history_list]" ]] && compstate[list]=''
+  _style -s history-entries stop stop
+
+  _style history-entries list || compstate[list]=''
 
   if [[ -n "$compstate[old_list]" &&
-    ( -n "$compconfig[history_stop]" || "$compstate[insert]" = menu ) ]]; then
+        ( -n "$stop" || "$compstate[insert]" = menu ) ]] ; then
     # array of matches is newest -> oldest (reverse of history order)
     if [[ "$direction" == 'older' ]]; then
       if [[ compstate[old_insert] -eq $_hist_menu_length ||
             "$_hist_stop" == 'oldest' ]]; then
         _hist_stop='oldest'
-        [[ "$compconfig[history_stop]" = verbose ]] &&
+	_style history-entries 
+        [[ "$stop" = verbose ]] &&
           _message 'beginning of history reached'
       elif [[ "$_hist_stop" == 'newest' ]]; then
         zle -Rc
@@ -46,8 +49,7 @@ _history_complete_word () {
     elif [[ "$direction" == 'newer' ]]; then
       if [[ compstate[old_insert] -eq 1 || "$_hist_stop" == 'newest' ]]; then
         _hist_stop='newest'
-        [[ "$compconfig[history_stop]" = verbose ]] &&
-          _message 'end of history reached'
+        [[ "$stop" = verbose ]] && _message 'end of history reached'
       elif [[ "$_hist_stop" == 'oldest' ]]; then
         zle -Rc
         _history_complete_word_gen_matches
@@ -66,14 +68,14 @@ _history_complete_word () {
 }
 
 _history_complete_word_gen_matches () {
-  if [[ -n "$compconfig[history_list]" ]]; then
-    if [[ -n "$compconfig[history_sort]" ]]; then
+  if _style history-entries list; then
+    if _style history-entries sort; then
       _description expl 'history word'
     else
       _description -V expl 'history word'
     fi
   else
-    if [[ -n "$compconfig[history_sort]" ]]; then
+    if _style history-entries sort; then
       expl=()
     else
       expl=('-V' '')
@@ -83,7 +85,7 @@ _history_complete_word_gen_matches () {
   [[ -n "$_hist_stop" ]] && PREFIX="$_hist_old_prefix"
 
   local rem_dups
-  if [[ -n "$compconfig[history_remove_all_dups]" ]]; then
+  if _style history-entries remove-all-dups; then
     rem_dups=''
   else
     rem_dups='-1'
diff --git a/Completion/Commands/_read_comp b/Completion/Commands/_read_comp
index 8a46d8af2..a956c65f7 100644
--- a/Completion/Commands/_read_comp
+++ b/Completion/Commands/_read_comp
@@ -22,8 +22,8 @@
 # Global variables used:
 #  _read_comp         Last completion string read from user
 
-emulate -L zsh
-setopt extendedglob nobadpattern # xtrace promptsubst
+# emulate -L zsh
+setopt localoptions extendedglob nobadpattern # xtrace promptsubst
 # local PS4='%N:%i:$((#key))> '
 
 # Took me ages to work this out.  If we're not on the first global
diff --git a/Completion/Core/.distfiles b/Completion/Core/.distfiles
index 63592dfaf..eeac55a97 100644
--- a/Completion/Core/.distfiles
+++ b/Completion/Core/.distfiles
@@ -3,6 +3,6 @@ DISTFILES_SRC='
     _approximate _compalso _complete _correct _description _expand
     _files _list _main_complete _match _menu _multi_parts
     _message _normal _oldlist _options _parameters _path_files
-    _sep_parts _set_options _unset_options
+    _sep_parts _set_options _sort_tags _unset_options
     compdump compinit compinstall
 '
diff --git a/Completion/Core/_alternative b/Completion/Core/_alternative
index f13fc9e5a..76a8380bc 100644
--- a/Completion/Core/_alternative
+++ b/Completion/Core/_alternative
@@ -1,22 +1,23 @@
 #autoload
 
 local tags def expl descr action mesgs nm="$compstack[nmatches]" subopts
+local opt curcontext="$curcontext"
+
+subopts=()
+while getopts 'O:C:' opt; do
+  case "$opt" in
+  O) subopts=( "${(@P)OPTARG}" ) ;;
+  C) curcontext="${curontext}:$OPTARG" ;;
+  esac
+done
 
-if [[ "$1" = -O?* ]]; then
-  subopts=( "${(@P)1[3,-1]}" )
-  shift
-elif [[ "$1" = -O ]]; then
-  subopts=( "${(@P)2}" )
-  shift 2
-else
-  subopts=()
-fi  
+shift OPTIND-1
 
 [[ "$1" = -(|-) ]] && shift
 
 mesgs=()
 
-_tags "$1" "${(@)argv[2,-1]%%:*}"
+_tags "${(@)argv%%:*}"
 
 while _tags; do
   for def; do
diff --git a/Completion/Core/_approximate b/Completion/Core/_approximate
index 235e324f7..910742fee 100644
--- a/Completion/Core/_approximate
+++ b/Completion/Core/_approximate
@@ -7,6 +7,7 @@
 
 local _comp_correct _correct_prompt comax
 local cfgacc cfgorig cfgps cfgins
+local curcontext="$curcontext" oldcontext
 
 # Only if all global matchers have been tried.
 
@@ -16,20 +17,16 @@ local cfgacc cfgorig cfgps cfgins
 
 [[ "${#:-$PREFIX$SUFFIX}" -le 1 ]] && return 1
 
-# Get the configuration values, using either the prefix `correct' or
-# `approximate'.
+# Probably set initial context.
 
-if [[ "$compstate[pattern_match]" = (|\**) ]]; then
-  cfgacc="${compconfig[approximate_accept]:-$compconfig[correct_accept]}"
-  cfgorig="${compconfig[approximate_original]:-$compconfig[correct_original]}"
-  cfgps="${compconfig[approximate_prompt]:-$compconfig[correct_prompt]}"
-  cfgins="${compconfig[approximate_insert]:-$compconfig[correct_insert]}"
-else
-  cfgacc="$compconfig[correct_accept]"
-  cfgorig="$compconfig[correct_original]"
-  cfgps="$compconfig[correct_prompt]"
-  cfgins="$compconfig[correct_insert]"
-fi
+[[ -z "$curcontext" ]] && curcontext=':approximate'
+
+oldcontext="$curcontext"
+
+_style -s '' accept cfgacc
+_style -s '' original cfgorig
+_style -s '' prompt cfgps
+_style -s '' insert cfgins
 
 # Get the number of errors to accept.
 
@@ -86,16 +83,18 @@ _correct_prompt="${cfgps//\\%e/1}"
 [[ -z "$compstate[pattern_match]" ]] && compstate[pattern_match]='*'
 
 while [[ _comp_correct -le comax ]]; do
+  curcontext="${oldcontext}:$_comp_correct"
+
   if _complete; then
     if [[ "$cfgins" = unambig* &&
           "${#compstate[unambiguous]}" -ge "${#:-$PREFIX$SUFFIX}" ]]; then
       compstate[pattern_insert]=unambiguous
     elif [[ compstate[nmatches] -gt 1 || "$cfgorig" = *always* ]]; then
-      local expl
+      local expl format
 
       if [[ "$cfgorig" = *show* ]]; then
-        if [[ -n "$compconfig[description_format]" ]]; then
-	  expl=(-X "${compconfig[description_format]//\\%d/original}")
+        if _style -s descriptions format format; then
+	  expl=(-X "${format//\\%d/original}")
         else
 	  expl=()
         fi
diff --git a/Completion/Core/_complete b/Completion/Core/_complete
index f351c7349..235265326 100644
--- a/Completion/Core/_complete
+++ b/Completion/Core/_complete
@@ -2,16 +2,21 @@
 
 # Generate all possible completions. Note that this is not intended as
 # a normal completion function, but as one possible value for the
-# compconfig[completer] parameter.
+# completer style.
 
-local comp name _tag_context="$_tag_context"
+local comp name curcontext="$curcontext" oldcontext
 
-[[ "$compstate[context]" != command || CURRENT -eq 1 ]] && 
-    _tag_context="-${compstate[context]:s/_/-/}-"
+# Probably set initial context.
+
+[[ -z "$curcontext" ]] && curcontext=':complete'
+
+oldcontext="$curcontext"
 
 # If we have a user-supplied context name, use only that.
 
 if [[ -n "$compcontext" ]]; then
+  curcontext="${curcontext}:$compcontext"
+
   comp="$_comps[$compcontext]"
   [[ -z "$comp" ]] || "$comp"
 
@@ -22,6 +27,7 @@ fi
 
 comp="$_comps[-first-]"
 if [[ ! -z "$comp" ]]; then
+  curcontext="${curcontext}:-first-"
   "$comp"
   if [[ "$_compskip" = all ]]; then
     _compskip=''
@@ -34,12 +40,17 @@ fi
 # For arguments and command names we use the `_normal' function.
 
 if [[ "$compstate[context]" = command ]]; then
+  curcontext="$oldcontext"
   _normal -s
 else
   # Let's see if we have a special completion definition for the other
   # possible contexts.
 
-  comp="$_comps[$_tag_context]"
+  local cname="-${compstate[context]:s/_/-/}-"
+
+  curcontext="${oldcontext}:$cname"
+
+  comp="$_comps[$cname]"
 
   # If not, we use default completion, if any.
 
diff --git a/Completion/Core/_correct b/Completion/Core/_correct
index c9c3d999c..abd70ddeb 100644
--- a/Completion/Core/_correct
+++ b/Completion/Core/_correct
@@ -8,7 +8,11 @@
 # Supported configuration keys are the same as for `_approximate', only
 # starting with `correct'.
 
-local ret=1 opm="$compstate[pattern_match]"
+local ret=1 opm="$compstate[pattern_match]" curcontext="$curcontext"
+
+# Probably set initial context.
+
+[[ -z "$curcontext" ]] && curcontext=':correct'
 
 compstate[pattern_match]='-'
 
diff --git a/Completion/Core/_description b/Completion/Core/_description
index 107be5cd6..8cd9cc2fb 100644
--- a/Completion/Core/_description
+++ b/Completion/Core/_description
@@ -1,6 +1,6 @@
 #autoload
 
-local gropt=-J
+local gropt=-J format
 
 if [[ "$1" = -[VJ]* ]]; then
   gropt="$1"
@@ -9,16 +9,20 @@ fi
 
 _lastdescr=( "$_lastdescr[@]" "$2" )
 
-if [[ -n "$compconfig[group_matches]" ]]; then
-  if [[ -n "$compconfig[description_format]" ]]; then
-    eval "$1=($gropt ${(q)2} -X ${(q)compconfig[description_format]//\\%d/$2})"
+_style -s descriptions format format
+
+if _style matches group; then
+  if [[ -n "$format" ]]; then
+    eval "$1=($gropt ${(q)2} -X ${(q)format//\\%d/$2})"
   else
     eval "$1=($gropt ${(q)2})"
   fi
 else
-  if [[ -n "$compconfig[description_format]" ]]; then
-    eval "$1=(-X ${(q)compconfig[description_format]//\\%d/$2})"
+  if [[ -n "$format" ]]; then
+    eval "$1=(-X ${(q)format//\\%d/$2})"
   else
     eval "$1=()"
   fi
 fi
+
+return 0
diff --git a/Completion/Core/_expand b/Completion/Core/_expand
index df9e0b9ea..97728bd3b 100644
--- a/Completion/Core/_expand
+++ b/Completion/Core/_expand
@@ -7,12 +7,16 @@
 # the expansions done produce no result or do not change the original
 # word from the line.
 
-local exp word="$PREFIX$SUFFIX" group=-V expl expl2 disp
+local exp word="$PREFIX$SUFFIX" group=-V expl expl2 disp orig menu prompt
+local curcontext="$curcontext" expr descr
+
+# Probably set initial context.
+
+[[ -z "$curcontext" ]] && curcontext=':expand'
 
 # First, see if we should insert all *completions*.
 
-if [[ -n "$compconfig[expand_completions]" &&
-      "${(e):-\$[$compconfig[expand_substitute]]}" -eq 1 ]]; then
+if _style -s '' completions expr && [[ "${(e):-\$[$expr]}" -eq 1 ]]; then
   compstate[insert]=all
   return 1
 fi
@@ -28,8 +32,7 @@ exp=("$word")
 # First try substitution. That weird thing spanning multiple lines
 # changes quoted spaces, tabs, and newlines into spaces.
 
-[[ -z "$compconfig[expand_substitute]" ||
-   "${(e):-\$[$compconfig[expand_substitute]]}" -eq 1 ]] &&
+_style -s '' substitute expr && [[ "${(e):-\$[$expr]}" -eq 1 ]] &&
     exp=( "${(e)exp//\\[ 	
 ]/ }" )
 
@@ -39,8 +42,7 @@ exp=("$word")
 
 # Now try globbing.
 
-[[ -z "$compconfig[expand_glob]" ||
-   "${(e):-\$[$compconfig[expand_glob]]}" -eq 1 ]] &&
+_style -s '' glob expr && [[ "${(e):-\$[$expr]}" -eq 1 ]] &&
     exp=( ${~exp}(N) )
 
 # If we don't have any expansions or only one and that is the same
@@ -51,9 +53,14 @@ exp=("$word")
 
 # Get the options for adding the original string and `all'-string.
 
-if [[ "$compconfig[expand_original]" = *show* ]]; then
-  if [[ -n "$compconfig[description_format]" ]]; then
-    expl=(-X "${compconfig[description_format]//\\%d/original}")
+_style -s '' original orig
+_style -s '' menu menu
+_style -s '' prompt prompt
+_style -s descriptions format descr
+
+if [[ "$orig" = *show* ]]; then
+  if [[ -n "$descr" ]]; then
+    expl=(-X "${descr//\\%d/original}")
   else
     expl=()
   fi
@@ -61,11 +68,9 @@ else
   expl=(-n)
 fi
 
-if [[ -n "$compconfig[expand_menu]" &&
-      "$compconfig[expand_menu]" != *only* &&
-      "$compconfig[expand_menu]" = *showall* ]]; then
-  if [[ -n "$compconfig[description_format]" ]]; then
-    expl2=(-ld disp -X "${compconfig[description_format]//\\%d/all words}")
+if [[ -n "$menu" && "$menu" != *only* && "$menu" = *showall* ]]; then
+  if [[ -n "$descr" ]]; then
+    expl2=(-ld disp -X "${descr//\\%d/all words}")
   else
     expl2=(-ld disp )
   fi
@@ -83,7 +88,7 @@ fi
 
 # We have expansions, should we menucomplete them?
 
-if [[ -z "$compconfig[expand_menu]" ]]; then
+if [[ -z "$menu" ]]; then
 
   # No, so if the user only wants a list, we add the strings
   # separately. Otherwise we add the whole array as one string,
@@ -92,14 +97,12 @@ if [[ -z "$compconfig[expand_menu]" ]]; then
   if [[ -z "$compstate[insert]" ]]; then
     compadd -U -V _expand -Q - "$exp[@]"
   else
-    [[ -n "$compconfig[expand_original]" && 
-       "$compconfig[expand_original]" != *last* ]] &&
+    [[ -n "$orig" && "$orig" != *last* ]] &&
         compadd "$expl[@]" -UQ -V _expand_original - "$word"
 
     compadd -UQ -V _expand - "$exp"
 
-    [[ -n "$compconfig[expand_original]" && 
-       "$compconfig[expand_original]" = *last* ]] &&
+    [[ -n "$orig" && "$orig" = *last* ]] &&
         compadd "$expl[@]" -UQ -V _expand_original - "$word"
 
     compstate[insert]=menu
@@ -107,31 +110,27 @@ if [[ -z "$compconfig[expand_menu]" ]]; then
 else
   # Sorting? We just use a different group type then.
 
-  [[ "$compconfig[expand_menu]" = *sort* ]] && group=-J
+  [[ "$menu" = *sort* ]] && group=-J
 
   # Now add the expansion string, probably also adding the original
   # and/or the string containing all expanded string.
 
-  [[ -n "$compconfig[expand_original]" && 
-     "$compconfig[expand_original]" != *last* ]] &&
+  [[ -n "$orig" && "$orig" != *last* ]] &&
       compadd "$expl[@]" -UQ -V _expand_original - "$word"
 
-  [[ $#exp -ne 1 && "$compconfig[expand_menu]" = *last* &&
-     "$compconfig[expand_menu]" != *only* ]] &&
+  [[ $#exp -ne 1 && "$menu" = *last* && "$menu" != *only* ]] &&
       compadd "$expl2[@]" -UQ -V _expand_all - "$exp"
 
-  if [[ -z "$compconfig[expand_prompt]" ]]; then
+  if [[ -z "$prompt" ]]; then
     compadd -UQ $group _expand - "$exp[@]"
   else
-    compadd -UQ -X "${compconfig[expand_prompt]//\\%o/$word}" \
+    compadd -UQ -X "${prompt//\\%o/$word}" \
             $group _expand - "$exp[@]"
   fi
-  [[ $#exp -ne 1 && "$compconfig[expand_menu]" != *last* &&
-     "$compconfig[expand_menu]" != *only* ]] &&
+  [[ $#exp -ne 1 && "$menu" != *last* && "$menu" != *only* ]] &&
       compadd "$expl2[@]" -UQ -V _expand_all - "$exp"
 
-  [[ -n "$compconfig[expand_original]" && 
-     "$compconfig[expand_original]" = *last* ]] &&
+  [[ -n "$orig" && "$orig" = *last* ]] &&
       compadd "$expl[@]" -UQ -V _expand_original - "$word"
 
   compstate[insert]=menu
diff --git a/Completion/Core/_files b/Completion/Core/_files
index 973eea69b..ba5445797 100644
--- a/Completion/Core/_files
+++ b/Completion/Core/_files
@@ -13,9 +13,9 @@ while getopts "P:S:qr:R:W:F:J:V:X:f/g:M:" opt; do
 done
 
 case "$type" in
-file) _tags any all-files                           ;;
-dir)  _tags any directories all-files               ;;
-*)    _tags any globbed-files directories all-files ;;
+file) _tags all-files                           ;;
+dir)  _tags directories all-files               ;;
+*)    _tags globbed-files directories all-files ;;
 esac
 
 while _tags; do
diff --git a/Completion/Core/_list b/Completion/Core/_list
index f0bdda08a..803da2f71 100644
--- a/Completion/Core/_list
+++ b/Completion/Core/_list
@@ -4,11 +4,15 @@
 # insert possible completions only after the list has been shown at
 # least once.
 
-local pre suf
+local pre suf curcontext="$curcontext" expr
+
+# Probably set initial context.
+
+[[ -z "$curcontext" ]] && curcontext=':list'
 
 # Get the strings to compare.
 
-if [[ -z "$compconfig[list_word]" ]]; then
+if _style '' word; then
   pre="$HISTNO$LBUFFER"
   suf="$RBUFFER"
 else
@@ -18,8 +22,8 @@ fi
 
 # Should we only show a list now?
 
-if [[ ( -z "$compconfig[list_condition]" ||
-        "${(e):-\$[$compconfig[list_condition]]}" -eq 1 ) &&
+_style -s '' condition expr
+if [[ ( -z "$expr" || "${(e):-\$[$expr]}" -eq 1 ) &&
       ( "$pre" != "$_list_prefix" || "$suf" != "$_list_suffix" ) ]]; then
 
   # Yes. Tell the completion code about it and save the new values
diff --git a/Completion/Core/_main_complete b/Completion/Core/_main_complete
index f9a8a19ad..ba31399b3 100644
--- a/Completion/Core/_main_complete
+++ b/Completion/Core/_main_complete
@@ -17,10 +17,9 @@
 # state than the global one for which you are completing.
 
 
-local comp post ret=1 _compskip _prio_num=1 _tag_context _cur_contexts
-local context state line opt_args val_args
+local comp post ret=1 _compskip _prio_num=1 _cur_context format
+local context state line opt_args val_args curcontext
 typeset -U _offered_tags _tried_tags _failed_tags _used_tags _unused_tags
-typeset -A _prio_names _prio_contexts _cur_tags _tag_contexts
 
 _offered_tags=()
 _tried_tags=()
@@ -42,7 +41,12 @@ fi
 
 # Get the names of the completers to use in the positional parameters.
 
-(( $# )) || set ${(s.:.)compconfig[completer]}
+if (( ! $# )); then
+  local tmp
+
+  _style -a '' completer tmp
+  set -- "$tmp[@]"
+fi
 
 # And now just call the completer functions defined.
 
@@ -66,9 +70,12 @@ done
 comppostfuncs=()
 
 _lastdescr=( "\`${(@)^_lastdescr:#}'" )
+
+_style -s warnings format format
+
 if [[ compstate[nmatches] -eq 0 &&
       compstate[matcher] -eq compstate[total_matchers] &&
-      -n "$compconfig[warning_format]" && $#_lastdescr -ne 0 ]]; then
+      -n "$format" && $#_lastdescr -ne 0 ]]; then
   local str
 
   compstate[list]=list
@@ -81,10 +88,10 @@ if [[ compstate[nmatches] -eq 0 &&
   *) str="${(j:, :)_lastdescr[1,-2]}, or $_lastdescr[-1]";;
   esac
 
-  compadd -UX "${compconfig[warning_format]//\\%d/$str}" -n ''
+  compadd -UX "${format//\\%d/$str}" -n ''
 fi
 
-[[ "$compconfig[last_prompt]" = always ]] && compstate[last_prompt]=yes
+_style '' last-prompt always && compstate[last_prompt]=yes
 
 _lastcomp=( "${(@kv)compstate}" )
 _lastcomp[completer]="$comp"
diff --git a/Completion/Core/_match b/Completion/Core/_match
index f4e5fc0ee..35d7c2ecb 100644
--- a/Completion/Core/_match
+++ b/Completion/Core/_match
@@ -1,7 +1,7 @@
 #autoload
 
 # This is intended to be used as a completer function after the normal
-# completer as in: `compconf completer=_complete:_match'.
+# completer as in: `compstyle "*" completer _complete _match'.
 # It temporarily switches on pattern matching, allowing you to try 
 # completion on patterns without having to setopt glob_complete.
 #
@@ -9,7 +9,8 @@
 # expand-or-complete function because otherwise the pattern will
 # be expanded using globbing.
 
-local tmp opm="$compstate[pattern_match]" ret=0
+local tmp opm="$compstate[pattern_match]" ret=0 curcontext="$curcontext"
+local orig ins
 
 # Do nothing if we don't have a pattern or there are still global
 # match specifications to try.
@@ -18,9 +19,16 @@ tmp="${${:-$PREFIX$SUFFIX}#[~=]}"
 [[ "$tmp:q" = "$tmp" ||
    compstate[matcher] -ne compstate[total_matchers] ]] && return 1
 
+# Probably set initial context.
+
+[[ -z "$curcontext" ]] && curcontext=':match'
+
+_style -s '' original orig
+_style -s '' insert ins
+
 # Try completion without inserting a `*'?
 
-if [[ -n "$compconfig[match_original]" ]]; then
+if [[ -n "$orig" ]]; then
   compstate[matcher]=-1
   compstate[pattern_match]='-'
   _complete && ret=1
@@ -28,7 +36,7 @@ if [[ -n "$compconfig[match_original]" ]]; then
   compstate[matcher]="$compstate[total_matchers]"
 
   if (( ret )); then
-    [[ "$compconfig[match_insert]" = unambig* &&
+    [[ "$ins" = unambig* &&
        $#compstate[unambiguous] -ge ${#:-${PREFIX}${SUFFIX}} ]] && 
         compstate[pattern_insert]=unambiguous
     return 0
@@ -37,7 +45,7 @@ fi
 
 # No completion with inserting `*'?
 
-[[ "$compconfig[match_original]" = only ]] && return 1
+[[ "$orig" = only ]] && return 1
 
 compstate[matcher]=-1
 compstate[pattern_match]='*'
@@ -45,7 +53,7 @@ _complete && ret=1
 compstate[pattern_match]="$opm"
 compstate[matcher]="$compstate[total_matchers]"
 
-[[ ret -eq 1 && "$compconfig[match_insert]" = unambig* &&
+[[ ret -eq 1 && "$ins" = unambig* &&
    $#compstate[unambiguous] -ge ${#:-${PREFIX}${SUFFIX}} ]] && 
     compstate[pattern_insert]=unambiguous
 
diff --git a/Completion/Core/_menu b/Completion/Core/_menu
index 4cbda4e14..e9558fe05 100644
--- a/Completion/Core/_menu
+++ b/Completion/Core/_menu
@@ -1,10 +1,16 @@
 #autoload
 
+local curcontext="$curcontext"
+
+# Probably set initial context.
+
+[[ -z "$curcontext" ]] && curcontext=':menu'
+
 # This completer is an example showing how menucompletion can be
 # implemented with the new completion system.
 # Use this one before the normal _complete completer, as in:
 #
-#   compconf completer=_menu:_complete
+#   compstyle "*" completer _menu _complete
 
 if [[ -n "$compstate[old_list]" ]]; then
 
diff --git a/Completion/Core/_message b/Completion/Core/_message
index ee869d33b..5c5c42e06 100644
--- a/Completion/Core/_message
+++ b/Completion/Core/_message
@@ -2,9 +2,9 @@
 
 local format
 
-_tags any messages || return 1
+_tags messages || return 1
 
-format="${compconfig[message_format]:-$compconfig[description_format]}"
+_style -s messages format format || _style -s descriptions format format
 
 if [[ -n "$format" ]]; then
   if [[ $compstate[nmatches] -eq 0 ]]; then
diff --git a/Completion/Core/_normal b/Completion/Core/_normal
index 5d0a18406..f31e7e6fc 100644
--- a/Completion/Core/_normal
+++ b/Completion/Core/_normal
@@ -1,7 +1,7 @@
 #autoload
 
 local comp command cmd1 cmd2 pat val name i ret=1 _compskip="$_compskip"
-local _sub_context
+local curcontext="$curcontext"
 
 # If we get the option `-s', we don't reset `_compskip'. This ensures
 # that a value set in the function for the `-first-' context is kept,
@@ -16,19 +16,24 @@ local _sub_context
 
 command="$words[1]"
 if [[ CURRENT -eq 1 ]]; then
+  curcontext="${curcontext}:-command-"
+
   comp="$_comps[-command-]"
   [[ -z "$comp" ]] || "$comp" && ret=0
 
   return ret
-elif [[ "$command[1]" == '=' ]]; then
-  eval cmd1\=$command
-  cmd2="$command[2,-1]"
-elif [[ "$command" == */* ]]; then
-  cmd1="$command"
-  cmd2="${command:t}"
 else
-  cmd1="$command"
-  cmd2="$commands[$command]"
+  if [[ "$command[1]" == '=' ]]; then
+    eval cmd1\=$command
+    cmd2="$command[2,-1]"
+  elif [[ "$command" == */* ]]; then
+    cmd1="$command"
+    cmd2="${command:t}"
+  else
+    cmd1="$command"
+    cmd2="$commands[$command]"
+  fi
+  curcontext="${curcontext}:${cmd1}"
 fi
 
 # See if there are any matching pattern completions.
diff --git a/Completion/Core/_oldlist b/Completion/Core/_oldlist
index 2efc08119..2408613da 100644
--- a/Completion/Core/_oldlist
+++ b/Completion/Core/_oldlist
@@ -1,18 +1,26 @@
 #autoload
 
+local curcontext="$curcontext" list menu
+
+# Probably set initial context.
+
+[[ -z "$curcontext" ]] && curcontext=':oldlist'
+
+_style -s '' list list
+_style -s '' menu menu
+
 # If this is a listing widget and there is already an old list,
-# and either the compconfig key oldlist_list is `always', or it is not `never'
+# and either the style :oldlist:list is `always', or it is not `never'
 # and the list is not already shown, then use the existing list for listing
 # (even if it was generated by another widget).
 # Do this also if there is an old list and it was generated by the
 # completer named by the oldlist_list key.
-if [[ -n $compstate[old_list] && $compconfig[oldlist_list] != never ]]; then
-  if [[ $WIDGET = *list* &&
-        ( $compconfig[oldlist_list] = always ||
-	  $compstate[old_list] != shown ) ]]; then
+
+if [[ -n $compstate[old_list] && $list != never ]]; then
+  if [[ $WIDGET = *list* && ( $list = always || $list != shown ) ]]; then
     compstate[old_list]=keep
     return 0
-  elif [[ $compconfig[oldlist_list] = *${_lastcomp[completer]}* ]]; then
+  elif [[ $list = *${_lastcomp[completer]}* ]]; then
     [[ "$_lastcomp[insert]" = unambig* ]] && compstate[to_end]=single
     compstate[old_list]=keep
     if [[ -o automenu ]]; then
@@ -25,16 +33,16 @@ if [[ -n $compstate[old_list] && $compconfig[oldlist_list] != never ]]; then
 fi
 
 # If this is a completion widget, and we have a completion inserted already,
-# and the compconfig key oldlist_menu is not never, then we cycle through the
+# and the style :oldlist:menu is not never, then we cycle through the
 # existing list (even if it was generated by another widget).
 
-if [[ $compconfig[oldlist_menu] = verbose &&
+if [[ $menu = verbose &&
       $LASTWIDGET = _verbose_list && $WIDGET != _verbose_list &&
       -z $compstate[old_insert] &&
       -n $compstate[old_list] ]]; then
   compstate[old_list]=keep
 elif [[ $WIDGET = *complete(|-prefix|-word) &&
-      $compconfig[oldlist_menu] != (never|verbose) ]]; then
+        $menu != (never|verbose) ]]; then
   if [[ -n $compstate[old_insert] ]]; then
     compstate[old_list]=keep
     if [[ $WIDGET = *reverse* ]]; then
diff --git a/Completion/Core/_options b/Completion/Core/_options
index 0dd92cf69..8664e239e 100644
--- a/Completion/Core/_options
+++ b/Completion/Core/_options
@@ -4,8 +4,6 @@
 
 local expl
 
-_tags any zsh-options || return 1
-
-_description expl 'zsh option'
-compadd "$expl[@]" "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - \
-    "${(@k)options}"
+_wanted zsh-options expl 'zsh option' &&
+    compadd "$expl[@]" "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - \
+        "${(@k)options}"
diff --git a/Completion/Core/_parameters b/Completion/Core/_parameters
index da479097e..3735702df 100644
--- a/Completion/Core/_parameters
+++ b/Completion/Core/_parameters
@@ -5,16 +5,13 @@
 
 local pars expl
 
-_tags any parameters || return 1
-
-_description expl parameter
+_wanted parameters expl parameter || return 1
 
 pars=( ${(k)parameters[(R)^*local*]} )
 
 compadd "$expl[@]" "$@" - $pars
 
 
-
 # The `-e' option does everything for parameter expansions of us. If
 # we wouldn't have it, we would use something like:
 
diff --git a/Completion/Core/_path_files b/Completion/Core/_path_files
index 6468215cc..41956d543 100644
--- a/Completion/Core/_path_files
+++ b/Completion/Core/_path_files
@@ -331,11 +331,11 @@ for prepath in "$prepaths[@]"; do
 	SUFFIX="${tsuf}"
       fi
 
-tmp4="$testpath"
-compquote tmp1 tmp4
+      tmp4="$testpath"
+      compquote tmp1 tmp4
 
-      if [[ -n $menu || "$compconfig[path_expand]" != *suffix* ]]; then
-        [[ -n "$compconfig[path_cursor]" ]] && compstate[to_end]=''
+      if [[ -n $menu ]] || ! _style paths expand '*suffix*'; then
+        _style paths cursor && compstate[to_end]=''
         if [[ "$tmp3" = */* ]]; then
 	  compadd -Qf -p "$linepath$tmp4" -s "/${tmp3#*/}" \
 	          -W "$prepath$realpath$testpath" "$ignore[@]" \
@@ -423,8 +423,8 @@ done
 
 exppaths=( "${(@)exppaths:#$orig}" )
 
-if [[ "$compconfig[path_expand]" = *prefix* &&
-      $#exppaths -gt 0 && nm -eq compstate[nmatches] ]]; then
+if _style paths expand '*prefix*' &&
+   [[ $#exppaths -gt 0 && nm -eq compstate[nmatches] ]]; then
   PREFIX="${opre}"
   SUFFIX="${osuf}"
   compadd -Q -S '' "$group[@]" "$expl[@]" \
diff --git a/Completion/Core/_requested b/Completion/Core/_requested
index 09c57ee09..6641afdcf 100644
--- a/Completion/Core/_requested
+++ b/Completion/Core/_requested
@@ -1,9 +1,9 @@
 #autoload
 
-# Reset the current context.
+comptags -C _cur_context
 
-_cur_contexts="${_tag_contexts[$tname]}"
-
-# Test if the tag given as argument was requested.
-
-[[ "${_cur_tags[${funcstack[2,-1]}]}" = *:${1}:* ]]
+comptags -R "$1" &&
+    if [[ $# -gt 1 ]]; then
+      _description "${(@)argv[2,-1]}"
+      return 0
+    fi
diff --git a/Completion/Core/_set_options b/Completion/Core/_set_options
index 55388d0c8..ae4d3784e 100644
--- a/Completion/Core/_set_options
+++ b/Completion/Core/_set_options
@@ -6,7 +6,6 @@
 
 local expl
 
-_tags any zsh-options || return 1
-
-_description 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 "$expl[@]" "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - \
+            $=_set_options
diff --git a/Completion/Core/_sort_tags b/Completion/Core/_sort_tags
index f1740511d..f44479d56 100644
--- a/Completion/Core/_sort_tags
+++ b/Completion/Core/_sort_tags
@@ -3,18 +3,18 @@
 comptry arguments values
 comptry options
 
-case "$contexts" in
+case "$curcontext" in
 # Some silly examples commented out:
 #
 # *p[bgpn]m*)           # change the order for file-completion
 #   comptry globbed-files directories
 #   comptry all-files
 #   ;;
-# *:dvips,-o*)          # automatic context set by _arguments
+# *:dvips:-o*)          # automatic context set by _arguments
 #   comptry all-files
 #   return
 #   ;;
-# *:kill,*)
+# *:kill:*)
 #   comptry processes
 #   return              # this return ensures that we use only processes
 #   ;;
diff --git a/Completion/Core/_style b/Completion/Core/_style
index a3b54686f..6e2de23df 100644
--- a/Completion/Core/_style
+++ b/Completion/Core/_style
@@ -1,50 +1,44 @@
 #autoload
 
-local all get val i
+local val ret
 
 # Should we return the value?
 
-if [[ "$1" = -g ]]; then
-  get=yes
-  shift
-fi
-
-# Get all styles defined for this context.
-
-all=()
-for i in "${(s.:.)_cur_contexts}"; do
-  all=("$all[@]" "${(@)_compstyles[(K)${i},${1}]}" )
-done
-all=":${(j.:.)${(@o)all:#}##??}:"
+case "$1" in
+-b)
+  compstyles -S "$context" "$2" val
+  ret="$?"
 
-if [[ "$all" = *:${2}[:\=]* ]]; then
-
-  # We have a definition for the style.
+  if [[ "$val" = (#I)(yes|true|1|on) ]]; then
+    eval "${3}=yes"
+  else
+    eval "${3}=no"
+  fi
 
+  return ret;
+  ;;
+-s)
+  compstyles -S "${curcontext}${2:+:${2}}" "$3" "$4"
+  return
+  ;;
+-a)
+  compstyles -A "${curcontext}${2:+:${2}}" "$3" "$4"
+  return
+  ;;
+-h)
+  compstyles -H "${curcontext}${2:+:${2}}" "$3" "$4"
+  return
+  ;;
+esac
+
+[[ "$1" = -(|-) ]] && shift
+
+if compstyles -S "${curcontext}${1:+:${1}}" "$2" val; then
   if [[ $# -eq 3 ]]; then
-    if [[ -n "$get" ]]; then
-
-      # We have to return the value.
-
-      if [[ "$all" = *,${2}\=* ]]; then
-        eval "${3}=\"${${all#*:${2}\=}%%:*}\""
-      else
-        eval "${3}=''"
-      fi
-    else
-
-      # We have to test the value.
-
-      if [[ "$all" = *:${2}\=* ]]; then
-        [[ "${${all#*:${2}\=}%%:*}" = ${~3} ]]
-      else
-        [[ '' -eq ${~3} ]]
-      fi
-
-      return
-    fi
+    [[ "$val" = ${~3} ]]
+  else
+    [[ "$val" = (#I)(yes|true|1|on) ]]
   fi
-  return 0
+else
+  return 1
 fi
-
-return 1
diff --git a/Completion/Core/_tags b/Completion/Core/_tags
index 5ed56df6e..5294ab3c7 100644
--- a/Completion/Core/_tags
+++ b/Completion/Core/_tags
@@ -1,40 +1,26 @@
 #autoload
 
-# We use the funcstack names to communicate to neighboring functions.
-
-local tname="$funcstack[2,-1]"
-
 if (( $# )); then
 
   # We have arguments: the tags supported in this context.
 
-  local command="${_tag_context:-${words[1]}}" _tags contexts name
+  local curcontext="$curcontext"
 
-  # We are given the `-c command-name' option.
-
-  if [[ "$1" = -c?* ]]; then
-    command="${1[3,-1]}"
+  if [[ "$1" = -C?* ]]; then
+    curcontext="${curcontext}:${1[3,-1]}"
     shift
-  elif [[ "$1" = -c ]]; then
-    command="$2"
+  elif [[ "$1" = -C ]]; then
+    curcontext="${curcontext}:${2}"
     shift 2
+  else
+    targs=()
   fi
 
   [[ "$1" = -(|-) ]] && shift
 
-  # Get the context names.
-
-  if [[ -n "$_sub_context" ]]; then
-    contexts="${1}:${_sub_context}"
-  else
-    contexts="${1}"
-  fi
-  contexts=":${command},${${contexts//::/:}//:/:${command},}:"
-  shift
+  # Set and remember offered tags.
 
-  _tags=()
-
-  # Remember offered tags.
+  comptags -i "$curcontext" "$@"
 
   _offered_tags=( "$_offered_tags[@]" "$@" )
   _last_tags=()
@@ -43,46 +29,35 @@ if (( $# )); then
 
   "${_sort_tags:-_sort_tags}" "$@"
 
-  # The sets are reported in $_tags, one element per set. Remove 
-  # tags that weren't requested.
-
-  _tags=( "${(M@)_tags:#*:(${(j:|:)~argv}):*}" )
-
-  # Store the sets in a `hidden' array.
-
-  name="_prio_arr$(( _prio_num++ ))"
-  _prio_names[$tname]="$name"
-  eval "${name}=( \"\$_tags[@]\" )"
-
   # Also store the context (used below and in _requested).
 
-  _cur_contexts="$contexts[2,-2]"
-  _tag_contexts[$tname]="$_cur_contexts"
+  _cur_context="$curcontext"
 
   # Return non-zero if at least one set of tags should be used.
 
-  return \!$#_tags
+  comptags -T
+
+  return
 fi
 
 # The other mode: switch to the next set of tags.
 
-local prios="$_prio_names[$tname]"
+local tags
 
 # Reset the current context.
 
-_cur_contexts="${_tag_contexts[$tname]}"
+comptags -C _cur_context
 
-_failed_tags=( "$_failed_tags[@]" "$_last_tags" )
+_failed_tags=( "$_failed_tags[@]" "$_last_tags[@]" )
 
 # Return failure if no sets remaining.
 
-(( ${(P)#prios} )) || return 1
+comptags -N || return 1
 
 # Otherwise get the next tags.
 
-_cur_tags[$tname]="${(@)${(@P)prios}[1]}:"
+comptags -S _last_tags
 
-_last_tags=( "${(@)${(@s.:.)${(@P)prios}[1]}:#}" )
 _tried_tags=( "$_tried_tags[@]" "$_last_tags[@]" )
 
 shift 1 "$prios"
diff --git a/Completion/Core/_unset_options b/Completion/Core/_unset_options
index 0c7b91b7a..8c8ed780d 100644
--- a/Completion/Core/_unset_options
+++ b/Completion/Core/_unset_options
@@ -6,7 +6,6 @@
 
 local expl
 
-_tags any zsh-options || return 1
-
-_description 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 "$expl[@]" "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - \
+            $=_unset_options
diff --git a/Completion/Core/_wanted b/Completion/Core/_wanted
new file mode 100644
index 000000000..7baa3e724
--- /dev/null
+++ b/Completion/Core/_wanted
@@ -0,0 +1,21 @@
+#autoload
+
+local targs
+
+if [[ "$1" = -C?* ]]; then
+  targs=( -C "${1[3,-1]}" )
+  shift
+elif [[ "$1" = -C ]]; then
+  targs=( -C "$2" )
+  shift 2
+else
+  targs=()
+fi
+
+[[ "$1" = -(|-) ]] && shift
+
+if [[ $# -gt 1 ]]; then
+  _tags "$targs[@]" "$1" && _description "${(@)argv[2,-1]}"
+else
+  _tags "$targs[@]" "$1"
+fi
diff --git a/Completion/Core/compdump b/Completion/Core/compdump
index b4530ea8e..67b6e0865 100644
--- a/Completion/Core/compdump
+++ b/Completion/Core/compdump
@@ -17,7 +17,7 @@ emulate -L zsh
 
 typeset _d_file _d_f _d_bks _d_line _d_als
 
-_d_file=${compconfig[dumpfile]-${0:h}/compinit.dump}.$HOST.$$
+_d_file=${_comp_dumpfile-${0:h}/compinit.dump}.$HOST.$$
 
 typeset -U _d_files
 _d_files=( ${^~fpath:/.}/_(|*[^~])(N:t) )
diff --git a/Completion/Core/compinit b/Completion/Core/compinit
index 0f614f322..6f2f39fcb 100644
--- a/Completion/Core/compinit
+++ b/Completion/Core/compinit
@@ -91,27 +91,14 @@ _postpatcomps=()
 
 typeset -gA _lastcomp
 
-# This is the associative array used for configuration.
-
-typeset -gA compconfig
-
-# Standard initialisation for `compconfig'.
+# Remember dumpfile.
 if [[ -n $_i_dumpfile ]]; then
   # Explicitly supplied dumpfile.
-  compconfig[dumpfile]="$_i_dumpfile"
+  _comp_dumpfile="$_i_dumpfile"
 else
-  compconfig[dumpfile]="${ZDOTDIR:-$HOME}/.zcompdump"
+  _comp_dumpfile="${ZDOTDIR:-$HOME}/.zcompdump"
 fi
 
-(( ${+compconfig[correct_accept]} )) || compconfig[correct_accept]=2n
-(( ${+compconfig[correct_prompt]} )) ||
-  compconfig[correct_prompt]='correct to:'
-(( ${+compconfig[completer]} )) || compconfig[completer]=_complete
-
-# This holds the style definitions.
-
-typeset -gA _compstyles
-
 # This can hold names of functions that are to be called after all
 # matches have been generated.
 
@@ -321,119 +308,181 @@ compdef() {
   fi
 }
 
-# Functional interface to configuration. This takes its arguments
-# and sets the according values in `compconfig'.
-# Arguments may be `foo=bar' to set key `foo' to `bar' or `baz' to
-# set key `baz' to the empty string.
-# If no arguments are given, all configurations keys set are displayed.
-# With the option `-l' as the first argument, the other arguments are
-# taken to be key names and the values for theses keys are printed, one
-# per line.
-# When listing is done and the `-L' option is given, the keys and
-# values are printed as invocations for this function, usable to be put
-# inte a setup script.
+# Do *not* use this...
 
 compconf() {
-  local i opt list
 
-  while getopts "lL" opt; do
-    if [[ "$opt" = l ]]; then
-      [[ -z "$list" ]] && list=yes
-    else
-      list=long
-    fi
-  done
-  shift OPTIND-1
+  local style name val i tmp cmt
 
-  if (( $# )); then
-    if [[ -n $list ]]; then
-      for i; do
-        if [[ $list = long ]]; then
-	  (( ${+compconfig[$i]} )) && print "compconf $i='$compconfig[$i]'"
-	else
-          print $compconfig[$i]
-	fi
-      done
-    else
-      for i; do
-        if [[ "$i" = *\=* ]]; then
-          compconfig[${i%%\=*}]="${i#*\=}"
-        else
-          compconfig[$i]=''
-        fi
-      done
-    fi
-  else
-    for i in ${(ok)compconfig}; do
-      if [[ $list = long ]]; then
-	print "compconf $i='$compconfig[$i]'"
-      else
-        print ${(r:25:)i} "$compconfig[$i]"
-      fi
-    done
+  if [[ -z "$_compconf_warn" ]]; then
+    _compconf_warn=yep
+
+    print "
+
+Hello
+
+\`compconf' will be removed in the near future. The \`styles' form of
+your setup should be available in the file:
+
+    \`${HOME}/.zsh-styles'
+
+
+Have fun
+
+   Sven
+" 1>&2
+    command rm -f ${HOME}/.zsh-styles
   fi
+
+  for i; do
+    name="${i%%\=*}"
+    val="${i#*\=}"
+
+    tmp=''
+    cmt=''
+
+    case "$name" in
+    urls_path)
+      tmp="'*:urls' path '$val'"
+      ;;
+    urls_localhttp)
+      tmp="'*:urls' local '${val//:/ }'"
+      ;;
+    describe_options)
+      tmp="'*:options' description '$val'"
+      ;;
+    describe_values)
+      tmp="'*:values' description '$val'"
+      ;;
+    autodescribe_options)
+      tmp="'*:options' auto-description '$val'"
+      ;;
+    description_format)
+      tmp="'*:descriptions' format '$val'"
+      ;;
+    message_format)
+      tmp="'*:messages' format '$val'"
+      ;;
+    warning_format)
+      tmp="'*:warnings' format '$val'"
+      ;;
+    option_prefix)
+      tmp="'*:options' prefix-needed yes"
+      [[ "$val" = hide* ]] &&
+          tmp="$tmp
+compstyle '*:options' prefix-hidden yes"
+      ;;    
+    group_matches)
+      tmp="'*:matches' group 'yes'"
+      ;;
+    colors_path)
+      tmp="'*:colors' path '$val'"
+      ;;
+    path_expand)
+      tmp="'*:paths' expand '$val'"
+      ;;
+    path_cursor)
+      tmp="'*:paths' cursor '$val'"
+      ;;
+    (approximate|incremental|predict|list|oldlist|match)_*)
+      tmp="':${name%%_*}' ${${name#*_}//_/-} '$val'"
+      ;;
+    correct_*)
+      cmt="# This one is a bit ugly. You may want to use only \`*:correct'
+# if you also have the \`correctword_*' or \`approximate_*' keys.
+"
+      tmp="':(correct(|-word)|approximate)' ${name#*_} '$val'"
+      ;;
+    correctword_*)
+      tmp="':correct-word' ${name#correctword_} '$val'"
+      ;;
+    expand_*)
+      cmt="# This one is a bit ugly. You may want to use only \`*:expand'
+# if you also have the \`expandword_*' keys.
+"
+      tmp="':expand(|expand-word)' ${name#*_} '$val'"
+      ;;
+    expandword_*)
+      tmp="':expand-word' ${name#expandword_} '$val'"
+      ;;
+    history_*)
+      tmp="'*:history-entries' ${name#history_} '$val'"
+      ;;
+    completer)
+      tmp="'*' completer ${val//:/ }"
+      ;;
+    last_prompt)
+      tmp="'*' last-prompt '$val'"
+      ;;
+    esac
+    [[ -n "$tmp" ]] && style="${style}${cmt}compstyle ${tmp}
+"
+  done
+
+  eval "${style}"
+
+  print "$style" >> ${HOME}/.zsh-styles
 }
 
 # Very simple interface for setting styles:
 #
 #   compstyle context -styles... context -styles ...
 #
-# Where context is of the form cmd-pat:ctxt-pat:tag-pat.
+# Where context is of the form :ctxt-pats:...:tag-pat.
 #
 # This will be improved if needed. Promised.
 
 compstyle() {
   if (( ! $# )); then
-    local pat
+    local pats styles vals pat style
+
+    compstyles -G pats
 
-    for pat in "${(@k)_compstyles}"; do
-      print -- "${(r:20:: :)pat} -- ${_compstyles[$pat]#??}"
+    for pat in "$pats[@]"; do
+      print "$pat"
+      compstyles -G styles "$pat"
+      for style in "$styles[@]"; do
+        compstyles -G vals "$pat" "$style"
+        print "    $style = $vals"
+      done
     done
 
     return 0
   fi
 
-  local sep pat test
-  typeset -Z 2 num
-
-  while (( $# )); do
-    num=0
-    for pat in "${(s:,:)1}"; do
-      if [[ "$pat" = \* ]]; then
-        (( num += 3 ))
-      elif [[ "$pat" = any ]]; then
-        (( num += 2 ))
-      elif [[ "$pat" != "$pat:q" ]]; then
-        (( num++ ))
-      fi
-    done
+  if [[ "$1" = -d ]]; then
+    case "$#" in
+    1) compstyles -d ;;
+    2) compstyles -d "$2" ;;
+    *) 
+      local pat="$2" style
 
-    pat="$1"
-    shift
+      shift
+
+      for style; do
+        compstyles -d "$pat" "$style"
+      done
+      ;;
+    esac
 
-    sep=$argv[(I)[^-]*]
+    return 0
+  fi
 
-    if (( sep )); then
-      _compstyles[$pat]="${num}${(j.:.)${(@)argv[1,sep-1]#-}}"
-      shift sep-1
-    else
-      _compstyles[$pat]="${num}${(j.:.)${(@)argv#-}}"
-      break
-    fi
-  done
+  [[ "$1" = -(|-) ]] && shift
+
+  compstyles -a "$@"
 
   return 0
 }
 
-# Default styles.
-
-compstyle '*,*,*' -description=yes -prefix-needed=yes -prefix-hidden=no
+# Default styles. This should be executed conditionally somehow.
 
-# Helper function for `_tags'. Will be moved into C-code.
-
-comptry() {
-  _tags=( "$_tags[@]" ":${(j.:.)argv}:" )
-}
+compstyle '*'        description   'yes'
+compstyle '*'        prefix-needed 'yes'
+compstyle '*'        prefix-hidden 'no'
+compstyle ':correct' accept        '2n'
+compstyle ':correct' prompt        'correct to:'
+compstyle '*'        completer     '_complete'
 
 # Utility function to call a function if it exists.
 #
@@ -506,10 +555,10 @@ autoload -U compdump compinstall
 
 # If we have a dump file, load it.
 
-if [[ -f "$compconfig[dumpfile]" ]]; then
-  read -rA _i_line < "$compconfig[dumpfile]"
+if [[ -f "$_comp_dumpfile" ]]; then
+  read -rA _i_line < "$_comp_dumpfile"
   if [[ _i_autodump -eq 1 && $_i_line[2] -eq $#_i_files ]]; then
-    builtin . "$compconfig[dumpfile]"
+    builtin . "$_comp_dumpfile"
     _i_done=yes
   fi
 fi
diff --git a/Completion/Core/compinstall b/Completion/Core/compinstall
index bd58d643b..f7cf94209 100644
--- a/Completion/Core/compinstall
+++ b/Completion/Core/compinstall
@@ -29,7 +29,7 @@ emulate -L zsh
 
 typeset _ci_options _ci_f _ci_fdir _ci_files _ci_dumpfile _ci_lines
 typeset _ci_type _ci_completer _ci_accept _ci_cprompt _ci_startline
-typeset _ci_endline _ci_ifile _ci_tmpf _ci_compconf _ci_warn
+typeset _ci_endline _ci_ifile _ci_tmpf _ci_compstyle _ci_warn
 typeset _ci_dtype _ci_existing _ci_line _ci_end
 
 # Look for the defaults.
@@ -45,14 +45,14 @@ typeset -A _ci_defaults
 if [[ -f $_ci_ifile ]]; then
   # This assumes the lines haven't been altered by the user too much
   # after they were added.
-  _ci_compconf=0
+  _ci_compstyle=0
   sed -n "/^$_ci_startline/,/^$_ci_endline/p" $_ci_ifile |
   while read -rA _ci_line; do
-    if (( $_ci_compconf )); then
-      # parse a compconf component as first argument
+    if (( $_ci_compstyle )); then
+      # parse a compstyle component as first argument
       if [[ $_ci_line[-1] != \\ ]]; then
 	_ci_end=-1
-	_ci_compconf=0
+	_ci_compstyle=0
       else
 	_ci_end=-2
       fi
@@ -72,11 +72,11 @@ if [[ -f $_ci_ifile ]]; then
       [[ $_ci_line[-2] = -d ]] && _ci_dumpfile=$_ci_line[-1]
     elif [[ $_ci_line[1] = _compdir=* ]]; then
       _ci_fdir=${_ci_line[1]##_compdir=}
-    elif [[ $_ci_line[1] = compconf ]]; then
-      # parse a compconf component as second argument (should be completer)
-      [[ $_ci_line[2] = completer=* ]] &&
-        _ci_completer=${_ci_line[2]#completer=}
-      [[ $_ci_line[-1] == \\ ]] && _ci_compconf=1
+    elif [[ $_ci_line[1] = compstyle ]]; then
+      # parse a compstyle component as second argument (should be completer)
+      [[ $_ci_line[3] = completer ]] &&
+        _ci_completer=${_ci_line[3,-1]}
+      [[ $_ci_line[-1] == \\ ]] && _ci_compstyle=1
       _ci_existing="${_ci_existing}$_ci_line
 "
     elif [[ $_ci_line[1] != \#* && $_ci_line[1] != (autoload|\[\[) ]]; then
@@ -208,7 +208,7 @@ approximate completion if that fails.  Would you like:
   A:  Approximate completion
   B:  Both"
   if [[ -n $_ci_completer ]]; then
-    print "  Default: use the current completer:\n$_ci_completer"
+    print "  Default: use the current completers:\n$_ci_completer"
   else
     print "Please type one of the keys above."
   fi
@@ -218,13 +218,13 @@ approximate completion if that fails.  Would you like:
       0*) _ci_completer=_complete
 	  break
 	  ;;
-      [cC]*) _ci_completer=_complete:_correct
+      [cC]*) _ci_completer='_complete _correct'
 	     break
 	     ;;
-      [aA]*) _ci_completer=_complete:_approximate
+      [aA]*) _ci_completer='_complete _approximate'
 	     break;
 	     ;;
-      [bB]*) _ci_completer=_complete:_correct:_approximate
+      [bB]*) _ci_completer='_complete _correct _approximate'
 	     break
 	     ;;
       *) [[ -n $_ci_completer ]] && break
@@ -233,7 +233,7 @@ approximate completion if that fails.  Would you like:
     esac
   done
 
-  _ci_lines="${_ci_lines}compconf completer=$_ci_completer"
+  _ci_lines="${_ci_lines}compstyle '*' completer $_ci_completer"
 
 
   if [[ $_ci_completer = *(correct|approx)* ]]; then
diff --git a/Completion/Debian/_apt b/Completion/Debian/_apt
index b0effba77..47c9f7e8c 100644
--- a/Completion/Debian/_apt
+++ b/Completion/Debian/_apt
@@ -75,7 +75,7 @@ _apt_arguments () {
   nul=$'\0'
   qnul="\$'\\0'"
 
-  comp_bool='compadd "$expl_bool[@]" '"$bool"
+  comp_bool='_tags values && compadd "$expl_bool[@]" '"$bool"
   comp_intlevel= #"_message 'intlevel'"
   comp_configfile='_files "$expl_configfile[@]"'
   comp_arbitem= #"_message 'Foo::Bar=bar'"
@@ -106,7 +106,7 @@ tmp2=("$tmp2[@]" $_ra_left${(M)^short_bool:#$~tmp1} $_ra_left${(M)^short_intleve
 tmp3=("$tmp3[@]" $_ra_left${(M)^short_hasarg:#$~tmp1} $_ra_left${(M)^short_configfile:#$~tmp1} $_ra_left${(M)^short_arbitem:#$~tmp1})
 _describe -o option tmp2 -- tmp3 -S='
 
-  comp_opt='[[ -prefix - || -z "$compconfig[option_prefix]" || "$compconfig[option_prefix]" = *\!$words[1]* ]]'" && { $comp_short; $comp_long }"
+  comp_opt='{ ! _style options prefix-needed || [[ "$PREFIX" = -* ]] } && { $comp_short; $comp_long }"
 
   regex_short=()
   regex_long=()
@@ -384,7 +384,7 @@ _apt-get () {
     /$'check\0'/ \| \
     /$'source\0'/ /$'[^\0]#\0'/ :'_deb_packages avail "$expl_packages[@]"' \# \| \
     /$'help\0/' \| \
-    /"[]"/	:'compadd "$expl_action[@]" update upgrade install remove dist-upgrade dselect-upgrade clean autoclean check source help'
+    /"[]"/	:'_tags actions && compadd "$expl_action[@]" 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'/ \| \
     /$'show\0'/ /$'[^\0]#\0'/ :'_deb_packages avail "$expl_packages[@]"' \# \| \
     /$'depends\0'/ \| \
-    /"[]"/ :'compadd "$expl_action[@]" help add gencaches showpkg stats dump dumpavail unmet check search show depends'
+    /"[]"/ :'_tags actions && compadd "$expl_action[@]" 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'/ \| \
-    /"[]"/	:'compadd "$expl_action[@]" add'
+    /"[]"/	:'_tags actions && compadd "$expl_action[@]" add'
 
   _apt-cdrom () {
     local expl_action expl_mount_point
@@ -473,11 +473,11 @@ _apt-config () {
     -- \
     /$'shell\0'/ \
       \( \
-	/$'[^\0]#\0'/ :'compadd "$expl_shell_var[@]" - "${(@k)parameters}"' \
-	/$'[^\0]#\0'/ :'compadd "$expl_config_key[@]" - ${${(f)"$(apt-config dump 2>&1)"}% *}' \
+	/$'[^\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)"}% *}' \
       \) \# \| \
     /$'dump\0'/ \| \
-    /"[]"/	:'compadd "$expl_action[@]" shell dump'
+    /"[]"/	:'_tags actions && compadd "$expl_action[@]" 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 cb74137bf..dd39d055d 100644
--- a/Completion/Debian/_deb_packages
+++ b/Completion/Debian/_deb_packages
@@ -17,11 +17,12 @@ if (( ! $+_deb_cache_dpkg_get_selections )); then
   )
 fi
 
-local command="$1"
+local command="$1" expl
 shift
 
-case "$command" in
-  installed) compadd "$@" - $_deb_cache_installed;;
-  uninstalled) compadd "$@" - $_deb_cache_uninstalled;;
-  avail) compadd "$@" - $_deb_cache_avail;;
-esac
+_wanted packages expl packages &&
+    case "$command" in
+    installed) compadd "$@" - $_deb_cache_installed;;
+    uninstalled) compadd "$@" - $_deb_cache_uninstalled;;
+    avail) compadd "$@" - $_deb_cache_avail;;
+    esac
diff --git a/Completion/Linux/_rpm b/Completion/Linux/_rpm
index 15f154db9..eb30924dc 100644
--- a/Completion/Linux/_rpm
+++ b/Completion/Linux/_rpm
@@ -43,14 +43,14 @@ local ret=1 tmp expl
 
 # Used by `_arguments', made local here.
 
-local context state lstate line
+local curcontext="$curcontext" state lstate line
 typeset -A opt_args
 
 state=''
 
 # Do simple completions or get the first state.
 
-_arguments -s \
+_arguments -C -s \
   '--rcfile:resource file:_files' \
   '--ftpproxy:FTP proxy server:_hosts' \
   '--ftpport:FTP port number:' \
@@ -187,32 +187,23 @@ while [[ -n "$state" ]]; do
     state=package_file
     ;&
   package)
-    _tags "$context" packages || return 1
-
-    _description expl 'RPM package'
-    compadd "$expl[@]" -M 'r:|-=* r:|=*' - $(rpm -qa) && ret=0
+    _wanted packages expl 'RPM package' &&
+        compadd "$expl[@]" -M 'r:|-=* r:|=*' - $(rpm -qa) && ret=0
     ;;
   package_file)
     if compset -P ftp://; then
-      _tags "$context" hosts || return 1
-
-      _hosts -S/ && ret=0
+      _tags hosts && _hosts -S/ && ret=0
     else
-      _tags "$context" files || return 1
-
-      _description expl 'RPM package file'
-      _files "$expl[@]" -g '*.(#i)rpm' && ret=0
-      _description expl 'ftp URL prefix'
-      compadd "$expl[@]" ftp://
+      _alternative \
+          'files:RPM package file:_files -g \*.\(\#i\)rpm' \
+	  'prefixes:ftp URL prefix:compadd ftp://' && ret=0
     fi
     ;;
   tags)
     if compset -P '*\{'; then
-      _tags "$context" tags || return 1
-
-      _description expl 'RPM tag'
-      compadd "$expl[@]" -M 'm:{a-z}={A-Z}' -S '}' - \
-              "${(@)${(@f)$(rpm --querytags)}#RPMTAG_}" && ret=0
+      _wanted tags expl 'RPM tag' &&
+          compadd "$expl[@]" -M 'm:{a-z}={A-Z}' -S '}' - \
+                  "${(@)${(@f)$(rpm --querytags)}#RPMTAG_}" && ret=0
     else
       _message 'RPM format'
     fi
@@ -227,7 +218,7 @@ while [[ -n "$state" ]]; do
       _description expl 'old path'
     fi
 
-    _tags "$context" directories || return 1
+    _tags directories || return 1
 
     _files "$expl[@]" -/ && ret=0
     ;;
diff --git a/Completion/User/_archie b/Completion/User/_archie
index 640fbc4ed..e1c9156fa 100644
--- a/Completion/User/_archie
+++ b/Completion/User/_archie
@@ -1,9 +1,9 @@
 #compdef archie
 
-local context state line expl
+local curcontext="$curcontext" state line expl
 typeset -A opt_args
 
-_arguments -s \
+_arguments -C -s \
   '-D+[debug level]:debug level:' \
   '-v[print version]' \
   '-V[verbose mode]' \
@@ -26,9 +26,6 @@ case "$state" in
 serverhost)
   : ${(A)archie_servers:=${(M)$(archie -L):#archie.*}}
 
-  _tags "${context}:server" hosts || return 1
-
-  _description expl 'archie servers'
-  compadd "$expl[@]" -  $archie_servers
+  _wanted hosts expl 'archie servers' && compadd "$expl[@]" -  $archie_servers
   ;;
 esac
diff --git a/Completion/User/_cvs b/Completion/User/_cvs
index 61435a9cf..cac9132b7 100644
--- a/Completion/User/_cvs
+++ b/Completion/User/_cvs
@@ -33,8 +33,11 @@ _cvs_command () {
 	watchers "")
 
   if (( CURRENT == 1 )); then
-    compadd "$@" ${(k)cmds} || compadd "$@" ${(kv)=cmds}
+    _tags commands && { compadd "$@" ${(k)cmds} || compadd "$@" ${(kv)=cmds} }
   else
+    local curcontext="$curcontext"
+
+    curcontext="${curcontext%:*}:$words[1]"
     _cvs_"${${(k)cmds[(R)* $words[1] *]}:-${(k)cmds[(i)$words[1]]}}"
   fi
 }
@@ -351,22 +354,24 @@ _cvs_update () {
 
 (( $+functions[_cvs_watch] )) ||
 _cvs_watch () {
+  local expl
+
   if (( CURRENT == 2 )); then
-    compadd on off add remove
+    _wanted values expl 'watch comamnd' && compadd on off add remove
   else
     case "$words[2]" in
       on|off) # "+lR"
 	_arguments -s \
-	-{l,R} \
-	':watch command:' \
-	':*:file:_cvs_files'
+	    -{l,R} \
+	    ':watch command:' \
+	    ':*:file:_cvs_files'
 	;;
       add|remove) # "+lRa:"
 	_arguments -s \
-	-{l,R} \
-	'*-a+:action:(edit unedit commit all none)' \
-	':watch command:' \
-	':*:file:_cvs_files'
+	    -{l,R} \
+	    '*-a+:action:(edit unedit commit all none)' \
+	    ':watch command:' \
+	    ':*:file:_cvs_files'
 	;;
     esac
   fi
@@ -376,18 +381,18 @@ _cvs_watch () {
 _cvs_watchers () {
   # "+lR"
   _arguments -s \
-    -{l,R} \
-    ':*:file:_cvs_files'
+      -{l,R} \
+      ':*:file:_cvs_files'
 }
 
 (( $+functions[_cvs_root] )) ||
 _cvs_root () {
-  compadd "$@" $_cvs_roots || _files "$@" -/
+  _tags files && { compadd "$@" $_cvs_roots || _files "$@" -/ }
 }
 
 (( $+functions[_cvs_tempdir] )) ||
 _cvs_tempdir () {
-  compadd "$@" $TMPPREFIX:h $TMPDIR /tmp
+  _tags directories && compadd "$@" $TMPPREFIX:h $TMPDIR /tmp
 }
 
 (( $+functions[_cvs_user_variable] )) ||
@@ -403,29 +408,29 @@ _cvs_user_variable () {
 
 (( $+functions[_cvs_bindir] )) ||
 _cvs_bindir () {
-  compadd "$@" /usr/local/bin || _files "$@" -/
+  _tags directories && { compadd "$@" /usr/local/bin || _files "$@" -/ }
 }
 
 (( $+functions[_cvs_editor] )) ||
 _cvs_editor () {
-  compadd "$@" vi
+  _tags commands && compadd "$@" vi
 }
 
 (( $+functions[_cvs_gzip_level] )) ||
 _cvs_gzip_level () {
-  compadd "$@" 9
+  _tags values && compadd "$@" 9
 }
 
 # define completion functions for cvs common options and arguments.
 
 (( $+functions[_cvs_D] )) ||
 _cvs_D () {
-  compadd "$@" today yesterday week\ ago month\ ago
+  _tags values && compadd "$@" today yesterday week\ ago month\ ago
 }
 
 (( $+functions[_cvs_k] )) ||
 _cvs_k () {
-  compadd "$@" kv kvl k o b v
+  _tags values && compadd "$@" kv kvl k o b v
 }
 
 (( $+functions[_cvs_m] )) ||
@@ -435,21 +440,26 @@ _cvs_m () {
 
 (( $+functions[_cvs_modules] )) ||
 _cvs_modules () {
-  local root=$CVSROOT
+  local root=$CVSROOT expl
+
   [[ -f CVS/Root ]] && root=$(<CVS/Root)
 
   if [[ $root = :* || ! -d $root ]]; then
     _message "module name"
   else
-    compadd - \
-      $root/^CVSROOT(:t) \
-      ${${(M)${(f)"$(<$root/CVSROOT/modules)"}:#[^#]*}%%[ 	]*}
+    _wanted modules expl module &&
+        compadd "$expl[@]" - \
+            $root/^CVSROOT(:t) \
+            ${${(M)${(f)"$(<$root/CVSROOT/modules)"}:#[^#]*}%%[ 	]*}
   fi
 }
 
 (( $+functions[_cvs_revisions] )) ||
 _cvs_revisions () {
-  compadd - ${${${(M)${(f)"$(cvs -q status -vl .)"}:#	*}##[ 	]##}%%[ 	]*}
+  local expl
+
+  _wanted values expl revision &&
+      compadd - ${${${(M)${(f)"$(cvs -q status -vl .)"}:#	*}##[ 	]##}%%[ 	]*}
 }
 
 # define completion functions for files maintained by cvs.
@@ -477,8 +487,7 @@ _cvs_extract_file_entries () {
 
 (( $+functions[_cvs_extract_modifiedfile_entries] )) ||
 _cvs_extract_modifiedfile_entries () {
-  if [[ -n "$compconfig[cvs_disable_stat]" ]] ||
-    ! { zmodload -e stat || zmodload stat }; then
+  if _style cvs disable-stat || ! { zmodload -e stat || zmodload stat }; then
     _cvs_extract_file_entries
     return
   fi
@@ -566,7 +575,7 @@ _cvs_files_removed () {
     local omit
     omit=(${pref}*(D:t))
     eval 'entries=(${entries:#('${(j:|:)${(@)omit:q}}')})'
-    compadd "$@" -P "$qpref" - ${entries:q} ||
+    _tags direcories && compadd "$@" -P "$qpref" - ${entries:q} ||
     _cvs_directories "$@"
   else
     _files "$@"
diff --git a/Completion/User/_dd b/Completion/User/_dd
index 9bcdc876d..3a980b48d 100644
--- a/Completion/User/_dd
+++ b/Completion/User/_dd
@@ -6,9 +6,9 @@ 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 '*,'
-  _description expl conversion
-  compadd "$expl[@]" -qS, -q \
-          ascii ebcdic ibm block unblock lcase ucase swab noerror sync
+  _wanted values expl conversion &&
+      compadd "$expl[@]" -qS, -q \
+              ascii ebcdic ibm block unblock lcase ucase swab noerror sync
 elif compset -P 1 'if\='; then
   _description expl 'input file'
   _files "$expl[@]"
@@ -16,6 +16,6 @@ elif compset -P 1 'of\='; then
   _description expl 'output file'
   _files "$expl[@]"
 else
-  _description expl option
-  compadd "$expl[@]" -S '=' if of ibs obs bs cbs skip files seek count conv
+  _wanted values expl option &&
+      compadd "$expl[@]" -S '=' if of ibs obs bs cbs skip files seek count conv
 fi
diff --git a/Completion/User/_flex b/Completion/User/_flex
index 5d5d55f7a..714e5b9d5 100644
--- a/Completion/User/_flex
+++ b/Completion/User/_flex
@@ -1,9 +1,9 @@
 #compdef flex
 
-local context state line ret=1
+local curcontext="$curcontext" state line ret=1
 typeset -A opt_args
 
-_arguments -s \
+_arguments -C -s \
   --help --version \
   '-b[generate backing-up information]' \
   '-d[make scanner running in debug mode]' \
diff --git a/Completion/User/_gcc b/Completion/User/_gcc
index 88f70ad52..7292a933c 100644
--- a/Completion/User/_gcc
+++ b/Completion/User/_gcc
@@ -1,6 +1,6 @@
 #compdef gcc
 
-local context state line ret=1 expl args
+local curcontext="$curcontext" state line ret=1 expl args
 typeset -A opt_args
 
 args=()
@@ -163,7 +163,7 @@ h8/300)
 esac
 
 
-_arguments -M 'L:|-{fW}no-=-{fW} r:|[_-]=* r:|=*' \
+_arguments -C -M 'L:|-{fW}no-=-{fW} r:|[_-]=* r:|=*' \
   "$args[@]" \
   -c -S -E -v -a -w -C -H -P -s '(-pg)-p' '(-p)-pg' \
   '-o:output file:_files' \
@@ -273,10 +273,8 @@ dump)
     'p[annotate assembler output]' && ret=0
   ;;
 library)
-  _tags "${context}" libraries || return 1
-
-  _description 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 "$expl[@]" - ${^=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 dab301b39..d037b83d9 100644
--- a/Completion/User/_gdb
+++ b/Completion/User/_gdb
@@ -10,19 +10,19 @@ local cur="$words[CURRENT]" prev w list ret=1 expl
 if compset -P '-(cd|directory)='; then
   _files -/
 elif compset -P '-tty='; then
-  _description expl 'terminal device'
-  compadd "$expl[@]" - /dev/tty*
+  _wanted devices expl 'terminal device' && compadd "$expl[@]" - /dev/tty*
 elif compset -P '-(exec|se)='; then
   _description expl executable
   _files "$expl[@]" -g '*(*)'
 elif compset -P '-(symbols|core|command)='; then
   _files
 elif [[ "$PREFIX" = -* ]]; then
-  _description expl option
-  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 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
+  fi
 else
   prev="$words[CURRENT-1]"
 
@@ -31,10 +31,10 @@ else
   (-[csx]) _files && return 0 ;;
   (-e)     _description expl executable
            _files "$expl[@]" -g '*(*)' && return 0 ;;
-  (-b)     _description -V 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 values expl -V 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 ;;
   esac
 
   w=( "${(@)words[2,-1]}" )
@@ -44,10 +44,7 @@ else
   done
 
   if [[ $#w -gt 1 ]]; then
-    _files               && ret=0
-    _pids -m "${w[1]:t}" && ret=0
-
-    return ret
+    _alternative 'files:: _files' "processes:: _pids -m ${w[1]:t}"
   else
     _description expl executable
     _files "$expl[@]" -g '*(*)'
diff --git a/Completion/User/_gprof b/Completion/User/_gprof
index cbc362331..a69a078ba 100644
--- a/Completion/User/_gprof
+++ b/Completion/User/_gprof
@@ -1,9 +1,9 @@
 #compdef gprof
 
-local context state line ret=1
+local curcontext="$curcontext" state line ret=1
 typeset -A opt_args
 
-_arguments -s -{a,b,c,D,h,i,l,L,s,T,v,w,x,y,z} \
+_arguments -C -s -{a,b,c,D,h,i,l,L,s,T,v,w,x,y,z} \
            -{A,C,e,E,f,F,J,n,N,O,p,P,q,Q,Z}:'function name:->funcs' \
 	   '-I:directory:_dir_list' \
 	   '-d-:debug level:' '-k:function names:->pair' \
@@ -17,7 +17,7 @@ _arguments -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 "${context}" functions || return 1
+  _tags functions || return 1
 
   [[ "$state" = pair ]] && pair=yes
 
diff --git a/Completion/User/_groups b/Completion/User/_groups
index bc955a8d2..f1963a8e7 100644
--- a/Completion/User/_groups
+++ b/Completion/User/_groups
@@ -2,15 +2,14 @@
 
 local expl
 
-_tags any groups || return 1
+_wanted groups expl group || return 1
 
 if (( ! $+groups )); then
-  if whence -p ypcat > /dev/null; then
-    : ${(A)groups:=${${(s: :)$(ypcat group.byname)}%%:*}} # If you use NIS
+  if (( ${+commands[ypcat]} )); then
+    : ${(A)groups:=${${(s: :)$(ypcat group.byname)}%%:*}} # If you use YP
   else
     : ${(A)groups:=${${(s: :)$(</etc/group)}%%:*}}
   fi
 fi
 
-_description expl group
 compadd "$@" "$expl[@]" - $groups
diff --git a/Completion/User/_gs b/Completion/User/_gs
index 0c9c11e10..2eebb8d23 100644
--- a/Completion/User/_gs
+++ b/Completion/User/_gs
@@ -8,10 +8,10 @@ if compset -N --; then
     return 1
   fi
 else
-  local context state line ret=1
+  local curcontext="$curcontext" state line ret=1
   typeset -A opt_args
 
-  _x_arguments \
+  _x_arguments -C \
     '-q[quiet startup]' \
     '-g-[set device size]:device size (<width>x<height>):' \
     '-r-[set resolution]:resolution (<val> or <x>x<y>):' \
@@ -25,38 +25,31 @@ else
     if [[ "$PREFIX" = *\=* ]]; then
       _message 'systemdict definition value'
     else
-      _tags "$context" names || return 1
-
-      _description expl 'systemdict definition name'
-      compadd "$expl[@]" -M 'm:{a-z}={A-Z}' - \
-              DISKFONTS NOCACHE NOBIND NODISPLAY NOPAUSE PLATFONTS SAFER \
-              WRITESYSTEMDICT && ret=0
+      _wanted names expl 'systemdict definition name' &&
+          compadd "$expl[@]" -M 'm:{a-z}={A-Z}' - \
+                  DISKFONTS NOCACHE NOBIND NODISPLAY NOPAUSE PLATFONTS SAFER \
+                  WRITESYSTEMDICT && ret=0
     fi
     ;;
   sname)
     if compset -P '*\='; then
       case "$IPREFIX" in
       *DEVICE\=)
-        _tags "$context" devices || return 1
-
-        _description expl 'ghostscript device'
-        compadd "$expl[@]" - "${(@)${=${$(gs -h)##* devices:}%%Search path:*}:#}" && ret=0
+        _wanted devices expl 'ghostscript device' &&
+            compadd "$expl[@]" - "${(@)${=${$(gs -h)##* devices:}%%Search path:*}:#}" && ret=0
         ;;
       *OutputFile\=)
-        _tags "$context" files || return 1
-
         _description expl 'output file'
-        _files && ret=0
+        _files "$expl[@]" && ret=0
         ;;
       *)
         _message 'systemdict value'
         return 1
       esac
     else
-      _tags "$context" names || return 1
-
-      _description expl 'systemdict name'
-      compadd "$expl[@]" -S\= -M 'm:{a-z}={A-Z}' - DEVICE OutputFile && ret=0
+      _wanted names expl 'systemdict name' &&
+          compadd "$expl[@]" -S\= -M 'm:{a-z}={A-Z}' - DEVICE OutputFile &&
+              ret=0
     fi
     ;;
   esac
diff --git a/Completion/User/_hosts b/Completion/User/_hosts
index d577c83ab..83480efe4 100644
--- a/Completion/User/_hosts
+++ b/Completion/User/_hosts
@@ -2,9 +2,7 @@
 
 local expl
 
-_tags any hosts || return 1
-
 : ${(A)hosts:=${(s: :)${(ps:\t:)${${(f)"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}}
 
-_description 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:|=*' "$@" "$expl[@]" - "$hosts[@]"
diff --git a/Completion/User/_killall b/Completion/User/_killall
index 5df1acbb9..ebe02f10c 100644
--- a/Completion/User/_killall
+++ b/Completion/User/_killall
@@ -1,6 +1,4 @@
 #compdef killall
 
-if compset -P 1 -; then
-  _description expl signal
-  compadd "$expl[@]" $signals[1,-3]
-fi
+compset -P 1 - && _wanted -C - signals expl signal &&
+    compadd "$expl[@]" $signals[1,-3]
diff --git a/Completion/User/_lynx b/Completion/User/_lynx
index 8399c4735..e3b57a9b4 100644
--- a/Completion/User/_lynx
+++ b/Completion/User/_lynx
@@ -1,9 +1,9 @@
 #compdef lynx
 
-local context state line
+local curcontext="$curcontext" state line
 typeset -A opt_args
 
-_arguments \
+_arguments -C \
   '-accept_all_cookies' \
   '-anonymous' \
   '-assume_charset=:MIMENAME:' \
diff --git a/Completion/User/_mailboxes b/Completion/User/_mailboxes
index 06906628e..97628ef9a 100644
--- a/Completion/User/_mailboxes
+++ b/Completion/User/_mailboxes
@@ -1,7 +1,7 @@
 #autoload
 
-emulate -L zsh
-setopt nullglob
+#emulate -L zsh
+setopt localoptions nullglob
 
 # This is still needlessly mutt-biased and should be fixed.
 
@@ -12,35 +12,31 @@ local maildirectory="${maildirectory:-~/Mail}"
 
 if (( ! $+_mailbox_cache )) then
 
-[[ -f ${~muttrc:-.} ]] && muttboxes=( ${$(grep mailboxes ${~muttrc})[2,-1]} )
+  [[ -f ${~muttrc:-.} ]] && muttboxes=( ${$(grep mailboxes ${~muttrc})[2,-1]} )
 
-mboxes=( ${~maildirectory}/*(^/) ${~pinedirectory}/**/*(.) )
-dirboxes=( ${~maildirectory}/*(/) )
+  mboxes=( ${~maildirectory}/*(^/) ${~pinedirectory}/**/*(.) )
+  dirboxes=( ${~maildirectory}/*(/) )
 
-while (( $#dirboxes ))
-do 
+  while (( $#dirboxes )); do
     i=$dirboxes[1]
     shift dirboxes
-    if [[ -d "$i/cur" ]]
-    then
-	maildirboxes=( $maildirboxes $i )
-    elif j=( $i/<1-> ) && [[ -n "$j" ]]
-    then
-	MHboxes=( $MHboxes $i )
+    if [[ -d "$i/cur" ]]; then
+      maildirboxes=( $maildirboxes $i )
+    elif j=( $i/<1-> ) && [[ -n "$j" ]]; then
+      MHboxes=( $MHboxes $i )
     else
-	mboxes=( $mboxes $i/*(.) )
-	dirboxes=( $dirboxes $i/*(/) )
+      mboxes=( $mboxes $i/*(.) )
+      dirboxes=( $dirboxes $i/*(/) )
     fi
-done
+  done
 
-[[ -n "$muttboxes" || -d ~/.elm || -d ~/.mutt ]] &&
-    _mailbox_cache=(\! \< \> $muttboxes)
-[[ -n "$mailpath" ]] &&
-    _mailbox_cache=($_mailbox_cache ${mailpath//\?*/})
-
-_mailbox_cache=($_mailbox_cache $mboxes $maildirboxes $MHboxes)
+  [[ -n "$muttboxes" || -d ~/.elm || -d ~/.mutt ]] &&
+      _mailbox_cache=(\! \< \> $muttboxes)
+  [[ -n "$mailpath" ]] &&
+      _mailbox_cache=($_mailbox_cache ${mailpath//\?*/})
 
+  _mailbox_cache=($_mailbox_cache $mboxes $maildirboxes $MHboxes)
 fi
 
-_description expl 'mailbox specification'
-compadd "$@" "$expl[@]" - "$_mailbox_cache[@]"
+_wanted files expl 'mailbox specification' &&
+    compadd "$@" "$expl[@]" - "$_mailbox_cache[@]"
diff --git a/Completion/User/_make b/Completion/User/_make
index f6544ffb0..1531b34d6 100644
--- a/Completion/User/_make
+++ b/Completion/User/_make
@@ -18,12 +18,11 @@ else
     file=''
   fi
 
-  _description expl 'make target'
-  [[ -n "$file" ]] &&
-    compadd "$expl[@]" - \
-      $(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
+  [[ -n "$file" ]] && _wanted targets expl 'make target' &&
+      compadd "$expl[@]" - \
+          $(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 }
 fi
diff --git a/Completion/User/_man b/Completion/User/_man
index 60bd23dd7..18b74d30b 100644
--- a/Completion/User/_man
+++ b/Completion/User/_man
@@ -22,7 +22,7 @@ if (( ! $#manpath )); then
 fi
 
 (( $#manpath )) || manpath=( ${(s.:.)$(manpath 2>/dev/null)} ) ||
-  manpath=( /usr/man(-/N) /(opt|usr)/(dt|share|X11R6|local)/(cat|)man(-/N) )
+    manpath=( /usr/man(-/N) /(opt|usr)/(dt|share|X11R6|local)/(cat|)man(-/N) )
 
 # `sman' is the SGML manual directory for Solaris 7.
 
@@ -33,5 +33,5 @@ else
   rep=( $manpath/(sman|man|cat)*/${~approx}$PREFIX${~star}$SUFFIX.<->*(N:t) )
 fi
 
-_description expl 'manual page'
-(( $#rep )) && compadd "$expl[@]" - ${rep%%.[^.]##(.gz|)}
+(( $#rep )) && _wanted manuals expl 'manual page' &&
+    compadd "$expl[@]" - ${rep%%.[^.]##(.gz|)}
diff --git a/Completion/User/_mh b/Completion/User/_mh
index 87ab8a18e..e4d042dc2 100644
--- a/Completion/User/_mh
+++ b/Completion/User/_mh
@@ -17,12 +17,12 @@ 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.
-  _description expl option
-  compadd "$expl[@]" - $($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";
-  }')
+  _wanted options expl option &&
+      compadd "$expl[@]" - $($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
 elif compset -P 1 '[+@]' || [[ "$prev" = -draftfolder ]]; then
   # Complete folder names.
@@ -53,11 +53,11 @@ elif [[ "$prev" = -(form|audit|filter) ]]; then
   _description expl 'MH template file'
   _files "$expl[@]" -W mhfpath -g '*(.)'
 elif [[ "$prev" = -(no|)cc ]]; then
-  _description expl 'CC address'
-  compadd "$expl[@]" all to cc me
+  _wanted -C "$prev" values expl 'CC address' &&
+      compadd "$expl[@]" all to cc me
 elif [[ "$prev" = -[rw]cache ]]; then
-  _description expl cache
-  compadd "$expl[@]" public private never ask
+  _wanted -C "$prev" values expl cache &&
+      compadd "$expl[@]" public private never ask
 else
   # Generate sequences.
   local foldnam folddir f ret
@@ -74,11 +74,11 @@ else
     # leaving foldnam empty works here
   fi
 
-  _description expl sequence
-  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
-
+  if _wanted sequences expl sequence; then
+    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
+  fi
   return ret
 fi
diff --git a/Completion/User/_mount b/Completion/User/_mount
index 39e31ee35..a68260ae7 100644
--- a/Completion/User/_mount
+++ b/Completion/User/_mount
@@ -5,7 +5,9 @@
 # arguments for the `mount' command for different operating systems
 # are below these table.
 
-local context state line ret=1 args fss deffs=iso9660 descr tmp
+local curcontext="$curcontext" state line ret=1
+local args fss deffs=iso9660 descr tmp
+
 typeset -A opt_args
 
 if (( ! $+_fs_any )); then
@@ -209,13 +211,13 @@ if [[ "$words[1]" = mount ]]; then
     ;;
   esac
 
-  _arguments "$args[@]" && ret=0
+  _arguments -C "$args[@]" && ret=0
 
 else
 
   # Completion for umount.
 
-  _arguments -s \
+  _arguments -C -s \
     '-h[show help]' \
     '-V[show version]' \
     '-v[verbose mode]' \
@@ -228,14 +230,13 @@ fi
 
 case "$state" in
 fstype)
-  _tags "$context" types || return 1
-
   compset -P '*,'
-  _description expl 'file system type'
-  compadd "$expl[@]" -qS, -M 'L:|no=' - "$fss[@]" && ret=0
+
+  _wanted types expl 'file system type' &&
+      compadd "$expl[@]" -qS, -M 'L:|no=' - "$fss[@]" && ret=0
   ;;
 fsopt)
-  _tags "$context" options || return 1
+  _tags options || return 1
 
   eval 'tmp=(' '"$_fs_'${(s:,:)^${opt_args[-t]:-${deffs}}}'[@]"' ')'
   tmp=( "$_fs_any[@]" "${(@)tmp:#}" )
@@ -245,7 +246,7 @@ devordir)
   if (( $+opt_args[-a] )); then
     _message "no device or directory with option \`-a'"
   else
-    _alternative "$context" \
+    _alternative \
         'devices:device:compadd /dev/\*' \
 	'directories:mount point:_files -/' && ret=0
   fi
@@ -260,7 +261,7 @@ udevordir)
     dev_tmp=( "${(@)${(@)tmp%% *}:#none}" )
     mp_tmp=( "${(@)${(@)tmp#* }%% *}" )
 
-    _alternative "$context" \
+    _alternative \
         'devices:device:compadd - $dev_tmp[@]' \
 	'directories:mount point:compadd - $mp_tmp[@]' && ret=0
   fi
diff --git a/Completion/User/_mutt b/Completion/User/_mutt
index 16b1b0c6d..98c59b2e0 100644
--- a/Completion/User/_mutt
+++ b/Completion/User/_mutt
@@ -1,8 +1,8 @@
 #compdef mutt
 
-local context state line muttrc="~/.muttrc" ret=1
+local curcontext="$curcontext" state line muttrc="~/.muttrc" ret=1
 
- _arguments \
+ _arguments -C \
  '::recipient:->userhost' \
  '-a:MIME attachment:_files' \
  '-b:BCC recipient:->userhost' \
@@ -25,7 +25,7 @@ local context state line muttrc="~/.muttrc" ret=1
  '-Z+:open first mailbox with new mail:' && ret=0
 
 if [[ "$state" = userhost ]]; then
-  _tags "$context" hosts || return 1
+  _tags hosts || return 1
 
   if compset -P '*@'; then
     _description expl 'remote host name'
diff --git a/Completion/User/_netscape b/Completion/User/_netscape
index 3caaad05e..2f0537133 100644
--- a/Completion/User/_netscape
+++ b/Completion/User/_netscape
@@ -1,9 +1,9 @@
 #compdef netscape
 
-local context state line ret=1
+local curcontext="$curcontext" state line ret=1
 typeset -A opt_args
 
-_x_arguments \
+_x_arguments -C \
   '-xrm:resource:_x_resource' \
   '-help[show usage message]' \
   '-version[show the version number and build date]' \
@@ -25,7 +25,7 @@ _x_arguments \
   '*:location:->urls' && ret=0
 
 [[ "$state" = "urls" ]] &&
-  _tags "$context" files && _files "$@" && return 0
+  _files "$@" && return 0
 
 
 # Handle netscape remote commands
@@ -40,35 +40,33 @@ if [[ "$state" = "remote" ]]; then
     openFile*) _files -W ~;;
     saveAs*) 
       if compset -P "*,"; then
-        if _tags "$context" types; then
-          _description expl 'data type'
-          compadd -s")" -M 'm:{a-zA-Z}={A-Za-z}' HTML Text PostScript &&
-              ret=0
+        _wanted types expl 'data type' &&
+            compadd -s")" -M 'm:{a-zA-Z}={A-Za-z}' HTML Text PostScript &&
+                ret=0
         fi
       else
-        _tags "$context" files && _path_files -W ~ && ret=0
+        _tags files && _path_files -W ~ && ret=0
       fi
     ;;
     mailto*)
       compset -P "*,"
       if compset -P '*@'; then
-        if _tags "$context" hosts; then
-          _description expl 'remote host name'
-          _hosts "$expl[@]" -q -S, && ret=0
+        _wanted hosts expl 'remote host name' &&
+            _hosts "$expl[@]" -q -S, && ret=0
         fi
       else
-        if _tags "$context" users; then
-          _description expl 'login name'
-          _users "$expl[@]" -q -S@ && ret=0
+        _wanted users expl 'login name' && _users "$expl[@]" -q -S@ && ret=0
         fi
       fi
     ;;
     *)
-      if _tags "$context" commands; then
+      if _wanted commands expl 'remote commands'; then
         if [[ "$QIPREFIX" ]]; then
-          compadd -q -S '(' -M 'm:{a-zA-Z}={A-Za-z}' $remote_commands && ret=0
+          compadd "$expl[@]" -qS '(' -M 'm:{a-zA-Z}={A-Za-z}' - \
+                  $remote_commands && ret=0
         else
-	  compadd -s'(' -S '' -M 'm:{a-zA-Z}={A-Za-z}' $remote_commands && ret=0
+	  compadd "$expl[@]" -s'(' -S '' -M 'm:{a-zA-Z}={A-Za-z}' - \
+                  $remote_commands && ret=0
 	fi
       fi
     ;;
@@ -77,15 +75,12 @@ fi
 
 if [[ "$state" = "urls" ]]; then
   # Complete netscape urls
-  if [[ -prefix about: ]]; then
-    if _tags "$context" values; then
-      _description expl 'about what'
-      compset -P about:
-      compadd authors blank cache document fonts global hype image-cache \
-          license logo memory-cache mozilla plugins && ret=0
-    fi
+  if compset about: ; then
+    _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 "$context" prefixes; then
+    if _tags prefixes; then
       _description expl 'URL prefix'
       compadd "$expl[@]" -S '' about: mocha: javascript:
       _urls "$@" && ret=0
diff --git a/Completion/User/_nslookup b/Completion/User/_nslookup
index f3e290505..495a0e3de 100644
--- a/Completion/User/_nslookup
+++ b/Completion/User/_nslookup
@@ -19,7 +19,7 @@
 # other characters than lower case letters, we try to call the function
 # `_nslookup_host'.
 
-local context state expl ret=1 setopts
+local context curstate="$curcontext" expl ret=1 setopts
 
 setopts=(
   'all[print current values]' \
@@ -52,17 +52,15 @@ if [[ -n "$compcontext" ]]; then
 
     funcall ret _nslookup_command && return ret
 
-    _tags any commands || return 1
-
-    _description expl 'command'
-    compadd "$expl[@]" - server lserver root finger ls view help set && ret=0
-    _hosts && ret=0
+    _alternative \
+        'commands:command:compadd server lserver root finger ls view help set' \
+	'hosts:: _host' && ret=0
     return ret
   elif [[ "$compstate[context]" = redirect ]]; then
 
     funcall ret _nslookup_redirect && return ret
 
-    _tags redirection files || return 1
+    _tags -C redirection files || return 1
 
     if [[ "$words[1]" != (finger|ls) ]]; then
       _message "redirection not allowed for command \`$words[1]'"
@@ -88,10 +86,7 @@ if [[ -n "$compcontext" ]]; then
 
   case "$words[1]" in
   (|l)server)
-    _tags argument hosts || return 1
-
-    _description expl 'new default server'
-    _hosts "$expl[@]"
+    _wanted hosts expl 'new default server' && _hosts "$expl[@]"
     return
     ;;
   root|exit|help|\?)
@@ -112,8 +107,6 @@ if [[ -n "$compcontext" ]]; then
     return
     ;;
   view)
-    _tags argument files || return 1
-
     _description expl 'view file'
     _files "$expl[@]"
     return
@@ -126,10 +119,7 @@ if [[ -n "$compcontext" ]]; then
     [[ -z "$state" ]] && return ret
     ;;
   *)
-    _tags argument hosts || return 1
-
-    _description expl 'server'
-    _hosts "$expl[@]"
+    _wanted hosts expl 'server' && _hosts "$expl[@]"
     return
   esac
 fi
@@ -140,7 +130,7 @@ if [[ -z "$state" ]]; then
   local line
   typeset -A opt_args
 
-  _arguments \
+  _arguments -C \
     "-${(@)^${(@M)setopts:#*\]:*}/\[/=[}" \
     "-${(@)^setopts:#(\(|*\]:)*}" \
     "${(@)^${(@)${(@M)setopts:#\(*}/\)/)-}/\(/(-}" \
@@ -151,7 +141,7 @@ fi
 # This is completion after `srchlist' for both types.
 
 if [[ -n "$state" ]]; then
-  _tags "$context" hosts || return 1
+  _tags hosts || return 1
 
   if compset -P '*/'; then
     _description expl 'search list entry'
diff --git a/Completion/User/_pbm b/Completion/User/_pbm
index c697ebaa6..9eecd0390 100644
--- a/Completion/User/_pbm
+++ b/Completion/User/_pbm
@@ -254,8 +254,7 @@ pgmtoppm)
     fi
     _x_color && ret=0
   
-    _description expl option
-    compadd "$expl[@]" - -map && ret=0
+    _wanted options expl option && compadd "$expl[@]" - -map && ret=0
   
     return ret
   elif [[ CURRENT -eq 3 && "$words[2]" = -map ]]; then
@@ -591,12 +590,12 @@ ppmquant)
   fi
   
   if [[ CURRENT -eq 2 ]]; then
-    _description expl option
-    if [[ -n "$opt" ]]; then
-      compadd "$expl[@]" - -map -fs -floyd && ret=0
-    else
-      compadd "$expl[@]" - -map && ret=0
-    fi
+    _wanted options expl option &&
+        if [[ -n "$opt" ]]; then
+          compadd "$expl[@]" - -map -fs -floyd && ret=0
+        else
+          compadd "$expl[@]" - -map && ret=0
+        fi
     _message 'number of colors'
   
     return ret
diff --git a/Completion/User/_perl_basepods b/Completion/User/_perl_basepods
index 2dc0874f0..7f257aed3 100644
--- a/Completion/User/_perl_basepods
+++ b/Completion/User/_perl_basepods
@@ -15,18 +15,19 @@ if [[ ${+_perl_basepods} -eq 0 ]]; then
     _perl_basepods=( ${$(basepods):t:r} )
   else
     local podpath
+
     podpath=$(perl -MConfig -e 'print "$Config{installprivlib}/pod"')
+
     if [[ ! -e $podpath/perl.pod ]]; then
       echo "Couldn't find perl.pod from Config.pm; giving up."
       return 1
     else
-      cd $podpath
-      _perl_basepods=( *.pod(:r:t) )
-      cd $OLDPWD
+      _perl_basepods=( ${podpath}/*.pod(:r:t) )
     fi
   fi
 fi
 
 local expl
-_description expl "Perl base pods"
-compadd "$expl[@]" - $_perl_basepods
+
+_wanted pods expl 'Perl base pods' &&
+    compadd "$expl[@]" - $_perl_basepods
diff --git a/Completion/User/_perl_builtin_funcs b/Completion/User/_perl_builtin_funcs
index 804488db9..7ac69828d 100644
--- a/Completion/User/_perl_builtin_funcs
+++ b/Completion/User/_perl_builtin_funcs
@@ -27,5 +27,6 @@ if [[ ${+_perl_builtin_funcs} -eq 0 ]]; then
 fi
 
 local expl
-_description expl "Perl built-in functions"
-compadd "$expl[@]" - $_perl_builtin_funcs
+
+_wanted functions expl 'Perl built-in functions' &&
+    compadd "$expl[@]" - $_perl_builtin_funcs
diff --git a/Completion/User/_perl_modules b/Completion/User/_perl_modules
index ef5c00628..272ebb5e4 100644
--- a/Completion/User/_perl_modules
+++ b/Completion/User/_perl_modules
@@ -42,5 +42,5 @@ if [[ ${+_perl_modules} -eq 0 ]]; then
 fi
 
 local expl
-_description expl "Perl modules"
-compadd "$expl[@]" - $_perl_modules
+
+_wanted modules expl 'Perl modules' && compadd "$expl[@]" - $_perl_modules
diff --git a/Completion/User/_ports b/Completion/User/_ports
index 9012dfd5e..ffd04ce5e 100644
--- a/Completion/User/_ports
+++ b/Completion/User/_ports
@@ -2,9 +2,6 @@
 
 local expl
 
-_tags any ports || return 1
-
 : ${(A)ports:=${${(M)${${(f)"$(</etc/services)"}:#\#*}#*/tcp}%%[ 	]*}}
 
-_description expl port
-compadd "$@" "$expl[@]" - "$ports[@]"
+_wanted ports expl port && compadd "$@" "$expl[@]" - "$ports[@]"
diff --git a/Completion/User/_rcs b/Completion/User/_rcs
index 272e54681..0831b1d0b 100644
--- a/Completion/User/_rcs
+++ b/Completion/User/_rcs
@@ -8,6 +8,5 @@ if [[ $compstate[nmatches] -eq nm && -d RCS && $words[1] != ci ]]; then
   local rep expl
 
   rep=(RCS/$PREFIX*$SUFFIX,v(:t:s/\,v//))
-  _description expl 'RCS file'
-  (( $#rep )) && compadd "$expl[@]" - $rep
+  (( $#rep )) && _wanted files expl 'RCS file' && compadd "$expl[@]" - $rep
 fi
diff --git a/Completion/User/_rlogin b/Completion/User/_rlogin
index 898f10870..d732cf8a9 100644
--- a/Completion/User/_rlogin
+++ b/Completion/User/_rlogin
@@ -38,25 +38,21 @@ _rlogin () {
     return ret
     ;;
   rcp)
-    local state line ret=1
+    local curcontext="$curcontext" state line ret=1
     typeset -A opt_args
 
-    _arguments -s \
+    _arguments -C -s \
       '-p[preserve modification times]' \
       '-r[recursively copy directories]' \
       '*:files:->files' && ret=0
 
     if [[ -n "$state" ]]; then
       if compset -P '*:'; then
-        _tags "$context" files || return 1
-
 	_files && ret=0
       elif compset -P '*@'; then
-        _tags "$context" hosts || return 1
-
-	_rlogin_hosts -S: -q && ret=0
+        _tags hosts && _rlogin_hosts -S: -q && ret=0
       else
-        _alternative "$context" \
+        _alternative \
 	    'files:: _files' \
 	    'hosts:: _rlogin_all_hosts -qS:' \
 	    'users:: _rlogin_users -qS@' && ret=0
@@ -68,24 +64,21 @@ _rlogin () {
 }
 
 _rlogin_users () {
-  _tags any users && _combination accounts_users_hosts users "$@"
+  _tags users && _combination accounts_users_hosts users "$@"
 }
 
 _rlogin_hosts () {
-  _tags any hosts || return 1
-
-  if [[ "$IPREFIX" == *@ ]]; then
-    _combination accounts_users_hosts "users=${IPREFIX/@}" hosts "$@"
-  else
-    _combination accounts_users_hosts \
-      ${opt_args[-l]:+"users=${opt_args[-l]:q}"} hosts "$@"
-  fi
+  _tags hosts &&
+      if [[ "$IPREFIX" == *@ ]]; then
+        _combination accounts_users_hosts "users=${IPREFIX/@}" hosts "$@"
+      else
+        _combination accounts_users_hosts \
+            ${opt_args[-l]:+"users=${opt_args[-l]:q}"} hosts "$@"
+      fi
 }
 
 _rlogin_all_hosts () {
-  _tags any hosts || return 1
-
-  _combination accounts_users_hosts hosts "$@"
+  _tags hosts && _combination accounts_users_hosts hosts "$@"
 }
 
 _rlogin "$@"
diff --git a/Completion/User/_socket b/Completion/User/_socket
index ad9232af9..b155e7ad4 100644
--- a/Completion/User/_socket
+++ b/Completion/User/_socket
@@ -5,19 +5,14 @@
 #  socket_hosts_ports
 #    The array that contains paris `host:port'.
 
-local context state line expl
+local curcontext="$curcontext" state line expl
 typeset -A opt_args
 
-if _tags any options &&
-   [[ $CURRENT -eq 2 && (
-      -z "$compconfig[option_prefix]" ||
-      "$compconfig[option_prefix]" = *\!${words[1]}* ||
-      "$PREFIX" = -* ) ]]; then
-  _description expl option
-  compadd -M 'r:|[_-]=* r:|=*' "$expl[@]" - -version
-fi
+[[ $CURRENT -eq 2 ]] && _wanted options expl option &&
+    { ! _style options prefix-needed || [[ "$PREFIX" = -* ]] } &&
+    compadd -M 'r:|[_-]=* r:|=*' "$expl[@]" - -version
 
-_arguments -s \
+_arguments -C -s \
   '-b[background]' \
   '-c[crlf]' \
   '-f[fork]' \
@@ -43,24 +38,17 @@ command)
 
 arg1)
   if (( $+opt_args[-s] )); then
-    _tags "$context" ports || return 1
-
-    _description expl 'port to listen'
-    _ports "$expl[@]"
+    _wanted ports expl 'port to listen' && _ports "$expl[@]"
   else
-    _tags "$context" hosts || return 1
-
-    _description expl 'host'
-    _combination socket_hosts_ports hosts "$expl[@]"
+    _wanted hosts expl 'host' &&
+        _combination socket_hosts_ports hosts "$expl[@]"
   fi
   ;;
 
 arg2)
   if (( ! $+opt_args[-s] )); then
-    _tags "$context" ports || return 1
-
-    _description expl 'port to connect'
-    _combination socket_hosts_ports hosts="${line[2]:q}" ports "$expl[@]"
+    _wanted ports expl 'port to connect' &&
+        _combination socket_hosts_ports hosts="${line[2]:q}" ports "$expl[@]"
   fi
   ;;
 esac
diff --git a/Completion/User/_ssh b/Completion/User/_ssh
index 2c71b49a0..e7c6d37f6 100644
--- a/Completion/User/_ssh
+++ b/Completion/User/_ssh
@@ -1,7 +1,7 @@
 #compdef ssh slogin scp ssh-add ssh-agent ssh-keygen
 
 _ssh () {
-  local context state lstate line ret=1 expl args tmp
+  local curcontext="$curcontext" state lstate line ret=1 expl args tmp
   typeset -A opt_args
 
   local accounts_users_hosts
@@ -27,7 +27,7 @@ _ssh () {
     )
     ;&
   ssh-opt)
-    _arguments -s \
+    _arguments -C -s \
       '-a[disable forwarding of authentication agent connection]' \
       '-c[select encryption cipher]:encryption cipher:(idea des 3des blowfish arcfour tss none)' \
       '-e[set escape character]:escape character (or `none'"'"'):' \
@@ -58,31 +58,25 @@ _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)*)
-	    _tags "$context" values && compadd yes no && ret=0
+	    _wanted values expl 'truth value' && compadd "$expl[@]" yes no &&
+                ret=0
             ;;
           *(#i)cipher*)
-	    if _tags "$context" values; then
-              _description expl 'encryption cipher'
-              compadd "$expl[@]" idea des 3des blowfish arcfour tss none && ret=0
-	    fi
+	    _wanted values expl 'encryption cipher' &&
+                compadd "$expl[@]" idea des 3des blowfish arcfour tss none && \
+                    ret=0
             ;;
           *(#i)globalknownhostsfile*)
-	    if _tags "$context" files; then
-              _description expl 'global file with known hosts'
-              _files "$expl[@]" && ret=0
-	    fi
+            _description expl 'global file with known hosts'
+            _files "$expl[@]" && ret=0
             ;;
           *(#i)hostname*)
-	    if _tags "$context" hosts; then
-              _description expl 'real host name to log into'
-              _ssh_hosts "$expl[@]" && ret=0
-	    fi
+	    _wanted hosts expl 'real host name to log into' &&
+                _ssh_hosts "$expl[@]" && ret=0
             ;;
           *(#i)identityfile*)
-	    if _tags "$context" files; then
-              _description expl 'SSH identity file'
-              _files "$expl[@]" && ret=0
-	    fi
+            _description expl 'SSH identity file'
+            _files "$expl[@]" && ret=0
             ;;
           *(#i)(local|remote)forward*)
             state=forward
@@ -94,44 +88,36 @@ _ssh () {
             _normal && ret=0
             ;;
           *(#i)stricthostkeychecking*)
-            _tags "$context" values && compadd yes no ask
+            _wanted values expl 'checking type' &&
+	        compadd "$expl[@]" yes no ask
             ;;
           *(#i)userknownhostsfile*)
-	    if _tags "$context" files; then
-              _description expl 'user file with known hosts'
-              _files "$expl[@]" && ret=0
-	    fi
+            _description expl 'user file with known hosts'
+            _files "$expl[@]" && ret=0
             ;;
           *(#i)user*)
-	    if _tags "$context" files; then
-              _description expl 'user to log in as'
-              _ssh_users "$expl[@]" && ret=0
-	    fi
+	    _wanted users expl 'user to log in as' &&
+                _ssh_users "$expl[@]" && ret=0
             ;;
           *(#i)xauthlocation*)
-	    if _tags "$context" files; then
-              _description expl 'xauth program'
-              _files "$expl[@]" -g '*(*)' && ret=0
-	    fi
+            _description expl 'xauth program'
+            _files "$expl[@]" -g '*(*)' && ret=0
             ;;
           esac
         else
-          if _tags "$context" values; then
-            _description expl 'configure file option'
-            compadd "$expl[@]" -M 'm:{a-z}={A-Z}' -S '=' - \
-                BatchMode ClearAllForwardings Cipher Compression \
-                CompressionLevel Host ConnectionAttempts EscapeChar \
-                FallBackToRsh ForwardAgent ForwardX11 \
-                GlobalKnownHostsFile HostName IdentityFile KeepAlive \
-                KerberosAuthentication KerberosTgtPassing LocalForward \
-                NumberOfPasswordPrompts PasswordAuthentication Port \
-                ProxyCommand RemoteForward RhostsAuthentication \
-                RhostsRSAAuthentication RSAAuthentication \
-                StrictHostKeyChecking TISAuthentication \
-                UsePriviledgedPort User UserKnownHostsFile UseRsh \
-                XAuthLocation \
-              && ret=0
-	  fi
+          _wanted values expl 'configure file option' &&
+              compadd "$expl[@]" -M 'm:{a-z}={A-Z}' -S '=' - \
+                  BatchMode ClearAllForwardings Cipher Compression \
+                  CompressionLevel Host ConnectionAttempts EscapeChar \
+                  FallBackToRsh ForwardAgent ForwardX11 \
+                  GlobalKnownHostsFile HostName IdentityFile KeepAlive \
+                  KerberosAuthentication KerberosTgtPassing LocalForward \
+                  NumberOfPasswordPrompts PasswordAuthentication Port \
+                  ProxyCommand RemoteForward RhostsAuthentication \
+                  RhostsRSAAuthentication RSAAuthentication \
+                  StrictHostKeyChecking TISAuthentication \
+                  UsePriviledgedPort User UserKnownHostsFile UseRsh \
+                  XAuthLocation && ret=0
         fi
         ;;
       forward)
@@ -139,7 +125,7 @@ _ssh () {
           if compset -P '*:'; then
             _message 'port number'
           else
-	    _tags "$context" hosts && _ssh_hosts -S: -q
+	    _wanted hosts expl host && _ssh_hosts -qS: "$expl[@]"
           fi
         else
           _message 'listen-port number'
@@ -154,17 +140,15 @@ _ssh () {
         ;;
       userhost)
         if compset -P '*@'; then
-	  if _tags "$context" hosts; then
-            _description expl 'remote host name'
-            _ssh_hosts "$expl[@]" && ret=0
-	  fi
+	  _wanted hosts expl 'remote host name' &&
+              _ssh_hosts "$expl[@]" && ret=0
         else
           if (( $+opt_args[-l] )); then
 	    tmp=()
 	  else
 	    tmp=( 'users:login name:_ssh_users -qS@' )
 	  fi
-	  _alternative "$context" \
+	  _alternative \
 	      'hosts:remote host name:_ssh_hosts' \
 	      "$tmp[@]" && ret=0
         fi
@@ -177,7 +161,7 @@ _ssh () {
     return ret
     ;;
   scp)
-    _arguments -s \
+    _arguments -C -s \
       '-c[select encryption cipher]:encryption cipher:(idea des 3des blowfish arcfour tss none)' \
       '-P[specify port on remote host]:port number on remote host:' \
       '-i[select identity file]:SSH identity file:_files' \
@@ -198,14 +182,14 @@ _ssh () {
       return
     elif [[ -n "$state" ]]; then
       if compset -P '*:'; then
-        _tags "$context" files && _files && ret=0
+        _files && ret=0
       elif compset -P '*@'; then
-        _tags "$context" hosts && _ssh_hosts -S: && ret=0
+        _wanted hosts expl host && _ssh_hosts -S: "$expl[@]" && ret=0
       else
-        _alternative "$context" \
+        _alternative \
 	    'files:: _files' \
-	    'hosts:: _ssh_hosts -S:' \
-	    'users:: _ssh_users -S@' && ret=0
+	    'hosts:host:_ssh_hosts -S:' \
+	    'users:user:_ssh_users -S@' && ret=0
       fi
     fi
     return ret
@@ -243,12 +227,10 @@ _ssh () {
 }
 
 _ssh_users () {
-  _tags any users && _combination accounts_users_hosts users "$@"
+  _combination accounts_users_hosts users "$@"
 }
 
 _ssh_hosts () {
-  _tags any hosts || return 1
-
   if [[ "$IPREFIX" == *@ ]]; then
     _combination accounts_users_hosts "users=${IPREFIX/@}" hosts "$@"
   else
diff --git a/Completion/User/_stty b/Completion/User/_stty
index 45408fbc1..06d0bf851 100644
--- a/Completion/User/_stty
+++ b/Completion/User/_stty
@@ -3,18 +3,19 @@
 local expl
 
 if [[ "$words[CURRENT-1]" = \
-  (*erase|discard|status|dsusp|intr|kill|lnext|quit|reprint|start|s*p) ]]
-then
-  _description expl 'control character'
-  compadd "$expl[@]" '^-' '^h' '^?' '^c' '^u'
+  (*erase|discard|status|dsusp|intr|kill|lnext|quit|reprint|start|s*p) ]]; then
+  _wanted characters expl 'control character' &&
+      compadd "$expl[@]" '^-' '^h' '^?' '^c' '^u'
 else
-  _description expl setting
   compset -P '[-+]'
-  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 "$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 
 fi
diff --git a/Completion/User/_tar b/Completion/User/_tar
index d779f6cf1..defaaf39a 100644
--- a/Completion/User/_tar
+++ b/Completion/User/_tar
@@ -37,10 +37,10 @@ if [[ "$words[2]" = *[txcdruA]*~-* ]]; then
 elif [[ $_tar_cmd != *[txcdruA]* && CURRENT -gt 2 ]]; then
   # look for more obscure long options: these aren't all handled.
   (( $words[(I)--(diff|compare)] )) && _tar_cmd="d$_tar_cmd"
-  (( $words[(I)--append] )) && _tar_cmd="r$_tar_cmd"
-  (( $words[(I)--update] )) && _tar_cmd="u$_tar_cmd"
+  (( $words[(I)--append] ))         && _tar_cmd="r$_tar_cmd"
+  (( $words[(I)--update] ))         && _tar_cmd="u$_tar_cmd"
   (( $words[(I)--(con|)catenate] )) && _tar_cmd="A$_tar_cmd"
-  (( $words[(I)--delete] )) && del=1
+  (( $words[(I)--delete] ))         && del=1
 fi
 
 # Next, we try to find the archive name and store it in `tf'. The name 
@@ -107,8 +107,8 @@ elif [[ ( "$_tar_cmd" = *[xt]* || -n $del ) && -n "$tf" ]]; then
     _tar_cache_name=$tf
   fi
 
-  _description expl 'file from archive'
-  _multi_parts "$expl[@]" / _tar_cache_list
+  _wanted archived-files expl 'file from archive' &&
+      _multi_parts "$expl[@]" / _tar_cache_list
 else
   
   # See if we should use a path prefix.  We have to use eval as the dir can
diff --git a/Completion/User/_telnet b/Completion/User/_telnet
index 8e584b040..597c0a021 100644
--- a/Completion/User/_telnet
+++ b/Completion/User/_telnet
@@ -5,7 +5,7 @@
 #  telnet_hosts_ports_users
 #    The array that contains 3-tuples `host:port:user'.
 
-local context state line expl
+local curcontext="$curcontext" state line expl
 typeset -A opt_args
 
 if (( ! $+_telnet_short )); then
@@ -52,44 +52,36 @@ if (( ! $+_telnet_short )); then
   done
 fi
 
-if _tags any options && (( $#_telnet_long )) &&
-   { ! _style options prefix-needed yes || [[ "$PREFIX" = [-+]* ]] } ; then
-  _description expl 'option'
-  _describe -o option _telnet_long "$expl[@]"
-fi
+(( $#_telnet_long )) && _wanted options expl option &&
+   { ! _style options prefix-needed || [[ "$PREFIX" = [-+]* ]] } &&
+    _describe -o option _telnet_long "$expl[@]"
 
-_arguments -s \
+_arguments -C -s \
   "$_telnet_short[@]" \
   ':host:->hosts' \
   ':port:->ports'
 
 case "$state" in
 hosts)
-  _tags "$context" hosts || return 1
-
-  _description expl 'host'
-  _combination telnet_hosts_ports_users \
-    ${opt_args[-l]:+users=${opt_args[-l]:q}} \
-    hosts "$expl[@]"
+  _wanted hosts expl host &&
+      _combination telnet_hosts_ports_users \
+          ${opt_args[-l]:+users=${opt_args[-l]:q}} \
+          hosts "$expl[@]"
   ;;
 
 ports)
-  _tags "$context" ports || return 1
-
-  _description expl 'port'
-  _combination telnet_hosts_ports_users \
-    ${opt_args[-l]:+users=${opt_args[-l]:q}} \
-    hosts="${line[2]:q}" \
-    ports "$expl[@]"
+  _wanted ports expl port &&
+      _combination telnet_hosts_ports_users \
+          ${opt_args[-l]:+users=${opt_args[-l]:q}} \
+          hosts="${line[2]:q}" \
+          ports "$expl[@]"
   ;;
 
 users)
-  _tags "$context" users || return 1
-
-  _description expl 'user'
-  _combination telnet_hosts_ports_users \
-    ${line[2]:+hosts="${line[2]:q}"} \
-    ${line[3]:+ports="${line[3]:q}"} \
-    users "$expl[@]"
+  _wanted users expl user &&
+      _combination telnet_hosts_ports_users \
+      ${line[2]:+hosts="${line[2]:q}"} \
+      ${line[3]:+ports="${line[3]:q}"} \
+      users "$expl[@]"
   ;;
 esac
diff --git a/Completion/User/_tiff b/Completion/User/_tiff
index e3a023c24..27ab33227 100644
--- a/Completion/User/_tiff
+++ b/Completion/User/_tiff
@@ -19,12 +19,12 @@ fi
 
 local _in_tiff=yes
 
-local context state line ret=1
+local curcontext="$curcontext" state line ret=1
 typeset -A opt_args
 
 case "$words[1]" in
 tiff2bw)
-  _arguments \
+  _arguments -C \
     '-c[specify compression scheme]:compression scheme:->compress' \
     '-r[specify rows per strip]:rows per strip:' \
     '-R[specify percentage of red channel]:percentage of red channel:' \
@@ -59,7 +59,7 @@ tiffcmp)
     ':second input TIFF file:_files -g \*.\(\#i\)' && ret=0
   ;;
 tiffcp)
-  _arguments \
+  _arguments -C \
     '-B[write output in bin-endian byte order]' \
     '-c[specify compression scheme]:compression scheme:->compress' \
     '-o[set initial TIFF directory (file offset)]:file offset:' \
@@ -74,7 +74,7 @@ tiffcp)
     '*:input TIFF file:_files -g \*.\(\#i\)' && ret=0
   ;;
 tiffdither)
-  _arguments \
+  _arguments -C \
     '-c[specify compression scheme]:compression scheme:->compress' \
     '-f[specify fill order]:fill order:(lsb2msb msb2lsb)' \
     '-r[specify rows per strip]:rows per strip:' \
@@ -102,7 +102,7 @@ tiffinfo)
     '*:input TIFF file:_files -g \*.\(\#i\)' && ret=0
   ;;
 tiffmedian)
-  _arguments \
+  _arguments -C \
     '-r[specify rows per strip]:rows per strip:' \
     '-C[specify number of colormap entries]:number of colormap entries:' \
     '-c[specify compression scheme]:compression scheme:->compress' \
@@ -135,14 +135,14 @@ fax2tiff)
     ':FAX input file:_files -g \*.\(\#i\)\(g\[34\]\|fax\)' && ret=0
   ;;
 gif2tiff)
-  _arguments \
+  _arguments -C \
     '-r[specify rows per strip]:rows per strip:' \
     '-c[specify compression scheme]:compression scheme:->compress' \
     ':input GIF file:_files -g \*.\(\#i\)gif' \
     ':output file:_files -g \*.\(\#i\)tiff' && ret=0
   ;;
 ppm2tiff)
-  _arguments \
+  _arguments -C \
     '-r[specify rows per strip]:rows per strip:' \
     '-c[specify compression scheme]:compression scheme:->compress' \
     '-R[specify resolution]:resolution:' \
@@ -150,14 +150,14 @@ ppm2tiff)
     ':output file:_files -g \*.\(\#i\)tiff' && ret=0
   ;;
 ras2tiff)
-  _arguments \
+  _arguments -C \
     '-r[specify rows per strip]:rows per strip:' \
     '-c[specify compression scheme]:compression scheme:->compress' \
     ':input raster image file:_files -g \*.\(\#i\)ras\(\|t\)' \
     ':output file:_files -g \*.\(\#i\)tiff' && ret=0
   ;;
 pal2rgb)
-  _arguments \
+  _arguments -C \
     '-C[specify number of bits for colormap entries]:bits for colormap entries:(8 16)' \
     '-p[set sample packing]:sample packing:(contig separate)' \
     '-c[specify compression scheme]:compression scheme:->compress' \
@@ -194,11 +194,10 @@ if [[ -n "$state" ]]; then
       ;;
     esac
   else
-    _tags "$context" values || return 1
-
-    _description expl 'compression scheme'
-    compadd "$expl[@]" - none g4 packbits && ret=0
-    compadd "$expl[@]" -qS: - lzw zip jpeg g3 && ret=0
+    if _wanted values expl 'compression scheme'; then
+      compadd "$expl[@]" - none g4 packbits && ret=0
+      compadd "$expl[@]" -qS: - lzw zip jpeg g3 && ret=0
+    fi
   fi
 fi
 
diff --git a/Completion/User/_urls b/Completion/User/_urls
index 8c0c6f8d8..787f3c0ca 100644
--- a/Completion/User/_urls
+++ b/Completion/User/_urls
@@ -4,9 +4,9 @@
 # Options:
 #  -f : complete files first.
 #
-# Configuration keys used:
+# Configuration styles used:
 #
-#  urls_path
+#  urls:path
 #    The path to a directory containing a URL database, such as:
 #
 #      % cd ~/.zsh/urls
@@ -29,90 +29,91 @@
 #      % cat bookmark/zsh/meta
 #      http://www.zsh.org/
 #
-#  urls_localhttp
-#    Specify a local web server in the form:
-#      hostname:doc root:user area
+#  urls:local
+#    Specify a local web server as an array with three elements:
+#      <hostname> <doc root> <user area>
 #    where hostname is the name of the web server, doc root is the path to
 #    the default web pages for the server and user area is the directory
 #    name used by a user placing web pages within their home area.
-#    e.g. compconf urls_localhttp=www:/usr/local/apache/htdocs:public_html
+#    E.g.:
+#      compstyle '*:urls:local' www /usr/local/apache/htdocs public_html
 
 local ipre scheme host user uhosts ret=1 expl
-local urls_path="${compconfig[urls_path]:-${ZDOTDIR:-$HOME}/.zsh/urls}"
-local localhttp_servername="${${(@s.:.)compconfig[urls_localhttp]}[1]}"
-local localhttp_documentroot="${${(@s.:.)compconfig[urls_localhttp]}[2]}"
-local localhttp_userdir="${${(@s.:.)compconfig[urls_localhttp]}[3]}"
+local urls_path localhttp
+_style -s urls path urls_path || urls_path="${ZDOTDIR:-$HOME}/.zsh/urls"
+_style -a urls local localhttp
+local localhttp_servername="$localhttp[1]"
+local localhttp_documentroot="$localhttp[2]"
+local localhttp_userdir="$localhttp[3]"
 
 if [[ "$1" = -f ]]; then
   shift
-  _tags argument:-f files && _files "$@" && return
+  _tags -C -f files && _files "$@" && return
 fi
 
 ipre="$IPREFIX"
 
 if ! compset -P '(#b)([-+.a-z0-9]#):' &&
-   _tags argument prefixes; then
-  _description expl 'URL prefix'
+   _wanted 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
-  return $ret
+  return ret
 fi
 scheme="$match[1]"
 
 case "$scheme" in
   http|ftp|gopher)
     if ! compset -P //; then
-      _tags "$scheme" slashes && compadd "$@" -S '' //
+      _wanted -C "$scheme" slashes expl 'end of prefix' &&
+          compadd "$expl[@]" "$@" -S '' //
       return
     fi
   ;;
   file)
     if ! compset -P //; then
-      _tags file files || return 1
+      _wanted -C file files expl 'local file' || return 1
 
       if [[ -prefix / ]]; then
-	_path_files "$@" -S '' -g '*(^/)' && ret=0
-	_path_files "$@" -S/ -r '/' -/ && ret=0
+	_path_files "$expl[@]" "$@" -S '' -g '*(^/)' && ret=0
+	_path_files "$expl[@]" "$@" -S/ -r '/' -/ && ret=0
       elif [[ -z "$PREFIX" ]]; then
-	compadd -S '/' -r '/' - "${PWD%/}"
-	ret=0
+	compadd "$expl[@]" -S '/' -r '/' - "${PWD%/}" && ret=0
       fi
-      return $ret
+      return ret
     fi
   ;;
   bookmark)
     if [[ -f "$urls_path/$scheme/$PREFIX$SUFFIX" &&
 	  -s "$urls_path/$scheme/$PREFIX$SUFFIX" ]]; then
-      _tags bookmark caches || return 1
-
-      compadd "$@" -QU -- "$ipre$(<"$urls_path/$scheme/$PREFIX$SUFFIX")" && ret=0
+      _wanted -C bookmark caches expl biikmarks &&
+          compadd "$expl[@]" "$@" -QU - \
+              "$ipre$(<"$urls_path/$scheme/$PREFIX$SUFFIX")" && ret=0
     else
-      _tags bookmark files || return 1
-
-      _description expl 'bookmark'
-      _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 'bookmark'; then
+        _path_files -W "$urls_path/$scheme" "$expl[@]" -S '' -g '*(^/)' && 
+            ret=0
+        _path_files -W "$urls_path/$scheme" -S/ -r '/' -/ && ret=0
+      fi
     fi
-    return $ret
+    return ret
   ;;
 esac
 
 # Complete hosts
 if ! compset -P '(#b)([^/]#)/' &&
-   _tags argument hosts; then
+   _wanted hosts expl host; then
   uhosts=($urls_path/$scheme/$PREFIX*$SUFFIX(/:t))
   (( $#uhosts )) || _hosts -S/ && ret=0
   [[ "$scheme" = http ]] && uhosts=($uhosts $localhttp_servername)
-  _description expl host
   compadd "$expl[@]" "$@" -QS/ - $uhosts && ret=0
-  return $ret
+  return ret
 fi
 host="$match[1]"
 
 # Complete part after hostname
 
-_tags local files || return 1
+_wanted -C local files expl 'local file' || return 1
 
 if [[ "$localhttp_servername" = "$host" ]]; then
   if compset -P \~; then
@@ -121,14 +122,14 @@ if [[ "$localhttp_servername" = "$host" ]]; then
       return
     fi
     user="$match[1]"
-    _path_files -W ~$user/$localhttp_userdir -g '*(^/)' && ret=0
-    _path_files -W ~$user/$localhttp_userdir -S/ -r '/' -/ && ret=0
+    _path_files "$expl[@]" -W ~$user/$localhttp_userdir -g '*(^/)' && ret=0
+    _path_files "$expl[@]" -W ~$user/$localhttp_userdir -S/ -r '/' -/ && ret=0
   else
-    _path_files -W $localhttp_documentroot -g '*(^/)' && ret=0
-    _path_files -W $localhttp_documentroot -S/ -r '/' -/ && ret=0
+    _path_files "$expl[@]" -W $localhttp_documentroot -g '*(^/)' && ret=0
+    _path_files "$expl[@]" -W $localhttp_documentroot -S/ -r '/' -/ && ret=0
   fi
 else
-  _path_files -W $urls_path/$scheme/$host -g '*(^/)' && ret=0
-  _path_files -W $urls_path/$scheme/$host -S/ -r '/' -/ && ret=0
+  _path_files "$expl[@]" -W $urls_path/$scheme/$host -g '*(^/)' && ret=0
+  _path_files "$expl[@]" -W $urls_path/$scheme/$host -S/ -r '/' -/ && ret=0
 fi
 return $ret
diff --git a/Completion/User/_use_lo b/Completion/User/_use_lo
index 56651dd67..5f2210997 100644
--- a/Completion/User/_use_lo
+++ b/Completion/User/_use_lo
@@ -3,6 +3,4 @@
 # This is for GNU-like commands which understand the --help option,
 # but which do not otherwise require special completion handling.
 
-[[ "$PREFIX" = --* ]] && _arguments -- && return 0
-
-_default
+_arguments || _default
diff --git a/Completion/User/_user_at_host b/Completion/User/_user_at_host
index c33a024d9..1f93daacc 100644
--- a/Completion/User/_user_at_host
+++ b/Completion/User/_user_at_host
@@ -1,17 +1,13 @@
 #autoload
 
 if [[ -prefix 1 *@ ]]; then
-
-  _tags any:user-at hosts || return 1
-
   local user=${PREFIX/@}
 
   compset -P 1 '*@'
-  _description expl "hostnames for $user"
-  _combination accounts_users_hosts users="$user" hosts "$expl[@]" "$@"
-else
-  _tags any users || return 1
 
-  _description expl "usernames"
-  _combination accounts_users_hosts users -S@ -q "$expl[@]" "$@"
+  _wanted -C user-at hosts expl "hostnames for $user" &&
+      _combination accounts_users_hosts users="$user" hosts "$expl[@]" "$@"
+else
+  _wanted users expl "usernames" &&
+      _combination accounts_users_hosts users -S@ -q "$expl[@]" "$@"
 fi
diff --git a/Completion/User/_users b/Completion/User/_users
index 9f2751c11..fdef36073 100644
--- a/Completion/User/_users
+++ b/Completion/User/_users
@@ -5,9 +5,7 @@
 
 local expl
 
-_tags any users || return 1
-
-_description expl user
+_wanted users expl user || return 1
 
 [[ "${(t)users}" = *array* ]] &&
     compadd "$expl[@]" "$@" - "$users[@]" && return 0
diff --git a/Completion/User/_users_on b/Completion/User/_users_on
index 221ebb0fd..3d35af02b 100644
--- a/Completion/User/_users_on
+++ b/Completion/User/_users_on
@@ -2,7 +2,7 @@
 
 local expl
 
-_tags any users || return 1
+_tags users || return 1
 
 if which users >/dev/null; then
   _description expl 'users logged on'
diff --git a/Completion/User/_wget b/Completion/User/_wget
index 3a15d3867..8e73bd45d 100644
--- a/Completion/User/_wget
+++ b/Completion/User/_wget
@@ -1,11 +1,11 @@
 #compdef wget
 
-local context state line
+local curcontext="$curcontext" state line
 typeset -A opt_args
 
 local tmp1 tmp2
 
-_arguments -s \
+_arguments -C -s \
   '(--version)-V[version]' '(-V)--version' \
   '(--help)-h[help]' '(-h)--help' \
   '(--background)-b[background]' '(-b)--background' \
diff --git a/Completion/User/_whois b/Completion/User/_whois
index 1e0f7707c..97306871e 100644
--- a/Completion/User/_whois
+++ b/Completion/User/_whois
@@ -102,7 +102,7 @@ _whois_setup () {
       if (( $#opts )); then opts="($opts)"; else opts=; fi
       if [[ $opt = h ]]; then
 	_whois_arguments=("$_whois_arguments[@]"
-	  "${opts}${hostopt}[specify host]:host:_whois_hosts")
+	  "${opts}${hostopt}:host:_whois_hosts")
       else
 	_whois_arguments=("$_whois_arguments[@]"
 	  "${opts}-${opt}[${${(@M)_whois_servers:#*:$opt}%:?}]")
@@ -112,11 +112,11 @@ _whois_setup () {
 }
 
 _whois_single () {
-  local context state line expl
+  local curcontext="$curcontext" state line expl
   typeset -A opt_args
   local tmp host
 
-  _arguments \
+  _arguments -C \
     "$_whois_arguments[@]" \
     ':identifier:->identifier'
 
@@ -144,11 +144,11 @@ _whois_single () {
 }
 
 _whois_multi () {
-  local state line expl
+  local curcontext="$curcontext" state line expl
   typeset -A opt_args
   local tmp host
 
-  _arguments \
+  _arguments -C \
     "$_whois_arguments[@]" \
     '*::identifier:->identifier'
 
@@ -189,14 +189,14 @@ _whois_fwhois () {
 }
 
 _whois_hosts () {
-  _tags any hosts &&
+  _tags hosts &&
     compadd "$@" \
       -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' \
       - ${_whois_servers%:?} || _hosts "$@"
 }
 
 _whois_ports () {
-  _tags any ports && compadd "$@" - whois || _ports "$@"
+  _tags ports && compadd "$@" - whois || _ports "$@"
 }
 
 (( $+functions[_whois:whois.internic.net] )) ||
@@ -204,10 +204,7 @@ _whois:whois.internic.net () {
   if (( CURRENT == 1 )); then
     local expl
 
-    _tags any string || return 1
-
-    _description expl string
-    compadd "$expl[@]" HELP DOMAIN HOST
+    _wanted string expl string && compadd "$expl[@]" HELP DOMAIN HOST
   else
     _message 'string'
   fi
@@ -218,10 +215,7 @@ _whois:whois.nic.ad.jp () {
   if (( CURRENT == 1 )); then
     local expl
 
-    _tags any string || return 1
-
-    _description expl string
-    compadd HELP DOM NET HOST PERSON CONN COM
+    _wanted string 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 d0876f6dd..1e86bf278 100644
--- a/Completion/User/_yp
+++ b/Completion/User/_yp
@@ -1,6 +1,6 @@
 #compdef ypcat ypmatch yppasswd ypwhich ypset ypserv ypbind yppush yppoll ypxfr domainname
 
-local context line state ret=1
+local curcontext="$curcontext" line state ret=1
 typeset -A opt_args
 
 if (( ! $+_yp_cache_maps )); then
@@ -16,17 +16,17 @@ fi
 
 case "$words[1]" in
 ypcat)
-  _arguments -s "$_yp_args[@]" ':map name:->map' && ret=0
+  _arguments -C -s "$_yp_args[@]" ':map name:->map' && ret=0
   ;;
 ypmatch)
-  _arguments -s "$_yp_args[@]" '*::key map:->keymap' && ret=0
+  _arguments -C -s "$_yp_args[@]" '*::key map:->keymap' && ret=0
   ;;
 yppasswd)
   _users
   return
   ;;
 ypwhich)
-  _arguments \
+  _arguments -C \
     '(-x)-d[specify domain]:domain name:' \
     '(-x -V2 -m -t)-V1[identify version 1 servers]' \
     '(-x -V1 -m -t)-V2[identify version 2 servers]' \
@@ -36,7 +36,7 @@ ypwhich)
     ':host:_hosts' && ret=0
   ;;
 ypset)
-  _arguments \
+  _arguments -C \
     '(-V2)-V1[bind version 1 servers]' \
     '(-V1)-V2[bind version 2 servers]' \
     '-d[specify domain]:domain name:' \
@@ -44,30 +44,30 @@ ypset)
     ':server:_hosts' && ret=0
     ;;
 ypserv)
-  _arguments \
+  _arguments -C \
     '-a[specify database routines]:database routines:((b\:btree d\:dbm/ndbm h\:hash))' && ret=0
   ;;
 ypbind)
-  _arguments \
+  _arguments -C \
     '-s[allow secure mode for ypbind]' \
     '-S[set domain and servers]:domain:->servers' \
     '(-ypsetme)-ypset[accept all ypset requests]' \
     '(-ypset)-ypsetme[accept only local ypset requests]' && ret=0
   ;;
 yppush)
-  _arguments \
+  _arguments -C \
     '-d[specify domain]:domain name:' \
     '-v[print messages]' \
     ':map name:->map' && ret=0
   ;;
 yppoll)
-  _arguments \
+  _arguments -C \
     '-d[specify domain]:domain name:' \
     '-h[specify host]:ask server on host:_hosts' \
     ':map name:->map' && ret=0
   ;;
 ypxfr)
-  _arguments \
+  _arguments -C \
     '-a[specify database routines]:database routines:((b\:btree d\:dbm/ndbm h\:hash))' \
     '-f[force transfer]' \
     '-c[don'"'"'t clear current map]' \
@@ -88,30 +88,22 @@ if [[ "$state" = map* ]]; then
   local expl
 
   if [[ $+opt_args[-t] -eq 0 && "$state" != maponly ]]; then
-    _tags "$context" maps nicknames
+    _tags maps nicknames
   else
-    _tags "$context" maps
+    _tags maps
   fi
 
   while _tags; do
-    if _requested maps; then
-      # The `-M ...' allows `pa.n<TAB>' to complete to `passwd.byname'.
-
-      _description expl 'map name'
-      compadd "$expl[@]" -M 'l:.|by=by l:.|=by r:|.=* r:|=*' - \
-              "$_yp_cache_maps[@]" && ret=0
-    fi
-    if _requested nicknames; then
-      _description expl 'nicknames'
-      compadd "$expl[@]" - "$_yp_cache_nicks[@]" && ret=0
-    fi
+    # 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:|=*' - \
+                "$_yp_cache_maps[@]" && ret=0
+    _requested nicknames expl nicknames &&
+        compadd "$expl[@]" - "$_yp_cache_nicks[@]" && ret=0
   done
 elif [[ "$state" = servers ]]; then
   if compset -P '*,'; then
-    if _tags "$context" hosts; then
-      _description expl 'server'
-      _hosts -qS, && ret=0
-    fi
+    _wanted hosts expl server && _hosts -qS, && ret=0
   else
     _message 'domain name'
   fi
diff --git a/Completion/X/_x_arguments b/Completion/X/_x_arguments
index 396a39ea2..b820b50b0 100644
--- a/Completion/X/_x_arguments
+++ b/Completion/X/_x_arguments
@@ -1,11 +1,20 @@
 #compdef -P */X11/*
 
-local ret
+local ret long xargs
 
-_arguments \
-  '-display:display:_x_display' \
-  '-geometry:geometry:_x_geometry' \
-  "$@"
+xargs=(
+  '-display:display:_x_display'
+  '-geometry:geometry:_x_geometry'
+)
+
+long=$argv[(I)--]
+if (( long )); then
+  argv[long]=( "$xargs[@]" -- )
+else
+  set -- "$@" "$xargs[@]"
+fi
+
+_arguments "$@"
 
 ret=$?
 
diff --git a/Completion/X/_x_color b/Completion/X/_x_color
index 4c1c73bf4..2daeb51d6 100644
--- a/Completion/X/_x_color
+++ b/Completion/X/_x_color
@@ -15,8 +15,9 @@ if (( ! $+_color_cache )); then
 
   # Cache of color names doesn't exist yet, create it.
 
-  if [[ -n "$compconfig[colors_path]" ]]; then
-    _color_cache=( "${(@)${(@f)$(< $compconfig[colors_path])}[2,-1]##*		}" )
+  _style -s colors path file
+  if [[ -n "$file" ]]; then
+    _color_cache=( "${(@)${(@f)$(< $file)}[2,-1]##*		}" )
   else
     file=( /usr/{lib,{{X11R6,openwin},local{,/X11{,R6}}}/lib}/X11/rgb.txt(N) )
 
@@ -29,8 +30,6 @@ if (( ! $+_color_cache )); then
   (( $#_color_cache )) || _color_cache=(white black gray red blue green)
 fi
 
-_tags any colors || return 1
-
-_description expl 'color specification'
-compadd "$@" "$expl[@]" -M 'm:{a-z}={A-Z} m:-=\  r:|[ A-Z0-9]=* r:|=*' - \
-        "$_color_cache[@]"
+_wanted colors expl 'color specification' &&
+    compadd "$@" "$expl[@]" -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 a22189f9d..8b057a537 100644
--- a/Completion/X/_x_cursor
+++ b/Completion/X/_x_cursor
@@ -14,7 +14,5 @@ if (( ! $+_cursor_cache )); then
   fi
 fi
 
-_tags any cursors || return 1
-
-_description expl 'cursor name'
-compadd "$@" "$expl[@]" -M 'm:-=_ r:|_=*' - "$_cursor_cache[@]"
+_wanted cursors expl 'cursor name' &&
+    compadd "$@" "$expl[@]" -M 'm:-=_ r:|_=*' - "$_cursor_cache[@]"
diff --git a/Completion/X/_x_display b/Completion/X/_x_display
index 7b9fbab9a..f547a64fa 100644
--- a/Completion/X/_x_display
+++ b/Completion/X/_x_display
@@ -1,5 +1,3 @@
 #autoload
 
-_tags any displays || return 1
-
-_hosts -S ':0 ' -r :
+_tags displays && _hosts -S ':0 ' -r :
diff --git a/Completion/X/_x_extension b/Completion/X/_x_extension
index 44e47d956..9321f4951 100644
--- a/Completion/X/_x_extension
+++ b/Completion/X/_x_extension
@@ -2,12 +2,10 @@
 
 local expl
 
-_tags any extensions || return 1
+_wanted extensions expl 'X extensions' || return 1
 
 (( $+_xe_cache )) || _xe_cache=( "${(@)${(@f)$(xdpyinfo)}[(r)number of extensions:*,-1][2,(r)default screen number:*][1,-2]//[      ]}" )
 
-_description expl 'X extension'
-
 if [[ "$1" = -a ]]; then
   shift
 
diff --git a/Completion/X/_x_font b/Completion/X/_x_font
index f4dfef79c..59c628d6d 100644
--- a/Completion/X/_x_font
+++ b/Completion/X/_x_font
@@ -2,7 +2,7 @@
 
 local expl
 
-_tags any fonts || return 1
+_wanted fonts expl font || return 1
 
 # This *has* to be improved some day...
 
@@ -12,5 +12,4 @@ if (( ! $+_font_cache )); then
  _font_cache=( "${(@)^${(@f)$(xlsfonts)}%%--*}--" )
 fi
 
-_description expl font
 compadd -M 'r:|-=* r:|=*' "$expl[@]" "$@" -S '' - "$_font_cache[@]"
diff --git a/Completion/X/_x_keysym b/Completion/X/_x_keysym
index fc2847c57..2e8f037b1 100644
--- a/Completion/X/_x_keysym
+++ b/Completion/X/_x_keysym
@@ -2,7 +2,7 @@
 
 local expl
 
-_tags any keysyms || return 1
+_wanted keysyms expl 'key symbol' || return 1
 
 if (( ! $+_keysym_cache )); then
   local file
@@ -18,5 +18,4 @@ if (( ! $+_keysym_cache )); then
   fi
 fi
 
-_description expl 'key symbol'
 compadd "$@" "$expl[@]" -M 'm:{a-z}={A-Z} r:|-=* r:|=*' - $_keysym_cache
diff --git a/Completion/X/_x_modifier b/Completion/X/_x_modifier
index 345243835..01052da65 100644
--- a/Completion/X/_x_modifier
+++ b/Completion/X/_x_modifier
@@ -2,8 +2,6 @@
 
 local expl
 
-_tags any modifiers || return 1
-
-_description expl modifier
-compadd "$@" "$expl[@]" -M 'm:{a-z}={A-Z}' - \
-        Shift Lock Control Mod1 Mod2 Mod3 Mod4 Mod5
+_wanted modifiers expl modifier &&
+    compadd "$@" "$expl[@]" -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 6d6e3112e..bf0ad4d33 100644
--- a/Completion/X/_x_window
+++ b/Completion/X/_x_window
@@ -2,7 +2,7 @@
 
 local list expl
 
-_tags any windows || return 1
+_tags windows || return 1
 
 list=( "${(@)${(M@)${(@f)$(xwininfo -root -tree)}:#[ 	]#0x[0-9a-f]# \"*}##[ 	]#}" )
 
diff --git a/Completion/X/_xmodmap b/Completion/X/_xmodmap
index d8ba420ce..e1594b949 100644
--- a/Completion/X/_xmodmap
+++ b/Completion/X/_xmodmap
@@ -1,9 +1,9 @@
 #compdef xmodmap
 
-local context state line ret=1
+local curcontext="$curcontext" state line ret=1
 typeset -A opt_args
 
-_x_arguments \
+_x_arguments -C \
   -{help,grammar,verbose,quiet} \
   '-n[only show what would be done]' \
   '*-e[specify expression]:expression:->expr' \
@@ -82,8 +82,7 @@ if [[ -n "$state" ]]; then
     [[ "$what" = *ksym* ]] && _x_keysym "$suf[@]" && ret=0
 
   else
-    if _tags any commands; then
-      _description expl command
+    if _wanted commands expl command; then
       compadd "$expl[@]" -S ' ' keycode keysym clear add remove && ret=0
       compadd "$expl[@]" -S ' = ' pointer && ret=0
     fi
diff --git a/Completion/X/_xt_arguments b/Completion/X/_xt_arguments
index 2604cfa83..4b40500f3 100644
--- a/Completion/X/_xt_arguments
+++ b/Completion/X/_xt_arguments
@@ -20,30 +20,39 @@
 
 # cf. XrmParseCommand(3X11), X11R6.4/xc/lib/Xt/Initialize.c, X(5)
 
-local ret
-
-_arguments \
-  -+{rv,synchronous} \
-  -{reverse,iconic} \
-  '-background:background color:_x_color' \
-  '-bd:border color:_x_color' \
-  '-bg:background color:_x_color' \
-  '-bordercolor:border color:_x_color' \
-  '-borderwidth:border width:_x_borderwidth' \
-  '-bw:border width:_x_borderwidth' \
-  '-display:display:_x_display' \
-  '-fg:foreground color:_x_color' \
-  '-font:font:_x_font' \
-  '-fn:font:_x_font' \
-  '-foreground:foreground color:_x_color' \
-  '-geometry:geometry:_x_geometry' \
-  '-name:name:_x_name' \
-  '-selectionTimeout:selection timeout (milliseconds):_x_selection_timeout' \
-  '-title:title:_x_title' \
-  '-xnllanguage:locale:_x_locale' \
-  '-xrm:resource:_x_resource' \
-  '-xtsessionID:session ID:_xt_session_id' \
-  "$@"
+local ret long xargs
+
+xargs=(
+  -+{rv,synchronous}
+  -{reverse,iconic}
+  '-background:background color:_x_color'
+  '-bd:border color:_x_color'
+  '-bg:background color:_x_color'
+  '-bordercolor:border color:_x_color'
+  '-borderwidth:border width:_x_borderwidth'
+  '-bw:border width:_x_borderwidth'
+  '-display:display:_x_display'
+  '-fg:foreground color:_x_color'
+  '-font:font:_x_font'
+  '-fn:font:_x_font'
+  '-foreground:foreground color:_x_color'
+  '-geometry:geometry:_x_geometry'
+  '-name:name:_x_name'
+  '-selectionTimeout:selection timeout (milliseconds):_x_selection_timeout'
+  '-title:title:_x_title'
+  '-xnllanguage:locale:_x_locale'
+  '-xrm:resource:_x_resource'
+  '-xtsessionID:session ID:_xt_session_id'
+)
+
+long=$argv[(I)--]
+if (( long )); then
+  argv[long]=( "$xargs[@]" -- )
+else
+  set -- "$@" "$xargs[@]"
+fi
+
+_arguments "$@"
 
 ret=$?
 
diff --git a/Completion/X/_xutils b/Completion/X/_xutils
index 27518e0cf..ed208dfe5 100644
--- a/Completion/X/_xutils
+++ b/Completion/X/_xutils
@@ -49,9 +49,9 @@ xhost)
   local expl type ret=1
 
   if compset -P '-'; then
-    _description expl 'disallow access'
-    compadd "$expl[@]" -M 'm:{a-z}={A-Z} r:|[:.]=* r:|=*' - \
-        "${${(@M)${(@f)$(xhost)}[2,-1]:#LOCAL:*}#INET:}"
+    _wanted displays expl 'disallow access' &&
+        compadd "$expl[@]" -M 'm:{a-z}={A-Z} r:|[:.]=* r:|=*' - \
+                "${${(@M)${(@f)$(xhost)}[2,-1]:#LOCAL:*}#INET:}"
   else
     compset -P +
 
@@ -66,9 +66,9 @@ xhost)
       krb)  _message 'Kerberos V5 principal';;
       esac
     else
-      _description expl 'name family'
-      compadd -S: - inet dnet nis krb && ret=0
-      _hosts && ret=0
+      _alternative \
+          'families:name family:compadd -S: - inet dnet nis krb' \
+	  'hosts:: _hosts' && ret=0
     fi
     return ret
   fi