about summary refs log tree commit diff
path: root/Completion
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>1999-08-19 11:18:05 +0000
committerTanaka Akira <akr@users.sourceforge.net>1999-08-19 11:18:05 +0000
commit9867c4091e71e6ed69889a9bfaee07275d2fa04e (patch)
tree37318116ff90f7b90df7cb9e894790d96be0849b /Completion
parent04979daf4f9b9645f22df1dfbb5974ab82294868 (diff)
downloadzsh-9867c4091e71e6ed69889a9bfaee07275d2fa04e.tar.gz
zsh-9867c4091e71e6ed69889a9bfaee07275d2fa04e.tar.xz
zsh-9867c4091e71e6ed69889a9bfaee07275d2fa04e.zip
manual/7448
Diffstat (limited to 'Completion')
-rw-r--r--Completion/Base/_arguments388
-rw-r--r--Completion/Base/_brace_parameter3
-rw-r--r--Completion/Base/_command_names11
-rw-r--r--Completion/Base/_condition5
-rw-r--r--Completion/Base/_equal7
-rw-r--r--Completion/Base/_long_options79
-rw-r--r--Completion/Base/_math11
-rw-r--r--Completion/Base/_parameter6
-rw-r--r--Completion/Base/_subscript13
-rw-r--r--Completion/Base/_tilde14
-rw-r--r--Completion/Base/_vars9
-rw-r--r--Completion/Builtins/_aliases5
-rw-r--r--Completion/Builtins/_arrays5
-rw-r--r--Completion/Builtins/_autoload5
-rw-r--r--Completion/Builtins/_bg_jobs5
-rw-r--r--Completion/Builtins/_bindkey8
-rw-r--r--Completion/Builtins/_builtin5
-rw-r--r--Completion/Builtins/_cd8
-rw-r--r--Completion/Builtins/_command5
-rw-r--r--Completion/Builtins/_disable22
-rw-r--r--Completion/Builtins/_echotc6
-rw-r--r--Completion/Builtins/_enable22
-rw-r--r--Completion/Builtins/_fc5
-rw-r--r--Completion/Builtins/_functions5
-rw-r--r--Completion/Builtins/_hash8
-rw-r--r--Completion/Builtins/_jobs5
-rw-r--r--Completion/Builtins/_kill11
-rw-r--r--Completion/Builtins/_limits5
-rw-r--r--Completion/Builtins/_sched4
-rw-r--r--Completion/Builtins/_set8
-rw-r--r--Completion/Builtins/_stat10
-rw-r--r--Completion/Builtins/_trap8
-rw-r--r--Completion/Builtins/_unhash22
-rw-r--r--Completion/Builtins/_vars_eq5
-rw-r--r--Completion/Builtins/_wait8
-rw-r--r--Completion/Builtins/_which9
-rw-r--r--Completion/Builtins/_zftp19
-rw-r--r--Completion/Builtins/_zle8
-rw-r--r--Completion/Builtins/_zmodload7
-rw-r--r--Completion/Commands/_history_complete_word6
-rw-r--r--Completion/Core/_description22
-rw-r--r--Completion/Core/_main_complete18
-rw-r--r--Completion/Core/_message19
-rw-r--r--Completion/Core/_normal41
-rw-r--r--Completion/Core/_options5
-rw-r--r--Completion/Core/_parameters8
-rw-r--r--Completion/Core/_path_files8
-rw-r--r--Completion/Core/_set_options5
-rw-r--r--Completion/Core/_unset_options5
-rw-r--r--Completion/Core/compdump6
-rw-r--r--Completion/Core/compinit29
-rw-r--r--Completion/Pbmplus/_asciitopnm3
-rw-r--r--Completion/Pbmplus/_fitstopgm3
-rw-r--r--Completion/Pbmplus/_fitstopnm4
-rw-r--r--Completion/Pbmplus/_g3topbm3
-rw-r--r--Completion/Pbmplus/_giftopnm4
-rw-r--r--Completion/Pbmplus/_macptopbm3
-rw-r--r--Completion/Pbmplus/_pbm_file20
-rw-r--r--Completion/Pbmplus/_pbmclean3
-rw-r--r--Completion/Pbmplus/_pbmmake3
-rw-r--r--Completion/Pbmplus/_pbmmask3
-rw-r--r--Completion/Pbmplus/_pbmpscale3
-rw-r--r--Completion/Pbmplus/_pbmreduce4
-rw-r--r--Completion/Pbmplus/_pbmtext3
-rw-r--r--Completion/Pbmplus/_pbmto10x3
-rw-r--r--Completion/Pbmplus/_pbmtobg3
-rw-r--r--Completion/Pbmplus/_pbmtoepsi3
-rw-r--r--Completion/Pbmplus/_pbmtolj3
-rw-r--r--Completion/Pbmplus/_pbmtoln035
-rw-r--r--Completion/Pbmplus/_pbmtolps3
-rw-r--r--Completion/Pbmplus/_pbmtomacp4
-rw-r--r--Completion/Pbmplus/_pbmtopgm3
-rw-r--r--Completion/Pbmplus/_pbmtopk11
-rw-r--r--Completion/Pbmplus/_pbmupc4
-rw-r--r--Completion/Pbmplus/_pgmcrater5
-rw-r--r--Completion/Pbmplus/_pgmkernel3
-rw-r--r--Completion/Pbmplus/_pgmnoise3
-rw-r--r--Completion/Pbmplus/_pgmnorm5
-rw-r--r--Completion/Pbmplus/_pgmoil3
-rw-r--r--Completion/Pbmplus/_pgmramp3
-rw-r--r--Completion/Pbmplus/_pgmtexture3
-rw-r--r--Completion/Pbmplus/_pgmtopbm5
-rw-r--r--Completion/Pbmplus/_pgmtoppm21
-rw-r--r--Completion/Pbmplus/_pktopbm4
-rw-r--r--Completion/Pbmplus/_pnmalias6
-rw-r--r--Completion/Pbmplus/_pnmarith3
-rw-r--r--Completion/Pbmplus/_pnmcat4
-rw-r--r--Completion/Pbmplus/_pnmcomp5
-rw-r--r--Completion/Pbmplus/_pnmconvol3
-rw-r--r--Completion/Pbmplus/_pnmcrop3
-rw-r--r--Completion/Pbmplus/_pnmcut3
-rw-r--r--Completion/Pbmplus/_pnmdepth3
-rw-r--r--Completion/Pbmplus/_pnmenlarge3
-rw-r--r--Completion/Pbmplus/_pnmflip5
-rw-r--r--Completion/Pbmplus/_pnmgamma16
-rw-r--r--Completion/Pbmplus/_pnmhistmap4
-rw-r--r--Completion/Pbmplus/_pnmindex4
-rw-r--r--Completion/Pbmplus/_pnmmargin4
-rw-r--r--Completion/Pbmplus/_pnmnlfilt3
-rw-r--r--Completion/Pbmplus/_pnmpad6
-rw-r--r--Completion/Pbmplus/_pnmpaste6
-rw-r--r--Completion/Pbmplus/_pnmrotate3
-rw-r--r--Completion/Pbmplus/_pnmscale16
-rw-r--r--Completion/Pbmplus/_pnmshear3
-rw-r--r--Completion/Pbmplus/_pnmtile3
-rw-r--r--Completion/Pbmplus/_pnmtoddif4
-rw-r--r--Completion/Pbmplus/_pnmtofits3
-rw-r--r--Completion/Pbmplus/_pnmtops5
-rw-r--r--Completion/Pbmplus/_pnmtorast3
-rw-r--r--Completion/Pbmplus/_pnmtosgi3
-rw-r--r--Completion/Pbmplus/_pnmtotiff5
-rw-r--r--Completion/Pbmplus/_pnmtoxwd4
-rw-r--r--Completion/Pbmplus/_ppm3d4
-rw-r--r--Completion/Pbmplus/_ppmbrighten3
-rw-r--r--Completion/Pbmplus/_ppmchange15
-rw-r--r--Completion/Pbmplus/_ppmdim3
-rw-r--r--Completion/Pbmplus/_ppmdist3
-rw-r--r--Completion/Pbmplus/_ppmdither7
-rw-r--r--Completion/Pbmplus/_ppmflash3
-rw-r--r--Completion/Pbmplus/_ppmforge13
-rw-r--r--Completion/Pbmplus/_ppmmake3
-rw-r--r--Completion/Pbmplus/_ppmmix3
-rw-r--r--Completion/Pbmplus/_ppmntsc3
-rw-r--r--Completion/Pbmplus/_ppmpat4
-rw-r--r--Completion/Pbmplus/_ppmquant26
-rw-r--r--Completion/Pbmplus/_ppmquantall3
-rw-r--r--Completion/Pbmplus/_ppmshift3
-rw-r--r--Completion/Pbmplus/_ppmspread3
-rw-r--r--Completion/Pbmplus/_ppmtoacad4
-rw-r--r--Completion/Pbmplus/_ppmtobmp3
-rw-r--r--Completion/Pbmplus/_ppmtogif3
-rw-r--r--Completion/Pbmplus/_ppmtoicr4
-rw-r--r--Completion/Pbmplus/_ppmtoilbm3
-rw-r--r--Completion/Pbmplus/_ppmtomap3
-rw-r--r--Completion/Pbmplus/_ppmtomitsu7
-rw-r--r--Completion/Pbmplus/_ppmtopj6
-rw-r--r--Completion/Pbmplus/_ppmtopjxl9
-rw-r--r--Completion/Pbmplus/_ppmtosixel3
-rw-r--r--Completion/Pbmplus/_ppmtotga3
-rw-r--r--Completion/Pbmplus/_ppmtouil3
-rw-r--r--Completion/Pbmplus/_ppmtoyuvsplit3
-rw-r--r--Completion/Pbmplus/_psidtopgm4
-rw-r--r--Completion/Pbmplus/_pstopnm10
-rw-r--r--Completion/Pbmplus/_rawtopgm5
-rw-r--r--Completion/Pbmplus/_rawtoppm6
-rw-r--r--Completion/Pbmplus/_rgb3toppm16
-rw-r--r--Completion/Pbmplus/_sgitopnm3
-rw-r--r--Completion/Pbmplus/_sldtoppm7
-rw-r--r--Completion/Pbmplus/_yuvsplittoppm3
-rw-r--r--Completion/Pbmplus/_yuvtoppm3
-rw-r--r--Completion/Pbmplus/_zeisstopnm3
-rw-r--r--Completion/User/_a2ps26
-rw-r--r--Completion/User/_bunzip25
-rw-r--r--Completion/User/_bzip25
-rw-r--r--Completion/User/_chown8
-rw-r--r--Completion/User/_colors6
-rw-r--r--Completion/User/_compress5
-rw-r--r--Completion/User/_configure4
-rw-r--r--Completion/User/_cursors5
-rw-r--r--Completion/User/_dd17
-rw-r--r--Completion/User/_find27
-rw-r--r--Completion/User/_gdb35
-rw-r--r--Completion/User/_groups5
-rw-r--r--Completion/User/_gunzip5
-rw-r--r--Completion/User/_gzip3
-rw-r--r--Completion/User/_hosts5
-rw-r--r--Completion/User/_make5
-rw-r--r--Completion/User/_man5
-rw-r--r--Completion/User/_mh27
-rw-r--r--Completion/User/_pdf5
-rw-r--r--Completion/User/_ps5
-rw-r--r--Completion/User/_pspdf7
-rw-r--r--Completion/User/_rcs5
-rw-r--r--Completion/User/_rlogin8
-rw-r--r--Completion/User/_strip5
-rw-r--r--Completion/User/_stty8
-rw-r--r--Completion/User/_su9
-rw-r--r--Completion/User/_tar15
-rw-r--r--Completion/User/_tar_archive10
-rw-r--r--Completion/User/_tex5
-rw-r--r--Completion/User/_uncompress3
-rw-r--r--Completion/User/_use_lo6
-rw-r--r--Completion/User/_x_options5
-rw-r--r--Completion/User/_xfig5
-rw-r--r--Completion/User/_xsetroot17
185 files changed, 1539 insertions, 240 deletions
diff --git a/Completion/Base/_arguments b/Completion/Base/_arguments
new file mode 100644
index 000000000..5170acb84
--- /dev/null
+++ b/Completion/Base/_arguments
@@ -0,0 +1,388 @@
+#autoload
+
+# Complete the arguments of the current command according to the
+# descriptions given as arguments to this function.
+
+local long args rest ws cur nth def nm expl descr action opt arg tmp
+
+# Associative arrays used to collect information about the options.
+
+typeset -A opts mopts dopts dmopts odopts odmopts
+
+# See if we support long options, too.
+
+nth=$argv[(I)--]
+if (( nth )); then
+  long=( "${(@)argv[nth+1,-1]}" )
+  argv=("${(@)argv[1,nth-1]}")
+else
+  long=()
+fi
+
+# Now parse the arguments...
+
+args=()
+nth=1
+while (( $# )); do
+
+  # This describes a one-shot option.
+
+  if [[ "$1" = [-+]* ]]; then
+    if [[ "$1" = *:* ]]; then
+
+      # If the option name ends in a `-', the first argument comes
+      # directly after the option, if it ends in a `+', the first
+      # argument *may* come directly after the option, otherwise it
+      # is in the next word.
+
+      if [[ "$1" = [^:]##-:* ]]; then
+        dopts[${${1%%:*}[1,-2]}]="${1#*:}"
+      elif [[ "$1" = [^:]##+:* ]]; then
+        odopts[${${1%%:*}[1,-2]}]="${1#*:}"
+      else
+        opts[${1%%:*}]="${1#*:}"
+      fi
+    else
+      opts[$1]=''
+    fi
+  elif [[ "$1" = \*[-+]* ]]; then
+
+    # The same for options that may appear more than once.
+
+    if [[ "$1" = *:* ]]; then
+      if [[ "$1" = [^:]##-:* ]]; then
+        dmopts[${${1[2,-1]%%:*}[1,-2]}]="${1#*:}"
+      elif [[ "$1" = [^:]##+:* ]]; then
+        odmopts[${${1[2,-1]%%:*}[1,-2]}]="${1#*:}"
+      else
+        mopts[${1[2,-1]%%:*}]="${1#*:}"
+      fi
+    else
+      mopts[${1[2,-1]}]=''
+    fi
+  elif [[ "$1" = \*:* ]]; then
+
+    # This is `*:...', describing `all other arguments'.
+
+    rest="${1[3,-1]}"
+  elif [[ "$1" = :* ]]; then
+
+    # This is `:...', describing `the next argument'.
+
+    args[nth++]="${1#*:}"
+  else
+
+    # And this is `n:...', describing the `n'th argument.
+
+    args[${1%%:*}]="${1#*:}"
+    nth=$(( ${1%%:*} + 1 ))
+  fi
+  shift
+done
+
+if [[ $#long -ne 0 && "$PREFIX" = --* ]]; then
+
+   # If the current words starts with `--' and we should use long
+   # options, just call...
+
+  _long_options "$long[@]"
+else
+
+  # Otherwise parse the command line...
+
+  ws=( "${(@)words[2,-1]}" )
+  cur=$(( CURRENT-2 ))
+  nth=1
+
+  # ...until the current word is reached.
+
+  while [[ cur -gt 0 ]]; do
+
+    # `def' holds the description for the option we are currently after.
+    # Check if the next argument for the option is optional.
+
+    if [[ "$def" = :* ]]; then
+      opt=yes
+    else
+      opt=''
+    fi
+    arg=''
+
+    # Remove one description/action pair from `def' if that isn't empty.
+
+    if [[ -n "$def" ]]; then
+      if [[ "$def" = ?*:*:* ]]; then
+        def="${def#?*:*:}"
+      else
+        def=''
+      fi
+    else
+
+      # If it is empty, and the word starts with `--' and we should
+      # complete long options, just ignore this word, otherwise make sure
+      # we test for options below and handle normal arguments.
+
+      if [[ $#long -eq 0 || "$ws[1]" != --* ]]; then
+        opt=yes
+	arg=yes
+      else
+        def=''
+      fi
+    fi
+
+    if [[ -n "$opt" ]]; then
+
+      # `opt' was set above if we have to test if the word is an option.
+      # We first test for the simple options -- those without arguments or
+      # those whose arguments have to be given as separate words.
+
+      if (( $+opts[$ws[1]] )); then
+
+        # Options that may only be given once are removed from the
+        # associative array so that we are not offered them again.
+
+        def="$opts[$ws[1]]"
+        unset "opts[$ws[1]]"
+      elif (( $+mopts[$ws[1]] )); then
+        def="$mopts[$ws[1]]"
+      else
+
+        # If the word is none of the simple options, test for those
+        # whose first argument has to or may come directly after the
+        # option. This is done in four loops looking very much alike.
+
+        if (( $#dopts )); then
+
+	  # First we get the option names.
+
+	  tmp=( "${(@k)dopts}" )
+
+	  # Then we loop over them and see if the current word begins
+	  # with one of the option names.
+
+	  while (( $#tmp )); do
+	    [[ "$ws[1]" = ${tmp[1]}* ]] && break
+	    shift 1 tmp
+	  done
+
+	  if (( $#tmp )); then
+
+	    # It does. So use the description for it, but only from
+	    # the second argument on, because we are searching the
+	    # description for the next command line argument.
+
+	    opt=''
+	    def="$dopts[$tmp[1]]"
+	    unset "dopts[$tmp[1]]"
+	    if [[ "$def" = ?*:*:* ]]; then
+              def="${def#?*:*:}"
+            else
+              def=''
+	    fi
+          fi
+        fi
+	if [[ -n "$opt" && $#dmopts -ne 0 ]]; then
+	  tmp=( "${(@k)dmopts}" )
+	  while (( $#tmp )); do
+	    [[ "$ws[1]" = ${tmp[1]}* ]] && break
+	    shift 1 tmp
+	  done
+
+	  if (( $#tmp )); then
+	    opt=''
+	    def="$dmopts[$tmp[1]]"
+	    if [[ "$def" = ?*:*:* ]]; then
+              def="${def#?*:*:}"
+            else
+              def=''
+            fi
+          fi
+	fi
+        if [[ -n "$opt" && $#odopts -ne 0 ]]; then
+	  tmp=( "${(@k)odopts}" )
+	  while (( $#tmp )); do
+	    [[ "$ws[1]" = ${tmp[1]}* ]] && break
+	    shift 1 tmp
+	  done
+
+	  if (( $#tmp )); then
+	    opt=''
+	    def="$odopts[$tmp[1]]"
+	    unset "odopts[$tmp[1]]"
+
+	    # For options whose first argument *may* come after the
+	    # option, we skip over the first description only if there
+	    # is something after the option name on the line.
+
+	    if [[ "$ws[1]" != "$tmp[1]" ]]; then
+	      if [[ "$def" = ?*:*:* ]]; then
+                def="${def#?*:*:}"
+              else
+                def=''
+              fi
+	    fi
+          fi
+        fi
+	if [[ -n "$opt" && $#odmopts -ne 0 ]]; then
+	  tmp=( "${(@k)odmopts}" )
+	  while (( $#tmp )); do
+	    [[ "$ws[1]" = ${tmp[1]}* ]] && break
+	    shift 1 tmp
+	  done
+
+	  if (( $#tmp )); then
+	    opt=''
+	    def="$odmopts[$tmp[1]]"
+	    if [[ "$ws[1]" != "$tmp[1]" ]]; then
+	      if [[ "$def" = ?*:*:* ]]; then
+                def="${def#?*:*:}"
+              else
+                def=''
+              fi
+            fi
+          fi
+	fi
+
+	# If we didn't find a matching option description and we were
+	# told to use normal argument descriptions, just increase
+	# our counter `nth'.
+
+        if [[ -n "$opt" && -n "$arg" ]]; then
+          def=''
+	  (( nth++ ))
+        fi
+      fi
+    fi
+
+    shift 1 ws
+    (( cur-- ))
+  done
+
+  # Now generate the matches.
+
+  nm="$compstate[nmatches]"
+
+  if [[ -z "$def" || "$def" = :* ]]; then
+
+    # We either don't have a description for an argument of an option
+    # or we have a description for a optional argument.
+
+    if [[ -z "$def" ]]; then
+
+      # If we have none at all, use the one for this argument position.
+
+      def="$args[nth]"
+      [[ -z "$def" ]] && def="$rest"
+    fi
+
+    # In any case, we have to complete option names here, but we may
+    # be in a string that starts with an option names and continues with
+    # the first argument, test that (again, four loops).
+
+    opt=yes
+    if (( $#dopts )); then
+
+      # Get the option names.
+
+      tmp=( "${(@k)dopts}" )
+      while (( $#tmp )); do
+        if compset -P "$tmp[1]"; then
+
+	  # The current string starts with the option name, so ignore
+	  # that and complete the rest of the string.
+
+	  def="$dopts[$tmp[1]]"
+	  opt=''
+	  break
+        fi
+	shift 1 tmp
+      done
+    fi
+    if [[ -n "$opt" && $#dmopts -ne 0 ]]; then
+      tmp=( "${(@k)dmopts}" )
+      while (( $#tmp )); do
+        if compset -P "$tmp[1]"; then
+	  def="$dmopts[$tmp[1]]"
+	  opt=''
+	  break
+        fi
+	shift 1 tmp
+      done
+    fi
+    if [[ -n "$opt" && $#odopts -ne 0 ]]; then
+      tmp=( "${(@k)odopts}" )
+      while (( $#tmp )); do
+        if compset -P "$tmp[1]"; then
+	  def="$odopts[$tmp[1]]"
+	  opt=''
+	  break
+        fi
+	shift 1 tmp
+      done
+    fi
+    if [[ -n "$opt" && $#odmopts -ne 0 ]]; then
+      tmp=( "${(@k)odmopts}" )
+      while (( $#tmp )); do
+        if compset -P "$tmp[1]"; then
+	  def="$odmopts[$tmp[1]]"
+	  opt=''
+	  break
+        fi
+	shift 1 tmp
+      done
+    fi
+    if [[ -n "$opt" ]]; then
+
+      # We aren't in an argument directly after a option name, so
+      # all option names are possible matches.
+
+      _description expl option
+      compadd "$expl[@]" - "${(@k)opts}" "${(@k)mopts}" \
+                           "${(@k)dopts}" "${(@k)dmopts}" \
+			   "${(@k)odopts}" "${(@k)odmopts}"
+    fi
+  fi
+
+  # Now add the matches from the description, if any.
+
+  if [[ -n "$def" ]]; then
+
+    # Ignore the leading colon describing optional arguments.
+
+    [[ "$def" = :* ]] && def="$def[2,-1]"
+
+    # Get the description and the action.
+
+    descr="${def%%:*}"
+    action="${${def#*:}%%:*}"
+
+    _description expl "$descr"
+
+    if [[ -z "$action" ]]; then
+
+      # An empty action means that we should just display a message.
+      _message "$descr"
+      return 1
+    elif [[ "$action[1]" = \( ]]; then
+
+      # Anything inside `(...)' is added directly.
+
+      compadd "$expl[@]" - ${=action[2,-2]}
+    elif [[ "$action" = \ * ]]; then
+
+      # If the action starts with a space, we just call it.
+
+      $=action
+    else
+
+      # Otherwise we call it with the description-arguments built above.
+
+      action=( $=action )
+      "$action[1]" "$expl[@]" "${(@)action[2,-1]}"
+    fi
+  fi
+
+  # Set the return value.
+
+  [[  nm -ne "$compstate[nmatches]" ]]
+fi
diff --git a/Completion/Base/_brace_parameter b/Completion/Base/_brace_parameter
index 9dfe46bd6..767743281 100644
--- a/Completion/Base/_brace_parameter
+++ b/Completion/Base/_brace_parameter
@@ -7,7 +7,8 @@ local lp ls n q suf=''
 if [[ "$SUFFIX" = *\}* ]]; then
   ISUFFIX="${SUFFIX#*\}}$ISUFFIX"
   SUFFIX="${SUFFIX%%\}*}"
-elif [[ "$LBUFFER" = *\$\{[^}]#\$\{[^}]#$PREFIX ]]; then
+elif [[ "$LBUFFER" = *\$\{[^}]#\$\{[^}]#$PREFIX ||
+        "$compstate[insert]" = *menu* ]]; then
   suf='}'
 else
   suf='} '
diff --git a/Completion/Base/_command_names b/Completion/Base/_command_names
index 61fea56dd..a0ec90262 100644
--- a/Completion/Base/_command_names
+++ b/Completion/Base/_command_names
@@ -1,18 +1,21 @@
 #compdef -command-
 
-local nm=$compstate[nmatches] ret=1
+local nm=$compstate[nmatches] ret=1 expl
 
 
 # Complete jobs in implicit fg and bg
 if [[ "$PREFIX[1]" = "%" ]]; then
-  compgen -j -P '%'
+  _description expl job
+  compgen "$expl[@]" -j -P '%'
   [[ nm -ne compstate[nmatches] ]] && return
 fi
 
-compgen -c && ret=0
+_description expl command
+compgen "$expl[@]" -c && ret=0
 
 if [[ nm -eq compstate[nmatches] ]]; then
-  _path_files -/g "*(*)"
+  _description expl 'executable file or directory'
+  _path_files "$expl[@]" -/g "*(*)"
 else
   return ret
 fi
diff --git a/Completion/Base/_condition b/Completion/Base/_condition
index c617d9d90..afac03195 100644
--- a/Completion/Base/_condition
+++ b/Completion/Base/_condition
@@ -7,10 +7,11 @@ if [[ "$prev" = -o ]]; then
 elif [[ "$prev" = -([no]t|ef) ]]; then
   _files
 else
-  local ret=1
+  local ret=1 expl
 
   _files && ret=0
-  compgen -v && ret=0
+  _description expl parameter
+  compgen "$expl[@]" -v && ret=0
 
   return ret
 fi
diff --git a/Completion/Base/_equal b/Completion/Base/_equal
index 0e2a11e46..14f28703c 100644
--- a/Completion/Base/_equal
+++ b/Completion/Base/_equal
@@ -1,3 +1,8 @@
 #compdef -equal-
 
-compgen -am
+local expl
+
+_description expl alias
+compgen "$expl[@]" -a
+_description expl command
+compgen "$expl[@]" -m
diff --git a/Completion/Base/_long_options b/Completion/Base/_long_options
index a50edee1c..f82de9ed5 100644
--- a/Completion/Base/_long_options
+++ b/Completion/Base/_long_options
@@ -9,9 +9,11 @@
 # For options that get an argument after a `=', the function also tries
 # to automatically find out what should be completed as the argument.
 # The possible completions for option-arguments can be described with
-# the arguments to this function. This is done by giving pairs of
-# patterns and actions as consecutive arguments. The actions specify
-# what should be done to complete arguments of those options that match 
+# the arguments to this function. Each argument contains one description
+# of the form <pattern>:<message>:<action>. The message will be printed 
+# above the possible completion if the `description_format' configuration
+# key is set (see the `_main_complete' file). The actions specify what
+# should be done to complete arguments of those options that match 
 # the pattern. The action may be a list of words in brackets or in
 # parentheses, separated by spaces. A list in brackets denotes
 # possible values for an optional argument, a list in parentheses
@@ -20,9 +22,9 @@
 # command (probably with arguments) that should be invoked to complete 
 # after the equal sign. E.g.:
 #
-#  _long_options '*\*'     '(yes no)' \
-#                '*=FILE*' '_files' \
-#                '*=DIR*'  '_files -/'
+#  _long_options '*\*:toggle:(yes no)' \
+#                '*=FILE*:file:_files' \
+#                '*=DIR*:directory:_files -/'
 #
 # This makes `yes' and `no' be completed as the argument of options
 # whose description ends in a star, file names for options that
@@ -46,23 +48,18 @@
 #      E.g. configure often lists only --enable but accepts both
 #      --enable and --disable options.
 #      _long_options -s '(#--enable- --disable)' will accept both forms.
-#
-# This function also accepts the `-X', `-J', and `-V' options which
-# are given to `compadd'. 
 
-local opt expl group test i name action ret=1 tmp suffix iopts sopts
+local opt test i name action descr expl ret=1 tmp suffix iopts sopts
 
 setopt extendedglob
 
 # Get the options.
 
-group=()
 expl=()
+
 if [[ $1 = -*~--* ]]; then
-  while getopts "J:V:X:ti:s:" opt; do
+  while getopts "ti:s:" opt; do
     case "$opt" in
-      [JV]) group=("-$opt" "$OPTARG");;
-      X)    expl=(-X "$OPTARG");;
       t)    test=yes;;
       i)    if [[ "$OPTARG[1]" = '(' ]]; then
               iopts=( ${=OPTARG[2,-2]} )
@@ -99,7 +96,7 @@ if [[ "$tmp" != $_lo_cache_cmd ]]; then
   # No, store the new command name and clear the old parameters.
 
   _lo_cache_cmd="$tmp"
-  (( $+_lo_cache_actions )) && unset "$_lo_cache_names[@]" _lo_cache_actions _lo_cache_names
+  (( $+_lo_cache_actions )) && unset "$_lo_cache_names[@]" _lo_cache_actions _lo_cache_names _lo_cache_descr
 
   local opts pattern anum=1 tmpo str
   typeset -U opts
@@ -136,16 +133,17 @@ if [[ "$tmp" != $_lo_cache_cmd ]]; then
   # use the positional parameters we were given and a few standard
   # ones. Then we loop through this table.
 
-  set -- "$@" '*=FILE*' '_files' '*=(DIR|PATH)*' '_files -/' '*' ''
+  set -- "$@" '*=FILE*:file:_files' '*=(DIR|PATH)*:directory:_files -/' '*:unknown:'
 
   while [[ $# -gt 1 ]]; do
 
     # First, we get the pattern and the action to use and take them
     # from the positional parameters.
 
-    pattern="$1"
-    action="$2"
-    shift 2
+    pattern="${1%%:*}"
+    descr="${${1#*:}%%:*}"
+    action="${1#*:*:}"
+    shift
 
     # We get all options matching the pattern and take them from the
     # list we have built. If no option matches the pattern, we
@@ -188,6 +186,7 @@ if [[ "$tmp" != $_lo_cache_cmd ]]; then
         tmpo=("${(@)${(@)tmpo%%\=*}//[^a-z0-9-]}")
         _lo_cache_names[anum]="_lo_cache_optarg_$anum"
         _lo_cache_actions[anum]="$action"
+	_lo_cache_descr[anum]="$descr"
         eval "_lo_cache_optarg_${anum}=(\"\$tmpo[@]\")"
 	(( anum++ ))
       fi
@@ -201,6 +200,7 @@ if [[ "$tmp" != $_lo_cache_cmd ]]; then
         tmpo=("${(@)${(@)tmpo%%\=*}//[^a-z0-9-]}")
         _lo_cache_names[anum]="_lo_cache_arg_$anum"
         _lo_cache_actions[anum]="$action"
+	_lo_cache_descr[anum]="$descr"
         eval "_lo_cache_arg_${anum}=(\"\$tmpo[@]\")"
 	(( anum++ ))
       fi
@@ -216,6 +216,7 @@ if [[ "$tmp" != $_lo_cache_cmd ]]; then
     if (( $#tmp )); then
       _lo_cache_names[anum]="$name"
       _lo_cache_actions[anum]="$action"
+      _lo_cache_descr[anum]="$descr"
       eval "${name}=(\"\$tmp[@]\")"
       (( anum++ ))
     fi
@@ -232,7 +233,7 @@ if [[ "$str" = *\=* ]]; then
   # It contains a `=', now we ignore anything up to it, but first save 
   # the old contents of the special parameters we change.
 
-  local oipre opre osuf pre parto parta pat patflags anum=1
+  local oipre opre osuf pre parto parta partd pat patflags anum=1
 
   oipre="$IPREFIX"
   opre="$PREFIX"
@@ -247,14 +248,23 @@ if [[ "$str" = *\=* ]]; then
 
   for name in "$_lo_cache_names[@]"; do
     action="$_lo_cache_actions[anum]"
+    descr="$_lo_cache_descr[anum]"
     if (( ${(@)${(@P)name}[(I)$pre]} )); then
       IPREFIX="${oipre}${pre}="
       PREFIX="${str#*\=}"
       SUFFIX=""
+
+      _description expl "$descr"
+
       if [[ "$action[1]" = (\[|\() ]]; then
-        compadd - ${=action[2,-2]}
+        compadd "$expl[@]" - ${=action[2,-2]}
       elif (( $#action )); then
-        $=action
+        if [[ "$action" = \ * ]]; then
+          $=action
+        else
+	  action=($=action)
+	  $action[1] "$expl[@]" $action[2,-1]
+        fi
       fi
 
       # We found the option string, return.
@@ -276,6 +286,7 @@ if [[ "$str" = *\=* ]]; then
       if [[ -z "$parto" ]]; then
         parto="$tmp[1]"
 	parta="$action"
+	partd="$descr"
       else
         parto=-
       fi
@@ -292,11 +303,17 @@ if [[ "$str" = *\=* ]]; then
     IPREFIX="${oipre}${parto}="
     PREFIX="${str#*\=}"
     SUFFIX=""
+
+    _description expl "$partd"
+
     if (( $#parta )); then
       if [[ "$parta[1]" = (\[|\() ]]; then
-        compadd - ${=parta[2,-2]}
-      else
+        compadd "$expl[@]" - ${=parta[2,-2]}
+      elif [[ "$parta" = \ * ]]; then
         $=parta
+      else
+	action=($=parta)
+	$action[1] "$expl[@]" $action[2,-1]
       fi
     else
       compadd -S '' - "$PREFIX"
@@ -329,15 +346,17 @@ anum=1
 for name in "$_lo_cache_names[@]"; do
   action="$_lo_cache_actions[anum]"
 
+  _description expl option
+
   if [[ "$name" = *_optarg_* ]]; then
-    compadd -M 'r:|-=* r:|=*' -Qq "$suffix[@]" -s "$str" - \
-            "${(@P)name}" && ret=0
+    compadd "$expl[@]" -M 'r:|-=* r:|=*' \
+            -Qq "$suffix[@]" -s "$str" - "${(@P)name}" && ret=0
   elif [[ "$name" = *_arg_* ]]; then
-    compadd -M 'r:|-=* r:|=*' -Q "$suffix[@]" -s "$str" - \
-            "${(@P)name}" && ret=0
+    compadd "$expl[@]" -M 'r:|-=* r:|=*' \
+            -Q "$suffix[@]" -s "$str" - "${(@P)name}" && ret=0
   elif [[ -z "$str" ]]; then
-    compadd -M 'r:|-=* r:|=*' -Q - \
-            "${(@P)name}" && ret=0
+    compadd "$expl[@]" -M 'r:|-=* r:|=*' - \
+            -Q "${(@P)name}" && ret=0
   fi
   (( anum++ ))
 done
diff --git a/Completion/Base/_math b/Completion/Base/_math
index 90a2c5f7b..82b97fe4a 100644
--- a/Completion/Base/_math
+++ b/Completion/Base/_math
@@ -1,5 +1,7 @@
 #compdef -math-
 
+local expl
+
 if [[ "$PREFIX" = *[^a-zA-Z0-9_]* ]]; then
   IPREFIX="$IPREFIX${PREFIX%%[a-zA-Z0-9_]#}"
   PREFIX="${PREFIX##*[^a-zA-Z0-9_]}"
@@ -9,10 +11,5 @@ if [[ "$SUFFIX" = *[^a-zA-Z0-9_]* ]]; then
   SUFFIX="${SUFFIX%%[^a-zA-Z0-9_]*}"
 fi
 
-compgen -v
-#compdef -math-
-
-IPREFIX="$IPREFIX${PREFIX%[a-zA-Z0-9_]*}"
-PREFIX="${PREFIX##*[^a-zA-Z0-9_]}"
-
-compgen -v
+_description expl parameter
+compgen "$expl[@]" -v
diff --git a/Completion/Base/_parameter b/Completion/Base/_parameter
index b235a5fee..5f6f56db2 100644
--- a/Completion/Base/_parameter
+++ b/Completion/Base/_parameter
@@ -1,3 +1,7 @@
 #compdef -parameter-
 
-_parameters -S ' ' -r '['
+if [[ "$compstate[insert]" = *menu* ]]; then
+  _parameters
+else
+  _parameters -S ' ' -r '['
+fi
diff --git a/Completion/Base/_subscript b/Completion/Base/_subscript
index be5f08f62..090a5f07a 100644
--- a/Completion/Base/_subscript
+++ b/Completion/Base/_subscript
@@ -1,17 +1,22 @@
 #compdef -subscript-
 
+local expl
+
 if [[ "$PREFIX" = :* ]]; then
+  _description expl 'character class'
   compadd -p: -S ':]' alnum alpha blank cntrl digit graph lower print punct \
       space upper xdigit
 elif [[ ${(Pt)${compstate[parameter]}} = assoc* ]]; then
+  _description expl 'association key'
   if [[ "$RBUFFER" = \]* ]]; then
-    compadd -S '' - "${(@kP)${compstate[parameter]}}"
+    compadd "$expl[@]" -S '' - "${(@kP)${compstate[parameter]}}"
   else
-    compadd -S ']' - "${(@kP)${compstate[parameter]}}"
+    compadd "$expl[@]" -S ']' - "${(@kP)${compstate[parameter]}}"
   fi
 elif [[ ${(Pt)${compstate[parameter]}} = array* ]]; then
   local list i j
 
+  _description expl 'array index'
   ind=( {1..${#${(P)${compstate[parameter]}}}} )
   list=()
   for i in "$ind[@]"; do
@@ -21,9 +26,9 @@ elif [[ ${(Pt)${compstate[parameter]}} = array* ]]; then
   done
 
   if [[ "$RBUFFER" = \]* ]]; then
-    compadd -S '' -V default -y list - "$ind[@]"
+    compadd "$expl[@]" -S '' -V default -y list - "$ind[@]"
   else
-    compadd -S ']' -V default -y list - "$ind[@]"
+    compadd "$expl[@]" -S ']' -V default -y list - "$ind[@]"
   fi
 else
   _compalso -math-
diff --git a/Completion/Base/_tilde b/Completion/Base/_tilde
index d03030821..f249d4ffa 100644
--- a/Completion/Base/_tilde
+++ b/Completion/Base/_tilde
@@ -7,7 +7,7 @@
 #   `(( compstate[nmatches] )) || compgen -nu -qS/'
 # below that.
 
-local c s dirs list
+local d c s dirs list
 
 if [[ "$SUFFIX" = */* ]]; then
   ISUFFIX="/${SUFFIX#*/}$ISUFFIX"
@@ -24,6 +24,8 @@ if compset -P +; then
   				        printf("%s\t%s\n", $1, $2); }' <<<$dirs)"
   list=("${(@)list%	*}")
   c=(-y '$dirs' -k "($list)")
+
+  _description d 'directory stack'
 elif compset -P -; then
   dirs="$(dirs -v)"
   list=("${(f)dirs}")
@@ -31,8 +33,16 @@ elif compset -P -; then
 					  printf("%s\t%s\n", $1, $2); }' <<<$dirs)"
   list=("${(@)list%	*}")
   c=(-y '$dirs' -k "($list)")
+
+  _description d 'directory stack'
 else
   c=(-nu)
+
+  if (( $# )); then
+    d=( "$@" )
+  else
+    _description d user
+  fi
 fi
 
-compgen "$c[@]" "$s[@]"
+compgen "$d[@]" "$c[@]" "$s[@]"
diff --git a/Completion/Base/_vars b/Completion/Base/_vars
index a40df7699..5a06488a5 100644
--- a/Completion/Base/_vars
+++ b/Completion/Base/_vars
@@ -4,17 +4,22 @@
 # `vared compconfig[<TAB>'.  However, in this version the [ must be
 # added by hand.
 
+local expl
+
 if [[ $PREFIX = *\[* ]]; then
   local var=${PREFIX%%\[*}
   local elt="${PREFIX#*\]}${SUFFIX%\]}"
   local addclose
+
   compset -p $(( ${#var} + 1 ))
   if ! compset -S \]; then
     addclose=(-S ']')
   fi
   if [[ ${(tP)var} = assoc* ]]; then
-    compadd $addclose - ${(kP)var}
+    _description expl 'association key'
+    compadd "$expl[@]" $addclose - ${(kP)var}
   fi
 else
-  compgen -v
+  _description expl parameter
+  compgen "$expl[@]" -v
 fi
diff --git a/Completion/Builtins/_aliases b/Completion/Builtins/_aliases
index 990f43457..3e4b789b6 100644
--- a/Completion/Builtins/_aliases
+++ b/Completion/Builtins/_aliases
@@ -1,3 +1,6 @@
 #compdef alias unalias
 
-compgen -a
+local expl
+
+_description expl alias
+compgen "$expl[@]" -a
diff --git a/Completion/Builtins/_arrays b/Completion/Builtins/_arrays
index b79bf711c..20681f527 100644
--- a/Completion/Builtins/_arrays
+++ b/Completion/Builtins/_arrays
@@ -1,3 +1,6 @@
 #compdef shift
 
-compgen -A
+local expl
+
+_description expl array
+compgen "$expl[@]" -A
diff --git a/Completion/Builtins/_autoload b/Completion/Builtins/_autoload
index f10fc34e7..4a97b2aec 100644
--- a/Completion/Builtins/_autoload
+++ b/Completion/Builtins/_autoload
@@ -1,3 +1,6 @@
 #compdef autoload
 
-compadd - ${^fpath}/*(N:t)
+local expl
+
+_description expl 'shell function'
+compadd "$expl[@]" - ${^fpath}/*(N:t)
diff --git a/Completion/Builtins/_bg_jobs b/Completion/Builtins/_bg_jobs
index ef1cd4d3c..65f21b483 100644
--- a/Completion/Builtins/_bg_jobs
+++ b/Completion/Builtins/_bg_jobs
@@ -1,3 +1,6 @@
 #compdef bg
 
-compgen -z -P '%'
+local expl
+
+_description expl 'suspended job'
+compgen "$expl[@]" -z -P '%'
diff --git a/Completion/Builtins/_bindkey b/Completion/Builtins/_bindkey
index 91ecfcc28..891e2cedb 100644
--- a/Completion/Builtins/_bindkey
+++ b/Completion/Builtins/_bindkey
@@ -7,8 +7,12 @@
 #
 # Where appropriate, will complete keymaps instead of widgets.
 
+local expl
+
 if [[ "$words[2]" = -*[DAN]* || "$words[CURRENT-1]" = -*M ]]; then
-  compadd - $(bindkey -l)
+  _description expl keymap
+  compadd "$expl[@]" - $(bindkey -l)
 else
-  compgen -b -M 'r:|-=* r:|=*'
+  _description expl widget
+  compgen "$expl[@]" -b -M 'r:|-=* r:|=*'
 fi
diff --git a/Completion/Builtins/_builtin b/Completion/Builtins/_builtin
index 0e6d613be..f925b88a8 100644
--- a/Completion/Builtins/_builtin
+++ b/Completion/Builtins/_builtin
@@ -5,5 +5,8 @@ if (( $CURRENT > 2 )); then
   (( CURRENT -- ))
   _normal
 else
-  compgen -eB
+  local expl
+
+  _description expl 'builtin command'
+  compgen "$expl[@]" -eB
 fi
diff --git a/Completion/Builtins/_cd b/Completion/Builtins/_cd
index 9ac29b8f8..92a14ec31 100644
--- a/Completion/Builtins/_cd
+++ b/Completion/Builtins/_cd
@@ -14,6 +14,8 @@
 emulate -L zsh
 setopt extendedglob nonomatch
 
+local expl
+
 if [[ CURRENT -eq 3 ]]; then
   # cd old new: look for old in $PWD and see what can replace it
   local rep
@@ -21,7 +23,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]}})
-  (( ! $#rep )) || compadd $rep
+  _description expl replacement
+  (( ! $#rep )) || compadd "$expl[@]" $rep
 elif [[ $PREFIX = [-+]* ]]; then
   # pushd: just complete the numbers, but show the full directory list with
   # numbers.
@@ -50,7 +53,8 @@ elif [[ $PREFIX = [-+]* ]]; then
   lines="${(F)list}"
   # get the array of numbers only
   list=(${list%%[ 	]*})
-  compgen -y '$lines' -Q -k list && ret=0
+  _description expl 'directory stack index'
+  compgen "$expl[@]" -y '$lines' -Q -k list && ret=0
   [[ -z $compstate[list] ]] && compstate[list]=list && ret=0
   [[ -n $compstate[insert] ]] && compstate[insert]=menu && ret=0
 
diff --git a/Completion/Builtins/_command b/Completion/Builtins/_command
index 6103ee81f..4ae274f1f 100644
--- a/Completion/Builtins/_command
+++ b/Completion/Builtins/_command
@@ -4,5 +4,8 @@ if [[ CURRENT -ge 3 ]]; then
   compset -n 2
   _normal
 else
-  compgen -em
+  local expl
+
+  _description expl command
+  compgen "$expl[@]" -em
 fi
diff --git a/Completion/Builtins/_disable b/Completion/Builtins/_disable
index 5572fbcf3..b219f4b7e 100644
--- a/Completion/Builtins/_disable
+++ b/Completion/Builtins/_disable
@@ -1,10 +1,22 @@
 #compdef disable
 
-local prev="$words[CURRENT-1]" ret=1
+local prev="$words[CURRENT-1]" ret=1 expl
 
-[[ "$prev" = -*a* ]] && compgen -ea && ret=0
-[[ "$prev" = -*f* ]] && compgen -eF && ret=0
-[[ "$prev" = -*r* ]] && compgen -ew && ret=0
-[[ "$prev" != -* ]]  && compgen -eB && ret=0
+if [[ "$prev" = -*a* ]]; then
+  _description expl alias
+  compgen "$expl[@]" -ea && ret=0
+fi
+if [[ "$prev" = -*f* ]]; then
+  _description expl 'shell function'
+  compgen "$expl[@]" -eF && ret=0
+fi
+if [[ "$prev" = -*r* ]]; then
+  _description expl 'reserved word'
+  compgen "$expl[@]" -ew && ret=0
+fi
+if [[ "$prev" != -* ]]; then
+  _description expl 'builtin command'
+  compgen "$expl[@]" -eB && ret=0
+fi
 
 return ret
diff --git a/Completion/Builtins/_echotc b/Completion/Builtins/_echotc
index 15dfcef08..46bf38261 100644
--- a/Completion/Builtins/_echotc
+++ b/Completion/Builtins/_echotc
@@ -1,3 +1,7 @@
 #compdef echotc
 
-compadd al dc dl do le up al bl cd ce cl cr dc dl do ho is le ma nd nl se so up
+local expl
+
+_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
diff --git a/Completion/Builtins/_enable b/Completion/Builtins/_enable
index 483661efe..a698a3895 100644
--- a/Completion/Builtins/_enable
+++ b/Completion/Builtins/_enable
@@ -1,10 +1,22 @@
 #compdef enable
 
-local prev="$words[CURRENT-1]" ret=1
+local prev="$words[CURRENT-1]" ret=1 expl
 
-[[ "$prev" = -*a* ]] && compgen -da && ret=0
-[[ "$prev" = -*f* ]] && compgen -dF && ret=0
-[[ "$prev" = -*r* ]] && compgen -dw && ret=0
-[[ "$prev" != -* ]]  && compgen -dB && ret=0
+if [[ "$prev" = -*a* ]]; then
+  _description expl alias
+  compgen "$expl[@]" -da && ret=0
+fi
+if [[ "$prev" = -*f* ]]; then
+  _description expl 'shell function'
+  compgen "$expl[@]" -dF && ret=0
+fi
+if [[ "$prev" = -*r* ]]; then
+  _description expl 'reserved word'
+  compgen "$expl[@]" -dw && ret=0
+fi
+if [[ "$prev" != -* ]]; then
+  _description expl 'builtin command'
+  compgen "$expl[@]" -dB && ret=0
+fi
 
 return ret
diff --git a/Completion/Builtins/_fc b/Completion/Builtins/_fc
index 5b493dc3b..8d5c82763 100644
--- a/Completion/Builtins/_fc
+++ b/Completion/Builtins/_fc
@@ -1,9 +1,10 @@
 #compdef fc
 
-local prev="$words[CURRENT-1]"
+local prev="$words[CURRENT-1]" expl
 
 if [[ "$prev" = -*e ]]; then
-  compgen -c
+  _description expl command
+  compgen "$expl[@]" -c
 elif [[ "$prev" = -[ARWI]## ]]; then
   _files
 fi
diff --git a/Completion/Builtins/_functions b/Completion/Builtins/_functions
index 52c37952b..7aa30b7bc 100644
--- a/Completion/Builtins/_functions
+++ b/Completion/Builtins/_functions
@@ -1,3 +1,6 @@
 #compdef functions unfunction
 
-compgen -F
+local expl
+
+_description expl 'shell function'
+compgen "$expl[@]" -F
diff --git a/Completion/Builtins/_hash b/Completion/Builtins/_hash
index b03cf7fb9..c8169c590 100644
--- a/Completion/Builtins/_hash
+++ b/Completion/Builtins/_hash
@@ -1,13 +1,17 @@
 #compdef hash
 
+local expl
+
 if [[ "$words[2]" = -*d* ]]; then
   if compset -P 1 '*\='; then
     _path_files -g '*(-/)'
   else
-    compgen -n -q -S '='
+    _description expl 'named directory'
+    compgen "$expl[@]" -n -q -S '='
   fi
 elif compset -P 1 '*\='; then
   _files -/g '*(*)'
 else
-  compgen -m -q -S '='
+  _description expl command
+  compgen "$expl[@]" -m -q -S '='
 fi
diff --git a/Completion/Builtins/_jobs b/Completion/Builtins/_jobs
index 9e2da24c6..b1ff31b4a 100644
--- a/Completion/Builtins/_jobs
+++ b/Completion/Builtins/_jobs
@@ -1,3 +1,6 @@
 #compdef disown fg jobs
 
-compgen -j -P '%'
+local expl
+
+_description expl job
+compgen "$expl[@]" -j -P '%'
diff --git a/Completion/Builtins/_kill b/Completion/Builtins/_kill
index 26f6bf5cd..264253e0a 100644
--- a/Completion/Builtins/_kill
+++ b/Completion/Builtins/_kill
@@ -1,15 +1,18 @@
 #compdef kill
 
-local list
+local list expl
 
 if compset -P 1 -; then
-  compadd $signals[1,-3]
+  _description expl signal
+  compadd "$expl[@]" $signals[1,-3]
 else
   local ret=1
 
-  compgen -P '%' -j && ret=0
+  _description expl job
+  compgen "$expl[@]" -P '%' -j && ret=0
   list=("${(@Mr:COLUMNS-1:)${(f)$(ps ${compconfig[ps_listargs]:-$compconfig[ps_args]} 2>/dev/null)}[2,-1]:#[ 	]#${PREFIX}[0-9]#${SUFFIX}[ 	]*}")
-  compadd -y list - ${${${(f)"$(ps $compconfig[ps_args] 2>/dev/null)"}[2,-1]## #}%% *} &&
+  _description expl 'process ID'
+  compadd "$expl[@]" -y list - ${${${(f)"$(ps $compconfig[ps_args] 2>/dev/null)"}[2,-1]## #}%% *} &&
     ret=0
 
   return ret
diff --git a/Completion/Builtins/_limits b/Completion/Builtins/_limits
index 0b8837d67..0072438c3 100644
--- a/Completion/Builtins/_limits
+++ b/Completion/Builtins/_limits
@@ -1,3 +1,6 @@
 #compdef limit unlimit
 
-compadd ${${(f)"$(limit)"}%% *}
+local expl
+
+_description expl 'process limits'
+compadd "$expl[@]" ${${(f)"$(limit)"}%% *}
diff --git a/Completion/Builtins/_sched b/Completion/Builtins/_sched
index 581438b0e..83aa744ce 100644
--- a/Completion/Builtins/_sched
+++ b/Completion/Builtins/_sched
@@ -1,3 +1,7 @@
 #compdef sched
 
+if [[ CURRENT -eq 2 ]]; then
+  _message 'time specification'
+  return 1
+fi
 compset -n 3 && _normal
diff --git a/Completion/Builtins/_set b/Completion/Builtins/_set
index 59a38b654..297a15d3b 100644
--- a/Completion/Builtins/_set
+++ b/Completion/Builtins/_set
@@ -1,9 +1,11 @@
 #compdef set
 
-local prev="$words[CURRENT-1]"
+local prev="$words[CURRENT-1]" expl
 
 if [[ "$prev" = [-+]o ]]; then
-  compgen -o
+  _description expl 'zsh option'
+  compgen "$expl[@]" -o
 elif [[ "$prev" = -A ]]; then
-  compgen -A
+  _description expl array
+  compgen "$expl[@]" -A
 fi
diff --git a/Completion/Builtins/_stat b/Completion/Builtins/_stat
index 3cdbb2618..5a39e56e5 100644
--- a/Completion/Builtins/_stat
+++ b/Completion/Builtins/_stat
@@ -1,10 +1,14 @@
 #compdef stat
 
+local expl
+
 if [[ "$words[CURRENT-1]" = -[AH] ]]; then
-  compgen -A
+  _description expl array
+  compgen "$expl[@]" -A
 else
+  _description expl 'inode element'
   [[ "$PREFIX[1]" = + ]] &&
-      compadd - +device +inode +mode +nlink +uid +gid +rdev +size \
-                +atime +mtime +ctime +blksize +block +link
+      compadd "$expl[@]" - +device +inode +mode +nlink +uid +gid +rdev +size \
+                           +atime +mtime +ctime +blksize +block +link
   _files
 fi
diff --git a/Completion/Builtins/_trap b/Completion/Builtins/_trap
index bb0630638..d6fc7b388 100644
--- a/Completion/Builtins/_trap
+++ b/Completion/Builtins/_trap
@@ -1,7 +1,11 @@
 #compdef trap
 
+local expl
+
 if [[ CURRENT -eq 2 ]]; then
-  compgen -c
+  _description expl command
+  compgen "$expl[@]" -c
 else
-  compgen -k signals
+  _description expl signal
+  compgen "$expl[@]" -k signals
 fi
diff --git a/Completion/Builtins/_unhash b/Completion/Builtins/_unhash
index 825c130b2..eb1787936 100644
--- a/Completion/Builtins/_unhash
+++ b/Completion/Builtins/_unhash
@@ -1,10 +1,22 @@
 #compdef unhash
 
-local fl="$words[2]" ret=1
+local fl="$words[2]" ret=1 expl
 
-[[ "$fl" = -*d* ]] && compgen -n && ret=0
-[[ "$fl" = -*a* ]] && compgen -a && ret=0
-[[ "$fl" = -*f* ]] && compgen -F && ret=0
-[[ "$fl" != -* ]]  && compgen -m && ret=0
+if [[ "$fl" = -*d* ]]; then
+  _description expl 'named directory'
+  compgen "$expl[@]" -n && ret=0
+fi
+if [[ "$fl" = -*a* ]]; then
+  _description expl alias
+  compgen "$expl[@]" -a && ret=0
+fi
+if [[ "$fl" = -*f* ]]; then
+  _description expl 'shell function'
+  compgen "$expl[@]" -F && ret=0
+fi
+if [[ "$fl" != -* ]]; then
+  _description expl command
+  compgen "$expl[@]" -m && ret=0
+fi
 
 return ret
diff --git a/Completion/Builtins/_vars_eq b/Completion/Builtins/_vars_eq
index 892c1f57e..16a55595e 100644
--- a/Completion/Builtins/_vars_eq
+++ b/Completion/Builtins/_vars_eq
@@ -1,3 +1,6 @@
 #compdef declare export integer local readonly typeset
 
-compgen -v -q -S '='
+local expl
+
+_description expl parameter
+compgen "$expl[@]" -v -q -S '='
diff --git a/Completion/Builtins/_wait b/Completion/Builtins/_wait
index 8f9339ebd..bcd39963f 100644
--- a/Completion/Builtins/_wait
+++ b/Completion/Builtins/_wait
@@ -11,10 +11,12 @@
 #    options for the ps command that are to be used when creating
 #    the list to display during completion.
 
-local list ret=1
+local list ret=1 expl
 
-compgen -P '%' -j && ret=0
+_description expl job
+compgen "$expl[@]" -P '%' -j && ret=0
 list=("${(@Mr:COLUMNS-1:)${(f)$(ps ${compconfig[ps_listargs]:-$compconfig[ps_args]} 2>/dev/null)}[2,-1]:#[ 	]#${PREFIX}[0-9]#${SUFFIX}[ 	]*}")
-compadd -y list - ${${${(f)"$(ps $compconfig[ps_args] 2>/dev/null)"}[2,-1]## #}%% *} && ret=0
+_description expl 'process ID'
+compadd "$expl[@]" -y list - ${${${(f)"$(ps $compconfig[ps_args] 2>/dev/null)"}[2,-1]## #}%% *} && ret=0
 
 return ret
diff --git a/Completion/Builtins/_which b/Completion/Builtins/_which
index db5271653..d67af7316 100644
--- a/Completion/Builtins/_which
+++ b/Completion/Builtins/_which
@@ -1,3 +1,10 @@
 #compdef which whence where type
 
-compgen -caF
+local expl
+
+_description expl command
+compgen "$expl[@]" -c
+_description expl alias
+compgen "$expl[@]" -a
+_description expl 'shell function'
+compgen "$expl[@]" -F
diff --git a/Completion/Builtins/_zftp b/Completion/Builtins/_zftp
index 32d32c2b7..e6f7ea683 100644
--- a/Completion/Builtins/_zftp
+++ b/Completion/Builtins/_zftp
@@ -7,11 +7,12 @@ _compskip=all
 # zfcd_match and zfget_match (used for old-style completion)
 # need to be installed for remote file and directory completion to work.
 
-local subcom
+local subcom expl
 
 if [[ $words[1] = zftp ]]; then
   if [[ $CURRENT -eq 2 ]]; then
-    compadd open params user login type ascii binary mode put \
+    _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
     return
   fi
@@ -24,13 +25,15 @@ case $subcom in
   *(cd|ls|dir))
    # complete remote directories; we could be smarter about hiding prefixes
    zfcd_match $PREFIX $SUFFIX
-   (( $#reply )) && compadd -S/ -q - $reply
+   _description expl 'remote directory'
+   (( $#reply )) && compadd "$expl[@]" -S/ -q - $reply
    ;;
 
   *(get(|at)|gcp|delete|remote))
    # complete remote files
    zfget_match $PREFIX $SUFFIX
-   (( $#reply )) && compadd -F fignore - $reply
+   _description expl 'remote file'
+   (( $#reply )) && compadd "$expl[@]" -F fignore - $reply
    ;;
 
   *(put(|at)|pcp))
@@ -40,18 +43,20 @@ case $subcom in
 
   *(open|anon|params))
   # complete hosts:  should do cleverer stuff with user names
-  compgen -k hosts
+  _description expl host
+  compgen "$expl[@]" -k hosts
   ;;
 
   *(goto|mark))
   # complete bookmarks.  First decide if ncftp mode is go.
+  _description expl bookmark
   if [[ $words[2] = -*n* ]]; then
     if [[ -f ~/.ncftp/bookmarks ]]; then
-      compadd - $(awk -F, 'NR > 2 { print $1 }' ~/.ncftp/bookmarks)
+      compadd "$expl[@]" - $(awk -F, 'NR > 2 { print $1 }' ~/.ncftp/bookmarks)
     fi
   else
     if [[ -f ${ZFTP_BMFILE:=${ZDOTDIR:-$HOME}/.zfbkmarks} ]]; then
-      compadd - $(awk '{print $1}' $ZFTP_BMFILE)
+      compadd "$expl[@]" - $(awk '{print $1}' $ZFTP_BMFILE)
     fi
   fi
   ;;
diff --git a/Completion/Builtins/_zle b/Completion/Builtins/_zle
index f0860c5e3..06e8fcad3 100644
--- a/Completion/Builtins/_zle
+++ b/Completion/Builtins/_zle
@@ -1,7 +1,11 @@
 #compdef zle
 
+local expl
+
 if [[ "$words[2]" = -N && CURRENT -eq 3 ]]; then
-  compgen -F
+  _description expl 'widget shell function'
+  compgen "$expl[@]" -F
 else
-  compgen -b
+  _description expl widget
+  compgen "$expl[@]" -b
 fi
diff --git a/Completion/Builtins/_zmodload b/Completion/Builtins/_zmodload
index d3a39b5de..9bac1484e 100644
--- a/Completion/Builtins/_zmodload
+++ b/Completion/Builtins/_zmodload
@@ -1,11 +1,14 @@
 #compdef zmodload
 
-local fl="$words[2]"
+local fl="$words[2]" expl
 
 if [[ "$fl" = -*(a*u|u*a)* || "$fl" = -*a* && CURRENT -ge 4 ]]; then
-  compgen -B
+  _description expl 'builtin command'
+  compgen "$expl[@]" -B
 elif [[ "$fl" = -*u* ]]; then
+  _description expl module
   compadd - $(zmodload)
 else
+  _description expl 'module file'
   compadd - ${^module_path}/*(N:t:r)
 fi
diff --git a/Completion/Commands/_history_complete_word b/Completion/Commands/_history_complete_word
index 8e99aec17..fb1c502c8 100644
--- a/Completion/Commands/_history_complete_word
+++ b/Completion/Commands/_history_complete_word
@@ -1,2 +1,6 @@
 #compdef -kn complete-word \e/
-compgen -Q -H 0 ''
+
+local expl
+
+_description expl 'history word'
+compgen "$expl[@]" -Q -H 0 ''
diff --git a/Completion/Core/_description b/Completion/Core/_description
new file mode 100644
index 000000000..874ba8a96
--- /dev/null
+++ b/Completion/Core/_description
@@ -0,0 +1,22 @@
+#autoload
+
+local gropt=-J
+
+if [[ "$1" = -V ]]; then
+  gropt=-V
+  shift
+fi
+
+if [[ -n "$compconfig[group_matches]" ]]; then
+  if [[ -n "$compconfig[description_format]" ]]; then
+    eval "$1=($gropt ${(q)2} -X ${(q)compconfig[description_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})"
+  else
+    eval "$1=()"
+  fi
+fi
diff --git a/Completion/Core/_main_complete b/Completion/Core/_main_complete
index 4ac45d2cc..6e84818ee 100644
--- a/Completion/Core/_main_complete
+++ b/Completion/Core/_main_complete
@@ -22,6 +22,24 @@
 #  last_prompt
 #    If this is set to `always' the cursor is moved up to the last prompt
 #    after printing a list even if a numeric argument was given.
+#
+#
+# Also, most completion functions use the configuration keys:
+#
+#  description_format
+#    If this is set to a non-empty string, it will be displayed above
+#    all matches generated. The sequence `%d' in this string is replaced
+#    by a short description of what is completed in the current position
+#    of the command line.
+#
+#  message_format
+#    Like `description_format', but used in places where no completions
+#    can automatically be generated but the completion system still wants
+#    to give a hint what is expected in that position.
+#
+#  group_matches
+#    If this is set to a non-empty string, different types of matches will
+#    be put in different groups.
 
 
 # If you want to complete only set or unset options for the unsetopt
diff --git a/Completion/Core/_message b/Completion/Core/_message
new file mode 100644
index 000000000..0837cdf2f
--- /dev/null
+++ b/Completion/Core/_message
@@ -0,0 +1,19 @@
+#autoload
+
+local format
+
+format="$compconfig[message_format]"
+[[ -z "$format" ]] && "$compconfig[description_format]"
+
+if [[ -n "$format" ]]; then
+  if [[ $compstate[nmatches] -eq 0 ]]; then
+    compstate[list]=list
+    compstate[insert]=''
+    compadd -UX "${format//\\%d/$1}" -n ''
+  else
+    compadd -X "${format//\\%d/$1}" -n ''
+  fi
+  compstate[force_list]=yes
+else
+  compadd -n ''
+fi
diff --git a/Completion/Core/_normal b/Completion/Core/_normal
index d4e948e41..ffacc8f04 100644
--- a/Completion/Core/_normal
+++ b/Completion/Core/_normal
@@ -29,13 +29,15 @@ fi
 
 # See if there are any matching pattern completions.
 
-if [[ "$_compskip" != *patterns* ]]; then
+if [[ "$_compskip" != (all|*patterns*) ]]; then
   for i in "$_patcomps[@]"; do
     pat="${i% *}"
     val="${i#* }"
     if [[ "$cmd1" == $~pat || "$cmd2" == $~pat ]]; then
       "$val" && ret=0
-      if [[ "$_compskip" = *patterns* || "$_compskip" = all ]]; then
+      if [[ "$_compskip" = *patterns* ]]; then
+        break
+      elif [[ "$_compskip" = all ]]; then
         unset _compskip
         return ret
       fi
@@ -55,15 +57,36 @@ fi
 
 # And generate the matches, probably using default completion.
 
-if [[ -z "$comp" ]]; then
-  if [[ "$_compskip" = *default* ]]; then
-    unset _compskip
-    return 1
+if [[ -n "$comp" ]]; then
+  _compskip=patterns
+  "$comp" && ret=0
+  [[ "$_compskip" = (all|*patterns*) ]] && return ret
+else
+  if [[ "$_compskip" != *default* ]]; then
+    name=-default-
+    comp="$_comps[-default-]"
   fi
-  name=-default-
-  comp="$_comps[-default-]"
 fi
-[[ -z "$comp" ]] || "$comp" && ret=0
+  
+if [[ "$_compskip" != (all|*patterns*) ]]; then
+  for i in "$_postpatcomps[@]"; do
+    pat="${i% *}"
+    val="${i#* }"
+    if [[ "$cmd1" == $~pat || "$cmd2" == $~pat ]]; then
+      _compskip=default
+      "$val" && ret=0
+      if [[ "$_compskip" = *patterns* ]]; then
+	break
+      elif [[ "$_compskip" = all ]]; then
+        unset _compskip
+        return ret
+      fi
+    fi
+  done
+fi
+
+[[ "$name" = -default- && -n "$comp" && "$_compskip" != (all|*default*) ]] &&
+  "$comp" && ret=0
 
 unset _compskip
 
diff --git a/Completion/Core/_options b/Completion/Core/_options
index 0a852e6ce..356cd70db 100644
--- a/Completion/Core/_options
+++ b/Completion/Core/_options
@@ -2,4 +2,7 @@
 
 # This should be used to complete all option names.
 
-compgen "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -o
+local expl
+
+_description expl 'zsh option'
+compgen "$expl[@]" "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -o
diff --git a/Completion/Core/_parameters b/Completion/Core/_parameters
index a579e5ead..824d8dbc9 100644
--- a/Completion/Core/_parameters
+++ b/Completion/Core/_parameters
@@ -4,9 +4,13 @@
 # extra options of compadd. It completes only non-local parameters. All
 # arguments are given to compadd.
 
+local expl
+
+_description expl parameter
+
 if zmodload -e parameter; then
   setopt localoptions extendedglob
-  compadd "$@" - ${(k)parameters[(R)^*local*]}
+  compadd "$expl[@]" "$@" - ${(k)parameters[(R)^*local*]}
 else
-  compadd "$@" - ${${${(f)"$(typeset +)"}:#*local *}##* }
+  compadd "$expl[@]" "$@" - ${${${(f)"$(typeset +)"}:#*local *}##* }
 fi
diff --git a/Completion/Core/_path_files b/Completion/Core/_path_files
index 9494d5a4a..9aebc89d0 100644
--- a/Completion/Core/_path_files
+++ b/Completion/Core/_path_files
@@ -91,6 +91,14 @@ while getopts "P:S:qr:R:W:F:J:V:X:f/g:" opt; do
   esac
 done
 
+if (( ! ( $#group + $#expl ) )); then
+  if [[ "$sopt" = -/ ]]; then
+    _description expl directory
+  else
+    _description expl file
+  fi
+fi
+
 [[ -n "$tmp1" && $#addsfx -ne 0 ]] && addsfx[1]=-qS
 
 # If we were given no file selection option, we behave as if we were given
diff --git a/Completion/Core/_set_options b/Completion/Core/_set_options
index 5f634a2cd..947afdeae 100644
--- a/Completion/Core/_set_options
+++ b/Completion/Core/_set_options
@@ -4,4 +4,7 @@
 # names of the options that were set when it was called in the array
 # `_set_options'.
 
-compadd "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - $=_set_options
+local expl
+
+_description expl 'set zsh option'
+compadd "$expl[@]" "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - $=_set_options
diff --git a/Completion/Core/_unset_options b/Completion/Core/_unset_options
index c5150c2e5..f6a1c58f0 100644
--- a/Completion/Core/_unset_options
+++ b/Completion/Core/_unset_options
@@ -4,4 +4,7 @@
 # names of the options that were set when it was called in the array
 # `_set_options'.
 
-compadd "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - $=_unset_options
+local expl
+
+_description expl 'unset zsh option'
+compadd "$expl[@]" "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - $=_unset_options
diff --git a/Completion/Core/compdump b/Completion/Core/compdump
index 8f8a3ee77..b4530ea8e 100644
--- a/Completion/Core/compdump
+++ b/Completion/Core/compdump
@@ -39,6 +39,12 @@ for _d_f in "$_patcomps[@]"; do
 done >> $_d_file
 print ")" >> $_d_file
 
+print "\n_postpatcomps=(" >> $_d_file
+for _d_f in "$_postpatcomps[@]"; do
+  print -r - "'${_d_f//\'/'\\''}'"
+done >> $_d_file
+print ")" >> $_d_file
+
 print >> $_d_file
 
 # Now dump the key bindings. We dump all bindings for zle widgets
diff --git a/Completion/Core/compinit b/Completion/Core/compinit
index 808c20f5b..f160e7dcf 100644
--- a/Completion/Core/compinit
+++ b/Completion/Core/compinit
@@ -68,10 +68,12 @@ while [[ $# -gt 0 && $1 = -[dDf] ]]; do
 done
 
 # The associative array containing the definitions for the commands.
-# Definitions for patterns will be stored in the normal array `_patcomps'.
+# Definitions for patterns will be stored in the normal arrays `_patcomps'
+# and `_postpatcomps'.
 
 typeset -gA _comps
 _patcomps=()
+_postpatcomps=()
 
 # The associative array use to report information about the last
 # cmpletion to the outside.
@@ -106,6 +108,9 @@ fi
 # function will be invoked when completing for a command whose name 
 # matches the pattern given as argument after the function name (in this
 # case only one argument is accepted).
+# The option `-P' is like `-p', but the function will be called after
+# trying to find a function defined for the command on the line if no
+# such function could be found.
 # With the `-k' option a function for a special completion keys is 
 # defined and immediatly bound to those keys. Here, the extra arguments
 # are the name of one of the builtin completion widgets and any number
@@ -147,11 +152,11 @@ compdef() {
 
   # Get the options.
 
-  while getopts "anpkd" opt; do
+  while getopts "anpPkd" opt; do
     case "$opt" in
     a)    autol=yes;;
     n)    new=yes;;
-    [pk]) if [[ -n "$type" ]]; then
+    [pPk]) if [[ -n "$type" ]]; then
             # Error if both `-p' and `-k' are given (or one of them
 	    # twice).
             echo "$0: type already set to $type"
@@ -159,6 +164,8 @@ compdef() {
 	  fi
 	  if [[ "$opt" = p ]]; then
 	    type=pattern
+	  elif [[ "$opt" = P ]]; then
+	    type=postpattern
 	  else
 	    type=key
 	  fi
@@ -187,6 +194,13 @@ compdef() {
 
       _patcomps=("$_patcomps[@]" "$1 $func")
       ;;
+    postpattern)
+      if [[ $# -gt 1 ]]; then
+        echo "$0: only one pattern allowed"
+	return 1
+      fi
+      _postpatcomps=("$_postpatcomps[@]" "$1 $func")
+      ;;
     key)
       if [[ $# -lt 2 ]]; then
         echo "$0: missing keys"
@@ -230,7 +244,12 @@ compdef() {
     pattern)
       # Note the space.
       for i; do
-        _patcomps=("${(@)patcomps:#$i *}")
+        _patcomps=("${(@)_patcomps:#$i *}")
+      done
+      ;;
+    postpattern)
+      for i; do
+        _postpatcomps=("${(@)_postpatcomps:#$i *}")
       done
       ;;
     key)
@@ -359,7 +378,7 @@ if [[ -z "$_i_done" ]]; then
       shift _i_line
       case $_i_tag in
       (\#compdef)
-	if [[ $_i_line[1] = -[pk](n|) ]]; then
+	if [[ $_i_line[1] = -[pPk](n|) ]]; then
 	  compdef ${_i_line[1]}a "${_i_file:t}" "${(@)_i_line[2,-1]}"
 	else
 	  compdef -na "${_i_file:t}" "${_i_line[@]}"
diff --git a/Completion/Pbmplus/_asciitopnm b/Completion/Pbmplus/_asciitopnm
new file mode 100644
index 000000000..70f95692c
--- /dev/null
+++ b/Completion/Pbmplus/_asciitopnm
@@ -0,0 +1,3 @@
+#compdef asciitopnm
+
+_arguments '-d:divisor:' ':height:' ':width:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_fitstopgm b/Completion/Pbmplus/_fitstopgm
new file mode 100644
index 000000000..de19bd9ea
--- /dev/null
+++ b/Completion/Pbmplus/_fitstopgm
@@ -0,0 +1,3 @@
+#compdef fitstopgm
+
+_arguments '-image:image number:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_fitstopnm b/Completion/Pbmplus/_fitstopnm
new file mode 100644
index 000000000..6dcd56134
--- /dev/null
+++ b/Completion/Pbmplus/_fitstopnm
@@ -0,0 +1,4 @@
+#compdef fitstopnm
+
+_arguments '-image:image number:' '-noraw' '-scanmax' '-printmax' \
+           '-min:minimum value:' '-max:maximum value:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_g3topbm b/Completion/Pbmplus/_g3topbm
new file mode 100644
index 000000000..c6cfa34fe
--- /dev/null
+++ b/Completion/Pbmplus/_g3topbm
@@ -0,0 +1,3 @@
+#compdef g3topbm
+
+_arguments '-kludge' '-reversebits' '-stretch' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_giftopnm b/Completion/Pbmplus/_giftopnm
new file mode 100644
index 000000000..1a3e6e1c3
--- /dev/null
+++ b/Completion/Pbmplus/_giftopnm
@@ -0,0 +1,4 @@
+#compdef giftopnm
+
+_arguments '-verbose' '-comments' '-image:image number:' \
+           ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_macptopbm b/Completion/Pbmplus/_macptopbm
new file mode 100644
index 000000000..ffcd280ad
--- /dev/null
+++ b/Completion/Pbmplus/_macptopbm
@@ -0,0 +1,3 @@
+#compdef macptopbm
+
+_arguments '-extraskip:number of bytes to skip:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pbm_file b/Completion/Pbmplus/_pbm_file
new file mode 100644
index 000000000..6f96d9460
--- /dev/null
+++ b/Completion/Pbmplus/_pbm_file
@@ -0,0 +1,20 @@
+#compdef -P (p[bgpn]m*|*top[bgpn]m)
+
+local expl
+
+if [[ "$words[1]" = pnm* ]]; then
+  pat='*.(#i)p[bgp]m'
+elif [[ "$words[1]" = *top[bgpn]m ]]; then
+  pat="*.(#i)${words[1]%%top[bgpn]m}"
+else
+  pat="*.(#i)${words[1][1,3]}"
+fi
+
+if (( $# )); then
+  expl=( "$@" )
+else
+  _description expl 'picture file'
+fi
+
+_path_files "$expl[@]" -g "$pat" ||
+    _files "$expl[@]" -g '*.(#i)p[bgp]m'
diff --git a/Completion/Pbmplus/_pbmclean b/Completion/Pbmplus/_pbmclean
new file mode 100644
index 000000000..8b265cb29
--- /dev/null
+++ b/Completion/Pbmplus/_pbmclean
@@ -0,0 +1,3 @@
+#compdef pbmclean
+
+_arguments '-connect' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pbmmake b/Completion/Pbmplus/_pbmmake
new file mode 100644
index 000000000..ffb437a5e
--- /dev/null
+++ b/Completion/Pbmplus/_pbmmake
@@ -0,0 +1,3 @@
+#compdef pbmmake
+
+_arguments '-white' '-black' '-gray' ':width:' ':height:'
diff --git a/Completion/Pbmplus/_pbmmask b/Completion/Pbmplus/_pbmmask
new file mode 100644
index 000000000..2207ce772
--- /dev/null
+++ b/Completion/Pbmplus/_pbmmask
@@ -0,0 +1,3 @@
+#compdef pbmmask
+
+_arguments '-expand' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pbmpscale b/Completion/Pbmplus/_pbmpscale
new file mode 100644
index 000000000..76c00b247
--- /dev/null
+++ b/Completion/Pbmplus/_pbmpscale
@@ -0,0 +1,3 @@
+#compdef pbmpscale
+
+_arguments ':scale factor:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pbmreduce b/Completion/Pbmplus/_pbmreduce
new file mode 100644
index 000000000..8a32e6a88
--- /dev/null
+++ b/Completion/Pbmplus/_pbmreduce
@@ -0,0 +1,4 @@
+#compdef pbmreduce
+
+_arguments '-floyd' '-fs' '-threshold' '-value:threshold value:' \
+           ':reduction factor:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pbmtext b/Completion/Pbmplus/_pbmtext
new file mode 100644
index 000000000..1ef1fd9f1
--- /dev/null
+++ b/Completion/Pbmplus/_pbmtext
@@ -0,0 +1,3 @@
+#compdef pbmtext
+
+_arguments '-font:font file:_files -g *.(#i)pbm' '*:text:'
diff --git a/Completion/Pbmplus/_pbmto10x b/Completion/Pbmplus/_pbmto10x
new file mode 100644
index 000000000..ce233e5ae
--- /dev/null
+++ b/Completion/Pbmplus/_pbmto10x
@@ -0,0 +1,3 @@
+#compdef pbmto10x
+
+_arguments '-h' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pbmtobg b/Completion/Pbmplus/_pbmtobg
new file mode 100644
index 000000000..729332745
--- /dev/null
+++ b/Completion/Pbmplus/_pbmtobg
@@ -0,0 +1,3 @@
+#compdef pbmtobg pbmtobbnbg
+
+_arguments ':raster operation:' ':x position:' ':y position:'
diff --git a/Completion/Pbmplus/_pbmtoepsi b/Completion/Pbmplus/_pbmtoepsi
new file mode 100644
index 000000000..7bba77295
--- /dev/null
+++ b/Completion/Pbmplus/_pbmtoepsi
@@ -0,0 +1,3 @@
+#compdef pbmtoepsi
+
+_arguments '--bbonly' ':file: _pbmfile'
diff --git a/Completion/Pbmplus/_pbmtolj b/Completion/Pbmplus/_pbmtolj
new file mode 100644
index 000000000..6ccc63b6d
--- /dev/null
+++ b/Completion/Pbmplus/_pbmtolj
@@ -0,0 +1,3 @@
+#compdef pbmtolj
+
+_arguments '-resolution:resolution:(75 100 150 300)' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pbmtoln03 b/Completion/Pbmplus/_pbmtoln03
new file mode 100644
index 000000000..12b106dea
--- /dev/null
+++ b/Completion/Pbmplus/_pbmtoln03
@@ -0,0 +1,5 @@
+#compdef pbmtoln03
+
+_arguments '-l:left margin:' '-r:right margin:' \
+           '-t:top margin:'  '-b:bottom margin:' \
+           '-f:form length:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pbmtolps b/Completion/Pbmplus/_pbmtolps
new file mode 100644
index 000000000..801948c11
--- /dev/null
+++ b/Completion/Pbmplus/_pbmtolps
@@ -0,0 +1,3 @@
+#compdef pbmtolps
+
+_arguments '-dpi:resolution:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pbmtomacp b/Completion/Pbmplus/_pbmtomacp
new file mode 100644
index 000000000..aa9e94e73
--- /dev/null
+++ b/Completion/Pbmplus/_pbmtomacp
@@ -0,0 +1,4 @@
+#compdef pbmtomacp
+
+_arguments '-l:left offset:' '-r:right offset:' \
+           '-t:top offset:'  '-b:bottom offset:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pbmtopgm b/Completion/Pbmplus/_pbmtopgm
new file mode 100644
index 000000000..29bd5422f
--- /dev/null
+++ b/Completion/Pbmplus/_pbmtopgm
@@ -0,0 +1,3 @@
+#compdef pbmtopgm
+
+_arguments ':width:' ':height:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pbmtopk b/Completion/Pbmplus/_pbmtopk
new file mode 100644
index 000000000..913d11106
--- /dev/null
+++ b/Completion/Pbmplus/_pbmtopk
@@ -0,0 +1,11 @@
+#compdef pbmtopk
+
+# This could be improved...
+
+_arguments '-s:design size:' '-C:coding scheme:' '-F:font family:' \
+           '-f:option file:_files' '-c:character number:' \
+           '-W:width:' '-H:height:' '-D:depth:' '-I:italic correction:' \
+           '-h:horizontal escapement:' '-v:vertical escapement:' \
+	   '-x:x offset:' '-y:y offset:' \
+           ':pk file:_files -g *.(#i)pk' ':tfm file:_files -g *.(#i)tfm' \
+	   '*:file: _pbm_file'
diff --git a/Completion/Pbmplus/_pbmupc b/Completion/Pbmplus/_pbmupc
new file mode 100644
index 000000000..b77488d57
--- /dev/null
+++ b/Completion/Pbmplus/_pbmupc
@@ -0,0 +1,4 @@
+#compdef pbmupc
+
+_arguments '-s1' '-s2' ':product type:' ':manufacturer code:' \
+           ':product code:'
diff --git a/Completion/Pbmplus/_pgmcrater b/Completion/Pbmplus/_pgmcrater
new file mode 100644
index 000000000..5905ea8a2
--- /dev/null
+++ b/Completion/Pbmplus/_pgmcrater
@@ -0,0 +1,5 @@
+#compdef pgmcrater
+
+_arguments '-number:number of craters:' '-gamma:factor:' \
+           '-height:height:' '-ysize:height:' \
+	   '-width:width:'   '-xsize:width:'
diff --git a/Completion/Pbmplus/_pgmkernel b/Completion/Pbmplus/_pgmkernel
new file mode 100644
index 000000000..83a3e6ae2
--- /dev/null
+++ b/Completion/Pbmplus/_pgmkernel
@@ -0,0 +1,3 @@
+#compdef pgmkernel
+
+_arguments '-weight:weight:' ':width:' ':height:'
diff --git a/Completion/Pbmplus/_pgmnoise b/Completion/Pbmplus/_pgmnoise
new file mode 100644
index 000000000..efcd5b82b
--- /dev/null
+++ b/Completion/Pbmplus/_pgmnoise
@@ -0,0 +1,3 @@
+#compdef pgmnoise
+
+_arguments ':width:' ':height:'
diff --git a/Completion/Pbmplus/_pgmnorm b/Completion/Pbmplus/_pgmnorm
new file mode 100644
index 000000000..e088550e9
--- /dev/null
+++ b/Completion/Pbmplus/_pgmnorm
@@ -0,0 +1,5 @@
+#compdef pgmnorm ppmnorm
+
+_arguments '-bpercent:black percentage:' '-bvalue:black pixel value:' \
+           '-wpercent:white percentage:' '-wvalue:white pixel value:' \
+	   ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pgmoil b/Completion/Pbmplus/_pgmoil
new file mode 100644
index 000000000..e1c7a0c0f
--- /dev/null
+++ b/Completion/Pbmplus/_pgmoil
@@ -0,0 +1,3 @@
+#compdef pgmoil
+
+_arguments '-n:smear size:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pgmramp b/Completion/Pbmplus/_pgmramp
new file mode 100644
index 000000000..9fa7c0b54
--- /dev/null
+++ b/Completion/Pbmplus/_pgmramp
@@ -0,0 +1,3 @@
+#compdef pgmramp
+
+_arguments '-lr' '-tb' '-rectangle' '-ellipse' ':width:' ':height:'
diff --git a/Completion/Pbmplus/_pgmtexture b/Completion/Pbmplus/_pgmtexture
new file mode 100644
index 000000000..48e29066a
--- /dev/null
+++ b/Completion/Pbmplus/_pgmtexture
@@ -0,0 +1,3 @@
+#compdef pgmtexture
+
+_arguments '-d:distance:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pgmtopbm b/Completion/Pbmplus/_pgmtopbm
new file mode 100644
index 000000000..642d6277b
--- /dev/null
+++ b/Completion/Pbmplus/_pgmtopbm
@@ -0,0 +1,5 @@
+#compdef pgmtopbm
+
+_arguments '-floyd' '-fs' '-threshold' '-dither8' '-d8' '-cluster3' '-c3' \
+           '-cluster4' '-c4' '-cluster8' '-c8' '-value:threshold value:' \
+	   ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pgmtoppm b/Completion/Pbmplus/_pgmtoppm
new file mode 100644
index 000000000..c8b1abec6
--- /dev/null
+++ b/Completion/Pbmplus/_pgmtoppm
@@ -0,0 +1,21 @@
+#compdef pgmtoppm
+
+local ret=1 expl
+
+if [[ CURRENT -eq 2 ]]; then
+  if compset -P '?*-'; then
+    _colors
+    return
+  fi
+  _colors && ret=0
+
+  _description expl option
+  compadd "$expl[@]" - -map && ret=0
+
+  return ret
+elif [[ CURRENT -eq 3 && "$words[2]" = -map ]]; then
+  _description expl 'map file'
+  _files "$expl[@]" -g '*.(#i)ppm'
+else
+  _pbm_file
+fi
diff --git a/Completion/Pbmplus/_pktopbm b/Completion/Pbmplus/_pktopbm
new file mode 100644
index 000000000..5b97fdd33
--- /dev/null
+++ b/Completion/Pbmplus/_pktopbm
@@ -0,0 +1,4 @@
+#compdef pktopbm
+
+_arguments ':pk file:_file -g *.(#i)pk' '-c:character number:' \
+           '*:file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmalias b/Completion/Pbmplus/_pnmalias
new file mode 100644
index 000000000..4dda6fb9f
--- /dev/null
+++ b/Completion/Pbmplus/_pnmalias
@@ -0,0 +1,6 @@
+#compdef pnmalias
+
+_arguments '-bgcolor:background color:_colors' \
+           '-fgcolor:foreground color:_colors' \
+	   '-bonly' '-fonly' '-balias' '-falias' \
+	   '-weight:central aliasing weight:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmarith b/Completion/Pbmplus/_pnmarith
new file mode 100644
index 000000000..568c923db
--- /dev/null
+++ b/Completion/Pbmplus/_pnmarith
@@ -0,0 +1,3 @@
+#compdef pnmarith
+
+_arguments '-add' '-subtract' '-multiply' '*:file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmcat b/Completion/Pbmplus/_pnmcat
new file mode 100644
index 000000000..6d71cae10
--- /dev/null
+++ b/Completion/Pbmplus/_pnmcat
@@ -0,0 +1,4 @@
+#compdef pnmcat
+
+_arguments '-white' '-black' '-leftright' '-lr' '-topbottom' '-tb' \
+           '-jtop' '-jbottom' '-jleft' '-jright' '*:file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmcomp b/Completion/Pbmplus/_pnmcomp
new file mode 100644
index 000000000..01f8bb33e
--- /dev/null
+++ b/Completion/Pbmplus/_pnmcomp
@@ -0,0 +1,5 @@
+#compdef pnmcomp
+
+_arguments '-invert' '-xoff:x offset:' '-yoff:y offset:' \
+           '-alpha:alpha mask file:_files -g *.(#i)pgm' \
+	   ':overlay file:_pbm_file' '*:file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmconvol b/Completion/Pbmplus/_pnmconvol
new file mode 100644
index 000000000..69785b3d1
--- /dev/null
+++ b/Completion/Pbmplus/_pnmconvol
@@ -0,0 +1,3 @@
+#compdef pnmconvol
+
+_arguments ':convolution file:_pbm_file' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmcrop b/Completion/Pbmplus/_pnmcrop
new file mode 100644
index 000000000..a7a29cacb
--- /dev/null
+++ b/Completion/Pbmplus/_pnmcrop
@@ -0,0 +1,3 @@
+#compdef pnmcrop
+
+_arguments '-white' '-black' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmcut b/Completion/Pbmplus/_pnmcut
new file mode 100644
index 000000000..7e3884b59
--- /dev/null
+++ b/Completion/Pbmplus/_pnmcut
@@ -0,0 +1,3 @@
+#compdef pnmcut
+
+_arguments ':x position:' ':y position:' ':width:' ':height:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmdepth b/Completion/Pbmplus/_pnmdepth
new file mode 100644
index 000000000..76263c595
--- /dev/null
+++ b/Completion/Pbmplus/_pnmdepth
@@ -0,0 +1,3 @@
+#compdef pnmdepth
+
+_arguments ':new maximum value:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmenlarge b/Completion/Pbmplus/_pnmenlarge
new file mode 100644
index 000000000..511122f9f
--- /dev/null
+++ b/Completion/Pbmplus/_pnmenlarge
@@ -0,0 +1,3 @@
+#compdef pnmenlarge
+
+_arguments ':enlargement factor:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmflip b/Completion/Pbmplus/_pnmflip
new file mode 100644
index 000000000..ecec27dd9
--- /dev/null
+++ b/Completion/Pbmplus/_pnmflip
@@ -0,0 +1,5 @@
+#compdef pnmflip
+
+_arguments '-leftright' '-lr' '-topbottom' '-tb' '-transpose' '-xy' \
+           '-rotate90' '-r90' '-ccw' '-rotate270' '-r270' '-cw' \
+	   ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmgamma b/Completion/Pbmplus/_pnmgamma
new file mode 100644
index 000000000..c9d141535
--- /dev/null
+++ b/Completion/Pbmplus/_pnmgamma
@@ -0,0 +1,16 @@
+#compdef pnmgamma
+
+local ret=1
+
+if [[ CURRENT -eq 2 ]]; then
+  _message 'gamma value or red gamma value'
+elif [[ CURRENT -eq 3 ]]; then
+  _pbm_file && ret=0
+  _message 'green gamma value'
+elif [[ CURRENT -eq 4 ]]; then
+  _message 'blue gamma value'
+elif [[ CURRENT -eq 5 ]]; then
+  _pbm_file && ret=0
+fi
+
+return ret
diff --git a/Completion/Pbmplus/_pnmhistmap b/Completion/Pbmplus/_pnmhistmap
new file mode 100644
index 000000000..b011c2d94
--- /dev/null
+++ b/Completion/Pbmplus/_pnmhistmap
@@ -0,0 +1,4 @@
+#compdef pnmhistmap
+
+_arguments '-black' '-white' '-max:maximum value:' '-verbose' \
+           ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmindex b/Completion/Pbmplus/_pnmindex
new file mode 100644
index 000000000..39b6bacbb
--- /dev/null
+++ b/Completion/Pbmplus/_pnmindex
@@ -0,0 +1,4 @@
+#compdef pnmindex
+
+_arguments '-size:image size:' '-across:images per row:' \
+           '-colors:number of colors:' '-black' '*:file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmmargin b/Completion/Pbmplus/_pnmmargin
new file mode 100644
index 000000000..90e196f8d
--- /dev/null
+++ b/Completion/Pbmplus/_pnmmargin
@@ -0,0 +1,4 @@
+#compdef pnmmargin
+
+_arguments '-white' '-black' '-color:color: _colors' \
+           ':border width:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmnlfilt b/Completion/Pbmplus/_pnmnlfilt
new file mode 100644
index 000000000..c5a25053d
--- /dev/null
+++ b/Completion/Pbmplus/_pnmnlfilt
@@ -0,0 +1,3 @@
+#compdef pnmnlfilt
+
+_arguments ':alpha value:' ':radius:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmpad b/Completion/Pbmplus/_pnmpad
new file mode 100644
index 000000000..9516c5281
--- /dev/null
+++ b/Completion/Pbmplus/_pnmpad
@@ -0,0 +1,6 @@
+#compdef pnmpad
+
+_arguments '-black' '-white' \
+           '-l-:left border width:' '-r-:right border width:' \
+           '-t-:top border width:' '-b-:bottom border width:' \
+           ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmpaste b/Completion/Pbmplus/_pnmpaste
new file mode 100644
index 000000000..2728d959d
--- /dev/null
+++ b/Completion/Pbmplus/_pnmpaste
@@ -0,0 +1,6 @@
+#compdef pnmpaste
+
+_arguments '-replace' '-or' '-and' '-xor' \
+           ':"from" picture file:_pbm_file' \
+	   ':x position:' ':y position:' \
+	   ':"into" picture file:_pbm_file'
diff --git a/Completion/Pbmplus/_pnmrotate b/Completion/Pbmplus/_pnmrotate
new file mode 100644
index 000000000..84e568ec9
--- /dev/null
+++ b/Completion/Pbmplus/_pnmrotate
@@ -0,0 +1,3 @@
+#compdef pnmrotate
+
+_arguments '-noantialias' ':rotation angle:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmscale b/Completion/Pbmplus/_pnmscale
new file mode 100644
index 000000000..3b56071b0
--- /dev/null
+++ b/Completion/Pbmplus/_pnmscale
@@ -0,0 +1,16 @@
+#compdef pnmscale
+
+local scale
+
+if [[ "$words[2]" = -* ]]; then
+  scale=()
+else
+  scale=( ':scale factor:' )
+fi
+
+_arguments '-xsize:width:'  '-width:width:' \
+           '-ysize:height:' '-height:height:' \
+	   '-xscale:horizontal scale factor:' \
+	   '-yscale:horizontal scale factor:' \
+	   '-xysize:width::height:' "$scale[@]" \
+	   ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmshear b/Completion/Pbmplus/_pnmshear
new file mode 100644
index 000000000..a94e4347b
--- /dev/null
+++ b/Completion/Pbmplus/_pnmshear
@@ -0,0 +1,3 @@
+#compdef pnmshear
+
+_arguments '-noantialias' ':shearing angle:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmtile b/Completion/Pbmplus/_pnmtile
new file mode 100644
index 000000000..eb2a45989
--- /dev/null
+++ b/Completion/Pbmplus/_pnmtile
@@ -0,0 +1,3 @@
+#compdef pnmtile
+
+_arguments ':width:' ':height:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmtoddif b/Completion/Pbmplus/_pnmtoddif
new file mode 100644
index 000000000..c7578c792
--- /dev/null
+++ b/Completion/Pbmplus/_pnmtoddif
@@ -0,0 +1,4 @@
+#compdef pnmtoddif
+
+_arguments '-resolution:horizontal resolution::vertical resolution:' \
+           ':file: _pbm_file' ':ddif file:_files -g *.(#i)ddif'
diff --git a/Completion/Pbmplus/_pnmtofits b/Completion/Pbmplus/_pnmtofits
new file mode 100644
index 000000000..fe3e33569
--- /dev/null
+++ b/Completion/Pbmplus/_pnmtofits
@@ -0,0 +1,3 @@
+#compdef pnmtofits
+
+_arguments '-max:maximum value:' '-min:minimum value:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmtops b/Completion/Pbmplus/_pnmtops
new file mode 100644
index 000000000..4b66701a0
--- /dev/null
+++ b/Completion/Pbmplus/_pnmtops
@@ -0,0 +1,5 @@
+#compdef pnmtops
+
+_arguments '-scale:scale factor:' '-turn' '-noturn' '-rle' '-runlength' \
+           '-dpi:output resolution:' \
+           '-width:page width:' '-height:page height' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmtorast b/Completion/Pbmplus/_pnmtorast
new file mode 100644
index 000000000..e6d04db0c
--- /dev/null
+++ b/Completion/Pbmplus/_pnmtorast
@@ -0,0 +1,3 @@
+#compdef pnmtorast
+
+_arguments '-standard' '-rle' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmtosgi b/Completion/Pbmplus/_pnmtosgi
new file mode 100644
index 000000000..efbbc3886
--- /dev/null
+++ b/Completion/Pbmplus/_pnmtosgi
@@ -0,0 +1,3 @@
+#compdef pnmtosgi
+
+_arguments '-verbatim' '-rle' '-imagename:image name:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmtotiff b/Completion/Pbmplus/_pnmtotiff
new file mode 100644
index 000000000..5cc170190
--- /dev/null
+++ b/Completion/Pbmplus/_pnmtotiff
@@ -0,0 +1,5 @@
+#compdef pnmtotiff
+
+_arguments '-none' '-packbits' '-lzw' '-g3' '-g4' '-2d' '-fill' \
+           '-predictor:LZW predictor:(1 2)' '-msb2lsb' '-lsb2msb' \
+	   '-rowsperstrip:number of rows per strip:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_pnmtoxwd b/Completion/Pbmplus/_pnmtoxwd
new file mode 100644
index 000000000..1c8b2393d
--- /dev/null
+++ b/Completion/Pbmplus/_pnmtoxwd
@@ -0,0 +1,4 @@
+#compdef pnmtoxwd
+
+_arguments '-pseudodepth:depth of PseudoColor dumps:' '-directcolor' \
+           ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppm3d b/Completion/Pbmplus/_ppm3d
new file mode 100644
index 000000000..8f3cc0434
--- /dev/null
+++ b/Completion/Pbmplus/_ppm3d
@@ -0,0 +1,4 @@
+#compdef ppm3d
+
+_arguments ':left picture file:_pbm_file' ':right picture file:_pbm_file' \
+           ':horizontal offset:'
diff --git a/Completion/Pbmplus/_ppmbrighten b/Completion/Pbmplus/_ppmbrighten
new file mode 100644
index 000000000..0fbc6ddaf
--- /dev/null
+++ b/Completion/Pbmplus/_ppmbrighten
@@ -0,0 +1,3 @@
+#compdef ppmbrighten
+
+_arguments '-n' '-s:saturation:' '-v:value:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmchange b/Completion/Pbmplus/_ppmchange
new file mode 100644
index 000000000..45c83ea2e
--- /dev/null
+++ b/Completion/Pbmplus/_ppmchange
@@ -0,0 +1,15 @@
+#compdef ppmchange
+
+local ret=1 expl
+
+_pbm_file && ret=0
+
+if (( CURRENT & 1 )); then
+  _description expl 'new color'
+else
+  _description expl 'old color'
+fi
+
+_colors "$expl[@]" && ret=0
+
+return ret
diff --git a/Completion/Pbmplus/_ppmdim b/Completion/Pbmplus/_ppmdim
new file mode 100644
index 000000000..7dd001809
--- /dev/null
+++ b/Completion/Pbmplus/_ppmdim
@@ -0,0 +1,3 @@
+#compdef ppmdim
+
+_arguments ':diminishing factor:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmdist b/Completion/Pbmplus/_ppmdist
new file mode 100644
index 000000000..c825cabb3
--- /dev/null
+++ b/Completion/Pbmplus/_ppmdist
@@ -0,0 +1,3 @@
+#compdef ppmdist
+
+_arguments '-intensity' '-frequency' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmdither b/Completion/Pbmplus/_ppmdither
new file mode 100644
index 000000000..94a52e68d
--- /dev/null
+++ b/Completion/Pbmplus/_ppmdither
@@ -0,0 +1,7 @@
+#compdef ppmdither
+
+_arguments '-dim:matrix size:' \
+           '-red:number of red shades:' \
+           '-green:number of green shades:' \
+           '-blue:number of blue shades:' \
+	   ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmflash b/Completion/Pbmplus/_ppmflash
new file mode 100644
index 000000000..addc5e460
--- /dev/null
+++ b/Completion/Pbmplus/_ppmflash
@@ -0,0 +1,3 @@
+#compdef ppmflash
+
+_arguments ':flash factor:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmforge b/Completion/Pbmplus/_ppmforge
new file mode 100644
index 000000000..ab8838afd
--- /dev/null
+++ b/Completion/Pbmplus/_ppmforge
@@ -0,0 +1,13 @@
+#compdef ppmforge
+
+_arguments '-clouds' '-night' \
+           '-dimension:fractal dimension:' '-hour:hour angle:' \
+	   '-inclination:inclination angle:' \
+	   '-tilt:inclination angle:' \
+	   '-mesh:FFT mesh size:' '-power:elevations power factor:' \
+	   '-glaciers:glacier elevation:' '-ice:polar ice cap extent:' \
+	   '-saturation:star color saturation:' \
+	   '-seed:randum number seed:' \
+	   '-stars:minimum star pixel percentage:' \
+	   '-width:width:' '-xsize:width:' \
+	   '-height:height:' '-ysize:height:'
diff --git a/Completion/Pbmplus/_ppmmake b/Completion/Pbmplus/_ppmmake
new file mode 100644
index 000000000..62512a261
--- /dev/null
+++ b/Completion/Pbmplus/_ppmmake
@@ -0,0 +1,3 @@
+#compdef ppmmake
+
+_arguments ':color: _colors' ':width:' ':height:'
diff --git a/Completion/Pbmplus/_ppmmix b/Completion/Pbmplus/_ppmmix
new file mode 100644
index 000000000..bde240b75
--- /dev/null
+++ b/Completion/Pbmplus/_ppmmix
@@ -0,0 +1,3 @@
+#compdef ppmmix
+
+_arguments ':fade factor:' ':file: _pbm_file' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmntsc b/Completion/Pbmplus/_ppmntsc
new file mode 100644
index 000000000..d4583f242
--- /dev/null
+++ b/Completion/Pbmplus/_ppmntsc
@@ -0,0 +1,3 @@
+#compdef ppmntsc
+
+_arguments ':dim factor:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmpat b/Completion/Pbmplus/_ppmpat
new file mode 100644
index 000000000..e1c377c3c
--- /dev/null
+++ b/Completion/Pbmplus/_ppmpat
@@ -0,0 +1,4 @@
+#compdef ppmpat
+
+_arguments -gingham{2,3} -g{2,3} -madras -tartan -poles -squig -camo -anticamo \
+           ':width:' ':height:'
diff --git a/Completion/Pbmplus/_ppmquant b/Completion/Pbmplus/_ppmquant
new file mode 100644
index 000000000..42071d959
--- /dev/null
+++ b/Completion/Pbmplus/_ppmquant
@@ -0,0 +1,26 @@
+#compdef ppmquant
+
+local ret=1 expl opt=yes
+
+if [[ "$words[2]" = -(fs|floyd) ]]; then
+  (( CURRENT-- ))
+  shift 1 words
+  opt=''
+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
+  _message 'number of colors'
+
+  return ret
+elif [[ CURRENT -eq 3 && "$words[2]" = -map ]]; then
+  _description expl 'map file'
+  _files "$expl[@]" -g '*.(#i)ppm'
+else
+  _pbm_file
+fi
diff --git a/Completion/Pbmplus/_ppmquantall b/Completion/Pbmplus/_ppmquantall
new file mode 100644
index 000000000..8fb85ab6d
--- /dev/null
+++ b/Completion/Pbmplus/_ppmquantall
@@ -0,0 +1,3 @@
+#compdef ppmquantall
+
+_arguments ':number of colors:' '*:file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmshift b/Completion/Pbmplus/_ppmshift
new file mode 100644
index 000000000..02fa9c465
--- /dev/null
+++ b/Completion/Pbmplus/_ppmshift
@@ -0,0 +1,3 @@
+#compdef ppmshift
+
+_arguments ':shift value:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmspread b/Completion/Pbmplus/_ppmspread
new file mode 100644
index 000000000..d0452ba0e
--- /dev/null
+++ b/Completion/Pbmplus/_ppmspread
@@ -0,0 +1,3 @@
+#compdef ppmspread
+
+_arguments ':maximum spread amount:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmtoacad b/Completion/Pbmplus/_ppmtoacad
new file mode 100644
index 000000000..245b8afcd
--- /dev/null
+++ b/Completion/Pbmplus/_ppmtoacad
@@ -0,0 +1,4 @@
+#compdef ppmtoacad
+
+_arguments '-dxb' '-poly' '-background:background color:_colors' \
+           '-white' '-aspect:pixel aspect ratio:' '-8' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmtobmp b/Completion/Pbmplus/_ppmtobmp
new file mode 100644
index 000000000..0ebaef1f6
--- /dev/null
+++ b/Completion/Pbmplus/_ppmtobmp
@@ -0,0 +1,3 @@
+#compdef ppmtobmp
+
+_arguments '-os2' '-windows' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmtogif b/Completion/Pbmplus/_ppmtogif
new file mode 100644
index 000000000..46e0a6663
--- /dev/null
+++ b/Completion/Pbmplus/_ppmtogif
@@ -0,0 +1,3 @@
+#compdef ppmtogif
+
+_arguments '-interlace' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmtoicr b/Completion/Pbmplus/_ppmtoicr
new file mode 100644
index 000000000..4df9c26f3
--- /dev/null
+++ b/Completion/Pbmplus/_ppmtoicr
@@ -0,0 +1,4 @@
+#compdef ppmtoicr
+
+_arguments '-windowname:window name:' '-expand:expansion factor:' \
+           '-display:display screen:' '-rle' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmtoilbm b/Completion/Pbmplus/_ppmtoilbm
new file mode 100644
index 000000000..ff19fa91a
--- /dev/null
+++ b/Completion/Pbmplus/_ppmtoilbm
@@ -0,0 +1,3 @@
+#compdef ppmtoilbm
+
+_arguments '-hamif' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmtomap b/Completion/Pbmplus/_ppmtomap
new file mode 100644
index 000000000..0476cfb44
--- /dev/null
+++ b/Completion/Pbmplus/_ppmtomap
@@ -0,0 +1,3 @@
+#compdef ppmtomap
+
+_arguments '-sort' '-square' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmtomitsu b/Completion/Pbmplus/_ppmtomitsu
new file mode 100644
index 000000000..e89047df1
--- /dev/null
+++ b/Completion/Pbmplus/_ppmtomitsu
@@ -0,0 +1,7 @@
+#compdef ppmtomitsu
+
+_arguments '-sharpness:sharpness:(1 2 3 4)' \
+           '-enlarge:enlargement factor:(1 2 3)' \
+	   '-media:output media:(A A4 AS A4S)' \
+	   '-copy:number of copies:(1 2 3 4 5 6 7 8 9)' \
+	   '-dpi300' '-tiny' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmtopj b/Completion/Pbmplus/_ppmtopj
new file mode 100644
index 000000000..d5b48f5c7
--- /dev/null
+++ b/Completion/Pbmplus/_ppmtopj
@@ -0,0 +1,6 @@
+#compdef ppmtopj
+
+_arguments '-gamma:gamma value:' '-xpos:x position:' '-rle' '-center' \
+           '-ypos:y position:' '-back:background brightness:(dark lite)' \
+	   '-render:rendering algorithm:(none snap bw dither diffuse monodither monodiffuse clusterdither monoclusterdither)' \
+	   ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmtopjxl b/Completion/Pbmplus/_ppmtopjxl
new file mode 100644
index 000000000..5ef79be94
--- /dev/null
+++ b/Completion/Pbmplus/_ppmtopjxl
@@ -0,0 +1,9 @@
+#compdef ppmtopjxl
+
+_arguments '-nopack' '-gamma:gamma value:' '-presentation' '-dark' \
+           '-diffuse' '-cluster' '-dither' \
+	   '-xshift:x shift:' '-yshift:y shift:' \
+	   '-xscale:x scale factor:' '-yscale:y scale factor:' \
+	   '-xsize:width:'  '-width:width:' \
+	   '-ysize:height:' '-height:height:' \
+	   ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmtosixel b/Completion/Pbmplus/_ppmtosixel
new file mode 100644
index 000000000..6272661aa
--- /dev/null
+++ b/Completion/Pbmplus/_ppmtosixel
@@ -0,0 +1,3 @@
+#compdef ppmtosixel
+
+_arguments '-raw' '-margin' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmtotga b/Completion/Pbmplus/_ppmtotga
new file mode 100644
index 000000000..adf09a2bd
--- /dev/null
+++ b/Completion/Pbmplus/_ppmtotga
@@ -0,0 +1,3 @@
+#compdef ppmtotga
+
+_arguments '-mono' '-cmap' '-rgb' '-norle' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmtouil b/Completion/Pbmplus/_ppmtouil
new file mode 100644
index 000000000..63b1ee167
--- /dev/null
+++ b/Completion/Pbmplus/_ppmtouil
@@ -0,0 +1,3 @@
+#compdef ppmtouil ppmtoxpm
+
+_arguments '-name:name prefix:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_ppmtoyuvsplit b/Completion/Pbmplus/_ppmtoyuvsplit
new file mode 100644
index 000000000..598b78797
--- /dev/null
+++ b/Completion/Pbmplus/_ppmtoyuvsplit
@@ -0,0 +1,3 @@
+#compdef ppmtoyuvsplit
+
+_arguments ':base name:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_psidtopgm b/Completion/Pbmplus/_psidtopgm
new file mode 100644
index 000000000..0ba7328aa
--- /dev/null
+++ b/Completion/Pbmplus/_psidtopgm
@@ -0,0 +1,4 @@
+#compdef psidtopgm
+
+_arguments ':width:' ':height:' ':bits per sample:' \
+           ':postscript file:_files -g *.(#i)(ps|eps)'
diff --git a/Completion/Pbmplus/_pstopnm b/Completion/Pbmplus/_pstopnm
new file mode 100644
index 000000000..b66f4041a
--- /dev/null
+++ b/Completion/Pbmplus/_pstopnm
@@ -0,0 +1,10 @@
+#compdef pstopnm
+
+_arguments '-forceplain' '-help' '-landscape' '-portrait' '-nocrop' \
+           '-pbm' '-pgm' '-ppm' '-verbose' \
+	   '-llx:loxer left x position:' '-lly:lower left y position:' \
+	   '-urx:upper right x position:' '-ury:upper right y position:' \
+	   '-xborder:x border fraction:' '-yborder:y border fraction:' \
+	   '-xmax:maximum width:' '-ymax:maximum height' \
+	   '-xsize:width:' '-ysize:height:' \
+	   ':postscript file:_files -g *.(#i)(ps|eps)'
diff --git a/Completion/Pbmplus/_rawtopgm b/Completion/Pbmplus/_rawtopgm
new file mode 100644
index 000000000..c8e87dbde
--- /dev/null
+++ b/Completion/Pbmplus/_rawtopgm
@@ -0,0 +1,5 @@
+#compdef rawtopgm
+
+_arguments '-headerskip:header bytes to skip:' \
+           '-rowskip:row padding to skip:' \
+	   ':width:' ':height:' ':grayscale bytes:'
diff --git a/Completion/Pbmplus/_rawtoppm b/Completion/Pbmplus/_rawtoppm
new file mode 100644
index 000000000..d4a0c333c
--- /dev/null
+++ b/Completion/Pbmplus/_rawtoppm
@@ -0,0 +1,6 @@
+#compdef rawtoppm
+
+_arguments '-headerskip:header bytes to skip:' \
+           '-rowskip:row padding to skip:' \
+	   '-rgb' '-rbg' '-grb' '-gbr' '-brg' '-bgr' '-interpixel' '-interrow' \
+	   ':width:' ':height:' ':grayscale bytes:'
diff --git a/Completion/Pbmplus/_rgb3toppm b/Completion/Pbmplus/_rgb3toppm
new file mode 100644
index 000000000..ac4df434d
--- /dev/null
+++ b/Completion/Pbmplus/_rgb3toppm
@@ -0,0 +1,16 @@
+#compdef rgb3toppm
+
+local expl
+
+if [[ CURRENT -eq 2 ]]; then
+  expl='red picture file'
+elif [[ CURRENT -eq 3 ]]; then
+  expl='green picture file'
+elif [[ CURRENT -eq 4 ]]; then
+  expl='blue picture file'
+fi
+
+if [[ -n "$expl" ]]; then
+  _description expl "$expl"
+  _files "$expl" -g '*.(#i)pgm'
+fi
diff --git a/Completion/Pbmplus/_sgitopnm b/Completion/Pbmplus/_sgitopnm
new file mode 100644
index 000000000..84189acc2
--- /dev/null
+++ b/Completion/Pbmplus/_sgitopnm
@@ -0,0 +1,3 @@
+#compdef sgitopnm
+
+_arguments '-verbose' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_sldtoppm b/Completion/Pbmplus/_sldtoppm
new file mode 100644
index 000000000..0ec01860c
--- /dev/null
+++ b/Completion/Pbmplus/_sldtoppm
@@ -0,0 +1,7 @@
+#compdef sldtoppm
+
+_arguments '-adjust' '-dir' '-info' '-verbose' \
+	   '-width:width:'   '-xsize:width:' \
+           '-height:height:' '-ysize:height:' \
+	   '-scale:scale factor:' \
+	   '-lib:slide name:' '-Lib:slide name:' ':file: _pbm_file'
diff --git a/Completion/Pbmplus/_yuvsplittoppm b/Completion/Pbmplus/_yuvsplittoppm
new file mode 100644
index 000000000..83d7c4d28
--- /dev/null
+++ b/Completion/Pbmplus/_yuvsplittoppm
@@ -0,0 +1,3 @@
+#compdef yuvsplittoppm
+
+_arguments ':base name:' ':width:' ':height:' '-ccir601'
diff --git a/Completion/Pbmplus/_yuvtoppm b/Completion/Pbmplus/_yuvtoppm
new file mode 100644
index 000000000..438249d34
--- /dev/null
+++ b/Completion/Pbmplus/_yuvtoppm
@@ -0,0 +1,3 @@
+#compdef yuvtoppm
+
+_arguments ':width:' ':height:' 'image bytes:'
diff --git a/Completion/Pbmplus/_zeisstopnm b/Completion/Pbmplus/_zeisstopnm
new file mode 100644
index 000000000..f38c02b93
--- /dev/null
+++ b/Completion/Pbmplus/_zeisstopnm
@@ -0,0 +1,3 @@
+#compdef zeisstopnm
+
+_arguments '-pgm' '-ppm' ':file: _pbm_file'
diff --git a/Completion/User/_a2ps b/Completion/User/_a2ps
index 26f4d200e..956e5a0ff 100644
--- a/Completion/User/_a2ps
+++ b/Completion/User/_a2ps
@@ -22,18 +22,18 @@ if [[ "$words[1]" != "$_a2ps_cache_cmd" ]]; then
   )
 fi
 
-_long_options -t '*\*'                '(yes no)' \
-                 '*=DIRECTION'        '(rows columns)' \
-                 '*=TYPE'             '(r n nr rn any)' \
-		 '--highlight-level*' '(none normal heavy)' \
-		 '--version-control*' '(none off t numbered nil 
+_long_options -t '*\*:toggle:(yes no)' \
+                 '*=DIRECTION:direction:(rows columns)' \
+                 '*=TYPE:type:(r n nr rn any)' \
+		 '--highlight-level*:highlight:(none normal heavy)' \
+		 '--version-control*:version control:(none off t numbered nil 
 		                        existing never simple)' \
-	         '--pretty-print*'    "[${_a2ps_cache_values[1]}]" \
-	         '--encoding*'        "(${_a2ps_cache_values[2]})" \
-	         '--medium*'          "[${_a2ps_cache_values[3]}]" \
-	         '--prologue*'        "[${_a2ps_cache_values[4]}]" \
-	         '--ppd*'             "[${_a2ps_cache_values[5]}]" \
-	         '--printer*'         "[${_a2ps_cache_values[6]}]" \
-	         '--user-option*'     "[${_a2ps_cache_values[7]}]" \
-	         '--variable*'        "[${_a2ps_cache_values[8]}]" ||
+	         "--pretty-print*:style:[${_a2ps_cache_values[1]}]" \
+	         "--encoding*:encoding:(${_a2ps_cache_values[2]})" \
+	         "--medium*:medium:[${_a2ps_cache_values[3]}]" \
+	         "--prologue*:prologue:[${_a2ps_cache_values[4]}]" \
+	         "--ppd*:printer description:[${_a2ps_cache_values[5]}]" \
+	         "--printer*:printer:[${_a2ps_cache_values[6]}]" \
+	         "--user-option*:user option:[${_a2ps_cache_values[7]}]" \
+	         "--variable*:variable:[${_a2ps_cache_values[8]}]" ||
     _files -F fignore -g '*~*.(ps|PS|eps|EPS)'
diff --git a/Completion/User/_bunzip2 b/Completion/User/_bunzip2
index f544c8c27..53f4388bc 100644
--- a/Completion/User/_bunzip2
+++ b/Completion/User/_bunzip2
@@ -1,3 +1,6 @@
 #compdef bunzip2 bzcat
 
-_files -g '*.bz2'
+local expl
+
+_description expl 'compressed file'
+_files "$expl[@]" -g '*.bz2'
diff --git a/Completion/User/_bzip2 b/Completion/User/_bzip2
index faf9f2501..15dd6f090 100644
--- a/Completion/User/_bzip2
+++ b/Completion/User/_bzip2
@@ -1,3 +1,6 @@
 #compdef bzip2
 
-_files -g '*~*.bz2'
+local expl
+
+_description expl 'file to compress'
+_files "$expl[@]" -g '*~*.bz2'
diff --git a/Completion/User/_chown b/Completion/User/_chown
index 1ec76b39e..c75dbc4b3 100644
--- a/Completion/User/_chown
+++ b/Completion/User/_chown
@@ -4,10 +4,14 @@ if [[ CURRENT -eq 2 || CURRENT -eq 3 && $words[CURRENT-1] = -* ]]; then
   if [[ $words[1] = chgrp ]] || compset -P '*[:.]'; then
     _groups
   else
+    local expl
+
+    _description expl user
+
     if [[ $OSTYPE = (solaris*|hpux*) ]]; then
-      compgen -u -S ':' -q
+      compgen "$expl[@]" -u -S ':' -q
     else
-      compgen -u -S '.' -q
+      compgen "$expl[@]" -u -S '.' -q
     fi
   fi
 else
diff --git a/Completion/User/_colors b/Completion/User/_colors
index 369a4365f..346142eea 100644
--- a/Completion/User/_colors
+++ b/Completion/User/_colors
@@ -1,5 +1,7 @@
 #autoload
 
+local expl
+
 if (( ! $+_color_cache )); then
   local file
 
@@ -17,4 +19,6 @@ if (( ! $+_color_cache )); then
   fi
 fi
 
-compadd -M 'm:{a-z}={A-Z} m:-=\  r:|[ A-Z0-9]=* r:|=*' - "$_color_cache[@]"
+_description expl 'color specification'
+compadd "$@" "$expl[@]" -M 'm:{a-z}={A-Z} m:-=\  r:|[ A-Z0-9]=* r:|=*' - \
+        "$_color_cache[@]"
diff --git a/Completion/User/_compress b/Completion/User/_compress
index 84ed42fb2..24363be07 100644
--- a/Completion/User/_compress
+++ b/Completion/User/_compress
@@ -1,3 +1,6 @@
 #compdef compress
 
-_files -g '*~*.Z'
+local expl
+
+_description expl 'file to compress'
+_files "$expl[@]" -g '*~*.Z'
diff --git a/Completion/User/_configure b/Completion/User/_configure
index 01c12dd62..5861682d0 100644
--- a/Completion/User/_configure
+++ b/Completion/User/_configure
@@ -5,5 +5,5 @@ _long_options -i '(--(disable|enable)-FEATURE* --(with|without)-PACKAGE*)' \
 	           #--enable- --disable-
 		   #--with- --without-
 		   #--without- --with-)' \
-	      '*=(E|)PREFIX*' '_files -/' \
-              '*=PROGRAM*'    '_command_names'
+	      '*=(E|)PREFIX*:prefix directory:_files -/' \
+              '*=PROGRAM*:program:_command_names'
diff --git a/Completion/User/_cursors b/Completion/User/_cursors
index 7e5cbc44e..59ecb5976 100644
--- a/Completion/User/_cursors
+++ b/Completion/User/_cursors
@@ -1,5 +1,7 @@
 #autoload
 
+local expl
+
 if (( ! $+_cursor_cache )); then
   local file
 
@@ -12,4 +14,5 @@ if (( ! $+_cursor_cache )); then
   fi
 fi
 
-compadd -M 'm:-=_ r:|_=*' - "$_cursor_cache[@]"
+_description expl 'cursor name'
+compadd "$@" "$expl[@]" -M 'm:-=_ r:|_=*' - "$_cursor_cache[@]"
diff --git a/Completion/User/_dd b/Completion/User/_dd
index e57074520..9bcdc876d 100644
--- a/Completion/User/_dd
+++ b/Completion/User/_dd
@@ -1,12 +1,21 @@
 #compdef dd
 
+local expl
+
 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 '*,'
-  compadd -qS, -q ascii ebcdic ibm block unblock lcase ucase swab noerror sync
-elif compset -P 1 '[io]f\='; then
-  _files
+  _description 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[@]"
+elif compset -P 1 'of\='; then
+  _description expl 'output file'
+  _files "$expl[@]"
 else
-  compadd -S '=' if of ibs obs bs cbs skip files seek count conv
+  _description expl option
+  compadd "$expl[@]" -S '=' if of ibs obs bs cbs skip files seek count conv
 fi
diff --git a/Completion/User/_find b/Completion/User/_find
index de8c3bff9..20e8f4ff7 100644
--- a/Completion/User/_find
+++ b/Completion/User/_find
@@ -1,27 +1,32 @@
 #compdef find
 
-local prev="$words[CURRENT-1]"
+local prev="$words[CURRENT-1]" expl
 
 if compset -N '-(ok|exec)' '\;'; then
   _normal
-elif compset -P 1 -; then
-  compadd daystart {max,min,}depth follow noleaf version xdev \
-    {a,c,}newer {a,c,m}{min,time} empty false {fs,x,}type gid inum links \
-    {i,}{l,}name {no,}{user,group} path perm regex size true uid used \
-    exec {f,}print{f,0,} ok prune ls
+elif [[ "$PREFIX" = -* ]]; then
+  _description expl option
+  compadd "$expl[@]" - -daystart -{max,min,}depth -follow -noleaf \
+    -version -xdev -{a,c,}newer -{a,c,m}{min,time} -empty -false \
+    -{fs,x,}type -gid -inum -links -{i,}{l,}name -{no,}{user,group} \
+    -path -perm -regex -size -true -uid -used -exec -{f,}print{f,0,} \
+    -ok -prune -ls
 elif [[ CURRENT -eq 2 ]]; then
   local ret=1
 
-  compgen -g '. ..' && ret=0
-  _files -g '*(-/)' && ret=0
+  _description expl directory
+  compgen "$expl[@]" -g '. ..' && ret=0
+  _files -/ && ret=0
 
   return ret
 elif [[ "$prev" = -((a|c|)newer|fprint(|0|f)) ]]; then
   _files
 elif [[ "$prev" = -fstype ]]; then
-  compadd ufs 4.2 4.3 nfs tmp mfs S51K S52K
+  _description expl 'file system type'
+  compadd "$expl[@]" ufs 4.2 4.3 nfs tmp mfs S51K S52K
 elif [[ "$prev" = -group ]]; then
-  compgen -k groups
+  _groups
 elif [[ "$prev" = -user ]]; then
-  compgen -u
+  _description expl user
+  compgen "$expl[@]" -u
 fi
diff --git a/Completion/User/_gdb b/Completion/User/_gdb
index ff54e6a07..1dba7819d 100644
--- a/Completion/User/_gdb
+++ b/Completion/User/_gdb
@@ -3,33 +3,38 @@
 # This uses the configuration keys `ps_args' and `ps_listargs'
 # described in the `_wait' function.
 
-local cur="$words[CURRENT]" prev w list ret=1
+local cur="$words[CURRENT]" prev w list ret=1 expl
 
-_long_options -t '*=(CORE|SYM)FILE'	'_files' \
-		 '*=EXECFILE'   	'_files *(*)' \
-		 '*=TTY'		'compadd /dev/tty*' && return 0
+_long_options -t '*=(CORE|SYM)FILE:core file:_files' \
+		 '*=EXECFILE:executable:_files *(*)' \
+		 '*=TTY:terminal device:compadd /dev/tty*' && return 0
 
 if compset -P '-(cd|directory)='; then
   _files -/
 elif compset -P '-tty='; then
-  compadd - /dev/tty*
+  _description expl 'terminal device'
+  compadd "$expl[@]" - /dev/tty*
 elif compset -P '-(exec|se)='; then
-  _files -/g '*(*)'
+  _description expl executable
+  _files "$expl[@]" -/g '*(*)'
 elif compset -P '-(symbols|core|command)='; then
   _files
-elif compset -P -; then
-  compadd -QS '' - symbols\= exec\= se\= core\= command\= directory\= \
-	           cd\= tty\=
-  compadd - help h s e c x d nx n quiet q batch fullname f b
+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
 else
   prev="$words[CURRENT-1]"
 
   case "$prev" in
   (-d) _files -/ && return 0 ;;
-  (-e) _files -/g '*(*)' && return 0 ;;
   (-[csx]) _files && return 0 ;;
-  (-b) compadd -V baud 0 50 75 110 134 150 200 300 600 1200 1800 2400 4800 \
-                       9600 19200 38400 57600 115200 230400 && 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 ;;
   esac
   w=( "${(@)words[2,-1]}" )
   while [[ "$w[1]" = -* ]]; do
@@ -39,12 +44,14 @@ else
 
   if [[ $#w -gt 1 ]]; then
     _files && ret=0
+    _description expl 'process ID'
     list=("${(F)${(@Mr:COLUMNS-1:)${(f)$(ps ${compconfig[ps_listargs]:-$compconfig[ps_args]} 2>/dev/null)}[2,-1]:#[ 	]#${PREFIX}[0-9]#${SUFFIX}[ 	]*${w[1]:t}}}
 ")
-    compadd -y list - ${${${(M)${(f)"$(ps $compconfig[ps_args] 2>/dev/null)"}:#*${w[1]:t}*}## #}%% *} && ret=0
+    compadd "$expl[@]" -y list - ${${${(M)${(f)"$(ps $compconfig[ps_args] 2>/dev/null)"}:#*${w[1]:t}*}## #}%% *} && ret=0
 
     return ret
   else
+    _description expl executable
     _files -/g '*(*)'
   fi
 fi
diff --git a/Completion/User/_groups b/Completion/User/_groups
index 975189174..61f63596e 100644
--- a/Completion/User/_groups
+++ b/Completion/User/_groups
@@ -1,6 +1,9 @@
 #compdef newgrp
 
+local expl
+
 : ${(A)groups:=${${(s: :)$(</etc/group)}%%:*}}
 # : ${(A)groups:=${${(s: :)$(ypcat group.byname)}%%:*}} # If you use NIS
 
-compadd $groups
+_description expl group
+compadd "$@" "$expl[@]" - $groups
diff --git a/Completion/User/_gunzip b/Completion/User/_gunzip
index 7868e0c24..78e62c4cc 100644
--- a/Completion/User/_gunzip
+++ b/Completion/User/_gunzip
@@ -1,3 +1,6 @@
 #compdef gunzip zcat
 
-_files -g '*.[gG][z]'
+local expl
+
+_description expl 'compressed file'
+_files "$expl[@]" -g '*.[gG][z]'
diff --git a/Completion/User/_gzip b/Completion/User/_gzip
index 59e74a441..8cd4d746e 100644
--- a/Completion/User/_gzip
+++ b/Completion/User/_gzip
@@ -1,3 +1,6 @@
 #compdef gzip
 
+local expl
+
+_description expl 'file to compress'
 _files -g '*~*.[gG][zZ]'
diff --git a/Completion/User/_hosts b/Completion/User/_hosts
index d498425bc..6b2f350aa 100644
--- a/Completion/User/_hosts
+++ b/Completion/User/_hosts
@@ -1,5 +1,8 @@
 #compdef ftp ncftp ping rwho rup xping traceroute nslookup telnet
 
+local expl
+
 : ${(A)hosts:=${(s: :)${(ps:\t:)${${(f)"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}}
 
-compadd -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' "$@" - "$hosts[@]"
+_description expl host
+compadd -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' "$@" "$expl[@]" - "$hosts[@]"
diff --git a/Completion/User/_make b/Completion/User/_make
index e9ee7979f..4c6095e95 100644
--- a/Completion/User/_make
+++ b/Completion/User/_make
@@ -1,6 +1,6 @@
 #compdef make gmake pmake
 
-local prev="$words[CURRENT-1]" file ret=1
+local prev="$words[CURRENT-1]" file ret=1 expl
 
 if [[ "$prev" = -[CI] ]]; then
   _files -/
@@ -18,7 +18,8 @@ else
     file=''
   fi
 
+  _description expl 'make target'
   [[ -n "$file" ]] &&
-    compadd - $(awk '/^[a-zA-Z0-9][^\/ 	]+:/ {print $1}' FS=: $file) && ret=0
+    compadd "$expl[@]" - $(awk '/^[a-zA-Z0-9][^\/ 	]+:/ {print $1}' FS=: $file) && ret=0
   (( ret )) && { compset -P 1 '*\='; _files }
 fi
diff --git a/Completion/User/_man b/Completion/User/_man
index 1a175506c..049fa7db7 100644
--- a/Completion/User/_man
+++ b/Completion/User/_man
@@ -2,7 +2,7 @@
 
 setopt localoptions rcexpandparam
 
-local rep
+local rep expl
 
 if [[ $words[2] = (<->*|ln) ]]; then
   rep=( $manpath/(man|cat)${words[2]}/$PREFIX*$SUFFIX.<->*(N:t:r) )
@@ -10,4 +10,5 @@ else
   rep=( $manpath/(man|cat)*/$PREFIX*$SUFFIX.<->*(N:t:r) )
 fi
 
-(( $#rep )) && compadd - $rep
+_description expl 'manual page'
+(( $#rep )) && compadd "$expl[@]" - $rep
diff --git a/Completion/User/_mh b/Completion/User/_mh
index f03e3d827..3a2e53794 100644
--- a/Completion/User/_mh
+++ b/Completion/User/_mh
@@ -8,7 +8,7 @@
 local mymhdir=~/Mail
 local mhlib=/usr/lib/mh
 
-local prev="$words[CURRENT-1]"
+local prev="$words[CURRENT-1]" expl
 
 # To be on the safe side, check this exists and if not, get it anyway.
 [[ -d $mymhdir ]] || mymhdir=$(mhpath +)
@@ -17,7 +17,8 @@ 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.
-  compadd - $($words[1] -help | perl -ne 'if (/^\s*-\(?(\S+)/) {
+  _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";
@@ -35,9 +36,11 @@ elif compset -P 1 '[+@]' || [[ "$prev" = -draftfolder ]]; then
   fi
 
   # painless, or what?
-  _path_files -W mhpath -/
+  _description expl 'MH folder'
+  _path_files "$expl[@]" -W mhpath -/
 elif [[ "$prev" = -(editor|(whatnow|rmm|show|more)proc) ]]; then
-  compgen -c
+  _description expl command
+  compgen "$expl[@]" -c
 elif [[ "$prev" = -file ]]; then
   _files
 elif [[ "$prev" = -(form|audit|filter) ]]; then
@@ -48,11 +51,14 @@ elif [[ "$prev" = -(form|audit|filter) ]]; then
   [[ -d $mhlib ]] || { mhlib=$(mhparam mhlproc); mhlib=$mhlib:h; }
   mhfpath=($mymhdir $mhlib)
 
-  compgen -W mhfpath -g '*(.)'
+  _description expl 'MH template file'
+  compgen "$expl[@]" -W mhfpath -g '*(.)'
 elif [[ "$prev" = -(no|)cc ]]; then
-  compadd all to cc me
+  _description expl 'CC address'
+  compadd "$expl[@]" all to cc me
 elif [[ "$prev" = -[rw]cache ]]; then
-  compadd public private never ask
+  _description expl cache
+  compadd "$expl[@]" public private never ask
 else
   # Generate sequences.
   local foldnam folddir f ret
@@ -69,10 +75,11 @@ else
     # leaving foldnam empty works here
   fi
 
-  compadd $(mark $foldnam 2>/dev/null | awk -F: '{ print $1 }') &&
+  _description expl sequence
+  compadd "$expl[@]" $(mark $foldnam 2>/dev/null | awk -F: '{ print $1 }') &&
       ret=0
-  compadd reply next cur prev first last all unseen && ret=0
-  compgen -W folddir -g '<->' && ret=0
+  compadd "$expl[@]" reply next cur prev first last all unseen && ret=0
+  compgen "$expl[@]" -W folddir -g '<->' && ret=0
 
   return ret
 fi
diff --git a/Completion/User/_pdf b/Completion/User/_pdf
index 076b0d111..795e8545b 100644
--- a/Completion/User/_pdf
+++ b/Completion/User/_pdf
@@ -1,8 +1,11 @@
 #compdef acroread pdf2dsc pdf2ps pdfimages pdfinfo pdftopbm pdftops pdftotext xpdf
 
+local expl
+
 # ghostscript:
 #  pdf2dsc pdf2ps
 # xpdf:
 #  pdfimages pdfinfo pdftopbm pdftops pdftotext xpdf
 
-_files -g '*.(#i)pdf'
+_description expl 'PDF file'
+_files "$expl[@]" -g '*.(#i)pdf'
diff --git a/Completion/User/_ps b/Completion/User/_ps
index b91ba8a68..086443586 100644
--- a/Completion/User/_ps
+++ b/Completion/User/_ps
@@ -1,5 +1,7 @@
 #compdef ps2epsi ps2pdf epsffit extractres fixdlsrps fixfmps fixmacps fixpsditps fixpspps fixscribeps fixtpps fixwfwps fixwpps fixwwps includeres psbook psmerge psnup psresize psselect pstops psmulti pswrap lpr lp
 
+local expl
+
 # ghostscript:
 #  ps2epsi ps2pdf
 # psutils:
@@ -7,4 +9,5 @@
 #  fixscribeps fixtpps fixwfwps fixwpps fixwwps includeres psbook psmerge
 #  psnup psresize psselect pstops
 
-_files -g '*.(#i)(ps|eps)'
+_description expl 'postscript file'
+_files "$expl[@]" -g '*.(#i)(ps|eps)'
diff --git a/Completion/User/_pspdf b/Completion/User/_pspdf
index 014d81ce3..ecc4cf82b 100644
--- a/Completion/User/_pspdf
+++ b/Completion/User/_pspdf
@@ -1,6 +1,11 @@
 #compdef gs gsbj gsdj gsdj500 gslj gslp gsnd ps2ascii ghostview gv gview mgv ggv pstoedit pstotgif
 
+local ret=1
+
 # ghostscript:
 #  gs gsbj gsdj gsdj500 gslj gslp gsnd ps2ascii
 
-_files -g '*.(#i)(ps|eps|pdf)'
+_ps && ret=0
+_pdf && ret=0
+
+return ret
diff --git a/Completion/User/_rcs b/Completion/User/_rcs
index af66739cb..272e54681 100644
--- a/Completion/User/_rcs
+++ b/Completion/User/_rcs
@@ -5,8 +5,9 @@ local nm=$compstate[nmatches]
 [[ $words[1] = ci || $words[1] = rcs ]] && _files
 
 if [[ $compstate[nmatches] -eq nm && -d RCS && $words[1] != ci ]]; then
-  local rep
+  local rep expl
 
   rep=(RCS/$PREFIX*$SUFFIX,v(:t:s/\,v//))
-  (( $#rep )) && compadd - $rep
+  _description expl 'RCS file'
+  (( $#rep )) && compadd "$expl[@]" - $rep
 fi
diff --git a/Completion/User/_rlogin b/Completion/User/_rlogin
index 03af65382..8756ec42d 100644
--- a/Completion/User/_rlogin
+++ b/Completion/User/_rlogin
@@ -1,15 +1,19 @@
 #compdef rlogin rsh ssh
 
+local expl
+
+_description expl user
+
 if [[ CURRENT -eq 2 ]];
   if compset -P 1 '*@'; then
    _hosts
   else
     local nm=${compstate[nmatches]}
     _hosts
-    [[ nm -eq compstate[nmatches] ]] && compgen -S @ -u
+    [[ nm -eq compstate[nmatches] ]] && compgen "$expl[@]" -S @ -u
   fi
 elif [[ CURRENT -eq 3 ]]; then
   compadd - -l
 else
-  compgen -S @ -u
+  compgen "$expl[@]" -S @ -u
 fi
diff --git a/Completion/User/_strip b/Completion/User/_strip
index d9f44cc5e..529176fdd 100644
--- a/Completion/User/_strip
+++ b/Completion/User/_strip
@@ -1,3 +1,6 @@
 #compdef strip
 
-_files -g '*(*)'
+local expl
+
+_description expl executable
+_files "$expl[@]" -g '*(*)'
diff --git a/Completion/User/_stty b/Completion/User/_stty
index 6e2afcde8..45408fbc1 100644
--- a/Completion/User/_stty
+++ b/Completion/User/_stty
@@ -1,12 +1,16 @@
 #compdef stty
 
+local expl
+
 if [[ "$words[CURRENT-1]" = \
   (*erase|discard|status|dsusp|intr|kill|lnext|quit|reprint|start|s*p) ]]
 then
-     compadd '^-' '^h' '^?' '^c' '^u'
+  _description expl 'control character'
+  compadd "$expl[@]" '^-' '^h' '^?' '^c' '^u'
 else
+  _description expl setting
   compset -P '[-+]'
-  compadd rows columns intr quit erase kill eof eol \
+  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 \
diff --git a/Completion/User/_su b/Completion/User/_su
index e5bf09d80..7b9744cd9 100644
--- a/Completion/User/_su
+++ b/Completion/User/_su
@@ -1,12 +1,13 @@
 #compdef su
 
-local shell comp name usr base
+local shell comp name usr base expl
 
 [[ $words[2] != - ]]
 (( base=$?+2 ))
 
 if [[ CURRENT -eq base ]]; then
-  compgen -u && return
+  _description expl user
+  compgen "$expl[@]" -u && return
   usr=root
 elif [[ CURRENT -ge base+1 ]]; then
   usr=$words[base]
@@ -14,9 +15,9 @@ else
   return
 fi
 
-shell=${"$(egrep "^$usr:" </etc/passwd)"##*:}
+shell="${${(M@)${(@f)$(</etc/passwd)}:#root*}##*:}"
 compset -n $base
 for name in $shell $shell:t -default-; do
   comp="$_comps[$name]"
-  [[ ! -z "$comp" ]] && "$comp" && return
+  [[ -n "$comp" ]] && "$comp" && return
 done  
diff --git a/Completion/User/_tar b/Completion/User/_tar
index 5fcce5c67..02551759a 100644
--- a/Completion/User/_tar
+++ b/Completion/User/_tar
@@ -72,11 +72,11 @@ if [[ "$PREFIX" = --* ]]; then
 
   # ...long options after `--'.
 
-  _long_options '--owner*'          "_tilde" \
-                '*=(PROG|COMMAND)*' "_command_names" \
-		'*=ARCHIVE*'        "_tar_archive" \
-		'*=NAME*'           "_files" \
-		'*=CONTROL*'        "[t numbered nil existing never simple]"
+  _long_options '--owner*:user:_tilde' \
+                '*=(PROG|COMMAND)*:program:_command_names' \
+		'*=ARCHIVE*:archive: _tar_archive' \
+		'*=NAME*:file:_files' \
+		'*=CONTROL*:version control:[t numbered nil existing never simple]'
 
 elif [[ ( CURRENT -gt 2 && "$words[CURRENT-1]" = -*f* &&
           "$words[CURRENT-1]" != --* ) ||
@@ -93,7 +93,7 @@ elif [[ ( "$_tar_cmd" = *[xt]* || -n $del ) && -n "$tf" ]]; then
   # filenames cached, plus the name of the tarfile so we know if it
   # changes.
 
-  local largs=-tf
+  local largs=-tf expl
 
   if [[ $_tar_cmd = *z* ]]; then
     largs=-tzf
@@ -110,7 +110,8 @@ elif [[ ( "$_tar_cmd" = *[xt]* || -n $del ) && -n "$tf" ]]; then
     _tar_cache_name=$tf
   fi
 
-  _multi_parts / _tar_cache_list
+  _description 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/_tar_archive b/Completion/User/_tar_archive
index 58e436c4d..9ddf434f5 100644
--- a/Completion/User/_tar_archive
+++ b/Completion/User/_tar_archive
@@ -7,14 +7,18 @@
 # If your version of `tar' supports this you may want to complete
 # things like `host:file' or `user@host:file' here.
 
+local expl
+
 [[ $# -eq 0 && $+_tar_cmd -ne 0 ]] && set "$_tar_cmd"
 
+_description expl 'archive file'
+
 if [[ "$1" = *[tx]* ]]; then
   if [[ "$1" = *[zZ]* ]]; then
-    _files -g '*.((tar|TAR).(gz|GZ|Z)|.tgz)'
+    _files "$expl[@]" -g '*.((tar|TAR).(gz|GZ|Z)|.tgz)'
   else
-    _files -g '*.(tar|TAR)'
+    _files "$expl[@]" -g '*.(tar|TAR)'
   fi
 else
-  _files
+  _files "$expl[@]"
 fi
diff --git a/Completion/User/_tex b/Completion/User/_tex
index ac926cfbe..d270c785a 100644
--- a/Completion/User/_tex
+++ b/Completion/User/_tex
@@ -1,3 +1,6 @@
 #compdef tex latex slitex
 
-_files -g '*.(tex|TEX|texinfo|texi)'
+local expl
+
+_description expl 'TeX or LaTeX file'
+_files "$expl[@]" -g '*.(tex|TEX|texinfo|texi)'
diff --git a/Completion/User/_uncompress b/Completion/User/_uncompress
index 0aa1e073f..5392d8fe9 100644
--- a/Completion/User/_uncompress
+++ b/Completion/User/_uncompress
@@ -1,3 +1,6 @@
 #compdef uncompress zmore
 
+local expl
+
+_description expl 'compressed file'
 _files -g '*.Z'
diff --git a/Completion/User/_use_lo b/Completion/User/_use_lo
index e469154ea..a22a5fdb2 100644
--- a/Completion/User/_use_lo
+++ b/Completion/User/_use_lo
@@ -3,8 +3,4 @@
 # This is for GNU-like commands which understand the --help option,
 # but which do not otherwise require special completion handling.
 
-if [[ $PREFIX = --* ]]; then
-  _long_options
-else
-  _default
-fi
+_long_options -t || _default
diff --git a/Completion/User/_x_options b/Completion/User/_x_options
index 9c3a303bb..4e6b6ba80 100644
--- a/Completion/User/_x_options
+++ b/Completion/User/_x_options
@@ -1,10 +1,13 @@
 #compdef -p */X11/*
 
+local expl
+
 # A simple pattern completion, just as an example.
 
 if [ "$words[CURRENT-1]" = "-display" ]; then
   _compskip=all
   _hosts -S ':0 ' -r :
 else
-  compadd -J options - -display -name -xrm
+  _description expl option  
+  compadd "$expl[@]" - -display -name -xrm
 fi
diff --git a/Completion/User/_xfig b/Completion/User/_xfig
index a3b30bb81..f1c2ca6f5 100644
--- a/Completion/User/_xfig
+++ b/Completion/User/_xfig
@@ -1,3 +1,6 @@
 #compdef xfig
 
-_files -g '*.fig'
+local expl
+
+_description expl 'xfig file'
+_files "$expl[@]" -g '*.fig'
diff --git a/Completion/User/_xsetroot b/Completion/User/_xsetroot
index 74a0b6180..adce06d08 100644
--- a/Completion/User/_xsetroot
+++ b/Completion/User/_xsetroot
@@ -1,15 +1,22 @@
 #compdef xsetroot
 
+local expl
+
 case "$words[CURRENT-1]" in
--cursor) _files -/g '*.(#i)(xbm|curs(|or))'; return;;
 -cursor_name) _cursors; return;;
--bitmap) _files -/g '*.(#i)xbm'; return;;
 -([fb]g|solid)) _colors; return;;
+-cursor) _description expl 'cursor file'
+         _files "$expl[@]" -/g '*.(#i)(xbm|curs(|or))'; return;;
+-bitmap) _description expl 'bitmap file'
+         _files "$expl[@]" -/g '*.(#i)xbm'; return;;
 esac
 
 if [[ CURRENT -gt 2 && "$words[CURRENT-2]" = -cursor ]]; then
-  _files -/g '*.(#i)(xbm|curs(|or)|mask)'
+  _description expl 'cursor mask file'
+  _files "$expl[@]" -/g '*.(#i)(xbm|curs(|or)|mask)'
 else
-  compadd -M 'm:-=_ r:|_=*' - -help -def -cursor -cursor_name -bitmap -mod -gray -grey \
-                       -fg -bg -rv -solid -name
+  _description expl option
+  compadd "$expl[@]" -M 'm:-=_ r:|_=*' - \
+          -help -def -cursor -cursor_name -bitmap -mod -gray -grey \
+          -fg -bg -rv -solid -name
 fi