about summary refs log tree commit diff
path: root/Completion
diff options
context:
space:
mode:
Diffstat (limited to 'Completion')
-rw-r--r--Completion/Base/_arguments289
-rw-r--r--Completion/Base/_brace_parameter9
-rw-r--r--Completion/Base/_condition5
-rw-r--r--Completion/Base/_long_options41
-rw-r--r--Completion/Base/_math5
-rw-r--r--Completion/Base/_parameter4
-rw-r--r--Completion/Base/_tilde2
-rw-r--r--Completion/Base/_vars3
-rw-r--r--Completion/Builtins/_vars_eq5
-rw-r--r--Completion/Builtins/_zftp63
-rw-r--r--Completion/Commands/_correct_filename2
-rw-r--r--Completion/Commands/_correct_word2
-rw-r--r--Completion/Commands/_expand_word2
-rw-r--r--Completion/Commands/_history_complete_word2
-rw-r--r--Completion/Commands/_most_recent_file2
-rw-r--r--Completion/Commands/_read_comp2
-rw-r--r--Completion/Core/_parameters61
-rw-r--r--Completion/Core/compinit2
-rw-r--r--Completion/User/_chown8
-rw-r--r--Completion/User/_dir_list4
-rw-r--r--Completion/User/_exec_funcs49
-rw-r--r--Completion/User/_find3
-rw-r--r--Completion/User/_gprof12
-rw-r--r--Completion/User/_rlogin2
-rw-r--r--Completion/User/_su5
-rw-r--r--Completion/User/_tar2
-rw-r--r--Completion/User/_users6
27 files changed, 355 insertions, 237 deletions
diff --git a/Completion/Base/_arguments b/Completion/Base/_arguments
index 120c50934..86cd1c498 100644
--- a/Completion/Base/_arguments
+++ b/Completion/Base/_arguments
@@ -6,7 +6,7 @@
 setopt localoptions extendedglob
 
 local long args rest ws cur nth def nm expl descr action opt arg tmp
-local single uns ret=1 soptseq soptseq1 sopts prefix
+local single uns ret=1 soptseq soptseq1 sopts prefix line
 
 # Associative arrays used to collect information about the options.
 
@@ -117,182 +117,185 @@ else
   sopts=''
 fi
 
-if [[ $#long -ne 0 && "$PREFIX" = --* ]]; then
-
-   # If the current words starts with `--' and we should use long
-   # options, just call...
+# Parse the command line...
 
-  _long_options "$long[@]"
-else
+ws=( "${(@)words[2,-1]}" )
+cur=$(( CURRENT-2 ))
+nth=1
+liine=( "$words[1]" )
 
-  # Otherwise parse the command line...
+# ...until the current word is reached.
 
-  ws=( "${(@)words[2,-1]}" )
-  cur=$(( CURRENT-2 ))
-  nth=1
+while [[ cur -gt 0 ]]; do
 
-  # ...until the current word is reached.
+  # `def' holds the description for the option we are currently after.
+  # Check if the next argument for the option is optional.
 
-  while [[ cur -gt 0 ]]; do
+  if [[ "$def" = :* ]]; then
+    opt=yes
+  else
+    opt=''
+  fi
+  arg=''
 
-    # `def' holds the description for the option we are currently after.
-    # Check if the next argument for the option is optional.
+  # Remove one description/action pair from `def' if that isn't empty.
 
-    if [[ "$def" = :* ]]; then
-      opt=yes
+  if [[ -n "$def" ]]; then
+    if [[ "$def" = ?*:*:* ]]; then
+      def="${def#?*:*:}"
     else
-      opt=''
+      def=''
     fi
-    arg=''
+  else
 
-    # Remove one description/action pair from `def' if that isn't empty.
+    # 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 [[ -n "$def" ]]; then
-      if [[ "$def" = ?*:*:* ]]; then
-        def="${def#?*:*:}"
-      else
-        def=''
-      fi
+    if [[ $#long -eq 0 || "$ws[1]" != --* ]]; then
+      opt=yes
+      arg=yes
     else
+      def=''
+    fi
+  fi
 
-      # 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 [[ -n "$opt" ]]; then
 
-      if [[ $#long -eq 0 || "$ws[1]" != --* ]]; then
-        opt=yes
-	arg=yes
-      else
-        def=''
-      fi
-    fi
+    # `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 [[ -n "$opt" ]]; then
+    if (( $+opts[$ws[1]] )); 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.
+      # Options that may only be given once are removed from the
+      # associative array so that we don't offer them again.
 
-      if (( $+opts[$ws[1]] )); then
+      def="$opts[$ws[1]]"
+      [[ -n "$oneshot[$ws[1]]" ]] && unset "opts[$ws[1]]"
+    else
+      uns=''
+      if [[ -n "$sopts" && "$ws[1]" = [-+]${~soptseq}[$sopts] ]]; then
+	tmp="${ws[1][1]}${ws[1][-1]}"
+	if (( $+opts[$tmp] )); then
+	  def="$opts[$tmp]"
+	  uns="${ws[1][2,-1]}"
+	  opt=''
+	fi
+      fi
 
-        # Options that may only be given once are removed from the
-        # associative array so that we don't offer them again.
+      # 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 two loops looking very much alike.
 
-        def="$opts[$ws[1]]"
-        [[ -n "$oneshot[$ws[1]]" ]] && unset "opts[$ws[1]]"
-      else
-        uns=''
-        if [[ -n "$sopts" && "$ws[1]" = [-+]${~soptseq}[$sopts] ]]; then
-	  tmp="${ws[1][1]}${ws[1][-1]}"
-	  if (( $+opts[$tmp] )); then
-	    def="$opts[$tmp]"
-	    uns="${ws[1][2,-1]}"
-	    opt=''
-	  fi
-        fi
+      if [[ -n "$opt" && $#dopts -ne 0 ]]; then
 
-        # 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 two loops looking very much alike.
+	# First we get the option names.
 
-        if [[ -n "$opt" && $#dopts -ne 0 ]]; then
+	tmp=( "${(@k)dopts}" )
 
-	  # First we get the option names.
+	# Then we loop over them and see if the current word begins
+	# with one of the option names.
 
-	  tmp=( "${(@k)dopts}" )
+	while (( $#tmp )); do
+          if [[ -n "$sopts" && $tmp[1] = [-+]? ]]; then
+	    if [[ "$ws[1]" = ${tmp[1][1]}${~soptseq}${tmp[1][2]}* ]]; then
+	      uns="${ws[1][2,-1]%%${tmp[1][2]}*}${tmp[1][2]}"
+	      break;
+	    fi
+	  elif [[ "$ws[1]" = ${tmp[1]}* ]]; then
+            break
+	  fi
+	  shift 1 tmp
+	done
 
-	  # Then we loop over them and see if the current word begins
-	  # with one of the option names.
+	if (( $#tmp )); then
 
-	  while (( $#tmp )); do
-            if [[ -n "$sopts" && $tmp[1] = [-+]? ]]; then
-	      if [[ "$ws[1]" = ${tmp[1][1]}${~soptseq}${tmp[1][2]}* ]]; then
-	        uns="${ws[1][2,-1]%%${tmp[1][2]}*}${tmp[1][2]}"
-		break;
-	      fi
-	    elif [[ "$ws[1]" = ${tmp[1]}* ]]; then
-              break
+	  # 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]]"
+	  [[ -n "$oneshot[$tmp[1]]" ]] && unset "dopts[$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
+          if [[ -n "$sopts" && $tmp[1] = [-+]? ]]; then
+	    if [[ "$ws[1]" = ${tmp[1][1]}${~soptseq}${tmp[1][2]}* ]]; then
+	      uns="${ws[1][2,-1]%%${tmp[1][2]}*}${tmp[1][2]}"
+	      break;
 	    fi
-	    shift 1 tmp
-	  done
+	  elif [[ "$ws[1]" = ${tmp[1]}* ]]; then
+	    break
+	  fi
+	  shift 1 tmp
+	done
 
-	  if (( $#tmp )); then
+	if (( $#tmp )); then
+	  opt=''
+	  def="$odopts[$tmp[1]]"
+	  [[ -n "$oneshot[$tmp[1]]" ]] && unset "odopts[$tmp[1]]"
 
-	    # 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.
+	  # 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.
 
-	    opt=''
-	    def="$dopts[$tmp[1]]"
-	    [[ -n "$oneshot[$tmp[1]]" ]] && unset "dopts[$tmp[1]]"
+	  if [[ ( -z "$sopts" && "$ws[1]" != "$tmp[1]" ) ||
+                ( -n "$sopts" && ( ( $tmp[1] = [-+]? && "$ws[1]" != "${tmp[1][1]}"${~soptseq}"${tmp[1][2]}" ) ||
+		  		   ( $tmp[1] != [-+]? && "$ws[1]" != "$tmp[1]" ) ) ) ]]; then
 	    if [[ "$def" = ?*:*:* ]]; then
               def="${def#?*:*:}"
             else
               def=''
-	    fi
-          fi
-        fi
-        if [[ -n "$opt" && $#odopts -ne 0 ]]; then
-	  tmp=( "${(@k)odopts}" )
-	  while (( $#tmp )); do
-            if [[ -n "$sopts" && $tmp[1] = [-+]? ]]; then
-	      if [[ "$ws[1]" = ${tmp[1][1]}${~soptseq}${tmp[1][2]}* ]]; then
-	        uns="${ws[1][2,-1]%%${tmp[1][2]}*}${tmp[1][2]}"
-		break;
-	      fi
-	    elif [[ "$ws[1]" = ${tmp[1]}* ]]; then
-	      break
-	    fi
-	    shift 1 tmp
-	  done
-
-	  if (( $#tmp )); then
-	    opt=''
-	    def="$odopts[$tmp[1]]"
-	    [[ -n "$oneshot[$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 [[ ( -z "$sopts" && "$ws[1]" != "$tmp[1]" ) ||
-                  ( -n "$sopts" && ( ( $tmp[1] = [-+]? && "$ws[1]" != "${tmp[1][1]}"${~soptseq}"${tmp[1][2]}" ) ||
-		  		     ( $tmp[1] != [-+]? && "$ws[1]" != "$tmp[1]" ) ) ) ]]; then
-	      if [[ "$def" = ?*:*:* ]]; then
-                def="${def#?*:*:}"
-              else
-                def=''
-              fi
-	    fi
-          fi
+            fi
+	  fi
         fi
+      fi
 
-        [[ -n "$sopts" && -n "$opt" && "$ws[1]" = [-+]${~soptseq} ]] && \
-            uns="${ws[1][2,-1]}"
+      [[ -n "$sopts" && -n "$opt" && "$ws[1]" = [-+]${~soptseq} ]] && \
+          uns="${ws[1][2,-1]}"
 
-	if [[ -n "$uns" ]]; then
-	  uns="${(j::)${(@k)oneshot[(I)${ws[1][1]}[$uns]]#[-+]}}"
-	  unset "opts[${(@)^opts[(I)${ws[1][1]}[$uns]]}]" \
-	        "dopts[${(@)^dopts[(I)${ws[1][1]}[$uns]]}]" \
-	        "odopts[${(@)^odopts[(I)${ws[1][1]}[$uns]]}]"
-	fi
+      if [[ -n "$uns" ]]; then
+	uns="${(j::)${(@k)oneshot[(I)${ws[1][1]}[$uns]]#[-+]}}"
+	unset "opts[${(@)^opts[(I)${ws[1][1]}[$uns]]}]" \
+	      "dopts[${(@)^dopts[(I)${ws[1][1]}[$uns]]}]" \
+	      "odopts[${(@)^odopts[(I)${ws[1][1]}[$uns]]}]"
+      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 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
+      if [[ -n "$opt" && -n "$arg" ]]; then
+        def=''
+	line=( "$line[@]" "$ws[1]" )
+	(( nth++ ))
       fi
     fi
+  fi
 
-    shift 1 ws
-    (( cur-- ))
-  done
+  shift 1 ws
+  (( cur-- ))
+done
+
+# Now generate the matches.
+
+if [[ $#long -ne 0 && "$PREFIX" = --* ]]; then
 
-  # Now generate the matches.
+  # If the current words starts with `--' and we should use long
+  # options, just call...
+
+  _long_options "$long[@]"
+
+else
 
   nm="$compstate[nmatches]"
 
@@ -379,9 +382,11 @@ else
         _description expl option
 	if [[ -n "$sopts" && -n "$PREFIX" && "$PREFIX" = [-+]${~soptseq}[$sopts] ]]; then
 	  if [[ "$PREFIX" = [-+]${~soptseq1} ]]; then
-	    compadd "$expl[@]" -Q - "${PREFIX}${(@k)^opts[(I)${PREFIX[1]}?]#?}" \
-				    "${PREFIX}${(@k)^dopts[(I)${PREFIX[1]}?]#?}" \
-				    "${PREFIX}${(@k)^odopts[(I)${PREFIX[1]}?]#?}" && ret=0
+	    compadd "$expl[@]" -Q \
+                    -y "( ${(k)opts} ${(k)dopts} ${(k)odopts} )" - \
+                    "${PREFIX}${(@k)^opts[(I)${PREFIX[1]}?]#?}" \
+		    "${PREFIX}${(@k)^dopts[(I)${PREFIX[1]}?]#?}" \
+		    "${PREFIX}${(@k)^odopts[(I)${PREFIX[1]}?]#?}" && ret=0
 	  else
 	    # The last option takes an argument in next word.
 	    compadd "$expl[@]" -Q - "${PREFIX}" && ret=0
@@ -418,11 +423,17 @@ else
       # An empty action means that we should just display a message.
       _message "$descr"
       return ret
-    elif [[ "$action[1]" = \( ]]; then
+    elif [[ "$action[1]" = \(*\) ]]; then
 
       # Anything inside `(...)' is added directly.
 
       compadd "$expl[@]" - ${=action[2,-2]}
+    elif [[ "$action" = \{*\} ]]; then
+
+      # A string in braces is evaluated.
+
+      eval "$action[2,-2]"
+
     elif [[ "$action" = \ * ]]; then
 
       # If the action starts with a space, we just call it.
diff --git a/Completion/Base/_brace_parameter b/Completion/Base/_brace_parameter
index 767743281..4a91dde73 100644
--- a/Completion/Base/_brace_parameter
+++ b/Completion/Base/_brace_parameter
@@ -2,16 +2,17 @@
 
 setopt localoptions extendedglob
 
-local lp ls n q suf=''
+local lp ls n q
 
 if [[ "$SUFFIX" = *\}* ]]; then
   ISUFFIX="${SUFFIX#*\}}$ISUFFIX"
   SUFFIX="${SUFFIX%%\}*}"
+  suf=()
 elif [[ "$LBUFFER" = *\$\{[^}]#\$\{[^}]#$PREFIX ||
         "$compstate[insert]" = *menu* ]]; then
-  suf='}'
+  suf=(-b '')
 else
-  suf='} '
+  suf=(-b ' ')
 fi
 
 lp="$LBUFFER[1,-${#PREFIX}-1]"
@@ -21,4 +22,4 @@ q=${(M)lp%%\"#}
 
 [[ n -gt 0 ]] && suf=''
 
-_parameters -Qs "${q[1,-n-1]}" -S "$suf" -r '-:?#%+=[/}'
+_parameters "$suf[@]" -Qs "${q[1,-n-1]}" -r '-:?#%+=[/}'
diff --git a/Completion/Base/_condition b/Completion/Base/_condition
index afac03195..84c9fea20 100644
--- a/Completion/Base/_condition
+++ b/Completion/Base/_condition
@@ -7,11 +7,10 @@ if [[ "$prev" = -o ]]; then
 elif [[ "$prev" = -([no]t|ef) ]]; then
   _files
 else
-  local ret=1 expl
+  local ret=1
 
   _files && ret=0
-  _description expl parameter
-  compgen "$expl[@]" -v && ret=0
+  _parameters && ret=0
 
   return ret
 fi
diff --git a/Completion/Base/_long_options b/Completion/Base/_long_options
index 0080a48b6..716ff8884 100644
--- a/Completion/Base/_long_options
+++ b/Completion/Base/_long_options
@@ -112,8 +112,9 @@ if [[ "$tmp" != $_lo_cache_cmd ]]; then
   # those hyphens and anything from the space or comma after the
   # option up to the end. 
 
-  opts=("--${(@)^${(@)${(@M)${(@ps:\n:j:\n:)${(@)${(@M)${(@f)$("$words[1]" --help)}:#[ 	]#-*}//,/
-}}:#[ 	]#--*}#*--}%%[, ]*}")
+  opts=("--${(@)^${(@)${(@)${(@M)${(@ps:\n:j:\n:)${(@)${(@M)${(@f)$("$words[1]" --help 2>&1)//\[--/
+--}:#[ 	]#-*}//,/
+}}:#[ 	]#--*}#*--}%%[, ]*}:#}")
 
   # Now remove all ignored options ...
 
@@ -256,15 +257,15 @@ if [[ "$str" = *\=* ]]; then
 
       _description expl "$descr"
 
-      if [[ "$action[1]" = (\[|\() ]]; then
+      if [[ "$action[1]" = (\[*\]|\(*\)) ]]; then
         compadd "$expl[@]" - ${=action[2,-2]}
-      elif (( $#action )); then
-        if [[ "$action" = \ * ]]; then
-          ${(e)=~action}
-        else
-	  action=($=action)
-	  ${(e)action[1]} "$expl[@]" ${(e)~action[2,-1]}
-        fi
+      elif [[ "$action" = \{*\} ]]; then
+        eval "$action[2,-2]"
+      elif [[ "$action" = \ * ]]; then
+        ${(e)=~action}
+      elif [[ -n "$action" ]]; then
+	action=($=action)
+	${(e)action[1]} "$expl[@]" ${(e)~action[2,-1]}
       else
         _message "$descr"
       fi
@@ -308,15 +309,15 @@ if [[ "$str" = *\=* ]]; then
 
     _description expl "$partd"
 
-    if (( $#parta )); then
-      if [[ "$parta[1]" = (\[|\() ]]; then
-        compadd "$expl[@]" - ${=parta[2,-2]}
-      elif [[ "$parta" = \ * ]]; then
-        ${(e)=~parta}
-      else
-	action=($=parta)
-	${(e)~parta[1]} "$expl[@]" ${(e)~action[2,-1]}
-      fi
+    if [[ "$parta[1]" = (\[*\]|\(*\)) ]]; then
+      compadd "$expl[@]" - ${=parta[2,-2]}
+    elif [[ "$parta" = \{*\} ]]; then
+      eval "$parta[2,-2]"
+    elif [[ "$parta" = \ * ]]; then
+      ${(e)=~parta}
+    elif [[ -n "$parta" ]]; then
+      action=($=parta)
+      ${(e)~action[1]} "$expl[@]" ${(e)~action[2,-1]}
     else
       compadd -S '' - "$PREFIX"
     fi
@@ -346,8 +347,6 @@ fi
 
 anum=1
 for name in "$_lo_cache_names[@]"; do
-  action="$_lo_cache_actions[anum]"
-
   _description expl option
 
   if [[ "$name" = *_optarg_* ]]; then
diff --git a/Completion/Base/_math b/Completion/Base/_math
index 82b97fe4a..b9743d6b4 100644
--- a/Completion/Base/_math
+++ b/Completion/Base/_math
@@ -1,7 +1,5 @@
 #compdef -math-
 
-local expl
-
 if [[ "$PREFIX" = *[^a-zA-Z0-9_]* ]]; then
   IPREFIX="$IPREFIX${PREFIX%%[a-zA-Z0-9_]#}"
   PREFIX="${PREFIX##*[^a-zA-Z0-9_]}"
@@ -11,5 +9,4 @@ if [[ "$SUFFIX" = *[^a-zA-Z0-9_]* ]]; then
   SUFFIX="${SUFFIX%%[^a-zA-Z0-9_]*}"
 fi
 
-_description expl parameter
-compgen "$expl[@]" -v
+_parameters
diff --git a/Completion/Base/_parameter b/Completion/Base/_parameter
index 5f6f56db2..aa9e3ce01 100644
--- a/Completion/Base/_parameter
+++ b/Completion/Base/_parameter
@@ -1,7 +1,7 @@
 #compdef -parameter-
 
 if [[ "$compstate[insert]" = *menu* ]]; then
-  _parameters
+  _parameters -s ''
 else
-  _parameters -S ' ' -r '['
+  _parameters -s ' '
 fi
diff --git a/Completion/Base/_tilde b/Completion/Base/_tilde
index f249d4ffa..cab371216 100644
--- a/Completion/Base/_tilde
+++ b/Completion/Base/_tilde
@@ -41,7 +41,7 @@ else
   if (( $# )); then
     d=( "$@" )
   else
-    _description d user
+    _description d 'user or named directory'
   fi
 fi
 
diff --git a/Completion/Base/_vars b/Completion/Base/_vars
index 5a06488a5..a81a49f48 100644
--- a/Completion/Base/_vars
+++ b/Completion/Base/_vars
@@ -20,6 +20,5 @@ if [[ $PREFIX = *\[* ]]; then
     compadd "$expl[@]" $addclose - ${(kP)var}
   fi
 else
-  _description expl parameter
-  compgen "$expl[@]" -v
+  _parameter
 fi
diff --git a/Completion/Builtins/_vars_eq b/Completion/Builtins/_vars_eq
index 16a55595e..d2cac8741 100644
--- a/Completion/Builtins/_vars_eq
+++ b/Completion/Builtins/_vars_eq
@@ -1,6 +1,3 @@
 #compdef declare export integer local readonly typeset
 
-local expl
-
-_description expl parameter
-compgen "$expl[@]" -v -q -S '='
+_parameters -q -S '='
diff --git a/Completion/Builtins/_zftp b/Completion/Builtins/_zftp
index e6f7ea683..7b3ee0f97 100644
--- a/Completion/Builtins/_zftp
+++ b/Completion/Builtins/_zftp
@@ -23,47 +23,46 @@ fi
 
 case $subcom in
   *(cd|ls|dir))
-   # complete remote directories; we could be smarter about hiding prefixes
-   zfcd_match $PREFIX $SUFFIX
-   _description expl 'remote directory'
-   (( $#reply )) && compadd "$expl[@]" -S/ -q - $reply
-   ;;
+    # complete remote directories; we could be smarter about hiding prefixes
+    zfcd_match $PREFIX $SUFFIX
+    _description expl 'remote directory'
+    (( $#reply )) && compadd "$expl[@]" -S/ -q - $reply
+    ;;
 
   *(get(|at)|gcp|delete|remote))
-   # complete remote files
-   zfget_match $PREFIX $SUFFIX
-   _description expl 'remote file'
-   (( $#reply )) && compadd "$expl[@]" -F fignore - $reply
-   ;;
+    # complete remote files
+    zfget_match $PREFIX $SUFFIX
+    _description expl 'remote file'
+    (( $#reply )) && compadd "$expl[@]" -F fignore - $reply
+    ;;
 
   *(put(|at)|pcp))
-   # complete local files
-   _files
-   ;;
+    # complete local files
+    _files
+    ;;
 
   *(open|anon|params))
-  # complete hosts:  should do cleverer stuff with user names
-  _description expl host
-  compgen "$expl[@]" -k hosts
-  ;;
+    # complete hosts:  should do cleverer stuff with user names
+    _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 "$expl[@]" - $(awk -F, 'NR > 2 { print $1 }' ~/.ncftp/bookmarks)
+    # complete bookmarks.  First decide if ncftp mode is go.
+    _description expl bookmark
+    if [[ $words[2] = -*n* ]]; then
+      if [[ -f ~/.ncftp/bookmarks ]]; then
+        compadd "$expl[@]" - $(awk -F, 'NR > 2 { print $1 }' ~/.ncftp/bookmarks)
+      fi
+    else
+      if [[ -f ${ZFTP_BMFILE:=${ZDOTDIR:-$HOME}/.zfbkmarks} ]]; then
+        compadd "$expl[@]" - $(awk '{print $1}' $ZFTP_BMFILE)
+      fi
     fi
-  else
-    if [[ -f ${ZFTP_BMFILE:=${ZDOTDIR:-$HOME}/.zfbkmarks} ]]; then
-      compadd "$expl[@]" - $(awk '{print $1}' $ZFTP_BMFILE)
-    fi
-  fi
-  ;;
+    ;;
 
   *)
-  # dunno... try ordinary completion after all.
-  unset _compskip
-  return 1
-  ;;
+    # dunno... try ordinary completion after all.
+    unset _compskip
+    return 1
+    ;;
 esac
diff --git a/Completion/Commands/_correct_filename b/Completion/Commands/_correct_filename
index e9415a81f..7431a4831 100644
--- a/Completion/Commands/_correct_filename
+++ b/Completion/Commands/_correct_filename
@@ -1,4 +1,4 @@
-#compdef -kn complete-word \C-xC
+#compdef -k complete-word \C-xC
 
 # Function to correct a filename.  Can be used as a completion widget,
 # or as a function in its own right, in which case it will print the
diff --git a/Completion/Commands/_correct_word b/Completion/Commands/_correct_word
index 4376de092..d0abcd4fe 100644
--- a/Completion/Commands/_correct_word
+++ b/Completion/Commands/_correct_word
@@ -1,4 +1,4 @@
-#compdef -kn complete-word \C-xc
+#compdef -k complete-word \C-xc
 
 # Simple completion front-end implementing spelling correction.
 # The maximum number of errors is set quite high, and
diff --git a/Completion/Commands/_expand_word b/Completion/Commands/_expand_word
index 481d5e6a0..570f06987 100644
--- a/Completion/Commands/_expand_word
+++ b/Completion/Commands/_expand_word
@@ -1,4 +1,4 @@
-#compdef -kn complete-word \C-xe
+#compdef -k complete-word \C-xe
 
 # Simple completion front-end implementing expansion.
 #
diff --git a/Completion/Commands/_history_complete_word b/Completion/Commands/_history_complete_word
index fb1c502c8..b55966062 100644
--- a/Completion/Commands/_history_complete_word
+++ b/Completion/Commands/_history_complete_word
@@ -1,4 +1,4 @@
-#compdef -kn complete-word \e/
+#compdef -k complete-word \e/
 
 local expl
 
diff --git a/Completion/Commands/_most_recent_file b/Completion/Commands/_most_recent_file
index f8d2bd80c..868da8993 100644
--- a/Completion/Commands/_most_recent_file
+++ b/Completion/Commands/_most_recent_file
@@ -1,4 +1,4 @@
-#compdef -kn complete-word \C-xm
+#compdef -k complete-word \C-xm
 
 # Complete the most recent file matching the pattern on the line so
 # far: globbing is active, i.e. *.txt will be expanded to the most recent
diff --git a/Completion/Commands/_read_comp b/Completion/Commands/_read_comp
index 0a4f549f1..a32879b56 100644
--- a/Completion/Commands/_read_comp
+++ b/Completion/Commands/_read_comp
@@ -1,4 +1,4 @@
-#compdef -kn complete-word \C-x\C-r
+#compdef -k complete-word \C-x\C-r
 
 # This allows an on-the-fly choice of completions.  On typing the key
 # sequence given above, you will be prompted for a string of arguments.  If
diff --git a/Completion/Core/_parameters b/Completion/Core/_parameters
index 824d8dbc9..a6336424c 100644
--- a/Completion/Core/_parameters
+++ b/Completion/Core/_parameters
@@ -1,16 +1,67 @@
 #autoload
 
 # This should be used to complete parameter names if you need some of the
-# extra options of compadd. It completes only non-local parameters. All
-# arguments are given to compadd.
+# extra options of compadd. It completes only non-local parameters.
+# If the first argument is `-s' or `-b' auto_param_slash will be tested
+# and slashes will be added to parameters containing a directory. `-s' is
+# for parameter expansions without braces and `-b' is for expansions with
+# braces. A `-' as the first argument is ignored and in all cases all
+# other arguments will be given to `compadd'.
 
-local expl
+
+setopt localoptions extendedglob
+
+local pars expl slash suf
+
+if [[ "$1" = -s ]]; then
+  slash=normal
+  suf="$2"
+  shift 2
+elif [[ "$1" = -b ]]; then
+  slash=brace
+  suf="$2"
+  shift 2
+elif [[ "$1" = - ]]; then
+  shift
+fi
 
 _description expl parameter
 
 if zmodload -e parameter; then
   setopt localoptions extendedglob
-  compadd "$expl[@]" "$@" - ${(k)parameters[(R)^*local*]}
+  pars=( ${(k)parameters[(R)^*local*]} )
+else
+  pars=( ${${${(f)"$(typeset +)"}:#*local *}##* } )
+fi
+
+if [[ -n "$slash" && -o autoparamslash ]]; then
+  local i dirs nodirs ret=1
+
+  dirs=()
+  nodirs=()
+  for i in $pars; do
+    if [[ -d "${(P)i}" ]]; then
+      dirs=( $dirs $i )
+    else
+      nodirs=( $nodirs $i )
+    fi
+  done
+
+  if [[ "$slash" = normal ]]; then
+    compadd -S "/${suf%% #}" -r ' [/:' "$expl[@]" "$@" - $dirs && ret=0
+    compadd -S "$suf" -r ' [:' "$expl[@]" "$@" - $nodirs && ret=0
+  elif [[ "$slash" = brace ]]; then
+    compadd -S "}/${suf%% #}" -r '-:?#%+=[/}' "$expl[@]" "$@" - $dirs && ret=0
+    compadd -S "}$suf" -r '-:?#%+=[/}' "$expl[@]" "$@" - $nodirs && ret=0
+  fi
+
+  return ret
 else
-  compadd "$expl[@]" "$@" - ${${${(f)"$(typeset +)"}:#*local *}##* }
+  if [[ "$slash" = normal ]]; then
+    compadd -S "$suf" -r ' [:' "$expl[@]" "$@" - $pars
+  elif [[ "$slash" = brace ]]; then
+    compadd -S "}$suf" -r '-:?#%+=[/}' "$expl[@]" "$@" - $pars
+  else
+    compadd "$expl[@]" "$@" - $pars
+  fi
 fi
diff --git a/Completion/Core/compinit b/Completion/Core/compinit
index f160e7dcf..04438327c 100644
--- a/Completion/Core/compinit
+++ b/Completion/Core/compinit
@@ -379,7 +379,7 @@ if [[ -z "$_i_done" ]]; then
       case $_i_tag in
       (\#compdef)
 	if [[ $_i_line[1] = -[pPk](n|) ]]; then
-	  compdef ${_i_line[1]}a "${_i_file:t}" "${(@)_i_line[2,-1]}"
+	  compdef ${_i_line[1]}na "${_i_file:t}" "${(@)_i_line[2,-1]}"
 	else
 	  compdef -na "${_i_file:t}" "${_i_line[@]}"
 	fi
diff --git a/Completion/User/_chown b/Completion/User/_chown
index c75dbc4b3..3a14d3f89 100644
--- a/Completion/User/_chown
+++ b/Completion/User/_chown
@@ -4,14 +4,10 @@ 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 "$expl[@]" -u -S ':' -q
+      _users -S ':' -q
     else
-      compgen "$expl[@]" -u -S '.' -q
+      _users -S '.' -q
     fi
   fi
 else
diff --git a/Completion/User/_dir_list b/Completion/User/_dir_list
new file mode 100644
index 000000000..8e3615dac
--- /dev/null
+++ b/Completion/User/_dir_list
@@ -0,0 +1,4 @@
+#autoload
+
+compset -P '*:'
+_files -S: -r ': \t\t\-' -/
diff --git a/Completion/User/_exec_funcs b/Completion/User/_exec_funcs
new file mode 100644
index 000000000..2fd64b230
--- /dev/null
+++ b/Completion/User/_exec_funcs
@@ -0,0 +1,49 @@
+#autoload
+
+# This should be called from `_arguments' or otherwise the calling
+# function has to set up an array named `line' that contains the
+# name of the executable as its seconf element or it has to supply
+# that name as an argument.
+# One option is recognized: `-p' means that we are completing a pair
+# of names separated by a slash.
+
+local cmd pair expl
+
+if [[ "$1" = -p ]]; then
+  pair=yes
+  shift
+fi
+
+if (( $# )); then
+  cmd="$1"
+elif [[ $#line -gt 1 ]]; then
+  cmd="$line[2]"
+else
+  return 1
+fi
+
+if [[ -n "$cmd" ]]; then
+  if [[ "$cmd" = /* ]]; then
+    tmp="$cmd"
+  else
+    tmp="$PWD/$cmd"
+  fi
+
+  if [[ "$tmp" != "$_es_command" ]]; then
+    _es_command="$tmp"
+    _es_funcs=( "${(@)${(@M)${(@f)$(nm $cmd)}:#[^ ]# [tT] ([^_]|_[^_])*}##* }" )
+  fi
+  
+  if [[ -n "$pair" ]]; then
+    if compset -P '*/'; then
+      _description expl 'call arc to function'
+    else
+      _description expl 'call arc from function'
+    fi
+  else
+    _description expl function
+  fi
+  compadd -M 'r:|_=* r:|=*' - "$_es_funcs[@]"
+else
+  return 1
+fi
diff --git a/Completion/User/_find b/Completion/User/_find
index 20e8f4ff7..3ccb14c32 100644
--- a/Completion/User/_find
+++ b/Completion/User/_find
@@ -27,6 +27,5 @@ elif [[ "$prev" = -fstype ]]; then
 elif [[ "$prev" = -group ]]; then
   _groups
 elif [[ "$prev" = -user ]]; then
-  _description expl user
-  compgen "$expl[@]" -u
+  _users
 fi
diff --git a/Completion/User/_gprof b/Completion/User/_gprof
new file mode 100644
index 000000000..0a1d621be
--- /dev/null
+++ b/Completion/User/_gprof
@@ -0,0 +1,12 @@
+#compdef gprof
+
+_arguments -s -{a,b,c,D,h,i,l,L,s,T,v,w,x,y,z} \
+           -{A,C,e,E,f,F,J,n,N,O,p,P,q,Q,Z}:'function name: _exec_funcs' \
+	   '-I:directory:_dir_list' \
+	   '-d-:debug level:' '-k:function names: _exec_funcs -p' \
+	   '-m:minimum execution count:' \
+	   ':executable:_files -g *(*)' \
+	   ':profile file:_files -g gmon.*' \
+	   -- -s '(#--[no-] --)' \
+           '*=name*:function name: _exec_funcs' \
+	   '*=dirs*:directory:_dir_list'
diff --git a/Completion/User/_rlogin b/Completion/User/_rlogin
index 8756ec42d..e61890702 100644
--- a/Completion/User/_rlogin
+++ b/Completion/User/_rlogin
@@ -15,5 +15,5 @@ if [[ CURRENT -eq 2 ]];
 elif [[ CURRENT -eq 3 ]]; then
   compadd - -l
 else
-  compgen "$expl[@]" -S @ -u
+  _users -S @
 fi
diff --git a/Completion/User/_su b/Completion/User/_su
index 7b9744cd9..df1b89f97 100644
--- a/Completion/User/_su
+++ b/Completion/User/_su
@@ -1,13 +1,12 @@
 #compdef su
 
-local shell comp name usr base expl
+local shell comp name usr base
 
 [[ $words[2] != - ]]
 (( base=$?+2 ))
 
 if [[ CURRENT -eq base ]]; then
-  _description expl user
-  compgen "$expl[@]" -u && return
+  _users && return
   usr=root
 elif [[ CURRENT -ge base+1 ]]; then
   usr=$words[base]
diff --git a/Completion/User/_tar b/Completion/User/_tar
index 02551759a..8135bf006 100644
--- a/Completion/User/_tar
+++ b/Completion/User/_tar
@@ -72,7 +72,7 @@ if [[ "$PREFIX" = --* ]]; then
 
   # ...long options after `--'.
 
-  _long_options '--owner*:user:_tilde' \
+  _long_options '--owner*:user:_users' \
                 '*=(PROG|COMMAND)*:program:_command_names' \
 		'*=ARCHIVE*:archive: _tar_archive' \
 		'*=NAME*:file:_files' \
diff --git a/Completion/User/_users b/Completion/User/_users
new file mode 100644
index 000000000..fc1e87e52
--- /dev/null
+++ b/Completion/User/_users
@@ -0,0 +1,6 @@
+#autoload
+
+local expl
+
+_description expl user
+compgen "$@" "$expl[@]" -u