diff options
Diffstat (limited to 'Completion')
-rw-r--r-- | Completion/Base/_command_names | 7 | ||||
-rw-r--r-- | Completion/Base/_default | 9 | ||||
-rw-r--r-- | Completion/Base/_parameter | 2 | ||||
-rw-r--r-- | Completion/Builtins/_cd | 25 | ||||
-rw-r--r-- | Completion/Commands/.distfiles | 3 | ||||
-rw-r--r-- | Completion/Commands/_history_complete_word | 2 | ||||
-rw-r--r-- | Completion/Commands/_read_comp | 158 | ||||
-rw-r--r-- | Completion/Core/_main_complete | 30 | ||||
-rw-r--r-- | Completion/Core/_match | 8 | ||||
-rw-r--r-- | Completion/Core/_oldlist | 24 | ||||
-rw-r--r-- | Completion/Core/_path_files | 7 | ||||
-rw-r--r-- | Completion/Core/compinit | 12 | ||||
-rw-r--r-- | Completion/Core/compinstall | 4 | ||||
-rw-r--r-- | Completion/Makefile.in | 35 | ||||
-rw-r--r-- | Completion/User/.distfiles | 2 | ||||
-rw-r--r-- | Completion/User/_ps | 2 | ||||
-rw-r--r-- | Completion/User/_tar | 1 | ||||
-rw-r--r-- | Completion/User/_use_lo | 10 |
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 |