about summary refs log tree commit diff
path: root/Completion
diff options
context:
space:
mode:
Diffstat (limited to 'Completion')
-rw-r--r--Completion/Base/_command_names7
-rw-r--r--Completion/Base/_default9
-rw-r--r--Completion/Base/_parameter2
-rw-r--r--Completion/Builtins/_cd25
-rw-r--r--Completion/Commands/.distfiles3
-rw-r--r--Completion/Commands/_history_complete_word2
-rw-r--r--Completion/Commands/_read_comp158
-rw-r--r--Completion/Core/_main_complete30
-rw-r--r--Completion/Core/_match8
-rw-r--r--Completion/Core/_oldlist24
-rw-r--r--Completion/Core/_path_files7
-rw-r--r--Completion/Core/compinit12
-rw-r--r--Completion/Core/compinstall4
-rw-r--r--Completion/Makefile.in35
-rw-r--r--Completion/User/.distfiles2
-rw-r--r--Completion/User/_ps2
-rw-r--r--Completion/User/_tar1
-rw-r--r--Completion/User/_use_lo10
18 files changed, 269 insertions, 72 deletions
diff --git a/Completion/Base/_command_names b/Completion/Base/_command_names
index 8f75f1a77..61fea56dd 100644
--- a/Completion/Base/_command_names
+++ b/Completion/Base/_command_names
@@ -2,6 +2,13 @@
 
 local nm=$compstate[nmatches] ret=1
 
+
+# Complete jobs in implicit fg and bg
+if [[ "$PREFIX[1]" = "%" ]]; then
+  compgen -j -P '%'
+  [[ nm -ne compstate[nmatches] ]] && return
+fi
+
 compgen -c && ret=0
 
 if [[ nm -eq compstate[nmatches] ]]; then
diff --git a/Completion/Base/_default b/Completion/Base/_default
index b49ca7115..03bbfd49f 100644
--- a/Completion/Base/_default
+++ b/Completion/Base/_default
@@ -11,4 +11,11 @@
 
 compcall || return 0
 
-_files
+_files && return
+
+# magicequalsubst allows arguments like <any-old-stuff>=~/foo to do
+# file name expansion after the =.  In that case, it's natural to
+# allow completion to handle file names after any equals sign.
+if [[ -o magicequalsubst ]] && compset -P 1 '*='; then
+  _files
+fi
diff --git a/Completion/Base/_parameter b/Completion/Base/_parameter
index 7200ae440..b235a5fee 100644
--- a/Completion/Base/_parameter
+++ b/Completion/Base/_parameter
@@ -1,3 +1,3 @@
 #compdef -parameter-
 
-compgen -v
+_parameters -S ' ' -r '['
diff --git a/Completion/Builtins/_cd b/Completion/Builtins/_cd
index 4a846c6aa..9ac29b8f8 100644
--- a/Completion/Builtins/_cd
+++ b/Completion/Builtins/_cd
@@ -11,11 +11,8 @@
 #    it's not a lot of use.  If you don't type the + or - it will
 #    complete directories as normal.
 
-local pushdminus
-[[ -o pushdminus ]] && pushdminus=1
-
-emulate -LR zsh
-setopt extendedglob
+emulate -L zsh
+setopt extendedglob nonomatch
 
 if [[ CURRENT -eq 3 ]]; then
   # cd old new: look for old in $PWD and see what can replace it
@@ -40,8 +37,8 @@ elif [[ $PREFIX = [-+]* ]]; then
   lines="$(dirs -v)"
   # turn the lines into an array, removing the current directory
   list=(${${(f)lines}##0*})
-  if [[ ( $IPREFIX = - && -z $pushdminus ) ||
-        ( $IPREFIX = + && -n $pushdminus ) ]]; then
+  if [[ ( $IPREFIX = - && ! -o pushdminus ) ||
+        ( $IPREFIX = + && -o pushdminus ) ]]; then
     # reverse the numbering: it counts the last one as -0, which
     # is a little strange.
     integer tot i
@@ -59,7 +56,19 @@ elif [[ $PREFIX = [-+]* ]]; then
 
   return ret
 elif [[ $PREFIX != (\~|/|./|../)* && $#cdpath -ne 0 ]]; then
-  _path_files -W "(. $cdpath)" -/
+  local tdir tdir2
+  # With cdablevars, we can convert foo/bar/... to ~foo/bar/... if
+  # there is no directory foo.  In that case we could also complete
+  # variable names, but it hardly seems worth it.
+  # Note we need a tilde because cdablevars also allows user home
+  # directories, hence we also need nonomatch to suppress error messages.
+  if [[ -o cdablevars && ! -d ${tdir::=${PREFIX%%/*}} &&
+    -d ${~tdir2::="~$tdir"} ]]; then
+      PREFIX="~$PREFIX"
+      _path_files -/
+  else
+    _path_files -W "(. $cdpath)" -/
+  fi
 else
   _path_files -/
 fi
diff --git a/Completion/Commands/.distfiles b/Completion/Commands/.distfiles
index 7b2a319fe..7fef35230 100644
--- a/Completion/Commands/.distfiles
+++ b/Completion/Commands/.distfiles
@@ -1,3 +1,4 @@
 DISTFILES_SRC='
-    .distfiles _correct_filename _correct_word _expand_word _most_recent_file 
+    .distfiles _correct_filename _correct_word _expand_word 
+    _history_complete_word _read_comp _most_recent_file 
 '
diff --git a/Completion/Commands/_history_complete_word b/Completion/Commands/_history_complete_word
new file mode 100644
index 000000000..fc67c0f14
--- /dev/null
+++ b/Completion/Commands/_history_complete_word
@@ -0,0 +1,2 @@
+#compdef -k complete-word \e/
+compgen -Q -H 0 ''
diff --git a/Completion/Commands/_read_comp b/Completion/Commands/_read_comp
new file mode 100644
index 000000000..a32879b56
--- /dev/null
+++ b/Completion/Commands/_read_comp
@@ -0,0 +1,158 @@
+#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
+# this string begins with `_', it will be taken as the name of a function to
+# evaluate to generate the completions; unambiguous strings in the function
+# name are automatically completed.
+#
+# Else it is taken to be a set of arguments for compgen to generate a list
+# of choices.  The possibilities are the same as the flags for generating
+# completions given in the zshcompctl manual page.  Note the arguments are
+# verbatim:  include minus signs, spaces, quotes, etc.
+#
+# On subsequent calls, the same completion will be re-performed.  To
+# force a new type of completion to be read, supply a numeric argument.
+#
+# For example,
+#  % bindkey | grep rever<C-xC-r>
+#  Completion: -b<RET>
+#  % bindkey | grep reverse-menu-complete _
+#
+# Global variables used:
+#  _read_comp         Last completion string read from user
+
+emulate -L zsh
+setopt extendedglob nobadpattern # xtrace promptsubst
+# local PS4='%N:%i:$((#key))> '
+
+# Took me ages to work this out.  If we're not on the first global
+# matcher specification, we mustn't do any I/O.
+if [[ compstate[matcher] -gt 1 && -z $_read_comp ]]; then
+  return 1
+fi
+
+if [[ compstate[matcher] -gt 1 ||
+  ( ${+NUMERIC} = 0 && -n $_read_comp ) ]]; then
+  if [[ $_read_comp = _* ]]; then
+    eval $_read_comp
+  else
+    eval "compgen $_read_comp"
+  fi
+  return
+fi
+
+_read_comp=
+
+local key search str str2 newch funcs funcs2 exact msg list
+integer pos
+
+msg="Completion: "
+
+zle -R $msg
+
+if ! read -k key; then
+  zle -cR ''
+  return 1
+fi
+
+while [[ '#key' -ne 10 && '#key' -ne 13 ]]; do
+  if [[ '#key' -eq 0 && '#key' -eq 3 || '#key' -eq 7 ]]; then
+    zle -cR ''
+    return 1
+  fi
+  if [[ ( '#key' -eq 8 || '#key' -eq 127 ) && -n $str ]]; then
+    # delete character
+    str="$str[1,-2]"
+    exact=
+    list=()
+  elif [[ '#key' -eq 21 ]]; then
+    # ^U: delete line
+    str=
+    exact=
+    list=()
+  elif [[ '#key' -eq 4 && $str = _[^\ ]# && $str != *' '* ]]; then
+    # ^D: list completions
+    list=(${$(whence -m "$str*" 2>/dev/null)%: function})
+  elif [[ ( -n $exact && $key != ' ' ) || '#key & 127' -lt 32 ]]; then
+    # If we've got an exact function, only allow a space after it.
+    # Don't try to insert non-printing characters.
+    if [[ -n $ZBEEP ]]; then
+      print -nb $ZBEEP
+    elif [[ -o beep ]]; then
+      print -n "\a"
+    fi
+    list=()
+  else
+    str="$str$key"
+    if [[ $str = _[^\ ]# ]]; then
+      # Rudimentary completion for function names.
+      # Allow arguments, i.e. don't do this after we've got a space.
+      funcs=(${$(whence -m "$str*" 2>/dev/null)%: function})
+      if [[ -o autolist && $#str -gt 1 ]]; then
+	list=($funcs)
+      else
+	list=()
+      fi
+      if (( $#funcs == 1 )); then
+	# Exact match; prompt the user for a newline to confirm
+	str=$funcs[1]
+	exact=" (Confirm)"
+      elif (( $#funcs == 0 )); then
+	# We can't call zle beep, because this isn't a zle widget.
+	if [[ -n $ZBEEP ]]; then
+	  print -nb $ZBEEP
+	elif [[ -o beep ]]; then
+	  print -n "\a"
+	fi
+	str="$str[1,-2]"
+	list=()
+      else
+	# Add characters to the string until a name doesn't
+	# match any more, then backtrack one character to get
+	# the longest unambiguous match.
+	str2=$str
+	pos=$#str2
+	while true; do
+	  (( pos++ ))
+	  newch=${funcs[1][pos]}
+	  [[ -z $newch ]] && break
+	  str2=$str2$newch
+	  funcs2=(${funcs##$str2*})
+	  (( $#funcs2 )) && break
+	  str=$str2
+	done
+      fi
+    else
+      exact=
+    fi
+  fi
+  if (( $#list )); then
+    zle -R "$msg$str$exact" $list
+  else
+    zle -cR "$msg$str$exact"
+  fi
+  if ! read -k key; then
+    zle -cR ''
+    return 1
+  fi
+done
+
+if [[ -z $str ]]; then
+  # string must be non-zero
+  return 1
+elif [[ $str = _* ]] && ! whence ${str%% *} >& /dev/null; then
+  # a function must be known to the shell
+  return 1
+else
+  # remember the string for re-use
+  _read_comp=$str
+fi
+
+zle -cR ''
+
+if [[ $str = _* ]]; then
+  eval $str
+else
+  eval "compgen $str"
+fi
diff --git a/Completion/Core/_main_complete b/Completion/Core/_main_complete
index 62e60a1cc..af659e1d4 100644
--- a/Completion/Core/_main_complete
+++ b/Completion/Core/_main_complete
@@ -15,9 +15,13 @@
 #    any matches, correction is tried and if that doesn't yield
 #    anything either, correcting completion is attempted.
 #
-# These completer functions are only used when this function is called
-# without arguments. If arguments are given, they should be names of
-# completer functions which will then be called.
+#    These completer functions are only used when this function is called
+#    without arguments. If arguments are given, they should be names of
+#    completer functions which will then be called.
+#
+#  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.
 
 
 # If you want to complete only set or unset options for the unsetopt
@@ -33,7 +37,7 @@
 # state than the global one for which you are completing.
 
 
-local comp
+local comp ret=1
 
 setopt localoptions nullglob rcexpandparam
 unsetopt markdirs globsubst shwordsplit nounset ksharrays
@@ -54,5 +58,21 @@ fi
 # And now just call the completer functions defined.
 
 for comp; do
-  "$comp" && return
+  if "$comp"; then
+    ret=0
+    break;
+  fi
 done
+
+[[ "$compconfig[last_prompt]" = always ]] && compstate[last_prompt]=yes
+
+_lastcomp=( "${(@kv)compstate}" )
+_lastcomp[completer]="$comp"
+_lastcomp[prefix]="$PREFIX"
+_lastcomp[suffix]="$SUFFIX"
+_lastcomp[iprefix]="$IPREFIX"
+_lastcomp[isuffix]="$ISUFFIX"
+_lastcomp[qiprefix]="$QIPREFIX"
+_lastcomp[qisuffix]="$QISUFFIX"
+
+return ret
diff --git a/Completion/Core/_match b/Completion/Core/_match
index 251c65381..a4499dc08 100644
--- a/Completion/Core/_match
+++ b/Completion/Core/_match
@@ -60,10 +60,8 @@ _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
+[[ ret -eq 1 && "$compconfig[match_insert]" = unambig* &&
+   $#compstate[unambiguous] -ge ${#:-${PREFIX}${SUFFIX}} ]] && 
+    compstate[pattern_insert]=unambiguous
 
 return 1-ret
diff --git a/Completion/Core/_oldlist b/Completion/Core/_oldlist
index f42197695..bdf12f90c 100644
--- a/Completion/Core/_oldlist
+++ b/Completion/Core/_oldlist
@@ -4,12 +4,24 @@
 # and either the compconfig key oldlist_list is `always', or it is not `never'
 # and the list is not already shown, then use the existing list for listing
 # (even if it was generated by another widget).
-if [[ -n $compstate[old_list] && $compconfig[oldlist_list] != never &&
-  $WIDGET = *list* &&
-  ( $compconfig[oldlist_list] = always || $compstate[old_list] != shown ) ]]
-then
-  compstate[old_list]=keep
-  return 0
+# Do this also if there is an old list and it was generated by the
+# completer named by the oldlist_list key.
+if [[ -n $compstate[old_list] && $compconfig[oldlist_list] != never ]]; then
+  if [[ $WIDGET = *list* &&
+        ( $compconfig[oldlist_list] = always ||
+	  $compstate[old_list] != shown ) ]]; then
+    compstate[old_list]=keep
+    return 0
+  elif [[ $compconfig[oldlist_list] = *${_lastcomp[completer]}* ]]; then
+    [[ "$_lastcomp[insert]" = unambig* ]] && compstate[to_end]=single
+    compstate[old_list]=keep
+    if [[ -o automenu ]]; then
+      compstate[insert]=menu
+    else
+      compadd -Qs "$SUFFIX" - "$PREFIX"
+    fi
+    return 0
+  fi
 fi
 
 # If this is a completion widget, and we have a completion inserted already,
diff --git a/Completion/Core/_path_files b/Completion/Core/_path_files
index 58f343367..e65f814e1 100644
--- a/Completion/Core/_path_files
+++ b/Completion/Core/_path_files
@@ -33,12 +33,11 @@ typeset -U prepaths exppaths
 setopt localoptions nullglob rcexpandparam extendedglob
 unsetopt markdirs globsubst shwordsplit nounset
 
+local sopt='-' gopt='' opt
 exppaths=()
 prepaths=('')
 ignore=()
 group=()
-sopt='-'
-gopt=''
 pats=()
 addpfx=()
 addsfx=()
@@ -377,9 +376,9 @@ done
 exppaths=( "${(@)exppaths:#$orig}" )
 
 if [[ -n "$compconfig[path_expand]" &&
-      $#exppaths -eq 0 && nm -eq compstate[nmatches] ]]; then
+      $#exppaths -eq 1 && 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] ]]
+[[ nm -ne compstate[nmatches] ]]
diff --git a/Completion/Core/compinit b/Completion/Core/compinit
index 9302d8243..63e4c0860 100644
--- a/Completion/Core/compinit
+++ b/Completion/Core/compinit
@@ -49,7 +49,7 @@ emulate -L zsh
 typeset _i_dumpfile _i_files _i_line _i_done _i_dir _i_autodump=1
 typeset _i_tag _i_file _i_addfiles
 
-while [[ $# -gt 0 && $1 = -[df] ]]; do
+while [[ $# -gt 0 && $1 = -[dDf] ]]; do
   if [[ "$1" = -d ]]; then
     _i_autodump=1
     shift
@@ -59,6 +59,7 @@ while [[ $# -gt 0 && $1 = -[df] ]]; do
     fi
   elif [[ "$1" = -D ]]; then
     _i_autodump=0
+    shift
   elif [[ "$1" = -f ]]; then
     # Not used any more; use _compdir
     shift
@@ -72,6 +73,11 @@ done
 typeset -gA _comps
 _patcomps=()
 
+# The associative array use to report information about the last
+# cmpletion to the outside.
+
+typeset -gA _lastcomp
+
 # This is the associative array used for configuration.
 
 typeset -gA compconfig
@@ -308,10 +314,10 @@ if [[ $#_i_files -lt 20 || $_compdir = */Core || -d $_compdir/Core ]]; then
     fi
     for _i_line in {1..$#i_addfiles}; do
       _i_file=${_i_addfiles[$_i_line]}
-      [[ -d $_i_file && -z ${fpath[(r)$_i_$file]} ]] ||
+      [[ -d $_i_file && -z ${fpath[(r)$_i_file]} ]] ||
         _i_addfiles[$_i_line]=
     done
-    fpath=($_i_addfiles $fpath)
+    fpath=($fpath $_i_addfiles)
     _i_files=( ${^~fpath:/.}/_(|*[^~])(N:t) )
   fi
 fi
diff --git a/Completion/Core/compinstall b/Completion/Core/compinstall
index 52b4bf707..bd58d643b 100644
--- a/Completion/Core/compinstall
+++ b/Completion/Core/compinstall
@@ -136,7 +136,7 @@ fi
 
 # Check if this is in fpath already, else put it there (with ~'s expanded).
 _ci_f=${~_ci_fdir}
-[[ -z ${fpath[(r)$_ci_f]} ]] && fpath=($_ci_f $fpath)
+[[ -z ${fpath[(r)$_ci_f]} ]] && fpath=($fpath $_ci_f)
 
 # Contract $HOME to ~ in the parameter to be used for writing.
 _ci_fdir=${_ci_fdir/#$HOME/\~}
@@ -183,7 +183,7 @@ ${_ci_dumpfile}.  Please edit a replacement."
 fi
 
 _ci_lines="${_ci_lines}_compdir=$_ci_fdir
-[[ -z \$fpath[(r)\$_compdir] ]] && fpath=(\$_compdir \$fpath)
+[[ -z \$fpath[(r)\$_compdir] ]] && fpath=(\$fpath \$_compdir)
 autoload -U compinit
 compinit"
 [[ $_ci_dtype != standard ]] && _ci_lines="${_ci_lines} $_ci_dumpfile"
diff --git a/Completion/Makefile.in b/Completion/Makefile.in
index 0ac4de304..27f88d01f 100644
--- a/Completion/Makefile.in
+++ b/Completion/Makefile.in
@@ -48,40 +48,7 @@ install: install.fns
 
 uninstall: uninstall.fns
 
-# install functions, including those in subdirectories, creating
-# install directory if necessary
-install.fns:
-	if test x$(fndir) != x && test x$(fndir) != xno; then \
-	  $(sdir_top)/mkinstalldirs $(fndir) || exit 1; \
-	  for file in $(FUNCTIONS_INSTALL); do \
-	    if test -f $$file; then \
-	      if test x$(FUNCTIONS_SUBDIRS) != x -a \
-	      x$(FUNCTIONS_SUBDIRS) != xno; then \
-	        subdir="`echo $$file | sed -e 's%/.*%%'`"; \
-	        $(sdir_top)/mkinstalldirs $(fndir)/$$subdir || exit 1; \
-	        $(INSTALL_DATA) $$file $(fndir)/$$subdir || exit 1; \
-	      else \
-	        $(INSTALL_DATA) $$file $(fndir) || exit 1; \
-	      fi; \
-	    fi; \
-	  done; \
-	fi; \
-	exit 0
-
-uninstall.fns:
-	if test x$(fndir) != x && test x$(fndir) != xno; then \
-	  for file in $(FUNCTIONS_INSTALL); do \
-	    if test -f $$file; then \
-	      if test x$(FUNCTIONS_SUBDIRS) != x -a \
-              x$(FUNCTIONS_SUBDIRS) != xno; then \
-	        rm -f $(fndir)/$$file; \
-	      else \
-	        rm -f "$(fndir)/`echo $$file | sed -e 's%^.*/%%'`"; \
-	      fi; \
-	    fi; \
-	  done; \
-	fi; \
-	exit 0
+@FUNCINST_MK@
 
 # ========== DEPENDENCIES FOR CLEANUP ==========
 
diff --git a/Completion/User/.distfiles b/Completion/User/.distfiles
index 07fddc134..c96f2ba3e 100644
--- a/Completion/User/.distfiles
+++ b/Completion/User/.distfiles
@@ -1,6 +1,6 @@
 DISTFILES_SRC='
     .distfiles
     _a2ps _chown _compress _configure _dd _dvi _find _groups _gunzip _gzip
-    _hosts _make _man _mh _pdf _ps _rcs _rlogin _strip _stty
+    _hosts _use_lo _make _man _mh _pdf _ps _rcs _rlogin _strip _stty
     _tar _tar_archive _tex _uncompress _x_options _xfig 
 '
diff --git a/Completion/User/_ps b/Completion/User/_ps
index 6c0d91a23..39e357b69 100644
--- a/Completion/User/_ps
+++ b/Completion/User/_ps
@@ -1,3 +1,3 @@
-#compdef  gs ghostview gview psnup psselect pswrap pstops pstruct lpr
+#compdef  gs ghostview gv gview psnup psselect pswrap pstops pstruct lpr lp
 
 _files -g '*([pP][sS]|eps)'
diff --git a/Completion/User/_tar b/Completion/User/_tar
index f443fefb7..5fcce5c67 100644
--- a/Completion/User/_tar
+++ b/Completion/User/_tar
@@ -75,6 +75,7 @@ if [[ "$PREFIX" = --* ]]; then
   _long_options '--owner*'          "_tilde" \
                 '*=(PROG|COMMAND)*' "_command_names" \
 		'*=ARCHIVE*'        "_tar_archive" \
+		'*=NAME*'           "_files" \
 		'*=CONTROL*'        "[t numbered nil existing never simple]"
 
 elif [[ ( CURRENT -gt 2 && "$words[CURRENT-1]" = -*f* &&
diff --git a/Completion/User/_use_lo b/Completion/User/_use_lo
new file mode 100644
index 000000000..e469154ea
--- /dev/null
+++ b/Completion/User/_use_lo
@@ -0,0 +1,10 @@
+#compdef gls gdiff
+
+# 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