about summary refs log tree commit diff
path: root/Completion
diff options
context:
space:
mode:
Diffstat (limited to 'Completion')
-rw-r--r--Completion/Base/_first4
-rw-r--r--Completion/Base/_subscript22
-rw-r--r--Completion/Base/_tilde26
-rw-r--r--Completion/Builtins/_autoload2
-rw-r--r--Completion/Builtins/_bindkey2
-rw-r--r--Completion/Builtins/_echotc2
-rw-r--r--Completion/Builtins/_kill6
-rw-r--r--Completion/Builtins/_limits2
-rw-r--r--Completion/Builtins/_wait15
-rw-r--r--Completion/Builtins/_zmodload4
-rw-r--r--Completion/Commands/.distfiles2
-rw-r--r--Completion/Commands/_correct_filename2
-rw-r--r--Completion/Commands/_most_recent_file4
-rw-r--r--Completion/Core/_approximate4
-rw-r--r--Completion/Core/_expand2
-rw-r--r--Completion/Core/_list2
-rw-r--r--Completion/Core/_match20
-rw-r--r--Completion/Core/_path_files16
-rw-r--r--Completion/Core/compdump17
-rw-r--r--Completion/Core/compinit108
-rw-r--r--Completion/Core/compinstall56
-rw-r--r--Completion/User/.distfiles6
-rw-r--r--Completion/User/_chown15
-rw-r--r--Completion/User/_dd5
-rw-r--r--Completion/User/_find6
-rw-r--r--Completion/User/_groups6
-rw-r--r--Completion/User/_make24
-rw-r--r--Completion/User/_mh6
-rw-r--r--Completion/User/_rlogin2
-rw-r--r--Completion/User/_x_options6
30 files changed, 233 insertions, 161 deletions
diff --git a/Completion/Base/_first b/Completion/Base/_first
index d9e7ee82c..8b4da019d 100644
--- a/Completion/Base/_first
+++ b/Completion/Base/_first
@@ -40,9 +40,9 @@
 #       PREFIX="$PREFIX[1,-2]"
 #       # If a numeric prefix is given, we use it as the number of
 #       # lines (multiplied by ten below) in the history to search.
-#       if [[ NUMERIC -gt 1 ]]; then
+#       if [[ ${NUMERIC:-1} -gt 1 ]]; then
 #         max=$NUMERIC
-#         NUMERIC=1
+#         unset NUMERIC
 #       else
 #         # The default is to search the last 100 lines.
 #         max=10
diff --git a/Completion/Base/_subscript b/Completion/Base/_subscript
index abaabec8c..66d88b00c 100644
--- a/Completion/Base/_subscript
+++ b/Completion/Base/_subscript
@@ -1,7 +1,27 @@
 #compdef -subscript-
 
 if [[ ${(Pt)${compstate[parameter]}} = assoc* ]]; then
-  compgen -S ']' -k "( ${(kP)${compstate[parameter]}} )"
+  if [[ "$RBUFFER" = \]* ]]; then
+    compadd -S '' - "${(@kP)${compstate[parameter]}}"
+  else
+    compadd -S ']' - "${(@kP)${compstate[parameter]}}"
+  fi
+elif [[ ${(Pt)${compstate[parameter]}} = array* ]]; then
+  local list i j
+
+  ind=( {1..${#${(P)${compstate[parameter]}}}} )
+  list=()
+  for i in "$ind[@]"; do
+    [[ "$i" = ${PREFIX}*${SUFFIX} ]] &&
+        list=( "$list[@]" 
+	  "${(r:4:: ::):)i} $(print -D ${(P)${compstate[parameter]}[$i]})" )
+  done
+
+  if [[ "$RBUFFER" = \]* ]]; then
+    compadd -S '' -V default -y list - "$ind[@]"
+  else
+    compadd -S ']' -V default -y list - "$ind[@]"
+  fi
 else
   _compalso -math-
 fi
diff --git a/Completion/Base/_tilde b/Completion/Base/_tilde
index c24c65701..d03030821 100644
--- a/Completion/Base/_tilde
+++ b/Completion/Base/_tilde
@@ -7,10 +7,32 @@
 #   `(( compstate[nmatches] )) || compgen -nu -qS/'
 # below that.
 
+local c s dirs list
+
 if [[ "$SUFFIX" = */* ]]; then
   ISUFFIX="/${SUFFIX#*/}$ISUFFIX"
   SUFFIX="${SUFFIX%%/*}"
-  compgen -nu -S ''
+  s=(-S '')
 else
-  compgen -nu -qS/
+  s=(-qS/)
 fi
+
+if compset -P +; then
+  dirs="$(dirs -v)"
+  list=("${(f)dirs}")
+  [[ -o pushdminus ]] && dirs="$(awk '{ $1 = '$#list' - $1 - 1;
+  				        printf("%s\t%s\n", $1, $2); }' <<<$dirs)"
+  list=("${(@)list%	*}")
+  c=(-y '$dirs' -k "($list)")
+elif compset -P -; then
+  dirs="$(dirs -v)"
+  list=("${(f)dirs}")
+  [[ ! -o pushdminus ]] && dirs="$(awk '{ $1 = '$#list' - $1 - 1;
+					  printf("%s\t%s\n", $1, $2); }' <<<$dirs)"
+  list=("${(@)list%	*}")
+  c=(-y '$dirs' -k "($list)")
+else
+  c=(-nu)
+fi
+
+compgen "$c[@]" "$s[@]"
diff --git a/Completion/Builtins/_autoload b/Completion/Builtins/_autoload
index d1c255b73..f10fc34e7 100644
--- a/Completion/Builtins/_autoload
+++ b/Completion/Builtins/_autoload
@@ -1,3 +1,3 @@
 #compdef autoload
 
-compgen -s '${^fpath}/*(N:t)'
+compadd - ${^fpath}/*(N:t)
diff --git a/Completion/Builtins/_bindkey b/Completion/Builtins/_bindkey
index 57b3d8a85..91ecfcc28 100644
--- a/Completion/Builtins/_bindkey
+++ b/Completion/Builtins/_bindkey
@@ -8,7 +8,7 @@
 # Where appropriate, will complete keymaps instead of widgets.
 
 if [[ "$words[2]" = -*[DAN]* || "$words[CURRENT-1]" = -*M ]]; then
-  compgen -s '$(bindkey -l)'
+  compadd - $(bindkey -l)
 else
   compgen -b -M 'r:|-=* r:|=*'
 fi
diff --git a/Completion/Builtins/_echotc b/Completion/Builtins/_echotc
index ce282437d..15dfcef08 100644
--- a/Completion/Builtins/_echotc
+++ b/Completion/Builtins/_echotc
@@ -1,3 +1,3 @@
 #compdef echotc
 
-compgen -k '(al dc dl do le up al bl cd ce cl cr dc dl do ho is le ma nd nl se so up)'
+compadd al dc dl do le up al bl cd ce cl cr dc dl do ho is le ma nd nl se so up
diff --git a/Completion/Builtins/_kill b/Completion/Builtins/_kill
index 4f8c1db6d..26f6bf5cd 100644
--- a/Completion/Builtins/_kill
+++ b/Completion/Builtins/_kill
@@ -3,13 +3,13 @@
 local list
 
 if compset -P 1 -; then
-  compgen -k "($signals[1,-3])"
+  compadd $signals[1,-3]
 else
   local ret=1
 
   compgen -P '%' -j && ret=0
-  list=("$(ps 2>/dev/null)")
-  compgen -y '$list' -s '${${${(f)"$(ps 2>/dev/null)"}[2,-1]## #}%% *}' && 
+  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
 
   return ret
diff --git a/Completion/Builtins/_limits b/Completion/Builtins/_limits
index 6835a6244..0b8837d67 100644
--- a/Completion/Builtins/_limits
+++ b/Completion/Builtins/_limits
@@ -1,3 +1,3 @@
 #compdef limit unlimit
 
-compgen -s '${${(f)"$(limit)"}%% *}'
+compadd ${${(f)"$(limit)"}%% *}
diff --git a/Completion/Builtins/_wait b/Completion/Builtins/_wait
index 41d09c9b2..8f9339ebd 100644
--- a/Completion/Builtins/_wait
+++ b/Completion/Builtins/_wait
@@ -1,9 +1,20 @@
 #compdef wait
 
+# This uses two configuration keys:
+#
+#  ps_args
+#    This can be set to options of the ps(1) command that should be
+#    used when invoking it to get the pids to complete.
+#
+#  ps_listargs
+#    This defaults to the value of the `ps_args' key and defines
+#    options for the ps command that are to be used when creating
+#    the list to display during completion.
+
 local list ret=1
 
 compgen -P '%' -j && ret=0
-list=("$(ps 2>/dev/null)")
-compgen -y '$list' -s '${${${(f)"$(ps 2>/dev/null)"}[2,-1]## #}%% *}' && 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
 
 return ret
diff --git a/Completion/Builtins/_zmodload b/Completion/Builtins/_zmodload
index 4b0e91442..d3a39b5de 100644
--- a/Completion/Builtins/_zmodload
+++ b/Completion/Builtins/_zmodload
@@ -5,7 +5,7 @@ local fl="$words[2]"
 if [[ "$fl" = -*(a*u|u*a)* || "$fl" = -*a* && CURRENT -ge 4 ]]; then
   compgen -B
 elif [[ "$fl" = -*u* ]]; then
-  compgen -s '$(zmodload)'
+  compadd - $(zmodload)
 else
-  compgen -s '${^module_path}/*(N:t:r)'
+  compadd - ${^module_path}/*(N:t:r)
 fi
diff --git a/Completion/Commands/.distfiles b/Completion/Commands/.distfiles
index 19a02ef39..f79d69704 100644
--- a/Completion/Commands/.distfiles
+++ b/Completion/Commands/.distfiles
@@ -1,3 +1,3 @@
 DISTFILES_SRC='
-    .distfiles _correct_filename _correct_word _most_recent_file 
+    .distfiles _correct_filename _most_recent_file 
 '
diff --git a/Completion/Commands/_correct_filename b/Completion/Commands/_correct_filename
index baef38edf..7431a4831 100644
--- a/Completion/Commands/_correct_filename
+++ b/Completion/Commands/_correct_filename
@@ -23,7 +23,7 @@ if [[ -z $WIDGET ]]; then
   file=$1
   local IPREFIX
 else
-  (( NUMERIC > 1 )) && max_approx=$NUMERIC
+  (( ${NUMERIC:-1} > 1 )) && max_approx=$NUMERIC
 fi
 
 if [[ $file = \~*/* ]]; then
diff --git a/Completion/Commands/_most_recent_file b/Completion/Commands/_most_recent_file
index c571483ca..868da8993 100644
--- a/Completion/Commands/_most_recent_file
+++ b/Completion/Commands/_most_recent_file
@@ -14,9 +14,9 @@ local file tilde etilde
 if [[ $PREFIX = \~*/* ]]; then
   tilde=${PREFIX%%/*}
   etilde=${~tilde}
-  file=($~PREFIX*$~SUFFIX(om[$NUMERIC]N))
+  file=($~PREFIX*$~SUFFIX(om[${NUMERIC:-1}]N))
   file=(${file/#$etilde/$tilde})
 else
-  file=($~PREFIX*$~SUFFIX(om[$NUMERIC]N))
+  file=($~PREFIX*$~SUFFIX(om[${NUMERIC:-1}]N))
 fi
 (( $#file )) && compadd -U -i "$IPREFIX" -I "$ISUFFIX" -f -Q $file
diff --git a/Completion/Core/_approximate b/Completion/Core/_approximate
index c63416901..61f21c5b9 100644
--- a/Completion/Core/_approximate
+++ b/Completion/Core/_approximate
@@ -89,14 +89,14 @@ fi
 
 # Get the number of errors to accept.
 
-if [[ "$cfgacc" = *[nN]* && NUMERIC -ne 1 ]]; then
+if [[ "$cfgacc" = *[nN]* && ${NUMERIC:-1} -ne 1 ]]; then
   # Stop if we also have a `!'.
 
   [[ "$cfgacc" = *\!* ]] && return 1
 
   # Prefer the numeric argument if that has a sensible value.
 
-  comax="$NUMERIC"
+  comax="${NUMERIC:-1}"
 else
   comax="${cfgacc//[^0-9]}"
 fi
diff --git a/Completion/Core/_expand b/Completion/Core/_expand
index aca3839d4..58e184657 100644
--- a/Completion/Core/_expand
+++ b/Completion/Core/_expand
@@ -17,7 +17,7 @@
 #    In this case, expansion of substitutions will be done if the
 #    expression evaluates to `1'. For example, with
 #
-#      compconf expand_substitute='NUMERIC != 1'
+#      compconf expand_substitute='${NUMERIC:-1} != 1'
 #
 #    substitution will be performed only if given an explicit numeric
 #    argument other than `1', as by typing ESC 2 TAB.
diff --git a/Completion/Core/_list b/Completion/Core/_list
index 0d5651c23..28a5161d1 100644
--- a/Completion/Core/_list
+++ b/Completion/Core/_list
@@ -14,7 +14,7 @@
 #    will be done if the expression evaluates to `1'.
 #    For example, with
 #
-#      compconf list_condition='NUMERIC != 1'
+#      compconf list_condition='${NUMERIC:-1} != 1'
 #
 #    delaying will be done only if given an explicit numeric argument
 #    other than `1'.
diff --git a/Completion/Core/_match b/Completion/Core/_match
index 3c639935c..251c65381 100644
--- a/Completion/Core/_match
+++ b/Completion/Core/_match
@@ -9,7 +9,7 @@
 # expand-or-complete function because otherwise the pattern will
 # be expanded using globbing.
 #
-# Configuration key used:
+# Configuration keys used:
 #
 #  match_original
 #    If this is set to a `only', pattern matching will only be tried
@@ -18,6 +18,11 @@
 #    no completions, matching will be tried again with a `*' inserted
 #    at the cursor position. If this key is not set or set to an empty
 #    string, matching will only be attempted with the `*' inserted.
+#
+#  match_insert
+#    If this is set to a string starting with `unambig', menucompletion
+#    will only be turned on if no unambiguous string could be built
+#    that is at least as long as the original string.
 
 local tmp opm="$compstate[pattern_match]" ret=0
 
@@ -37,7 +42,12 @@ if [[ -n "$compconfig[match_original]" ]]; then
   compstate[pattern_match]="$opm"
   compstate[matcher]="$compstate[total_matchers]"
 
-  (( ret )) && return 0
+  if (( ret )); then
+    [[ "$compconfig[match_insert]" = unambig* &&
+       $#compstate[unambiguous] -ge ${#:-${PREFIX}${SUFFIX}} ]] && 
+        compstate[pattern_insert]=unambiguous
+    return 0
+  fi
 fi
 
 # No completion with inserting `*'?
@@ -50,4 +60,10 @@ _complete && ret=1
 compstate[pattern_match]="$opm"
 compstate[matcher]="$compstate[total_matchers]"
 
+if (( ! ret )); then
+  [[ "$compconfig[match_insert]" = unambig* &&
+     $#compstate[unambiguous] -ge ${#:-${PREFIX}${SUFFIX}} ]] && 
+      compstate[pattern_insert]=unambiguous
+fi
+
 return 1-ret
diff --git a/Completion/Core/_path_files b/Completion/Core/_path_files
index d0d1c6a0a..58f343367 100644
--- a/Completion/Core/_path_files
+++ b/Completion/Core/_path_files
@@ -11,12 +11,17 @@
 # with one of the suffixes thus given are treated like files with one
 # of the suffixes in the `fignore' array in normal completion.
 #
-# This function supports one configuration key:
+# This function supports two configuration keys:
 #
 #  path_expand
 #    If this is set to a non-empty string, the partially typed path
 #    from the line will be expanded as far as possible even if trailing
 #    pathname components can not be completed.
+#
+#  path_cursor
+#    If this is set to an non-empty string, the cursor will be placed
+#    in the path after the ambiguous pathname component even when using
+#    menucompletion.
 
 local linepath realpath donepath prepath testpath exppath
 local tmp1 tmp2 tmp3 tmp4 i orig pre suf tpre tsuf
@@ -304,10 +309,11 @@ for prepath in "$prepaths[@]"; do
       # it as far as possible.
 
       if [[ -n $menu ]]; then
+        [[ -n "$compconfig[path_cursor]" ]] && compstate[to_end]=''
         if [[ "$tmp3" = */* ]]; then
 	  compadd -Uf -p "$linepath$testpath" -s "/${tmp3#*/}" \
 	          -W "$prepath$realpath$testpath" "$ignore[@]" \
-		  "$addpfx[@]" "$addsfx[@]" "$remsfx[@]" \
+		  "$addpfx[@]" "$addsfx[@]" "$remsfx[@]" -M 'r:|/=* r:|=*' \
 		  "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
 		  - "${(@)tmp1%%/*}"
 	else
@@ -371,9 +377,9 @@ done
 exppaths=( "${(@)exppaths:#$orig}" )
 
 if [[ -n "$compconfig[path_expand]" &&
-      $#exppaths -ne 0 && nm -eq compstate[nmatches] ]]; then
-  compadd -U -S '' "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
-          -p "$linepath" - "${(@)exppaths}"
+      $#exppaths -eq 0 && nm -eq compstate[nmatches] ]]; then
+  compadd -QU -S '' "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
+          -M 'r:|/=* r:|=*' -p "$linepath" - "${(@)exppaths}"
 fi
 
 [[ nm -eq compstate[nmatches] ]]
diff --git a/Completion/Core/compdump b/Completion/Core/compdump
index 5ee04e028..f2729acc5 100644
--- a/Completion/Core/compdump
+++ b/Completion/Core/compdump
@@ -1,4 +1,4 @@
-# This is a file to be sourced to dump the definitions for new-style
+# This is a function to dump the definitions for new-style
 # completion defined by 'compinit' in the same directory.  The output
 # should be directed into the "compinit.dump" in the same directory as
 # compinit. If you rename init, just stick .dump onto the end of whatever
@@ -9,12 +9,14 @@
 # To do this, simply remove the .dump file, start a new shell, and
 # create the .dump file as before.  Again, compinit -d handles this
 # automatically.
-#
-# It relies on KSH_ARRAYS not being set.
 
 # Print the number of files used for completion. This is used in compinit
 # to see if auto-dump should re-dump the dump-file.
 
+emulate -L zsh
+
+typeset _d_file _d_f _d_bks _d_line _d_als
+
 _d_file=${compconfig[dumpfile]-${0:h}/compinit.dump}
 
 typeset -U _d_files
@@ -22,8 +24,6 @@ _d_files=( ${^~fpath}/_(|*[^~])(N:t) )
 
 print "#files: $#_d_files" > $_d_file
 
-unset _d_files
-
 # First dump the arrays _comps and _patcomps.  The quoting hieroglyphyics
 # ensure that a single quote inside a variable is itself correctly quoted.
 
@@ -44,11 +44,13 @@ print >> $_d_file
 # Now dump the key bindings. We dump all bindings for zle widgets
 # whose names start with a underscore.
 # We need both the zle -C's and the bindkey's to recreate.
+# We can ignore any zle -C which rebinds a standard widget (second
+# argument to zle does not begin with a `_').
 
 _d_bks=()
 zle -lL |
   while read -rA _d_line; do
-    if [[ ${_d_line[5]} = _* ]]; then
+    if [[ ${_d_line[3]} = _* && ${_d_line[5]} = _* ]]; then
       print -r - ${_d_line}
       _d_bks=($_d_bks ${_d_line[3]})
     fi
@@ -86,4 +88,5 @@ done >> $_d_file
 
 print >> $_d_file
 
-unset _d_line _d_zle _d_bks _d_als _d_f _f_file
+unfunction compdump
+autoload -U compdump
diff --git a/Completion/Core/compinit b/Completion/Core/compinit
index 23bc94cf9..e078cc33c 100644
--- a/Completion/Core/compinit
+++ b/Completion/Core/compinit
@@ -41,15 +41,13 @@
 # See the file `compdump' for how to speed up initialisation.
 
 # If we got the `-d'-flag, we will automatically dump the new state (at
-# the end).
-# `-f dir' is used to pass down the directory where this file was
-#   found.  This is necessary if functionargzero is not set.
-# If we were given an argument, this will be taken as the name of the
-# file in which to store the dump.
-
-_i_fdir=''
-_i_dumpfile=''
-_i_autodump=0
+# the end).  This takes the dumpfile as an argument.
+
+emulate -L zsh
+
+typeset _i_dumpfile _i_files _i_line _i_done _i_dir _i_autodump=0
+typeset _i_tag _i_file
+
 while [[ $# -gt 0 && $1 = -[df] ]]; do
   if [[ "$1" = -d ]]; then
     _i_autodump=1
@@ -59,56 +57,27 @@ while [[ $# -gt 0 && $1 = -[df] ]]; do
       shift
     fi
   elif [[ "$1" = -f ]]; then
-    # Used by compinstall to pass down directory where compinit was found
+    # Not used any more; use _compdir
     shift
-    _i_fdir="$1"
     shift
   fi
 done
-# Get the directory if we don't have it already and we can
-if [[ -z "$_i_fdir" && -o functionargzero && $0 = */* ]]; then
-  _i_fdir=${0:h}
-fi
 
 # The associative array containing the definitions for the commands.
 # Definitions for patterns will be stored in the normal array `_patcomps'.
 
-typeset -A _comps
+typeset -gA _comps
 _patcomps=()
 
 # This is the associative array used for configuration.
 
-typeset -A compconfig
+typeset -gA compconfig
 
 # Standard initialisation for `compconfig'.
 if [[ -n $_i_dumpfile ]]; then
   # Explicitly supplied dumpfile.
   compconfig[dumpfile]="$_i_dumpfile"
-elif [[ -o functionargzero ]]; then
-  # We can deduce it from the name of this script
-  compconfig[dumpfile]="$0.dump"
-elif [[ -n $_i_fdir ]]; then
-  # We were told what directory to use.
-  compconfig[dumpfile]="$_i_fdir/compinit.dump"
 else
-  compconfig[dumpfile]=''
-fi
-
-if [[ -n $compconfig[dumpfile] ]]; then
-  # Check the file is writeable.  If it doesn't exist, the
-  # only safe way is to try and create it.
-  if [[ -f $compconfig[dumpfile] ]]; then
-    [[ -w $compconfig[dumpfile] ]] || compconfig[dumpfile]=''
-  elif touch $compconfig[dumpfile] >& /dev/null; then
-    rm -f $compconfig[dumpfile]
-  else
-    compconfig[dumpfile]=''
-  fi
-fi
-
-if [[ -z $compconfig[dumpfile] ]]; then
-  # If no dumpfile given, or it was not writeable, then use
-  # user's ZDOTDIR.
   compconfig[dumpfile]="${ZDOTDIR:-$HOME}/.zcompdump"
 fi
 
@@ -215,7 +184,11 @@ compdef() {
       fi
 
       # Define the widget.
-      zle -C "$func" "$1" "$func"
+      if [[ $1 = .* ]]; then
+	zle -C "$func" "$1" "$func"
+      else
+	zle -C "$func" ".$1" "$func"
+      fi
       shift
 
       # And bind the keys...
@@ -321,22 +294,32 @@ _i_files=( ${^~fpath:/.}/_(|*[^~])(N:t) )
 if [[ $#_i_files -lt 20 ]]; then
   # Too few files:  we need some more directories
   # Assume that we need to add the compinit directory to fpath.
-  if [[ -n $_i_fdir ]]; then
-    if [[ $_i_fdir = */Core ]]; then
+  if [[ -n $_compdir ]]; then
+    if [[ $_compdir = */Core ]]; then
       # Add all the Completion subdirectories
-      fpath=(${_i_fdir:h}/*(/) $fpath)
-    elif [[ -d $_i_fdir/Core ]]; then
+      fpath=(${_compdir:h}/*(/) $fpath)
+    elif [[ -d $_compdir/Core ]]; then
       # Likewise
-      fpath=(${_i_fdir}/*(/) $fpath)
-    else
-      fpath=($_i_fdir $fpath)
+      fpath=(${_compdir}/*(/) $fpath)
     fi
     _i_files=( ${^~fpath:/.}/_(|*[^~])(N:t) )
   fi
 fi
 
+
+# Rebind the standard widgets
+for _i_line in complete-word delete-char-or-list expand-or-complete \
+  expand-or-complete-prefix list-choices menu-complete \
+  menu-expand-or-complete reverse-menu-complete; do
+  zle -C $_i_line .$_i_line _main_complete
+done
+zle -la menu-select && zle -C menu-select .menu-select _main_complete
+
 _i_done=''
 
+# Make sure compdump is available, even if we aren't going to use it.
+autoload -U compdump compinstall
+
 # If we have a dump file, load it.
 
 if [[ -f "$compconfig[dumpfile]" ]]; then
@@ -345,7 +328,6 @@ if [[ -f "$compconfig[dumpfile]" ]]; then
     builtin . "$compconfig[dumpfile]"
     _i_done=yes
   fi
-  unset _i_line
 fi
 if [[ -z "$_i_done" ]]; then
   for _i_dir in $fpath; do
@@ -369,30 +351,12 @@ if [[ -z "$_i_done" ]]; then
     done
   done
 
-  bindkey |
-    while read -rA _i_line; do
-      case "$_i_line[2]" in
-      (complete-word) ;&
-      (delete-char-or-list) ;&
-      (expand-or-complete) ;&
-      (expand-or-complete-prefix) ;&
-      (list-choices) ;&
-      (menu-complete) ;&
-      (menu-expand-or-complete) ;&
-      (reverse-menu-complete)
-	zle -C _complete_$_i_line[2] $_i_line[2] _main_complete
-	bindkey "${_i_line[1][2,-2]}" _complete_$_i_line[2]
-	;;
-      esac
-    done
-
-  unset _i_dir _i_line _i_file _i_tag
-
   # If autodumping was requested, do it now.
 
-  if [[ -n ${_i_fdir} && $_i_autodump = 1 ]]; then
-    builtin . ${_i_fdir}/compdump
+  if [[ $_i_autodump = 1 ]]; then
+    compdump
   fi
 fi
 
-unset _i_files _i_initname _i_done _i_autodump _i_fdir _i_dumpfile
+unfunction compinit
+autoload -U compinit
diff --git a/Completion/Core/compinstall b/Completion/Core/compinstall
index 5086cc7d2..255565b3f 100644
--- a/Completion/Core/compinstall
+++ b/Completion/Core/compinstall
@@ -3,7 +3,7 @@
 # available in some directory; they should have been installed with the
 # the shell (except we haven't written that yet).
 #
-# Source this script (e.g. `. /path/compinstall') and answer the questions.
+# Run this script as a function and answer the questions.
 #
 # Normally, this will alter ~/.zshrc (or wherever ZDOTDIR puts it), but you
 # can make that unwritable and it will leave the lines in a temporary file
@@ -23,33 +23,13 @@
 #  - Could add code for setting other completers and options.
 #  - Could add keys for context-sensitive help.
 
-# Save the options.  We will need to trap ^C to make sure they get
-# restored properly.
-typeset -A _ci_options
-_ci_options=($(setopt kshoptionprint;setopt))
-[[ -o kshoptionprint ]] || _ci_options[kshoptionprint]=off
-[[ -o monitor ]] && _ci_options[monitor]=on
-[[ -o zle ]] && _ci_options[zle]=on
-
-emulate zsh
-
-TRAPINT() { 
-  unsetopt ${(k)_ci_options[(R)off]}
-  setopt ${(k)_ci_options[(R)on]}
-
-  unset _ci_options _ci_f _ci_fdir _ci_files _ci_dumpfile _ci_lines
-  unset _ci_type _ci_completer _ci_accept _ci_cprompt _ci_startline
-  unset _ci_endline _ci_ifile _ci_tmpf _ci_defaults _ci_compconf _ci_warn
-  unset _ci_dtype _ci_existing _ci_line
-
-  if (( $1 )); then
-    print Aborted.
-    unfunction TRAPINT
-    return 1
-  fi
-  return 0
-}
 
+emulate -L zsh
+
+typeset _ci_options _ci_f _ci_fdir _ci_files _ci_dumpfile _ci_lines
+typeset _ci_type _ci_completer _ci_accept _ci_cprompt _ci_startline
+typeset _ci_endline _ci_ifile _ci_tmpf _ci_compconf _ci_warn
+typeset _ci_dtype _ci_existing _ci_line
 
 # Look for the defaults.
 _ci_startline='# The following lines were added by compinstall'
@@ -60,6 +40,7 @@ _ci_lines=''
 _ci_existing=''
 
 typeset -A _ci_defaults
+
 if [[ -f $_ci_ifile ]]; then
   # This assumes the lines haven't been altered by the user too much
   # after they were added.
@@ -83,10 +64,12 @@ if [[ -f $_ci_ifile ]]; then
       fi
       _ci_existing="${_ci_existing}  $_ci_line
 "
-    elif [[ $_ci_line[1] = . && $_ci_line[2] = */compinit ]]; then
-      # parse the line sourcing compinit
-      [[ $_ci_line[3] = -f ]]  && _ci_fdir=$_ci_line[4]
+    elif [[ $_ci_line[1] = compinit ]]; then
+      # parse the line running compinit
+      [[ $_ci_line[2] = -f ]]  && _ci_fdir=$_ci_line[3]
       [[ $_ci_line[-2] = -d ]] && _ci_dumpfile=$_ci_line[-1]
+    elif [[ $_ci_line[1] = _compdir=* ]]; then
+      _ci_fdir=${_ci_line[1]##_compdir=}
     elif [[ $_ci_line[1] = compconf ]]; then
       # parse a compconf component as second argument (should be completer)
       [[ $_ci_line[2] = completer=* ]] &&
@@ -94,7 +77,7 @@ if [[ -f $_ci_ifile ]]; then
       [[ $_ci_line[-1] == \\ ]] && _ci_compconf=1
       _ci_existing="${_ci_existing}$_ci_line
 "
-    elif [[ $_ci_line[1] != \#* ]]; then
+    elif [[ $_ci_line[1] != \#* && $_ci_line[1] != (autoload|\[\[) ]]; then
       if [[ -z $_ci_warn ]]; then
 	_ci_warn=1
 	print "Warning:  existing lines in compinstall setup not understood:"
@@ -166,7 +149,7 @@ fi
 # Set up the dumpfile
 _ci_dtype=existing
 if [[ -z $_ci_dumpfile ]]; then
-  _ci_dumpfile="${_ci_fdir}/compinit.dump"
+  _ci_dumpfile="${ZDOTDIR:-$HOME}/.zcompdump"
   _ci_dtype=standard
 fi
 
@@ -184,7 +167,6 @@ else
 I will force completion to dump its status, which will speed up the shell's
 start-up considerably.  However, I can't write the file I'd like to, namely
 ${_ci_dumpfile}.  Please edit a replacement."
-  _ci_dumpfile='~/.compinit.dump'
   vared _ci_dumpfile
   while ! touch ${~_ci_dumpfile} >& /dev/null; do
     print "Sorry, I can't write that either.  Try again."
@@ -193,7 +175,10 @@ ${_ci_dumpfile}.  Please edit a replacement."
   [[ -s $_ci_dumpfile ]] || rm -f $_ci_dumpfile
 fi
 
-_ci_lines="${_ci_lines}. $_ci_fdir/compinit -f $_ci_fdir -d"
+_ci_lines="${_ci_lines}_compdir=$_ci_fdir
+[[ -z \$fpath[(r)\$_compdir] ]] && fpath=(\$_compdir \$fpath)
+autoload -U compinit
+compinit -d"
 [[ $_ci_dtype != standard ]] && _ci_lines="${_ci_lines} $_ci_dumpfile"
 _ci_lines="${_ci_lines}
 "
@@ -363,6 +348,7 @@ $_ci_lines$_ci_endline" >>$_ci_ifile &&
   print "\nSuccessfully appended lines to $_ci_ifile."
 fi
 
-TRAPINT 0
+unfunction compinstall
+autoload -U compinstall
 
 return 0
diff --git a/Completion/User/.distfiles b/Completion/User/.distfiles
index ee0017035..07fddc134 100644
--- a/Completion/User/.distfiles
+++ b/Completion/User/.distfiles
@@ -1,6 +1,6 @@
 DISTFILES_SRC='
     .distfiles
-    _a2ps _compress _configure _dd _dvi _find _gunzip _gzip _hosts
-    _make _man _mh _pdf _ps _rcs _rlogin _strip _stty _tar _tar_archive
-    _tex _uncompress _x_options _xfig 
+    _a2ps _chown _compress _configure _dd _dvi _find _groups _gunzip _gzip
+    _hosts _make _man _mh _pdf _ps _rcs _rlogin _strip _stty
+    _tar _tar_archive _tex _uncompress _x_options _xfig 
 '
diff --git a/Completion/User/_chown b/Completion/User/_chown
new file mode 100644
index 000000000..1ec76b39e
--- /dev/null
+++ b/Completion/User/_chown
@@ -0,0 +1,15 @@
+#compdef chown chgrp
+
+if [[ CURRENT -eq 2 || CURRENT -eq 3 && $words[CURRENT-1] = -* ]]; then
+  if [[ $words[1] = chgrp ]] || compset -P '*[:.]'; then
+    _groups
+  else
+    if [[ $OSTYPE = (solaris*|hpux*) ]]; then
+      compgen -u -S ':' -q
+    else
+      compgen -u -S '.' -q
+    fi
+  fi
+else
+  _files
+fi
diff --git a/Completion/User/_dd b/Completion/User/_dd
index 6094d60b7..e57074520 100644
--- a/Completion/User/_dd
+++ b/Completion/User/_dd
@@ -4,10 +4,9 @@ if compset -P 1 'conv\='; then
   # If there's a comma present, ignore up to the last one.  The
   # test alone will have that effect.
   compset -p '*,'
-  compgen -S, -q \
-      -k '(ascii ebcdic ibm block unblock lcase ucase swab noerror sync)'
+  compadd -qS, -q ascii ebcdic ibm block unblock lcase ucase swab noerror sync
 elif compset -P 1 '[io]f\='; then
   _files
 else
-  compgen -S '=' -k '(if of ibs obs bs cbs skip files seek count conv)'
+  compadd -S '=' if of ibs obs bs cbs skip files seek count conv
 fi
diff --git a/Completion/User/_find b/Completion/User/_find
index dd00b0ed1..de8c3bff9 100644
--- a/Completion/User/_find
+++ b/Completion/User/_find
@@ -5,10 +5,10 @@ local prev="$words[CURRENT-1]"
 if compset -N '-(ok|exec)' '\;'; then
   _normal
 elif compset -P 1 -; then
-  compgen -s 'daystart {max,min,}depth follow noleaf version xdev \
+  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'
+    exec {f,}print{f,0,} ok prune ls
 elif [[ CURRENT -eq 2 ]]; then
   local ret=1
 
@@ -19,7 +19,7 @@ elif [[ CURRENT -eq 2 ]]; then
 elif [[ "$prev" = -((a|c|)newer|fprint(|0|f)) ]]; then
   _files
 elif [[ "$prev" = -fstype ]]; then
-  compgen -k '(ufs 4.2 4.3 nfs tmp mfs S51K S52K)'
+  compadd ufs 4.2 4.3 nfs tmp mfs S51K S52K
 elif [[ "$prev" = -group ]]; then
   compgen -k groups
 elif [[ "$prev" = -user ]]; then
diff --git a/Completion/User/_groups b/Completion/User/_groups
new file mode 100644
index 000000000..975189174
--- /dev/null
+++ b/Completion/User/_groups
@@ -0,0 +1,6 @@
+#compdef newgrp
+
+: ${(A)groups:=${${(s: :)$(</etc/group)}%%:*}}
+# : ${(A)groups:=${${(s: :)$(ypcat group.byname)}%%:*}} # If you use NIS
+
+compadd $groups
diff --git a/Completion/User/_make b/Completion/User/_make
index 4770c0d7a..add58dbf0 100644
--- a/Completion/User/_make
+++ b/Completion/User/_make
@@ -1,4 +1,24 @@
 #compdef make gmake pmake
 
-compgen -s "\$(awk '/^[a-zA-Z0-9][^\/ 	]+:/ {print \$1}' FS=: [mM]akefile /dev/null)" ||
-_files
+local prev="$words[CURRENT-1]" file ret=1
+
+if [[ "$prev" = -[CI] ]]; then
+  _files -/
+elif [[ "$prev" = -[foW] ]]; then
+  _files
+else
+  file="$words[(I)-f]"
+  if (( file )); then
+    file="$words[file+1]"
+  elif [[ -e Makefile ]]; then
+    file=Makefile
+  elif [[ -e makefile ]]; then
+    file=makefile
+  else
+    file=''
+  fi
+
+  [[ -n "$file" ]] &&
+    compadd - $(awk '/^[a-zA-Z0-9][^/ 	]+:/ {print $1}' FS=: $file) && ret=0
+  (( ret )) && _files
+fi
diff --git a/Completion/User/_mh b/Completion/User/_mh
index e228d31b0..f03e3d827 100644
--- a/Completion/User/_mh
+++ b/Completion/User/_mh
@@ -23,7 +23,7 @@ if compset -P 1 -; then
     print $n =~ s/^\[([a-z]+)\]// ? "$n\n$1$n\n" : "$n\n";
   }')
   return
-elif compset -P 1 '[+@] || [ "$prev" = -draftfolder ]]; then
+elif compset -P 1 '[+@]' || [[ "$prev" = -draftfolder ]]; then
   # Complete folder names.
   local mhpath
 
@@ -39,7 +39,7 @@ elif compset -P 1 '[+@] || [ "$prev" = -draftfolder ]]; then
 elif [[ "$prev" = -(editor|(whatnow|rmm|show|more)proc) ]]; then
   compgen -c
 elif [[ "$prev" = -file ]]; then
-  compgen -f
+  _files
 elif [[ "$prev" = -(form|audit|filter) ]]; then
   # Need some MH template file, which may be in our own MH directory
   # or with the standard library.
@@ -69,7 +69,7 @@ else
     # leaving foldnam empty works here
   fi
 
-  compgen -s '$(mark $foldnam 2>/dev/null | awk -F: '\''{ print $1 }'\'')' &&
+  compadd $(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
diff --git a/Completion/User/_rlogin b/Completion/User/_rlogin
index 9f5f3d628..b792ba0d1 100644
--- a/Completion/User/_rlogin
+++ b/Completion/User/_rlogin
@@ -3,7 +3,7 @@
 if [[ CURRENT -eq 2 ]]; then
   compgen -k hosts
 elif [[ CURRENT -eq 3 ]]; then
-  compgen -k '(-l)'
+  compadd - -l
 else
   compgen -u
 fi
diff --git a/Completion/User/_x_options b/Completion/User/_x_options
index cd45c87f6..a9c18b0d1 100644
--- a/Completion/User/_x_options
+++ b/Completion/User/_x_options
@@ -2,4 +2,8 @@
 
 # A simple pattern completion, just as an example.
 
-compgen -J options -k '(-display -name -xrm)'
+if [ "$words[CURRENT-1]" = "-display" ]; then
+  compgen -k hosts -S':0'
+else
+  compadd -J options - -display -name -xrm
+fi