diff options
57 files changed, 1312 insertions, 1089 deletions
diff --git a/ChangeLog b/ChangeLog index c130ef4f8..22a31359c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +2000-04-11 Sven Wischnowsky <wischnow@informatik.hu-berlin.de> + + * 10632: Completion/Base/_brace_parameter, Completion/Base/_condition, + Completion/Base/_default, Completion/Base/_describe, + Completion/Base/_first, Completion/Base/_jobs, + Completion/Base/_values, Completion/Builtins/_compdef, + Completion/Builtins/_hash, Completion/Builtins/_pids, + Completion/Builtins/_popd, Completion/Builtins/_sched, + Completion/Builtins/_signals, Completion/Builtins/_vars, + Completion/Builtins/_zcompile, Completion/Builtins/_zftp, + Completion/Builtins/_zpty, Completion/Builtins/_zstyle, + Completion/Commands/_next_tags, Completion/Core/_all_labels, + Completion/Core/_files, Completion/Core/_next_label, + Completion/Core/_requested, Completion/Core/_wanted, + Completion/Debian/_apt, Completion/Debian/_deb_packages, + Completion/User/_cvs, Completion/User/_gdb, + Completion/User/_gprof, Completion/User/_groups, + Completion/User/_lp, Completion/User/_mh, Completion/User/_mount, + Completion/User/_netscape, Completion/User/_nslookup, + Completion/User/_rlogin, Completion/User/_socket, + Completion/User/_tiff, Completion/User/_urls, + Completion/User/_users, Completion/User/_users_on, + Completion/User/_whois, Completion/X/_x_colormapid, + Completion/X/_x_display, Completion/X/_x_extension, + Completion/X/_x_font, Completion/X/_x_keysym, + Completion/X/_x_window, Completion/X/_xmodmap, + Completion/X/_xutils, Completion/X/_xwit, Doc/Zsh/compsys.yo, + Etc/completion-style-guide, Functions/Zftp/zfcd_match, + Functions/Zftp/zfget_match, Src/Zle/computil.c: _wanted now tests + both tags and labels; change places where _wanted was called + without a command; allow multiple patterns per string in + file-patterns; update _next_tags to work with labels + 2000-04-10 Bart Schaefer <schaefer@brasslantern.com> * 10628: Doc/Zsh/compsys.yo, Completion/User/_make: Check for diff --git a/Completion/Base/_brace_parameter b/Completion/Base/_brace_parameter index 092376e78..fde6d4f0f 100644 --- a/Completion/Base/_brace_parameter +++ b/Completion/Base/_brace_parameter @@ -1,5 +1,3 @@ -#defcomp -brace-parameter- +#compdef -brace-parameter- -# Simple but without spiffy suffix handling: compgen -v -S '} ' - -compadd -S '} ' -r '-:?#%+=[/' - "${(@)${${${(f)$(typeset)}%%\=*}##* }:gs/'//}" +_parameters -e diff --git a/Completion/Base/_condition b/Completion/Base/_condition index 3e45e1b8f..b6a4eff7a 100644 --- a/Completion/Base/_condition +++ b/Completion/Base/_condition @@ -1,10 +1,55 @@ -#defcomp -condition- +#compdef -condition- -if [[ -current -1 -o ]]; then - complist -o -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -elif [[ -current -1 -nt || -current -1 -ot || -current -1 -ef ]]; then - _files +local prev="$words[CURRENT-1]" ret=1 + +if [[ "$prev" = -o ]]; then + _tags -C -o options && _options +elif [[ "$prev" = -([a-hkprsuwxLOGSN]|[no]t|ef) ]]; then + _tags -C "$prev" files && _files else - _files - complist -v + if [[ "$PREFIX" = -* ]] || + ! zstyle -T ":completion:${curcontext}:options" prefix-needed; then + + if [[ "$prev" = (\[\[|\|\||\&\&|\!|\() ]]; then + _describe -o 'condition code' \ + '( -a:existing\ file + -b:block\ special\ file + -c:character\ special\ file + -d:directory + -e:existing\ file + -f:regular\ file + -g:setgid\ bit + -h:symbolic\ link + -k:sticky\ bit + -n:non-empty\ string + -o:option + -p:named\ pipe + -r:readable\ file + -s:non-empty\ file + -t:terminal\ file\ descriptor + -u:setuid\ bit + -w:writable\ file + -x:executable\ file + -z:empty\ string + -L:symbolic\ link + -O:own\ file + -G:group-owned\ file + -S:socket + -N:unread\ file)' && ret=0 + else + _describe -o 'condition code' \ + '( -nt:newer\ than + -ot:older\ than + -ef:same\ file + -eq:numerically\ equal + -ne:numerically\ not\ equal + -lt:numerically\ less\ than + -le:numerically\ less\ then\ or\ equal + -lt:numerically\ greater\ than + -le:numerically\ greater\ then\ or\ equal)' && ret=0 + fi + fi + _alternative 'files:: _files' 'parameters:: _parameters' && ret=0 + + return ret fi diff --git a/Completion/Base/_default b/Completion/Base/_default index fd5869e2e..e5091a544 100644 --- a/Completion/Base/_default +++ b/Completion/Base/_default @@ -12,8 +12,6 @@ if { zstyle -s ":completion:${curcontext}:" use-compctl ctl || compcall "$opt[@]" || return 0 fi -_wanted files || return 1 - _files && return 0 # magicequalsubst allows arguments like <any-old-stuff>=~/foo to do diff --git a/Completion/Base/_describe b/Completion/Base/_describe index 6e6f4f4a9..ca2d3e4cf 100644 --- a/Completion/Base/_describe +++ b/Completion/Base/_describe @@ -14,8 +14,6 @@ fi # Do the tests. `showd' is set if the descriptions should be shown. -_wanted "$_type" || return 1 - zstyle -T ":completion:${curcontext}:$_type" verbose && _showd=yes _descr="$1" @@ -24,30 +22,35 @@ shift [[ "$_type" = options ]] && zstyle -t ":completion:${curcontext}:options" prefix-hidden && _hide=yes -while _next_label "$_type" _expl "$_descr"; do +_tags "$_type" +while _tags; do + while _next_label "$_type" _expl "$_descr"; do - if [[ -n "$_showd" ]]; then - compdescribe -I ' -- ' "$@" - else - compdescribe -i "$@" - fi + if [[ -n "$_showd" ]]; then + compdescribe -I ' -- ' "$@" + else + compdescribe -i "$@" + fi - while compdescribe -g _args _tmpd _tmpmd _tmps _tmpms; do + while compdescribe -g _args _tmpd _tmpmd _tmps _tmpms; do - # See if we should remove the option prefix characters. + # See if we should remove the option prefix characters. - if [[ -n "$_hide" ]]; then - if [[ "$PREFIX" = --* ]]; then - _tmpd=( "${(@)_tmpd#--}" ) - _tmps=( "${(@)_tmps#--}" ) - elif [[ "$PREFIX" = [-+]* ]]; then - _tmpd=( "${(@)_tmpd#[-+]}" ) - _tmps=( "${(@)_tmps#[-+]}" ) + if [[ -n "$_hide" ]]; then + if [[ "$PREFIX" = --* ]]; then + _tmpd=( "${(@)_tmpd#--}" ) + _tmps=( "${(@)_tmps#--}" ) + elif [[ "$PREFIX" = [-+]* ]]; then + _tmpd=( "${(@)_tmpd#[-+]}" ) + _tmps=( "${(@)_tmps#[-+]}" ) + fi fi - fi - compadd "$_args[@]" "$_expl[@]" -ld _tmpd - "$_tmpmd[@]" && _ret=0 - compadd "$_args[@]" "$_expl[@]" -d _tmps - "$_tmpms[@]" && _ret=0 + compadd "$_args[@]" "$_expl[@]" -ld _tmpd - "$_tmpmd[@]" && _ret=0 + compadd "$_args[@]" "$_expl[@]" -d _tmps - "$_tmpms[@]" && _ret=0 + done done + (( _ret )) || return 0 done -return _ret + +return 1 diff --git a/Completion/Base/_first b/Completion/Base/_first index d9e7ee82c..93602f307 100644 --- a/Completion/Base/_first +++ b/Completion/Base/_first @@ -35,28 +35,35 @@ # and hitting TAB. # # if [[ "$PREFIX" = *,, ]]; then -# local max i=1 +# local max i=1 expl opt # # 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 # fi -# # We first search in the last ten lines, then in the last -# # twenty lines, and so on... +# # We first search in the last ten words, then in the last +# # twenty words, and so on... # while [[ i -le max ]]; do -# if compgen -X "%Bhistory ($n):%b" -Q -H $(( i*10 )) ''; then +# if zstyle -t ":completion:${curcontext}:history-words" sort; then +# opt=-J +# else +# opt=-V +# fi +# if _wanted "$opt" history-words expl "history ($n)" \ +# compadd "$expl[@]" -Q - \ +# "${(@)${(@)historywords:#[\$'\"]*}[1,i*10]}"; then # # We have found at least one matching word, so we switch # # on menu-completion and make sure that no other -# # completion function is called by setting _comp_skip. +# # completion function is called by setting _compskip. # compstate[insert]=menu -# _comp_skip=1 -# return +# _compskip=all +# return 0 # fi # (( i++ )) # done diff --git a/Completion/Base/_jobs b/Completion/Base/_jobs index 45983ad16..359cf0905 100644 --- a/Completion/Base/_jobs +++ b/Completion/Base/_jobs @@ -2,8 +2,6 @@ local expl disp jobs job jids pfx='%' desc how expls -_wanted jobs || return 1 - if [[ "$1" = -t ]]; then zstyle -T ":completion:${curcontext}:jobs" prefix-needed && [[ "$PREFIX" != %* && compstate[nmatches] -ne 0 ]] && return 1 @@ -79,7 +77,7 @@ else fi if [[ -n "$desc" ]]; then - _all_labels jobs expl "$expls" compadd "$@" -ld disp - "%$^jobs[@]" + _wanted jobs expl "$expls" compadd "$@" -ld disp - "%$^jobs[@]" else - _all_labels jobs expl "$expls" compadd "$@" - "%$^jobs[@]" + _wanted jobs expl "$expls" compadd "$@" - "%$^jobs[@]" fi diff --git a/Completion/Base/_values b/Completion/Base/_values index eff7b94ce..39c8df201 100644 --- a/Completion/Base/_values +++ b/Completion/Base/_values @@ -18,7 +18,7 @@ if compvalues -i "$@"; then if ! compvalues -D descr action; then - _wanted values || return 1 + _tags values || return 1 curcontext="${oldcontext%:*}:values" diff --git a/Completion/Builtins/_compdef b/Completion/Builtins/_compdef index d47a560c9..6287810e5 100644 --- a/Completion/Builtins/_compdef +++ b/Completion/Builtins/_compdef @@ -19,15 +19,13 @@ case $state in _wanted commands expl 'completed command' compadd - ${(k)_comps} ;; cfun) - if _wanted functions; then - list=( ${^fpath:/.}/_(|*[^~])(N:t) ) - if zstyle -T ":completion:${curcontext}:functions" prefix-hidden; then - disp=( ${list[@]#_} ) - _all_labels functions expl 'completion function' \ - compadd -d disp - "$list[@]" - else - _all_labels functions expl 'completion function' compadd - "$list[@]" - fi + list=( ${^fpath:/.}/_(|*[^~])(N:t) ) + if zstyle -T ":completion:${curcontext}:functions" prefix-hidden; then + disp=( ${list[@]#_} ) + _wanted functions expl 'completion function' \ + compadd -d disp - "$list[@]" + else + _wanted functions expl 'completion function' compadd - "$list[@]" fi ;; style) diff --git a/Completion/Builtins/_hash b/Completion/Builtins/_hash index 171c5e2e8..c577fc4d7 100644 --- a/Completion/Builtins/_hash +++ b/Completion/Builtins/_hash @@ -1,13 +1,16 @@ -#defcomp hash +#compdef hash -if [[ -mword 1 -*d* ]]; then - if [[ -string 1 '=' ]]; then - _path_files -g '*(-/)' +local expl + +if [[ "$words[2]" = -*d* ]]; then + if compset -P 1 '*='; then + _wanted -C -d-value files expl directories _path_files -/ else - complist -n -q -S '=' + _wanted -C -d named-directories expl 'named directory' \ + compadd -q -S '=' - "${(@k)nameddirs}" fi -elif [[ -string 1 '=' ]]; then - _files -/g '*(*)' +elif compset -P 1 '*='; then + _wanted -C value values expl 'executable file' _files "$expl[@]" -g '*(-*)' else - complist -m -q -S '=' + _wanted -C name commands expl command compadd -q -S '=' - "${(@k)commands}" fi diff --git a/Completion/Builtins/_pids b/Completion/Builtins/_pids index 7dec90e7d..1d02f5530 100644 --- a/Completion/Builtins/_pids +++ b/Completion/Builtins/_pids @@ -5,7 +5,7 @@ local out list expl match desc listargs args -_wanted processes || return 1 +_tags processes || return 1 if [[ "$1" = -m ]]; then match="${2}*" @@ -29,6 +29,6 @@ else desc=() fi -_all_labels processes expl 'process ID' \ +_wanted processes expl 'process ID' \ compadd "$@" "$desc[@]" - \ ${${${(M)${(f)"${out}"}[2,-1]:#[ ]#${PREFIX}[0-9]#${SUFFIX}[ ]#*${~match}}## #}%% *} diff --git a/Completion/Builtins/_popd b/Completion/Builtins/_popd index 2a3413253..19b773173 100644 --- a/Completion/Builtins/_popd +++ b/Completion/Builtins/_popd @@ -12,8 +12,6 @@ local expl list lines revlines disp ! zstyle -T ":completion:${curcontext}:directory-stack" prefix-needed || [[ $PREFIX = [-+]* ]] || return 1 -_wanted directory-stack || return 1 - if zstyle -T ":completion:${curcontext}:directory-stack" verbose; then # get the list of directories with their canonical number # and turn the lines into an array, removing the current directory @@ -39,5 +37,5 @@ else disp=() fi -_all_labels -V directory-stack expl 'directory stack' \ +_wanted -V directory-stack expl 'directory stack' \ compadd "$@" "$disp[@]" -Q - "$list[@]" diff --git a/Completion/Builtins/_sched b/Completion/Builtins/_sched index 98ecb3642..82b8a7c91 100644 --- a/Completion/Builtins/_sched +++ b/Completion/Builtins/_sched @@ -4,15 +4,13 @@ local expl lines disp if [[ CURRENT -eq 2 ]]; then if compset -P -; then - _wanted -C - jobs || return 1 - lines=(${(f)"$(sched)"}) if zstyle -T ":completion:${curcontext}:jobs" verbose; then disp=( -ld lines ) else disp=() fi - [[ -z $lines ]] || _all_labels jobs expl 'scheduled jobs' \ + [[ -z $lines ]] || _wanted jobs expl 'scheduled jobs' \ compadd "$disp[@]" - {1..$#lines} return else diff --git a/Completion/Builtins/_signals b/Completion/Builtins/_signals index aa95a8499..447d9d16c 100644 --- a/Completion/Builtins/_signals +++ b/Completion/Builtins/_signals @@ -20,10 +20,9 @@ done [[ "$1" = -(|-) ]] && shift -if _wanted signals && - { [[ -z "$minus" ]] || - ! zstyle -T ":completion:${curcontext}:signals" prefix-needed || - [[ "$PREFIX" = -* ]] } ; then +if [[ -z "$minus" ]] || + ! zstyle -T ":completion:${curcontext}:signals" prefix-needed || + [[ "$PREFIX" = -* ]]; then local disp tmp if zstyle -t ":completion:${curcontext}:signals" prefix-hidden; then @@ -32,7 +31,7 @@ if _wanted signals && else disp=() fi - _all_labels signals expl signal \ + _wanted signals expl signal \ compadd "$@" "$disp[@]" -M 'm:{a-z}={A-Z}' - \ "${minus}${(@)^signals[1,last]}" fi diff --git a/Completion/Builtins/_vars b/Completion/Builtins/_vars index 43cdf5d2c..711a0a1f2 100644 --- a/Completion/Builtins/_vars +++ b/Completion/Builtins/_vars @@ -1,8 +1,8 @@ #compdef getopts read unset vared # This will handle completion of keys of associative arrays, e.g. at -# `vared compconfig[<TAB>'. However, in this version the [ must be -# added by hand. +# `vared foo[<TAB>'. However, in this version the [ must be added +# by hand. if [[ $PREFIX = *\[* ]]; then local var=${PREFIX%%\[*} @@ -16,13 +16,9 @@ if [[ $PREFIX = *\[* ]]; then if [[ ${(tP)var} = assoc* ]]; then local expl - _tags subscript association-keys || return 1 - - _description expl 'association key' - compadd "$expl[@]" $addclose - ${(kP)var} + _wanted -C subscript association-keys expl 'association key' \ + compadd $addclose - ${(kP)var} fi else - _tags any parameters || return 1 - _parameters fi diff --git a/Completion/Builtins/_zcompile b/Completion/Builtins/_zcompile index 5ec6f96ce..c82226dc2 100644 --- a/Completion/Builtins/_zcompile +++ b/Completion/Builtins/_zcompile @@ -18,5 +18,6 @@ _arguments -s \ if (( $+opt_args[-c] )); then _wanted functions expl 'function to write' compadd - ${(k)functions} else - _wanted file expl 'zsh source file' _files + _description files expl 'zsh source file' + _files "$expl[@]" fi diff --git a/Completion/Builtins/_zftp b/Completion/Builtins/_zftp index 0d6530dfc..610af2607 100644 --- a/Completion/Builtins/_zftp +++ b/Completion/Builtins/_zftp @@ -28,35 +28,34 @@ fi case $subcom in *(cd|ls|dir)) # complete remote directories - _wanted directories && zfcd_match $PREFIX $SUFFIX + _tags directories && zfcd_match $PREFIX $SUFFIX ;; *(get(|at)|gcp|delete|remote)) # complete remote files - _wanted files && zfget_match $PREFIX $SUFFIX + _tags files && zfget_match $PREFIX $SUFFIX ;; *(put(|at)|pcp)) # complete local files - _wanted files && _files + _files ;; *(open|anon|params)) # complete hosts: should do cleverer stuff with user names - _wanted hosts && _hosts + _hosts ;; *(goto|mark)) # complete bookmarks. First decide if ncftp mode is go. - _wanted bookmarks || return 1 if [[ $words[2] = -*n* ]]; then if [[ -f ~/.ncftp/bookmarks ]]; then - _all_labels bookmarks expl bookmark \ + _wanted bookmarks expl bookmark \ compadd - $(awk -F, 'NR > 2 { print $1 }' ~/.ncftp/bookmarks) fi else if [[ -f ${ZFTP_BMFILE:=${ZDOTDIR:-$HOME}/.zfbkmarks} ]]; then - _all_labels bookmarks expl bookmark \ + _wanted bookmarks expl bookmark \ compadd - $(awk '{print $1}' $ZFTP_BMFILE) fi fi @@ -72,7 +71,7 @@ case $subcom in # complete arguments like sess1:file1 sess2:file2 if [[ $PREFIX = *:* ]]; then # complete file in the given session - _wanted files || return 1 + _tags files || return 1 local sess=${PREFIX%%:*} oldsess=$ZFTP_SESSION compset -p $(( $#sess + 1 )) [[ -n $sess ]] && zftp session $sess diff --git a/Completion/Builtins/_zpty b/Completion/Builtins/_zpty index d8c77ff2e..ac631baf4 100644 --- a/Completion/Builtins/_zpty +++ b/Completion/Builtins/_zpty @@ -11,13 +11,13 @@ _arguments -C -s \ '(-e -b -d -w -r)-L[list defined commands as calls]' \ '(-r)*::args:_normal' -if [[ $state = name ]] && _wanted names; then +if [[ $state = name ]]; then list=( ${${(f)"$(zpty)"}#*\) } ) names=( ${list%%:*} ) if zstyle -T ":completion:${curcontext}" verbose; then zformat -a list ' --' ${${(f)"$(zpty)"}#*\) } - _all_labels names expl 'zpty command names' compadd -d list - "$names[@]" + _wanted names expl 'zpty command names' compadd -d list - "$names[@]" else - _all_labels names expl 'zpty command names' compadd - "$names[@]" + _wanted names expl 'zpty command names' compadd - "$names[@]" fi fi diff --git a/Completion/Builtins/_zstyle b/Completion/Builtins/_zstyle index b4e151d78..b19303300 100644 --- a/Completion/Builtins/_zstyle +++ b/Completion/Builtins/_zstyle @@ -96,20 +96,18 @@ while [[ -n $state ]]; do case "$ostate" in contexts) - if _wanted contexts; then - if [[ $PREFIX != :*: ]]; then - _all_labels contexts expl context compadd -P : -S : completion zftp - elif [[ $PREFIX = :completion:* ]]; then - mesg='' - case "$PREFIX" in - :completion:[^:]#) mesg=function ;; - :completion:[^:]#:[^:]#) mesg=completer ;; - :completion:[^:]#:[^:]#:[^:]#) mesg='command or context' ;; - :completion:[^:]#:[^:]#:[^:]#:[^:]#) mesg=argument ;; - :completion:[^:]#:[^:]#:[^:]#:[^:]#:[^:]#) mesg=tag ;; - esac - [[ -n "$mesg" ]] && _message "$mesg" - fi + if [[ $PREFIX != :*: ]]; then + _wanted contexts expl context compadd -P : -S : completion zftp + elif [[ $PREFIX = :completion:* ]] && _tags contexts; then + mesg='' + case "$PREFIX" in + :completion:[^:]#) mesg=function ;; + :completion:[^:]#:[^:]#) mesg=completer ;; + :completion:[^:]#:[^:]#:[^:]#) mesg='command or context' ;; + :completion:[^:]#:[^:]#:[^:]#:[^:]#) mesg=argument ;; + :completion:[^:]#:[^:]#:[^:]#:[^:]#:[^:]#) mesg=tag ;; + esac + [[ -n "$mesg" ]] && _message "$mesg" fi ;; diff --git a/Completion/Commands/_next_tags b/Completion/Commands/_next_tags index d9a5f08d8..a308b307c 100644 --- a/Completion/Commands/_next_tags +++ b/Completion/Commands/_next_tags @@ -3,30 +3,103 @@ # Main widget. _next_tags() { - local comp ins + local ins ops="$PREFIX$SUFFIX" - if [[ -z $compstate[old_list] ]]; then - comp=() + unfunction _all_labels _next_label + + _all_labels() { + local gopt=-J len tmp pre suf ret=1 descr spec + + if [[ "$1" = -([12]|)[VJ] ]]; then + gopt="$1" + shift + fi + + tmp=${argv[(ib:4:)-]} + len=$# + if [[ tmp -lt len ]]; then + pre=$(( tmp-1 )) + suf=$tmp + elif [[ tmp -eq $# ]]; then + pre=-2 + suf=$(( len+1 )) + else + pre=4 + suf=5 + fi + + while comptags -A "$1" curtag spec; do + [[ "$_next_tags_not" = *\ ${spec}\ * ]] && continue + _comp_tags="$_comp_tags $spec " + if [[ "$curtag" = *:* ]]; then + zformat -f descr "${curtag#*:}" "d:$3" + _description "$gopt" "${curtag%:*}" "$2" "$descr" + curtag="${curtag%:*}" + + "$4" "${(P@)2}" "${(@)argv[5,-1]}" + else + _description "$gopt" "$curtag" "$2" "$3" + + "${(@)argv[4,pre]}" "${(P@)2}" "${(@)argv[suf,-1]}" && ret=0 + fi + done + + return ret + } + + _next_label() { + local gopt=-J descr spec + + if [[ "$1" = -([12]|)[VJ] ]]; then + gopt="$1" + shift + fi + + if comptags -A "$1" curtag spec; then + [[ "$_next_tags_not" = *\ ${spec}\ * ]] && continue + _comp_tags="$_comp_tags $spec " + if [[ "$curtag" = *:* ]]; then + zformat -f descr "${curtag#*:}" "d:$3" + _description "$gopt" "${curtag%:*}" "$2" "$descr" + curtag="${curtag%:*}" + eval "${2}=( \${(P)2} \$argv[4,-1] )" + else + _description "$gopt" "$curtag" "$2" "$3" + eval "${2}=( \$argv[4,-1] \${(P)2} )" + fi + + return 0 + fi + + return 1 + } + + if [[ "${LBUFFER%${PREFIX}}" = "$_next_tags_pre" ]]; then + PREFIX="$_next_tags_pfx" + SUFFIX="$_next_tags_sfx" else - comp=(_complete) + _next_tags_pre="${LBUFFER%${PREFIX}}" + if [[ "$LASTWIDGET" = (_next_tags|list-*|*complete*) ]]; then + PREFIX="$_lastcomp[prefix]" + SUFFIX="$_lastcomp[suffix]" + fi fi - (( $+_sort_tags )) || _next_tags_not= - - _sort_tags=_next_tags_sort - _next_tags_pre="${LBUFFER%${PREFIX}}" _next_tags_not="$_next_tags_not $_lastcomp[tags]" + _next_tags_pfx="$PREFIX" + _next_tags_sfx="$SUFFIX" if [[ -n "$compstate[old_insert]" ]]; then - PREFIX="$_lastcomp[prefix]" - SUFFIX="$_lastcomp[suffix]" ins=1 + else + ins=unambiguous fi - _main_complete "$comp[@]" + _main_complete _complete _next_tags_completer - [[ $compstate[insert] = automenu ]] && - compstate[insert]=automenu-unambiguous + [[ $compstate[insert] = automenu ]] && compstate[insert]=automenu-unambiguous + [[ $compstate[insert] = *unambiguous && -n "$ops" && + -z "$_lastcomp[unambiguous]" ]] && compadd -Uns "$SUFFIX" - "$PREFIX" compstate[insert]="$ins" compstate[list]='list force' @@ -34,11 +107,19 @@ _next_tags() { compprefuncs=( "$compprefuncs[@]" _next_tags_pre ) } +# Completer, for wrap-around. + +_next_tags_completer() { + _next_tags_not= + + _complete +} + # Pre-completion function. _next_tags_pre() { - # Probably `remove' our sort function. A better test would be nice, but + # Probably `remove' our label functions. A better test would be nice, but # I think one should still be able to edit the current word between # attempts to complete it. @@ -47,65 +128,10 @@ _next_tags_pre() { compstate[insert]=menu:2 return 0 elif [[ ${LBUFFER%${PREFIX}} != ${_next_tags_pre}* ]]; then - unset _sort_tags + unfunction _all_labels _next_label + autoload -U _all_labels _next_label else compprefuncs=( "$compprefuncs[@]" _next_tags_pre ) - [[ -n "$compstate[old_list]" && -n "$_next_tags_reset" ]] && - _next_tags_not= _next_tags_reset= - fi -} - -# Helper function for sorting tags. Most of this is copied from _tags. - -_next_tags_sort() { - local order tags tag nodef tmp - - zstyle -a ":completion:${curcontext}:" tag-order order || - order=('arguments values' options) - - # But we also remove the tags we've already tried... - - tags=( "${(@)order:#(${(j:|:)~${=_next_tags_not}})(|:*)}" ) - - # ... unless that would remove all offered tags. - - if [[ $funcstack[4] = _files ]]; then - if zstyle -a ":completion:${curcontext}:" file-patterns tmp; then - [[ "$tags" = *${${tmp[-1]##[^\\]:}%:*}* ]] && - tags=( $order ) _next_tags_reset=yes - else - [[ "$tags" = *all-files* ]] && tags=( $order ) _next_tags_reset=yes - fi - else - [[ $#tags -ne $#order && "$tags" != *(${(j:|:)~argv})* ]] && - tags=( $order ) _next_tags_reset=yes - fi - for tag in $tags; do - case $tag in - -) nodef=yes;; - *\(\)) "${${tag%%[ ]#\(\)}##[ ]#}" "$@";; - \!*) comptry "${(@)argv:#(${(j:|:)~${=~tag[2,-1]}})}";; - ?*) comptry -m "$tag";; - esac - done - - if [[ -z "$nodef" ]]; then - if [[ $funcstack[4] = _files ]]; then - if zstyle -a ":completion:${curcontext}:" file-patterns tmp; then - [[ "$argv" = *${${tmp[-1]#*[^\\]:}%:*}* ]] && _next_tags_reset=yes - else - [[ "$argv" = *all-files* ]] && _next_tags_reset=yes - fi - fi - tmp=( "${(@)argv:#(${(j:|:)~${=_next_tags_not}})(|:*)}" ) - - # $prev is set in _tags! - - if [[ -n "$prev" && ( $#tmp -ne 0 || $funcstack[4] = _files ) ]]; then - comptry "$tmp[@]" - else - comptry "$argv[@]" - fi fi } diff --git a/Completion/Core/_all_labels b/Completion/Core/_all_labels index fa7118ec4..a03112ee4 100644 --- a/Completion/Core/_all_labels +++ b/Completion/Core/_all_labels @@ -1,11 +1,7 @@ #autoload -local gopt=-J len tmp pre suf tloop ret=1 descr +local gopt=-J len tmp pre suf ret=1 descr spec -if [[ "$1" = -t ]]; then - tloop=yes - shift -fi if [[ "$1" = -([12]|)[VJ] ]]; then gopt="$1" shift @@ -24,21 +20,19 @@ else suf=5 fi -while [[ -z "$tloop" ]] || comptags -N; do - while comptags -A "$1" curtag; do - if [[ "$curtag" = *:* ]]; then - zformat -f descr "${curtag#*:}" "d:$3" - _description "$gopt" "${curtag%:*}" "$2" "$descr" - curtag="${curtag%:*}" +while comptags -A "$1" curtag spec; do + _comp_tags="$_comp_tags $spec " + if [[ "$curtag" = *:* ]]; then + zformat -f descr "${curtag#*:}" "d:$3" + _description "$gopt" "${curtag%:*}" "$2" "$descr" + curtag="${curtag%:*}" - "$4" "${(P@)2}" "${(@)argv[5,-1]}" - else - _description "$gopt" "$curtag" "$2" "$3" + "$4" "${(P@)2}" "${(@)argv[5,-1]}" + else + _description "$gopt" "$curtag" "$2" "$3" - "${(@)argv[4,pre]}" "${(P@)2}" "${(@)argv[suf,-1]}" && ret=0 - fi - done - [[ -z "$tloop" || ret -eq 0 ]] && break + "${(@)argv[4,pre]}" "${(P@)2}" "${(@)argv[suf,-1]}" && ret=0 + fi done return ret diff --git a/Completion/Core/_files b/Completion/Core/_files index 8a9bbfc95..a64e5c093 100644 --- a/Completion/Core/_files +++ b/Completion/Core/_files @@ -6,7 +6,7 @@ zparseopts -a opts \ '/=tmp' 'f=tmp' 'g+:-=tmp' q n 1 2 P: S: r: R: W: X+: M+: F: J+: V+: type="${(@j::M)${(@)tmp#-}#?}" -(( $tmp[(I)-g*] )) && glob="${(j: :)${(@M)tmp:#-g*}#-g}" +(( $tmp[(I)-g*] )) && glob="${(j:,:)${(@M)tmp:#-g*}#-g}" ign=$opts[(I)-F] if (( ign )); then ign=( $=opts[ign+1] ) @@ -20,56 +20,59 @@ else fi if zstyle -a ":completion:${curcontext}:" file-patterns tmp; then - [[ "$type" = */* ]] && glob="$glob *(-/)" + [[ "$type" = */* ]] && glob="$glob,*(-/)" pats=() for i in ${tmp//\\%p/ ${${glob:-\*}//:/\\:} }; do if [[ $i = *[^\\]:* ]]; then - pats=( "$pats[@]" " $i" ) + pats=( "$pats[@]" " $i " ) else - pats=( "$pats[@]" " ${i}:files" ) + pats=( "$pats[@]" " ${i}:files " ) fi done else if [[ "$type" = *g* ]]; then if [[ "$type" = */* ]]; then - pats=( " ${glob//:/\\:} *(-/):globbed-files" '*:all-files' ) + pats=( " ${glob//:/\\:}:globbed-files *(-/):directories" '*:all-files ' ) else - pats=( " ${glob//:/\\:}:globbed-files" - '*(-/):directories' '*:all-files' ) + pats=( " ${glob//:/\\:}:globbed-files " + '*(-/):directories ' '*:all-files ' ) fi elif [[ "$type" = */* ]]; then - pats=( '*(-/):directories' '*:all-files' ) + pats=( '*(-/):directories ' '*:all-files ' ) else - pats=( '*:all-files' ) + pats=( '*:all-files ' ) fi fi -for def in "$pats[@]"; do ###"${(@)${(@)pats#*[^\\]:}%%:*}"; do +for def in "$pats[@]"; do + def="${def##[[:blank:]]#}" + while [[ "$def" = *[^\\][[:blank:]]* ]]; do + sdef="${(M)def#*[^\\][[:blank:]]}" + tag="${${sdef#*[^\\]:}%%:*}" + pat="${${${sdef%%:${tag}*}//\\\\:/:}//,/ }" - tag="${${def#*[^\\]:}%%:*}" - pat="${${def%%:${tag}*}//\\\\:/:}" - - if [[ "$pat" != \ # ]]; then - if [[ "$def" = *:${tag}:* ]]; then - descr="${def#*:${tag}:}" + if [[ "$sdef" = *:${tag}:* ]]; then + descr="${(Q)sdef#*:${tag}:}" else descr=file end=yes fi - fi - if _wanted "$tag"; then - _comp_ignore=() - while _next_label "$tag" expl "$descr"; do - _comp_ignore=( $_comp_ignore $ign ) - if [[ -n "$end" ]]; then - _path_files -g "$pat" "$opts[@]" "$expl[@]" && ret=0 - else - _path_files "$expl[@]" -g "$pat" "$opts[@]" && ret=0 - fi + _tags "$tag" + while _tags; do + _comp_ignore=() + while _next_label "$tag" expl "$descr"; do + _comp_ignore=( $_comp_ignore $ign ) + if [[ -n "$end" ]]; then + _path_files -g "$pat" "$opts[@]" "$expl[@]" && ret=0 + else + _path_files "$expl[@]" -g "$pat" "$opts[@]" && ret=0 + fi + done done - (( ret )) || return 0 - fi + def="${${def#${sdef}}##[[:blank:]]#}" + done + (( ret )) || return 0 done return 1 diff --git a/Completion/Core/_next_label b/Completion/Core/_next_label index e309e53ea..d2d698171 100644 --- a/Completion/Core/_next_label +++ b/Completion/Core/_next_label @@ -1,13 +1,14 @@ #autoload -local gopt=-J descr +local gopt=-J descr spec if [[ "$1" = -([12]|)[VJ] ]]; then gopt="$1" shift fi -if comptags -A "$1" curtag; then +if comptags -A "$1" curtag spec; then + _comp_tags="$_comp_tags $spec " if [[ "$curtag" = *:* ]]; then zformat -f descr "${curtag#*:}" "d:$3" _description "$gopt" "${curtag%:*}" "$2" "$descr" diff --git a/Completion/Core/_requested b/Completion/Core/_requested index bd838a28e..90fdec279 100644 --- a/Completion/Core/_requested +++ b/Completion/Core/_requested @@ -8,7 +8,6 @@ if [[ "$1" = -([12]|)[VJ] ]]; then fi if comptags -R "$1"; then - _comp_tags="$_comp_tags $1" if [[ $# -gt 3 ]]; then _all_labels "$gopt" "$@" elif [[ $# -gt 1 ]]; then diff --git a/Completion/Core/_wanted b/Completion/Core/_wanted index 32875ec57..958f9e18e 100644 --- a/Completion/Core/_wanted +++ b/Completion/Core/_wanted @@ -17,17 +17,10 @@ if [[ "$1" = -([12]|)[VJ] ]]; then shift fi -if [[ $# -gt 3 ]]; then - if _tags "$targs[@]" "$1"; then - _comp_tags="$_comp_tags $1" +_tags "$targs[@]" "$1" - _all_labels -t "$gopt" "$@" - else - return 1 - fi -elif [[ $# -gt 1 ]]; then - _tags -- "$targs[@]" "$1" && _comp_tags="$_comp_tags $1" && - _description "$gopt" "$@" -else - _tags -- "$targs[@]" "$1" && _comp_tags="$_comp_tags $1" -fi +while _tags; do + _all_labels "$gopt" "$@" && return 0 +done + +return 1 diff --git a/Completion/Debian/_apt b/Completion/Debian/_apt index 169b5f5f7..66129c949 100644 --- a/Completion/Debian/_apt +++ b/Completion/Debian/_apt @@ -75,7 +75,7 @@ _apt_arguments () { nul=$'\0' qnul="\$'\\0'" - comp_bool='_wanted values && compadd "$expl_bool[@]" '"$bool" + comp_bool='_wanted values expl_bool "boolean value" compadd "$expl_bool[@]" '"$bool" comp_intlevel= #"_message 'intlevel'" comp_configfile='_files "$expl_configfile[@]"' comp_arbitem= #"_message 'Foo::Bar=bar'" diff --git a/Completion/Debian/_deb_packages b/Completion/Debian/_deb_packages index b5e4ffd85..7973d9868 100644 --- a/Completion/Debian/_deb_packages +++ b/Completion/Debian/_deb_packages @@ -1,7 +1,57 @@ #autoload -if (( ! $+_deb_packages )); then - _deb_packages=( $(awk '/^Package:/ { print $2 }' /var/lib/dpkg/status) ) -fi +# Usage: _deb_packages expl... avail|installed|uninstalled -compadd "$@" - $_deb_packages +_deb_packages_update_avail () { + if (( ! $+_deb_packages_cache_avail )); then + _deb_packages_cache_avail=( + ${(f)"$(apt-cache dumpavail | awk '/^Package:/ { print $2 }')"} + ) + fi + cachevar=_deb_packages_cache_avail +} + +_deb_packages_update_installed () { + if (( ! $+_deb_packages_cache_installed )); then + _deb_packages_cache_installed=( + ${${${(f)"$(dpkg --get-selections)"}:#*deinstall}%% *} + ) + fi + cachevar=_deb_packages_cache_installed +} + +_deb_packages_update_uninstalled () { + _deb_packages_update_avail + _deb_packages_update_installed + if (( ! $+_deb_packages_cache_uninstalled )); then + _deb_packages_cache_uninstalled=( + ${_deb_packages_cache_avail:#${(j:|:)~${_deb_packages_cache_installed:q}}} + ) + fi + cachevar=_deb_packages_cache_uninstalled +} + +_deb_packages () { + local command="$argv[$#]" expl cachevar pkgset + + [[ "$command" = (installed|uninstalled|avail) ]] || { + _message "_deb_packages:unknown command: $command" + return + } + + zstyle -s ":completion:${curcontext}:" packageset pkgset + + [[ "$pkgset" = (installed|uninstalled|avail|available) ]] || { + pkgset="$command" + } + + [[ "$pkgset" = "available" ]] && pkgset="avail" + + expl=("${(@)argv[1,-2]}") + + _deb_packages_update_$pkgset + + _tags packages && compadd "$expl[@]" - "${(@P)cachevar}" +} + +_deb_packages "$@" diff --git a/Completion/User/_cvs b/Completion/User/_cvs index 356c7a80a..ce928fe50 100644 --- a/Completion/User/_cvs +++ b/Completion/User/_cvs @@ -19,662 +19,640 @@ _cvs () { # define cvs command dispatch function. -if ! builtin functions _cvs_command >&-; then - _cvs_command () { - typeset -A cmds - cmds=(add " ad new " admin " adm rcs " annotate " ann " - checkout " co get " commit " ci com " diff " di dif " - edit "" editors "" export " exp ex " - history " hi his " import " im imp " init "" - log " lo rlog " login " logon lgn " logout "" - rdiff " patch pa " release " re rel " remove " rm delete " - status " st stat " rtag " rt rfreeze " tag " ta freeze " - unedit "" update " up upd " watch "" - watchers "") - - if (( CURRENT == 1 )); then - compadd "$@" ${(k)cmds} || compadd "$@" ${(kv)=cmds} +(( $+functions[_cvs_command] )) || +_cvs_command () { + local cmd + typeset -A cmds + cmds=(add " ad new " admin " adm rcs " annotate " ann " + checkout " co get " commit " ci com " diff " di dif " + edit "" editors "" export " exp ex " + history " hi his " import " im imp " init "" + log " lo rlog " login " logon lgn " logout "" + rdiff " patch pa " release " re rel " remove " rm delete " + status " st stat " rtag " rt rfreeze " tag " ta freeze " + unedit "" update " up upd " watch "" + watchers "") + + if (( CURRENT == 1 )); then + _tags commands && { compadd "$@" ${(k)cmds} || compadd "$@" ${(kv)=cmds} } + else + local curcontext="$curcontext" + + cmd="${${(k)cmds[(R)* $words[1] *]}:-${(k)cmds[(i)$words[1]]}}" + if (( $#cmd )); then + curcontext="${curcontext%:*:*}:cvs-${cmd}:" + _cvs_$cmd else - case "${${(k)cmds[(R)* $words[1] *]}:-$words[1]}" in - add) _cvs_add;; - admin) _cvs_admin;; - annotate) _cvs_annotate;; - checkout) _cvs_checkout;; - commit) _cvs_commit;; - diff) _cvs_diff;; - edit) _cvs_edit;; - editors) _cvs_editors;; - export) _cvs_export;; - history) _cvs_history;; - import) _cvs_import;; - init) _cvs_init;; - log) _cvs_log;; - login) _cvs_login;; - logout) _cvs_logout;; - rdiff) _cvs_rdiff;; - release) _cvs_release;; - remove) _cvs_remove;; - status) _cvs_status;; - rtag) _cvs_rtag;; - tag) _cvs_tag;; - unedit) _cvs_unedit;; - update) _cvs_update;; - watch) _cvs_watch;; - watchers) _cvs_watchers;; - *) _message "unknown cvs command: $words[1]";; - esac + _message "unknown cvs command: $words[1]" fi - } -fi + fi +} # define completion functions for each cvs command -if ! builtin functions _cvs_add >&-; then - _cvs_add () { - # "+k:m:" - _arguments -s \ - '-k+:keyword substitution:_cvs_k' \ - '-m+:message:_cvs_m' \ - '*:file:_cvs_files_unmaintained' \ - } -fi - -if ! builtin functions _cvs_admin >&-; then - _cvs_admin () { - # "+ib::c:a:A:e:l::u::LUn:N:m:o:s:t::IqxV:k:" - _arguments -s \ - -{i,L,U,I,q,x} \ - '-b-:default branch:(1.1.1)' \ - '-c+:comment leader (not used):' \ - '-a+:login names (not work with CVS):' \ - '-A+:access list to append (not work with CVS):' \ - '-e+:access list to erase (not work with CVS):' \ - '-l-:revision to lock:' \ - '-u-:revision to unlock:' \ - '-n+:symbolic-name[\:revision]:' \ - '-N+:symbolic-name[\:revision]:' \ - '-m+:revision\:msg:' \ - '-o+:range to delete:' \ - '-s+:state[\:revision]:' \ - '-t-:descriptive text:_cvs_admin_t' \ - '-V+:version (obsolete):' \ - '-k+:keyword substitution:_cvs_k' \ - '*:file:_cvs_files' - } -fi +(( $+functions[_cvs_add] )) || +_cvs_add () { + # "+k:m:" + _arguments -s \ + '-k+:keyword substitution:_cvs_k' \ + '-m+:message:_cvs_m' \ + '*:file:_cvs_files_unmaintained' \ +} -if ! builtin functions _cvs_admin_t >&-; then - _cvs_admin_t () { - if compset -P -; then - _message 'descriptive text' - else - _files "$@" - fi - } -fi - -if ! builtin functions _cvs_annotate >&-; then - _cvs_annotate () { - # "+lr:D:fR" - _arguments -s \ - -{l,f,R} \ - '-r+:tag:_cvs_revisions' \ - '-D+:date:_cvs_D' \ - '*:file:_cvs_files' - } -fi - -if ! builtin functions _cvs_checkout >&-; then - _cvs_checkout () { - # "+ANnk:d:flRpQqcsr:D:j:P" - _arguments -s \ - -{A,N,n,f,l,R,q,c,s,P} \ - '-k+:keyword substitution:_cvs_k' \ - '-d+:directory:_files -/' \ - '-r+:tag:_cvs_revisions' \ - '-D+:date:_cvs_D' \ - '-j+:tag:_cvs_revisions' \ - '*:module:_cvs_modules' - } -fi - -if ! builtin functions _cvs_commit >&-; then - _cvs_commit () { - # "+nlRm:fF:r:" - _arguments -s \ - -{n,l,R,f} \ - '-m+:message:_cvs_m' \ - '-F+:log message file:_files' \ - '-r+:tag:_cvs_revisions' \ - '*:file:_cvs_files_modified' - } -fi +(( $+functions[_cvs_admin] )) || +_cvs_admin () { + # "+ib::c:a:A:e:l::u::LUn:N:m:o:s:t::IqxV:k:" + _arguments -s \ + -{i,L,U,I,q,x} \ + '-b-:default branch:(1.1.1)' \ + '-c+:comment leader (not used):' \ + '-a+:login names (not work with CVS):' \ + '-A+:access list to append (not work with CVS):' \ + '-e+:access list to erase (not work with CVS):' \ + '-l-:revision to lock:' \ + '-u-:revision to unlock:' \ + '-n+:symbolic-name(\:revision):' \ + '-N+:symbolic-name(\:revision):' \ + '-m+:revision\:msg:' \ + '-o+:range to delete:' \ + '-s+:state(\:revision):' \ + '-t-:descriptive text:_cvs_admin_t' \ + '-V+:version (obsolete):' \ + '-k+:keyword substitution:_cvs_k' \ + '*:file:_cvs_files' +} -if ! builtin functions _cvs_diff >&-; then - _cvs_diff () { - # "+abcdefhilnpstuw0123456789BHNRC:D:F:I:L:U:V:W:k:r:" - _arguments -s \ - -{l,R} \ - '-D+:date:_cvs_D' \ - '-k+:keyword substitution:_cvs_k' \ - '-r+:tag:_cvs_revisions' \ - -{h,p,0,1,2,3,4,5,6,7,8,9} \ - '--binary' \ - '--brief' \ - '--changed-group-format=:format:' \ - '-c' '-C+:lines:' '--context=-:lines:' \ - '-e' '--ed' \ - '-t' '--expand-tabs' \ - '-f' '--forward-ed' \ - '--horizon-lines=:lines:' \ - '--ifdef=:name:' \ - '-w' '--ignore-all-space' \ - '-B' '--ignore-blank-lines' \ - '-i' '--ignore-case' \ - '-I+:regex:' '--ignore-matching-lines=:regex:' \ - '-b' '--ignore-space-change' \ - '--initial-tab' \ - '*-L+:label:' '*--label=:label:' \ - '--left-column' \ - '--line-format=:format:' \ - '-d' '--minimal' \ - '-N' '--new-file' \ - '--new-group-format=:format:' \ - '--new-line-format=:format:' \ - '--old-group-format=:format:' \ - '--old-line-format=:format:' \ - '--paginate' \ - '-n' '--rcs' \ - '-s' '--report-identical-files' \ - '--show-c-function' \ - '-F+:regex:' '--show-function-line=:regex:' \ - '-y' '--side-by-side' \ - '-H' '--speed-large-files' \ - '--suppress-common-lines' \ - '-a' '--text' \ - '--unchanged-group-format=:format:' \ - '--unchanged-line-format=:format:' \ - '-u' '-U+:lines:' '--unified=-:lines:' \ - '-W:columns:' '--width=:columns:' \ - '*:file:_cvs_diff_arg' - } -fi +(( $+functions[_cvs_admin_t] )) || +_cvs_admin_t () { + if compset -P -; then + _message 'descriptive text' + else + _files "$@" + fi +} -if ! builtin functions _cvs_diff_arg >&-; then - _cvs_diff_arg () { - _cvs_files_modified || _cvs_files - } -fi +(( $+functions[_cvs_annotate] )) || +_cvs_annotate () { + # "+lr:D:fR" + _arguments -s \ + -{l,f,R} \ + '-r+:tag:_cvs_revisions' \ + '-D+:date:_cvs_D' \ + '*:file:_cvs_files' +} -if ! builtin functions _cvs_edit >&-; then - _cvs_edit () { - # "+lRa:" - _arguments -s \ - -{l,R} \ - '-a+:action:(edit unedit commit all none)' - '*:file:_cvs_files' - } -fi +(( $+functions[_cvs_checkout] )) || +_cvs_checkout () { + # "+ANnk:d:flRpQqcsr:D:j:P" + _arguments -s \ + -{A,N,n,f,l,R,q,c,s,P} \ + '-k+:keyword substitution:_cvs_k' \ + '-d+:directory:_files -/' \ + '-r+:tag:_cvs_revisions' \ + '-D+:date:_cvs_D' \ + '-j+:tag:_cvs_revisions' \ + '*:module:_cvs_modules' +} -if ! builtin functions _cvs_editors >&-; then - _cvs_editors () { - # "+lR" - _arguments -s \ - -{l,R} \ - '*:file:_cvs_files' - } -fi - -if ! builtin functions _cvs_export >&-; then - _cvs_export () { - # "+Nnk:d:flRQqr:D:" - _arguments -s \ - -{N,n,f,l,R,Q,q} \ - '-k+:keyword substitution:_cvs_k' \ - '-d+:directory:_files -/' \ - '-r+:tag:_cvs_revisions' \ - '-D+:date:_cvs_D' \ - '*:module:_cvs_modules' - } -fi - -if ! builtin functions _cvs_history >&-; then - _cvs_history () { - # "+Tacelow?D:b:f:m:n:p:r:t:u:x:X:z:" - _arguments -s \ - -{T,a,c,e,l,o,w,\?} \ - '-D+:date:_cvs_D' \ - '-b+:string:' \ - '-f+:arg:' \ - '-m+:module:_cvs_modules' \ - '-n+:arg:' \ - '*-p+:repository:' \ - '-r+:rev:' \ - '-t+:tag:' \ - '-u+:user name:' \ - '-x+:type:_cvs_history_x' \ - '-X+:arg:' \ - '-z+:arg:' \ - '*:file:_cvs_files' - } -fi - -if ! builtin functions _cvs_history_x >&-; then - _cvs_history_x () { - compset -P '*' - - compadd "$@" -y '( - F\ --\ release - O\ --\ checkout - E\ --\ export - T\ --\ rtag - C\ --\ merge\ collision-detected - G\ --\ merge\ succeed - U\ --\ working\ file\ was\ copied - W\ --\ working\ file\ was\ deleted - A\ --\ A\ file\ was\ added - M\ --\ A\ file\ was\ modified - R\ --\ A\ file\ was\ removed - )' F O E T C G U W A M R - } -fi - -if ! builtin functions _cvs_import >&-; then - _cvs_import () { - # "+Qqdb:m:I:k:W:" - _arguments -s \ - -{Q,q,d} \ - '-b+:branch:' \ - '-m+:message:_cvs_m' \ - '*-I+:name:_files' \ - '-k+:keyword substitution:_cvs_k' \ - '*-W+:spec:' \ - ':repository:_cvs_modules' \ - ':vendor tag:' \ - ':release tag:' - } -fi +(( $+functions[_cvs_commit] )) || +_cvs_commit () { + # "+nlRm:fF:r:" + _arguments -s \ + -{n,l,R,f} \ + '-m+:message:_cvs_m' \ + '-F+:log message file:_files' \ + '-r+:tag:_cvs_revisions' \ + '*:file:_cvs_files_modified' +} -if ! builtin functions _cvs_init >&-; then - _cvs_init () { - false - } -fi +(( $+functions[_cvs_diff] )) || +_cvs_diff () { + # "+abcdefhilnpstuw0123456789BHNRC:D:F:I:L:U:V:W:k:r:" + _arguments -s \ + -{l,R} \ + '-D+:date:_cvs_D' \ + '-k+:keyword substitution:_cvs_k' \ + '-r+:tag:_cvs_revisions' \ + -{h,p,0,1,2,3,4,5,6,7,8,9} \ + '--binary' \ + '--brief' \ + '--changed-group-format=:format:' \ + '-c' '-C+:lines:' '--context=-:lines:' \ + '-e' '--ed' \ + '-t' '--expand-tabs' \ + '-f' '--forward-ed' \ + '--horizon-lines=:lines:' \ + '--ifdef=:name:' \ + '-w' '--ignore-all-space' \ + '-B' '--ignore-blank-lines' \ + '-i' '--ignore-case' \ + '-I+:regex:' '--ignore-matching-lines=:regex:' \ + '-b' '--ignore-space-change' \ + '--initial-tab' \ + '*-L+:label:' '*--label=:label:' \ + '--left-column' \ + '--line-format=:format:' \ + '-d' '--minimal' \ + '-N' '--new-file' \ + '--new-group-format=:format:' \ + '--new-line-format=:format:' \ + '--old-group-format=:format:' \ + '--old-line-format=:format:' \ + '--paginate' \ + '-n' '--rcs' \ + '-s' '--report-identical-files' \ + '--show-c-function' \ + '-F+:regex:' '--show-function-line=:regex:' \ + '-y' '--side-by-side' \ + '-H' '--speed-large-files' \ + '--suppress-common-lines' \ + '-a' '--text' \ + '--unchanged-group-format=:format:' \ + '--unchanged-line-format=:format:' \ + '-u' '-U+:lines:' '--unified=-:lines:' \ + '-W:columns:' '--width=:columns:' \ + '*:file:_cvs_diff_arg' +} -if ! builtin functions _cvs_login >&-; then - _cvs_login () { - false - } -fi +(( $+functions[_cvs_diff_arg] )) || +_cvs_diff_arg () { + _cvs_files_modified || _cvs_files +} -if ! builtin functions _cvs_logout >&-; then - _cvs_logout () { - false - } -fi - -if ! builtin functions _cvs_rdiff >&-; then - _cvs_rdiff () { - # "+V:k:cuftsQqlRD:r:" - _arguments -s \ - -{c,u,f,t,s,Q,q,l,R} \ - '-V+:version:' \ - '-k+:keyword substitution:_cvs_k' \ - '*-D+:date:_cvs_D' \ - '*-r+:tag:_cvs_revisions' \ - '*:module:_cvs_modules' - } -fi - -if ! builtin functions _cvs_release >&-; then - _cvs_release () { - # "+Qdq" - _arguments -s \ - -{Q,d,q} \ - '*:directory:_files -/' - } -fi - -if ! builtin functions _cvs_remove >&-; then - _cvs_remove () { - # "+flR" - _arguments -s \ - -{f,l,R} \ - '*:file:_cvs_files_removed' - } -fi +(( $+functions[_cvs_edit] )) || +_cvs_edit () { + # "+lRa:" + _arguments -s \ + -{l,R} \ + '-a+:action:(edit unedit commit all none)' \ + '*:file:_cvs_files' +} -if ! builtin functions _cvs_status >&-; then - _cvs_status () { - # "+vlR" - _arguments -s \ - -{v,l,R} \ - '*:file:_cvs_files' - } -fi - -if ! builtin functions _cvs_tag >&-; then - _cvs_tag () { - # "+FQqlRcdr:D:bf" - _arguments -s \ - -{F,Q,q,l,R,c,d,b,f} \ - '-r+:tag:_cvs_revisions' \ - '-D+:date:_cvs_D' \ - '*:file:_cvs_files' - } -fi +(( $+functions[_cvs_editors] )) || +_cvs_editors () { + # "+lR" + _arguments -s \ + -{l,R} \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_export] )) || +_cvs_export () { + # "+Nnk:d:flRQqr:D:" + _arguments -s \ + -{N,n,f,l,R,Q,q} \ + '-k+:keyword substitution:_cvs_k' \ + '-d+:directory:_files -/' \ + '-r+:tag:_cvs_revisions' \ + '-D+:date:_cvs_D' \ + '*:module:_cvs_modules' +} + +(( $+functions[_cvs_history] )) || +_cvs_history () { + # "+Tacelow?D:b:f:m:n:p:r:t:u:x:X:z:" + _arguments -s \ + -{T,a,c,e,l,o,w,\?} \ + '-D+:date:_cvs_D' \ + '-b+:string:' \ + '-f+:file:_cvs_files' \ + '-m+:module:_cvs_modules' \ + '-n+:module:_cvs_modules' \ + '*-p+:repository:' \ + '-r+:rev:' \ + '-t+:tag:' \ + '-u+:user name:' \ + '-x+:type:_cvs_history_x' \ + '-X+:arg:' \ + '-z+:timezone:' \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_history_x] )) || +_cvs_history_x () { + _values -s '' 'type' \ + 'F[release]' \ + 'O[checkout]' \ + 'E[export]' \ + 'T[rtag]' \ + 'C[merge collision-detected]' \ + 'G[merge succeed]' \ + 'U[working file was copied]' \ + 'W[working file was deleted]' \ + 'A[A file was added]' \ + 'M[A file was modified]' \ + 'R[A file was removed]' +} + +(( $+functions[_cvs_import] )) || +_cvs_import () { + # "+Qqdb:m:I:k:W:" + _arguments -s \ + -{Q,q,d} \ + '-b+:branch:' \ + '-m+:message:_cvs_m' \ + '*-I+:name:_files' \ + '-k+:keyword substitution:_cvs_k' \ + '*-W+:spec:' \ + ':repository:_cvs_modules' \ + ':vendor tag:' \ + ':release tag:' +} + +(( $+functions[_cvs_init] )) || +_cvs_init () { + false +} + +(( $+functions[_cvs_log] )) || +_cvs_log () { + # "+bd:hlNRr::s:tw::" + _arguments -s \ + -{b,h,l,N,R,t} \ + '-d+:dates:' \ + '-r-:revisions:' \ + '-s+:states:' \ + '-w-:logins:' \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_login] )) || +_cvs_login () { + false +} + +(( $+functions[_cvs_logout] )) || +_cvs_logout () { + false +} + +(( $+functions[_cvs_rdiff] )) || +_cvs_rdiff () { + # "+V:k:cuftsQqlRD:r:" + _arguments -s \ + -{c,u,f,t,s,Q,q,l,R} \ + '-V+:version:' \ + '-k+:keyword substitution:_cvs_k' \ + '*-D+:date:_cvs_D' \ + '*-r+:tag:_cvs_revisions' \ + '*:module:_cvs_modules' +} + +(( $+functions[_cvs_release] )) || +_cvs_release () { + # "+Qdq" + _arguments -s \ + -{Q,d,q} \ + '*:directory:_files -/' +} + +(( $+functions[_cvs_remove] )) || +_cvs_remove () { + # "+flR" + _arguments -s \ + -{f,l,R} \ + '*:file:_cvs_files_removed' +} + +(( $+functions[_cvs_rtag] )) || +_cvs_rtag () { + # "+FanfQqlRdbr:D:" + _arguments -s \ + -{F,a,n,f,Q,q,l,R,d,b} \ + '*-D+:date:_cvs_D' \ + '*-r+:tag:_cvs_revisions' \ + ':tag:' \ + '*:module:_cvs_modules' +} + +(( $+functions[_cvs_status] )) || +_cvs_status () { + # "+vlR" + _arguments -s \ + -{v,l,R} \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_tag] )) || +_cvs_tag () { + # "+FQqlRcdr:D:bf" + _arguments -s \ + -{F,Q,q,l,R,c,d,b,f} \ + '-r+:tag:_cvs_revisions' \ + '-D+:date:_cvs_D' \ + ':tag:' \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_unedit] )) || +_cvs_unedit () { + # "+lR" + _arguments -s \ + -{l,R} \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_update] )) || +_cvs_update () { + # "+ApCPflRQqduk:r:D:j:I:W:" + _arguments -s \ + -{A,C,p,P,f,l,R,Q,q,d,u} \ + '-k+:keyword substitution:_cvs_k' \ + '-r+:tag:_cvs_revisions' \ + '-D+:date:_cvs_D' \ + '-j+:tag:_cvs_revisions' \ + '*-I+:name:_files' \ + '*-W+:spec:' \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_watch] )) || +_cvs_watch () { + local expl + + if (( CURRENT == 2 )); then + _wanted values expl 'watch command' compadd on off add remove + else + case "$words[2]" in + on|off) # "+lR" + _arguments -s \ + -{l,R} \ + ':watch command:' \ + '*:file:_cvs_files' + ;; + add|remove) # "+lRa:" + _arguments -s \ + -{l,R} \ + '*-a+:action:(edit unedit commit all none)' \ + ':watch command:' \ + '*:file:_cvs_files' + ;; + esac + fi +} -if ! builtin functions _cvs_unedit >&-; then - _cvs_unedit () { - # "+lR" - _arguments -s \ +(( $+functions[_cvs_watchers] )) || +_cvs_watchers () { + # "+lR" + _arguments -s \ -{l,R} \ '*:file:_cvs_files' - } -fi - -if ! builtin functions _cvs_update >&-; then - _cvs_update () { - # "+ApPflRQqduk:r:D:j:I:W:" - _arguments -s \ - -{A,p,P,f,l,R,Q,q,d,u} \ - '-k+:keyword substitution:_cvs_k' \ - '-r+:tag:_cvs_revisions' \ - '-D+:date:_cvs_D' \ - '-j+:tag:_cvs_revisions' \ - '*-I+:name:_files' \ - '*-W+:spec:' \ - '*:file:_cvs_files' - } -fi +} -if ! builtin functions _cvs_watch >&-; then - _cvs_watch () { - if (( CURRENT == 2 )); then - compadd on off add remove - else - case "$words[2]" in - on|off) # "+lR" - _arguments -s \ - -{l,R} \ - ':watch command:' \ - ':*:file:_cvs_files' - ;; - add|remove) # "+lRa:" - _arguments -s \ - -{l,R} \ - '*-a+:action:(edit unedit commit all none)' \ - ':watch command:' \ - ':*:file:_cvs_files' - ;; - esac - fi - } -fi +(( $+functions[_cvs_loadstat] )) || +_cvs_loadstat () { + zstyle -t ":completion:${curcontext}:" disable-stat && return + (( $+_cvs_loadstat_tried )) && return + _cvs_loadstat_tried=yes -if ! builtin functions _cvs_watchers >&-; then - _cvs_watchers () { - # "+lR" - _arguments -s \ - -{l,R} \ - ':*:file:_cvs_files' - } -fi + zmodload -i zsh/stat 2>/dev/null +} -if ! builtin functions _cvs_root >&-; then - _cvs_root () { - compadd "$@" $_cvs_roots || _files "$@" -/ - } -fi +(( $+functions[_cvs_root] )) || +_cvs_root () { + local cvspassfile id -if ! builtin functions _cvs_tempdir >&-; then - _cvs_tempdir () { - compadd "$@" $TMPPREFIX:h $TMPDIR /tmp - } -fi + typeset -gU _cvs_roots -if ! builtin functions _cvs_user_variable >&-; then - _cvs_user_variable () { - if compset -P '*='; then - _default + if [[ -f "${cvspassfile::=${CVS_PASSFILE:-$HOME/.cvspass}}" ]]; then + _cvs_loadstat + if (( $+builtins[stat] )); then + id="$(LC_ALL=C builtin stat -g +mtime -F '%Y/%m/%d-%T' "$cvspassfile")" else - _message "variable=value" + id="$(LC_ALL=C ls -l "$cvspassfile")" + fi + if [[ "$id" != "$_cvs_pass_id" ]]; then + _cvs_roots=($_cvs_roots ${${(f)"$(<$cvspassfile)"}%% *}) + _cvs_pass_id="$id" fi + fi + + _tags files && { + compadd -M 'r:|[:@./]=* r:|=*' "$@" $_cvs_roots || _files "$@" -/ } -fi +} + +(( $+functions[_cvs_tempdir] )) || +_cvs_tempdir () { + _tags directories && compadd "$@" $TMPPREFIX:h $TMPDIR /tmp +} + +(( $+functions[_cvs_user_variable] )) || +_cvs_user_variable () { + if compset -P '*='; then + _default + else + _message "variable=value" + fi +} # define completion functions for cvs global options. -if ! builtin functions _cvs_bindir >&-; then - _cvs_bindir () { - compadd "$@" /usr/local/bin || _files "$@" -/ - } -fi +(( $+functions[_cvs_bindir] )) || +_cvs_bindir () { + _tags directories && { compadd "$@" /usr/local/bin || _files "$@" -/ } +} -if ! builtin functions _cvs_editor >&-; then - _cvs_editor () { - compadd "$@" vi - } -fi +(( $+functions[_cvs_editor] )) || +_cvs_editor () { + _tags commands && compadd "$@" vi +} -if ! builtin functions _cvs_gzip_level >&-; then - _cvs_gzip_level () { - compadd "$@" 9 - } -fi +(( $+functions[_cvs_gzip_level] )) || +_cvs_gzip_level () { + _tags values && compadd "$@" 9 +} # define completion functions for cvs common options and arguments. -if ! builtin functions _cvs_D >&-; then - _cvs_D () { - compadd "$@" today yesterday week\ ago month\ ago - } -fi +(( $+functions[_cvs_D] )) || +_cvs_D () { + _tags values && compadd "$@" today yesterday week\ ago month\ ago +} -if ! builtin functions _cvs_k >&-; then - _cvs_k () { - compadd "$@" kv kvl k o b v - } -fi +(( $+functions[_cvs_k] )) || +_cvs_k () { + _tags values && compadd "$@" kv kvl k o b v +} -if ! builtin functions _cvs_m >&-; then - _cvs_m () { - _message "log message" - } -fi +(( $+functions[_cvs_m] )) || +_cvs_m () { + _message "log message" +} -if ! builtin functions _cvs_modules >&-; then - _cvs_modules () { - local root=$CVSROOT - [[ -f CVS/Root ]] && root=$(<CVS/Root) +(( $+functions[_cvs_modules] )) || +_cvs_modules () { + local root=$CVSROOT expl - if [[ $root = :* || ! -d $root ]]; then - _message "module name" - else - compadd - \ - $root/^CVSROOT(:t) \ - ${${(M)${(f)"$(<$root/CVSROOT/modules)"}:#[^#]*}%%[ ]*} - fi - } -fi + [[ -f CVS/Root ]] && root=$(<CVS/Root) -if ! builtin functions _cvs_revisions >&-; then - _cvs_revisions () { - compadd - ${${${(M)${(f)"$(cvs -q status -vl .)"}:# *}##[ ]##}%%[ ]*} - } -fi + if [[ $root = :* || ! -d $root ]]; then + _message "module name" + else + _wanted modules expl module \ + compadd - $root/^CVSROOT(:t) \ + ${${(M)${(f)"$(<$root/CVSROOT/modules)"}:#[^#]*}%%[ ]*} + fi +} + +(( $+functions[_cvs_revisions] )) || +_cvs_revisions () { + local expl + + _wanted values expl revision \ + compadd - ${${${(M)${(f)"$(cvs -q status -vl .)"}:# *}##[ ]##(No Tags Exist)#}%%[ ]*} +} # define completion functions for files maintained by cvs. -if ! builtin functions _cvs_setup_prefix >&-; then - _cvs_setup_prefix () { - if [[ -prefix */ ]]; then - qpref="${PREFIX%/*}/" - pref=$~qpref - else - qpref= - pref=./ - fi - } -fi +(( $+functions[_cvs_setup_prefix] )) || +_cvs_setup_prefix () { + if [[ -prefix */ ]]; then + qpref="${PREFIX%/*}/" + pref=$~qpref + else + qpref= + pref=./ + fi +} -if ! builtin functions _cvs_extract_directory_entries >&-; then - _cvs_extract_directory_entries () { - entries=($entries ${${${(M)rawentries:#D/*}#D/}%%/*}) - } -fi +(( $+functions[_cvs_extract_directory_entries] )) || +_cvs_extract_directory_entries () { + entries=($entries ${${${(M)rawentries:#D/*}#D/}%%/*}) +} -if ! builtin functions _cvs_extract_file_entries >&-; then - _cvs_extract_file_entries () { - entries=($entries ${${${(M)rawentries:#/*}#/}%%/*}) - } -fi - -if ! builtin functions _cvs_extract_modifiedfile_entries >&-; then - _cvs_extract_modifiedfile_entries () { - if [[ -n "$compconfig[_cvs_disable_stat]" ]] || - ! { zmodload -e stat || zmodload stat }; then - _cvs_extract_file_entries - return - fi +(( $+functions[_cvs_extract_file_entries] )) || +_cvs_extract_file_entries () { + entries=($entries ${${${(M)rawentries:#/*}#/}%%/*}) +} - local ents pats - ents=(${${${${(M)rawentries:#/*}#/}/\\/[^\\/]#\\///}%/[^/]#/[^/]#}) - pats=(${${${(f)"$(LANG=C builtin stat -gn +mtime -F '%a %b %e %T %Y' ${pref}*(D))"}##*/}/ //}) - eval 'ents=(${ents:#('${(j:|:)${(@)pats:q}}')})' - entries=($entries ${ents%%/*}) - } -fi - -if ! builtin functions _cvs_setup_allentries >&-; then - _cvs_setup_allentries () { - entries=() - if [[ -f ${pref}CVS/Entries ]]; then - local rawentries - rawentries=(${(f)"$(<${pref}CVS/Entries)"}) - _cvs_extract_file_entries - _cvs_extract_directory_entries - fi - } -fi - -if ! builtin functions _cvs_setup_direntries >&-; then - _cvs_setup_direntries () { - entries=() - if [[ -f ${pref}CVS/Entries ]]; then - local rawentries - rawentries=(${(f)"$(<${pref}CVS/Entries)"}) - _cvs_extract_directory_entries - fi - } -fi - -if ! builtin functions _cvs_setup_modentries >&-; then - _cvs_setup_modentries () { - entries=() - if [[ -f ${pref}CVS/Entries ]]; then - local rawentries - rawentries=(${(f)"$(<${pref}CVS/Entries)"}) - _cvs_extract_modifiedfile_entries - _cvs_extract_directory_entries - fi - } -fi +(( $+functions[_cvs_extract_modifiedfile_entries] )) || +_cvs_extract_modifiedfile_entries () { + _cvs_loadstat + if (( ! $+builtins[stat] )); then + _cvs_extract_file_entries + return + fi -if ! builtin functions _cvs_directories >&-; then - _cvs_directories () { - if [[ -d ${pref}CVS ]]; then - _cvs_setup_direntries - (( $#entries )) && compgen "$@" -g "${(j:|:)${(@)entries:q}}" - else - _files "$@" - fi - } -fi - -if ! builtin functions _cvs_files >&-; then - _cvs_files () { - local qpref pref entries - _cvs_setup_prefix - if [[ -d ${pref}CVS ]]; then - _cvs_setup_allentries - (( $#entries )) && compgen "$@" -g "${(j:|:)${(@)entries:q}}" - else - _files "$@" - fi - } -fi - -if ! builtin functions _cvs_files_modified >&-; then - _cvs_files_modified () { - local qpref pref entries - _cvs_setup_prefix - if [[ -d ${pref}CVS ]]; then - _cvs_setup_modentries - (( $#entries )) && compgen "$@" -g "${(j:|:)${(@)entries:q}}" - else - _files "$@" - fi - } -fi - -if ! builtin functions _cvs_files_removed >&-; then - _cvs_files_removed () { - local qpref pref entries - _cvs_setup_prefix - if [[ -d ${pref}CVS ]]; then - _cvs_setup_allentries - setopt localoptions unset - local omit - omit=(${pref}*(D:t)) - eval 'entries=(${entries:#('${(j:|:)${(@)omit:q}}')})' - compadd "$@" -P "$qpref" - ${entries:q} || - _cvs_directories "$@" - else - _files "$@" - fi - } -fi - -if ! builtin functions _cvs_files_unmaintained >&-; then - _cvs_files_unmaintained () { - local qpref pref entries - _cvs_setup_prefix - if [[ -d ${pref}CVS ]]; then - _cvs_setup_allentries - setopt localoptions unset - local omit - omit=($_cvs_ignore_default ${entries:q} ${=cvsignore}) - [[ -r ~/.cvsignore ]] && omit=($omit $(<~/.cvsignore)) - [[ -r ${pref}.cvsignore ]] && omit=($omit $(<${pref}.cvsignore)) - compgen "$@" -g '*~(*/|)('${(j:|:)omit}')(D)' || - compgen "$@" -g '*~(*/|)('${(j:|:)${(@)entries:q}}')(D)' || - _cvs_directories "$@" - else - _files "$@" - fi - } -fi + local ents pats + ents=(${${${${(M)rawentries:#/*}#/}/\\/[^\\/]#\\///}%/[^/]#/[^/]#}) + pats=(${${${(f)"$(LC_ALL=C builtin stat -gn +mtime -F '%a %b %e %T %Y' ${pref}*(D))"}##*/}/ //}) + eval 'ents=(${ents:#('${(j:|:)${(@)pats:q}}')})' + entries=($entries ${ents%%/*}) +} -# define configuration variables. +(( $+functions[_cvs_setup_allentries] )) || +_cvs_setup_allentries () { + entries=() + if [[ -f ${pref}CVS/Entries ]]; then + local rawentries + rawentries=(${(f)"$(<${pref}CVS/Entries)"}) + _cvs_extract_file_entries + _cvs_extract_directory_entries + fi +} + +(( $+functions[_cvs_setup_direntries] )) || +_cvs_setup_direntries () { + entries=() + if [[ -f ${pref}CVS/Entries ]]; then + local rawentries + rawentries=(${(f)"$(<${pref}CVS/Entries)"}) + _cvs_extract_directory_entries + fi +} + +(( $+functions[_cvs_setup_modentries] )) || +_cvs_setup_modentries () { + entries=() + if [[ -f ${pref}CVS/Entries ]]; then + local rawentries + rawentries=(${(f)"$(<${pref}CVS/Entries)"}) + _cvs_extract_modifiedfile_entries + _cvs_extract_directory_entries + fi +} -if (( ! $+_cvs_roots )); then - if [[ -f ~/.cvspass ]]; then - _cvs_roots=(${${(f)"$(<~/.cvspass)"}%% *}) +(( $+functions[_cvs_directories] )) || +_cvs_directories () { + if [[ -d ${pref}CVS ]]; then + _cvs_setup_direntries + (( $#entries )) && _files "$@" -g "${(j:|:)${(@)entries:q}}" else - _cvs_roots=() + _files "$@" fi -fi +} + +(( $+functions[_cvs_files] )) || +_cvs_files () { + local qpref pref entries + _cvs_setup_prefix + if [[ -d ${pref}CVS ]]; then + _cvs_setup_allentries + (( $#entries )) && _files "$@" -g "${(j:|:)${(@)entries:q}}" + else + _files "$@" + fi +} + +(( $+functions[_cvs_files_modified] )) || +_cvs_files_modified () { + local qpref pref entries + _cvs_setup_prefix + if [[ -d ${pref}CVS ]]; then + _cvs_setup_modentries + (( $#entries )) && _files "$@" -g "${(j:|:)${(@)entries:q}}" + else + _files "$@" + fi +} + +(( $+functions[_cvs_files_removed] )) || +_cvs_files_removed () { + local qpref pref entries + _cvs_setup_prefix + if [[ -d ${pref}CVS ]]; then + _cvs_setup_allentries + setopt localoptions unset + local omit + omit=(${pref}*(D:t)) + eval 'entries=(${entries:#('${(j:|:)${(@)omit:q}}')})' + _tags directories && compadd "$@" -P "$qpref" - ${entries:q} || + _cvs_directories "$@" + else + _files "$@" + fi +} + +(( $+functions[_cvs_files_unmaintained] )) || +_cvs_files_unmaintained () { + local qpref pref entries + _cvs_setup_prefix + if [[ -d ${pref}CVS ]]; then + _cvs_setup_allentries + setopt localoptions unset + local omit + omit=($_cvs_ignore_default ${entries:q} ${=cvsignore}) + [[ -r ~/.cvsignore ]] && omit=($omit $(<~/.cvsignore)) + [[ -r ${pref}.cvsignore ]] && omit=($omit $(<${pref}.cvsignore)) + _path_files "$@" -g '*~(*/|)('${(j:|:)omit}')(D)' || + _path_files "$@" -g '*~(*/|)('${(j:|:)${(@)entries:q}}')(D)' || + _cvs_directories "$@" + else + _files "$@" + fi +} + +# define configuration variables. -if (( ! $+_cvs_ignore_default )); then - _cvs_ignore_default=( - RCS SCCS CVS CVS.adm RCSLOG 'cvslog.*' tags TAGS .make.state .nse_depinfo - '*\~' '\#*' '.\#*' ',*' '_$*' '*$' '*.old' '*.bak' '*.BAK' '*.orig' '*.rej' - '.del-*' '*.a' '*.olb' '*.o' '*.obj' '*.so' '*.exe' '*.Z' '*.elc' '*.ln' - core - ) -fi +(( $+_cvs_ignore_default )) || +_cvs_ignore_default=( + RCS SCCS CVS CVS.adm RCSLOG 'cvslog.*' tags TAGS .make.state .nse_depinfo + '*\~' '\#*' '.\#*' ',*' '_$*' '*$' '*.old' '*.bak' '*.BAK' '*.orig' '*.rej' + '.del-*' '*.a' '*.olb' '*.o' '*.obj' '*.so' '*.exe' '*.Z' '*.elc' '*.ln' + core +) # call real _cvs. -_cvs "$@" +[[ -o kshautoload ]] || _cvs "$@" diff --git a/Completion/User/_gdb b/Completion/User/_gdb index a29eaf8b2..0445e18e9 100644 --- a/Completion/User/_gdb +++ b/Completion/User/_gdb @@ -17,7 +17,8 @@ elif compset -P '-(exec|se)='; then elif compset -P '-(symbols|core|command)='; then _files elif [[ "$PREFIX" = -* ]]; then - if _wanted options; then + _tags options + while _tags; do while _next_label options expl option; do compadd "$expl[@]" -QS '' - -symbols\= -exec\= -se\= -core\= -command\= \ -directory\= -cd\= -tty\= && ret=0 @@ -25,7 +26,7 @@ elif [[ "$PREFIX" = -* ]]; then -batch -fullname -f -b && ret=0 done (( ret )) || return 0 - fi + done else prev="$words[CURRENT-1]" diff --git a/Completion/User/_gprof b/Completion/User/_gprof index 0a1d621be..659e921e8 100644 --- a/Completion/User/_gprof +++ b/Completion/User/_gprof @@ -1,12 +1,58 @@ #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' \ +local curcontext="$curcontext" state line ret=1 +typeset -A opt_args + +_arguments -C -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:->funcs' \ '-I:directory:_dir_list' \ - '-d-:debug level:' '-k:function names: _exec_funcs -p' \ + '-d-:debug level:' '-k:function names:->pair' \ '-m:minimum execution count:' \ - ':executable:_files -g *(*)' \ - ':profile file:_files -g gmon.*' \ + ':executable:_files -g \*\(\*\)' \ + ':profile file:_files -g gmon.\*' \ -- -s '(#--[no-] --)' \ - '*=name*:function name: _exec_funcs' \ - '*=dirs*:directory:_dir_list' + '*=name*:function name:->funcs' \ + '*=dirs*:directory:_dir_list' && ret=0 + +if [[ -n "$state" ]]; then + local cmd pair expl + + _tags functions || return 1 + + [[ "$state" = pair ]] && pair=yes + + if [[ $#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" != "$_gprof_command" ]]; then + _gprof_command="$tmp" + _gprof_funcs=( "${(@)${(@M)${(@f)$(nm $cmd)}:#[^ ]# [tT] ([^_]|_[^_])*}##* }" ) + fi + + if [[ -n "$pair" ]]; then + if compset -P '*/'; then + expl='call arc to function' + else + expl='call arc from function' + fi + else + expl=function + fi + _wanted functions expl "$expl" \ + compadd "$expl[@]" -M 'r:|_=* r:|=*' - "$_gprof_funcs[@]" && ret=0 + else + return 1 + fi +fi + +return ret diff --git a/Completion/User/_groups b/Completion/User/_groups index 27444d26d..7ee9969cd 100644 --- a/Completion/User/_groups +++ b/Completion/User/_groups @@ -2,7 +2,7 @@ local expl groups tmp -_wanted groups || return 1 +_tags groups || return 1 if ! zstyle -a ":completion:${curcontext}:" groups groups; then (( $+_cache_groups )) || @@ -16,4 +16,4 @@ if ! zstyle -a ":completion:${curcontext}:" groups groups; then groups=( "$_cache_groups[@]" ) fi -_all_labels groups expl group compadd "$@" - "$groups[@]" +_wanted groups expl group compadd "$@" - "$groups[@]" diff --git a/Completion/User/_lp b/Completion/User/_lp index e996507ce..60cf8cfd0 100644 --- a/Completion/User/_lp +++ b/Completion/User/_lp @@ -36,28 +36,27 @@ if (( ! $+_lp_cache )); then fi if compset -P -P || [[ "$words[CURRENT-1]" = -P ]]; then - if _wanted printers; then - if zstyle -T ":completion:${curcontext}:printers" verbose; then - zformat -a list ' -- ' "$_lp_cache[@]" - disp=(-ld list) - else - disp=() - fi - _all_labels printers expl printer \ - compadd "$disp[@]" - "${(@)_lp_cache%%:*}" && return 0 + if zstyle -T ":completion:${curcontext}:printers" verbose; then + zformat -a list ' -- ' "$_lp_cache[@]" + disp=(-ld list) + else + disp=() + fi + _wanted printers expl printer \ + compadd "$disp[@]" - "${(@)_lp_cache%%:*}" && return 0 - (( $+_lp_alias_cache )) || return 1 + (( $+_lp_alias_cache )) || return 1 - if zstyle -T ":completion:${curcontext}:printers" verbose; then - zformat -a list ' -- ' "$_lp_alias_cache[@]" - disp=(-ld list) - else - disp=() - fi - compadd "$expl[@]" "$disp[@]" - "${(@)_lp_alias_cache%%:*}" + if zstyle -T ":completion:${curcontext}:printers" verbose; then + zformat -a list ' -- ' "$_lp_alias_cache[@]" + disp=(-ld list) else - return 1 + disp=() fi + _wanted printers expl printer \ + compadd "$disp[@]" - "${(@)_lp_alias_cache%%:*}" && return 0 + + return 1 else if [[ "${words[1]:t}" = (lpq|lprm) ]]; then if [[ "$words" = *-P* ]]; then diff --git a/Completion/User/_mh b/Completion/User/_mh index 724b45e5a..29d6bc2a1 100644 --- a/Completion/User/_mh +++ b/Completion/User/_mh @@ -17,16 +17,13 @@ if compset -P 1 -; then # get list of options, which MH commands can generate themselves # awk is just too icky to use for this, sorry. send me one if # you come up with it. - if _wanted options; then - _all_labels options expl option \ - compadd - $($words[1] -help | perl -ne 'if (/^\s*-\(?(\S+)/) { + _wanted options expl option \ + compadd - $($words[1] -help | perl -ne 'if (/^\s*-\(?(\S+)/) { $n = $1; $n =~ s/\)//g; print $n =~ s/^\[([a-z]+)\]// ? "$n\n$1$n\n" : "$n\n"; }') - return - fi - return 1 + return elif compset -P 1 '[+@]' || [[ "$prev" = -draftfolder ]]; then # Complete folder names. local mhpath @@ -72,13 +69,15 @@ else # leaving foldnam empty works here fi - if _wanted sequences; then + _tags sequences + while _tags; do while _next_label sequences expl sequence; do compadd "$expl[@]" $(mark $foldnam 2>/dev/null | awk -F: '{ print $1 }') && ret=0 compadd "$expl[@]" reply next cur prev first last all unseen && ret=0 _files "$expl[@]" -W folddir -g '<->' && ret=0 done - fi + (( ret )) || return 0 + done return ret fi diff --git a/Completion/User/_mount b/Completion/User/_mount index a148fff27..418b7974f 100644 --- a/Completion/User/_mount +++ b/Completion/User/_mount @@ -543,7 +543,7 @@ fstype) compadd "$expl[@]" -qS, -M 'L:|no=' - "$fss[@]" && ret=0 ;; fsopt) - _wanted options || return 1 + _tags options || return 1 eval 'tmp=(' '"$_fs_'${(s:,:)^${opt_args[$typeops]:-${deffs}}}'[@]"' ')' tmp=( "$_fs_any[@]" "${(@)tmp:#}" ) diff --git a/Completion/User/_netscape b/Completion/User/_netscape index 82fa4509a..ed2bccc75 100644 --- a/Completion/User/_netscape +++ b/Completion/User/_netscape @@ -56,16 +56,14 @@ if [[ "$state" = "remote" ]]; then fi ;; *) - if _wanted commands; then - if [[ -z "$QIPREFIX" ]]; then - _all_labels commands expl 'remote commands' \ - compadd -s'(' -S '' -M 'm:{a-zA-Z}={A-Za-z}' - \ - $remote_commands && ret=0 - else - _all_labels commands expl 'remote commands' \ - compadd -qS '(' -M 'm:{a-zA-Z}={A-Za-z}' - \ - $remote_commands && ret=0 - fi + if [[ -z "$QIPREFIX" ]]; then + _wanted commands expl 'remote commands' \ + compadd -s'(' -S '' -M 'm:{a-zA-Z}={A-Za-z}' - \ + $remote_commands && ret=0 + else + _wanted commands expl 'remote commands' \ + compadd -qS '(' -M 'm:{a-zA-Z}={A-Za-z}' - \ + $remote_commands && ret=0 fi ;; esac @@ -78,12 +76,14 @@ if [[ "$state" = "urls" ]]; then compadd authors blank cache document fonts global hype image-cache \ license logo memory-cache mozilla plugins && ret=0 else - if _wanted prefixes; then + _tags prefixes + while _tags; do while _next_label prefixes expl 'URL prefix'; do compadd "$expl[@]" -S '' about: mocha: javascript: && ret=0 _urls "$@" && ret=0 done - fi + (( ret )) || return 0 + done fi fi diff --git a/Completion/User/_nslookup b/Completion/User/_nslookup index 7d2a12142..44ab4cacc 100644 --- a/Completion/User/_nslookup +++ b/Completion/User/_nslookup @@ -19,9 +19,7 @@ # other characters than lower case letters, we try to call the function # `_nslookup_host'. -setopt localoptions extendedglob - -local state expl ret=1 setopts +local context curstate="$curcontext" expl ret=1 setopts setopts=( 'all[print current values]' \ @@ -40,7 +38,7 @@ setopts=( '(noignoretc)ignoretc[ignore packet truncation errors]' \ '(ignoretc)noignoretc[don'"'"'t ignore packet truncation errors]' \ 'class[change query class]:query class:((in\:Internet\ class chaos\:CHAOS\ class hesiod\:MIT\ Athena\ Hesiod\ class any\:wildcard\ \(any\ of\ the\ above\)))' - 'domain[change default domain]:default domain:_hosts' + "domain[change default domain]:default domain:_domains" 'srchlist[change default domain and search list]: :->srchlist' 'port[change name server port]:name server port:' {query,}type'[change type of information query]:query information type:((a\:internet\ address cname\:canonical\ name\ for\ alias hinfo\:CPU\ and\ operating\ system\ type minfo\:mailbox\ or\ mail\ list\ information mx\:mail\ exchanger ns\:name\ server\ for\ zone ptr\:host\ name\ or\ other\ information soa\:domain\'"'"'s\ \`start-of-authority\'"'"'\ information txt\:text\ information uinfo\:user\ information wks\:supported\ well-known\ services))' @@ -52,23 +50,25 @@ setopts=( if [[ -n "$compcontext" ]]; then if [[ CURRENT -eq 1 ]]; then - funcall ret _nslookup_command && return ret + _funcall ret _nslookup_command && return ret - _description expl 'command' - compadd "$expl[@]" - server lserver root finger ls view help set && ret=0 - _hosts && ret=0 + _alternative \ + 'commands:command:(server lserver root finger ls view help set exit)' \ + 'hosts:: _hosts' && ret=0 return ret elif [[ "$compstate[context]" = redirect ]]; then - funcall ret _nslookup_redirect && return ret + _funcall ret _nslookup_redirect && return ret + + _tags -C redirection files || return 1 if [[ "$words[1]" != (finger|ls) ]]; then _message "redirection not allowed for command \`$words[1]'" return 1 elif [[ "$compstate[redirect]" = '>' ]]; then - _description expl 'write to file' + _description files expl 'write to file' elif [[ "$compstate[redirect]" = '>>' ]]; then - _description expl 'append to file' + _description files expl 'append to file' else _message "unknown redirection operator \`$compstate[redirect]'" return 1 @@ -79,15 +79,14 @@ if [[ -n "$compcontext" ]]; then fi if [[ "$words[1]" = [a-z]## ]]; then - funcall ret _nslookup_$words[1] && return ret + _funcall ret _nslookup_$words[1] && return ret else - funcall ret _nslookup_host && return ret + _funcall ret _nslookup_host && return ret fi case "$words[1]" in (|l)server) - _description expl 'new default server' - _hosts "$expl[@]" + _wanted hosts expl 'new default server' _hosts return ;; root|exit|help|\?) @@ -104,24 +103,23 @@ if [[ -n "$compcontext" ]]; then '-d[all records]' \ '-h[CPU and operating system information]' \ '-s[well-known services]' \ - ':domain:_hosts' + ":domain:_domains" return ;; view) - _description expl 'view file' + _description files expl 'view file' _files "$expl[@]" return ;; set) - typeset -A values + typeset -A val_args _values 'state information' "$setopts[@]" && ret=0 [[ -z "$state" ]] && return ret ;; *) - _description expl 'server' - _hosts "$expl[@]" + _wanted hosts expl 'server' _hosts return esac fi @@ -130,9 +128,9 @@ fi if [[ -z "$state" ]]; then local line - typeset -A options + typeset -A opt_args - _arguments \ + _arguments -C \ "-${(@)^${(@M)setopts:#*\]:*}/\[/=[}" \ "-${(@)^setopts:#(\(|*\]:)*}" \ "${(@)^${(@)${(@M)setopts:#\(*}/\)/)-}/\(/(-}" \ @@ -143,15 +141,17 @@ fi # This is completion after `srchlist' for both types. if [[ -n "$state" ]]; then + _tags domains || return 1 + if compset -P '*/'; then - _description expl 'search list entry' + _description domains expl 'search list entry' else - _description expl 'default domain name and first search list entry' + _description domains expl 'default domain name and first search list entry' fi if [[ -n "$_vals_cache_multi" ]]; then - _hosts "$expl[@]" -qS/ -r "/\\- \\t\\n$_vals_cache_multi" + _domains "$expl[@]" -qS/ -r "/\\- \\t\\n$_vals_cache_multi" else - _hosts "$expl[@]" -qS/ + _domains "$expl[@]" -qS/ fi return fi diff --git a/Completion/User/_rlogin b/Completion/User/_rlogin index bf8ff751d..2509bd79c 100644 --- a/Completion/User/_rlogin +++ b/Completion/User/_rlogin @@ -28,7 +28,7 @@ _rlogin () { return ret ;; rcp) - local curcontext="$curcontext" state line ret=1 + local curcontext="$curcontext" state line ret=1 expl typeset -A opt_args _arguments -C -s \ @@ -40,7 +40,7 @@ _rlogin () { if compset -P '*:'; then _files && ret=0 elif compset -P '*@'; then - _wanted hosts && _rlogin_hosts -S: -q && ret=0 + _wanted hosts expl host _rlogin_hosts -S: -q && ret=0 else _alternative \ 'files:: _files' \ @@ -54,11 +54,11 @@ _rlogin () { } _rlogin_users () { - _wanted users && _combination -s '[:@]' my-accounts users-hosts users "$@" + _tags users && _combination -s '[:@]' my-accounts users-hosts users "$@" } _rlogin_hosts () { - _wanted hosts && + _tags hosts && if [[ "$IPREFIX" == *@ ]]; then _combination -s '[:@]' my-accounts users-hosts "users=${IPREFIX/@}" hosts "$@" else diff --git a/Completion/User/_socket b/Completion/User/_socket index 353a66fd5..af9c8ab0a 100644 --- a/Completion/User/_socket +++ b/Completion/User/_socket @@ -1,34 +1,55 @@ #compdef socket -local state line expl -typeset -A options +# Style used: +# +# hosts-ports +# The style that contains pairs `host:port'. -_arguments -s \ - -{b,c,f,q,r,v,w} \ - -{s,l} \ - '-p:command:->command' \ +local curcontext="$curcontext" state line expl +typeset -A opt_args + +[[ $CURRENT -eq 2 ]] && + { ! zstyle -T ":completion:${curcontext}:options" prefix-needed || + [[ "$PREFIX" = -* ]] } && + _wanted options expl option \ + compadd -M 'r:|[_-]=* r:|=*' "$expl[@]" - -version + +_arguments -C -s \ + '-b[background]' \ + '-c[crlf]' \ + '-f[fork]' \ + '-q[quit]' \ + '-r[read only]' \ + '-v[verbose]' \ + '-w[write only]' \ + '-s[server]' \ + '-l[loop]' \ + '-p[program]:command:->command' \ ':arg1:->arg1' \ ':arg2:->arg2' case "$state" in command) compset -q - _normal + if [[ $CURRENT -eq 1 ]]; then + _command_names -e "$@" + else + _normal + fi ;; arg1) - if (( $+options[-s] )); then - _message 'port' + if (( $+opt_args[-s] )); then + _ports else - _description expl 'host' - _hosts "$expl[@]" + _wanted hosts expl 'host' _combination '' hosts-ports hosts - fi ;; arg2) - if (( ! $+options[-s] )); then - _description expl 'port' - _hostports $line[2] "$expl[@]" + if (( ! $+opt_args[-s] )); then + _wanted ports expl 'port to connect' \ + _combination '' hosts-ports hosts="${line[1]:q}" ports - fi ;; esac diff --git a/Completion/User/_tiff b/Completion/User/_tiff index 9616009c3..608325fdf 100644 --- a/Completion/User/_tiff +++ b/Completion/User/_tiff @@ -195,12 +195,14 @@ if [[ -n "$state" ]]; then ;; esac else - if _wanted values; then + _tags values + while _tags; do while _next_label values expl 'compression scheme'; do compadd "$expl[@]" - none g4 packbits && ret=0 compadd "$expl[@]" -qS: - lzw zip jpeg g3 && ret=0 done - fi + (( ret )) || return 0 + done fi fi diff --git a/Completion/User/_urls b/Completion/User/_urls index 3989f2219..4234aa274 100644 --- a/Completion/User/_urls +++ b/Completion/User/_urls @@ -49,18 +49,22 @@ local localhttp_userdir="$localhttp[3]" if [[ "$1" = -f ]]; then shift - _wanted -C -f files && _files "$@" && return + _wanted -C -f files _files "$@" && return 0 fi ipre="$IPREFIX" -if ! compset -P '(#b)([-+.a-z0-9]#):' && _wanted -C argument prefixes; then - while _next_label prefixes expl 'URL prefix' "$@"; do - [[ -d $urls_path/bookmark ]] && - compadd "$expl[@]" -S '' bookmark: && ret=0 - compadd "$expl[@]" -S '' file: ftp:// gopher:// http:// && ret=0 +if ! compset -P '(#b)([-+.a-z0-9]#):'; then + _tags -C argument prefixes + while _tags; do + while _next_label prefixes expl 'URL prefix' "$@"; do + [[ -d $urls_path/bookmark ]] && + compadd "$expl[@]" -S '' bookmark: && ret=0 + compadd "$expl[@]" -S '' file: ftp:// gopher:// http:// && ret=0 + done + (( ret )) || return 0 done - return ret + return 1 fi scheme="$match[1]" @@ -73,17 +77,19 @@ case "$scheme" in ;; file) if ! compset -P //; then - _wanted -C file files || return 1 - - while _next_label files expl 'local file' "$@"; do - if [[ -prefix / ]]; then - _path_files "$expl[@]" -S '' -g '*(^/)' && ret=0 - _path_files "$expl[@]" -S/ -r '/' -/ && ret=0 - elif [[ -z "$PREFIX" ]]; then - compadd "$expl[@]" -S '/' -r '/' - "${PWD%/}" && ret=0 - fi + _tags -C file files + while _tags; do + while _next_label files expl 'local file' "$@"; do + if [[ -prefix / ]]; then + _path_files "$expl[@]" -S '' -g '*(^/)' && ret=0 + _path_files "$expl[@]" -S/ -r '/' -/ && ret=0 + elif [[ -z "$PREFIX" ]]; then + compadd "$expl[@]" -S '/' -r '/' - "${PWD%/}" && ret=0 + fi + done + (( ret )) || return 0 done - return ret + return 1 fi ;; bookmark) @@ -93,34 +99,40 @@ case "$scheme" in compadd "$@" -U - \ "$ipre$(<"$urls_path/$scheme/${(Q)PREFIX}${(Q)SUFFIX}")" && ret=0 else - if _wanted -C bookmark files; then + _tags -C bookmark files + while _tags; do while _next_label files expl 'bookmark'; do _path_files -W "$urls_path/$scheme" "$expl[@]" -S '' -g '*(^/)' && ret=0 _path_files -W "$urls_path/$scheme" -S/ -r '/' -/ && ret=0 done - fi + (( ret )) || return 0 + done fi return ret ;; esac # Complete hosts -if ! compset -P '(#b)([^/]#)/' && _wanted hosts; then +if ! compset -P '(#b)([^/]#)/'; then uhosts=($urls_path/$scheme/$PREFIX*$SUFFIX(/:t)) - while _next_label hosts expl host "$@"; do - (( $#uhosts )) || _hosts -S/ && ret=0 - [[ "$scheme" = http ]] && uhosts=($uhosts $localhttp_servername) - compadd "$expl[@]" -S/ - $uhosts && ret=0 + _tags hosts + while _tags; do + while _next_label hosts expl host "$@"; do + (( $#uhosts )) || _hosts -S/ && ret=0 + [[ "$scheme" = http ]] && uhosts=($uhosts $localhttp_servername) + compadd "$expl[@]" -S/ - $uhosts && ret=0 + done + (( ret )) || return 0 done - return ret + return 1 fi host="$match[1]" # Complete part after hostname -_wanted -C local files || return 1 +_tags -C local files || return 1 if [[ "$localhttp_servername" = "$host" ]]; then if compset -P \~; then @@ -129,20 +141,29 @@ if [[ "$localhttp_servername" = "$host" ]]; then return fi user="$match[1]" - while _next_label files expl 'local file'; do - _path_files "$expl[@]" -W ~$user/$localhttp_userdir -g '*(^/)' && ret=0 - _path_files "$expl[@]" -W ~$user/$localhttp_userdir -S/ -r '/' -/ && ret=0 + while _tags; do + while _next_label files expl 'local file'; do + _path_files "$expl[@]" -W ~$user/$localhttp_userdir -g '*(^/)' && ret=0 + _path_files "$expl[@]" -W ~$user/$localhttp_userdir -S/ -r '/' -/ && ret=0 + done + (( ret )) || return 0 done else - while _next_label files expl 'local file'; do - _path_files "$expl[@]" -W $localhttp_documentroot -g '*(^/)' && ret=0 - _path_files "$expl[@]" -W $localhttp_documentroot -S/ -r '/' -/ && ret=0 + while _tags; do + while _next_label files expl 'local file'; do + _path_files "$expl[@]" -W $localhttp_documentroot -g '*(^/)' && ret=0 + _path_files "$expl[@]" -W $localhttp_documentroot -S/ -r '/' -/ && ret=0 + done + (( ret )) || return 0 done fi else - while _next_label files expl 'local file'; do - _path_files "$expl[@]" -W $urls_path/$scheme/$host -g '*(^/)' && ret=0 - _path_files "$expl[@]" -W $urls_path/$scheme/$host -S/ -r '/' -/ && ret=0 + while _tags; do + while _next_label files expl 'local file'; do + _path_files "$expl[@]" -W $urls_path/$scheme/$host -g '*(^/)' && ret=0 + _path_files "$expl[@]" -W $urls_path/$scheme/$host -S/ -r '/' -/ && ret=0 + done + (( ret )) || return 0 done fi return $ret diff --git a/Completion/User/_users b/Completion/User/_users index d04731af9..dce0fd584 100644 --- a/Completion/User/_users +++ b/Completion/User/_users @@ -2,9 +2,7 @@ local expl users -_wanted users || return 1 - zstyle -a ":completion:${curcontext}:" users users && - _all_labels users expl user compadd "$@" - "$users[@]" && return 0 + _wanted users expl user compadd "$@" - "$users[@]" && return 0 -_all_labels users expl user compadd "$@" - "${(@k)userdirs}" +_wanted users expl user compadd "$@" - "${(@k)userdirs}" diff --git a/Completion/User/_users_on b/Completion/User/_users_on index b19cff6e7..b5c05e12b 100644 --- a/Completion/User/_users_on +++ b/Completion/User/_users_on @@ -2,10 +2,8 @@ local expl -_wanted users || return 1 - -if which users >/dev/null; then - _all_labels users expl 'users logged on' \ +if (( $+commands[users] )); then + _wanted users expl 'users logged on' \ compadd "$@" - $(_call users users) && return 0 else # Other methods of finding out users logged on should be added here diff --git a/Completion/User/_whois b/Completion/User/_whois index 827ebe627..4b6d73b86 100644 --- a/Completion/User/_whois +++ b/Completion/User/_whois @@ -1,12 +1,14 @@ -#compdef whois +#compdef whois fwhois _whois () { - setopt localoptions extendedglob _whois_setup - $_whois_comp + case "$0" in + fwhois) _whois_fwhois;; + *) $_whois_comp;; + esac } -builtin functions _whois_setup >&- || +(( $+functions[_whois_setup] )) || _whois_setup () { (( $+_whois_defaultserver )) || _whois_defaultserver='whois.internic.net' @@ -65,6 +67,7 @@ _whois_setup () { (( $+_whois_arguments )) || { local help="$(whois </dev/null 2>&1)" local tmp opt opts + local hostopt=-h+ if [[ $help = *"user[@<whois.server>]"* ]]; then _whois_comp=_whois_fwhois @@ -72,6 +75,7 @@ _whois_setup () { _whois_comp=_whois_multi else _whois_comp=_whois_single + hostopt=-h fi _whois_arguments=() @@ -96,25 +100,29 @@ _whois_setup () { for opt in $tmp; do opts=(-${^tmp:#$opt}) if (( $#opts )); then opts="($opts)"; else opts=; fi - _whois_arguments=("$_whois_arguments[@]" - "${opts}-${opt}[${${${(@M)_whois_servers:#*:$opt}%:?}:-specify host}]${(M)${(M)opt:#h}/h/:host:_whois_hosts}" - ) + if [[ $opt = h ]]; then + _whois_arguments=("$_whois_arguments[@]" + "${opts}${hostopt}:host:_whois_hosts") + else + _whois_arguments=("$_whois_arguments[@]" + "${opts}-${opt}[${${(@M)_whois_servers:#*:$opt}%:?}]") + fi done } } _whois_single () { - local state line expl + local curcontext="$curcontext" state line expl typeset -A opt_args local tmp host - _arguments \ + _arguments -C \ "$_whois_arguments[@]" \ ':identifier:->identifier' case "$state" in identifier) - if [[ -z "$QIPREFIX" ]]; then + if [[ -z "$QIPREFIX" && -z "$PREFIX" ]]; then compadd -QS '' \' return fi @@ -126,7 +134,7 @@ _whois_single () { break fi done - if builtin functions "_whois:$host" >&-; then + if (( $+functions[_whois:$host] )); then "_whois:$host" "$expl[@]" else _message "identifier" @@ -136,11 +144,11 @@ _whois_single () { } _whois_multi () { - local state line expl + local curcontext="$curcontext" state line expl typeset -A opt_args local tmp host - _arguments \ + _arguments -C \ "$_whois_arguments[@]" \ '*::identifier:->identifier' @@ -153,7 +161,7 @@ _whois_multi () { break fi done - if builtin functions "_whois:$host" >&-; then + if (( $+functions[_whois:$host] )); then "_whois:$host" "$expl[@]" else _message "identifier" @@ -166,13 +174,13 @@ _whois_fwhois () { if compset -P '*@'; then _whois_hosts "$@" else - if [[ -z "$QIPREFIX" ]]; then + if [[ -z "$QIPREFIX" && -z "$PREFIX" ]]; then compadd -QS '' \' return fi compset -q host="$_whois_defaultserver" - if builtin functions "_whois:$host" >&-; then + if (( $+functions[_whois:$host] )); then "_whois:$host" "$@" else _message "identifier" @@ -181,28 +189,33 @@ _whois_fwhois () { } _whois_hosts () { - compadd "$@" \ - -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' \ - - ${_whois_servers%:?} || _hosts "$@" + _tags hosts && + compadd "$@" \ + -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' \ + - ${_whois_servers%:?} || _hosts "$@" } _whois_ports () { - compadd "$@" - whois || _ports "$@" + _tags ports && compadd "$@" - whois || _ports "$@" } -builtin functions _whois:whois.internic.net >&- || +(( $+functions[_whois:whois.internic.net] )) || _whois:whois.internic.net () { if (( CURRENT == 1 )); then - compadd HELP DOMAIN HOST + local expl + + _wanted strings expl string compadd HELP DOMAIN HOST else _message 'string' fi } -builtin functions _whois:whois.nic.ad.jp >&- || +(( $+functions[_whois:whois.nic.ad.jp] )) || _whois:whois.nic.ad.jp () { if (( CURRENT == 1 )); then - compadd HELP DOM NET HOST PERSON CONN COM + local expl + + _wanted strings expl string compadd HELP DOM NET HOST PERSON CONN COM else _message 'string' fi diff --git a/Completion/X/_x_colormapid b/Completion/X/_x_colormapid index 3c637c1d9..61b0a72f1 100644 --- a/Completion/X/_x_colormapid +++ b/Completion/X/_x_colormapid @@ -2,7 +2,7 @@ local expl list desc -_wanted colormapids || return 1 +_tags colormapids || return 1 list=(${(f)"$(xprop -root -f RGB_COLOR_MAP 32xcccccccxx ': $0\n'|awk -F'[ ():]' '/^[a-zA-Z_]+\(RGB_COLOR_MAP\)/ {print $5, "--", $1}')"}) @@ -12,5 +12,5 @@ else desc=() fi -_all_labels colormapids expl 'colormap id' \ +_wanted colormapids expl 'colormap id' \ compadd "$@" "$desc[@]" - "${(@)list%% *}" diff --git a/Completion/X/_x_display b/Completion/X/_x_display index 94c3fa9a4..f547a64fa 100644 --- a/Completion/X/_x_display +++ b/Completion/X/_x_display @@ -1,3 +1,3 @@ #autoload -_wanted displays && _hosts -S ':0 ' -r : +_tags displays && _hosts -S ':0 ' -r : diff --git a/Completion/X/_x_extension b/Completion/X/_x_extension index 11e53fa6c..5b742a78c 100644 --- a/Completion/X/_x_extension +++ b/Completion/X/_x_extension @@ -2,18 +2,18 @@ local expl -_wanted extensions || return 1 +_tags extensions || return 1 (( $+_xe_cache )) || _xe_cache=( "${(@)${(@f)$(xdpyinfo)}[(r)number of extensions:*,-1][2,(r)default screen number:*][1,-2]//[ ]}" ) if [[ "$1" = -a ]]; then shift - _all_labels extensions expl 'X extensions' \ + _wanted extensions expl 'X extensions' \ compadd "$@" -M 'm:{a-z}={A-Z} r:|-=* r:|=*' - all "$_xe_cache[@]" else [[ "$1" = - ]] && shift - _all_labels extensions expl 'X extensions' \ + _wanted extensions expl 'X extensions' \ compadd "$@" -M 'm:{a-z}={A-Z} r:|-=* r:|=*' - "$_xe_cache[@]" fi diff --git a/Completion/X/_x_font b/Completion/X/_x_font index 43a713b34..228542bd2 100644 --- a/Completion/X/_x_font +++ b/Completion/X/_x_font @@ -2,7 +2,7 @@ local expl -_wanted fonts || return 1 +_tags fonts || return 1 # This *has* to be improved some day... @@ -12,5 +12,5 @@ if (( ! $+_font_cache )); then _font_cache=( "${(@)^${(@f)$(_call fonts xlsfonts)}%%--*}--" ) fi -_all_labels fonts expl font \ +_wanted fonts expl font \ compadd -M 'r:|-=* r:|=*' "$@" -S '' - "$_font_cache[@]" diff --git a/Completion/X/_x_keysym b/Completion/X/_x_keysym index f50762f7e..8d4cfa1f8 100644 --- a/Completion/X/_x_keysym +++ b/Completion/X/_x_keysym @@ -2,7 +2,7 @@ local expl -_wanted keysyms || return 1 +_tags keysyms || return 1 if (( ! $+_keysym_cache )); then local file @@ -18,5 +18,5 @@ if (( ! $+_keysym_cache )); then fi fi -_all_labels keysyms expl 'key symbol' \ +_wanted keysyms expl 'key symbol' \ compadd "$@" -M 'm:{a-z}={A-Z} r:|-=* r:|=*' - $_keysym_cache diff --git a/Completion/X/_x_window b/Completion/X/_x_window index 1862db9a7..24d6048a7 100644 --- a/Completion/X/_x_window +++ b/Completion/X/_x_window @@ -2,17 +2,17 @@ local list expl -_wanted windows || return 1 +_tags windows || return 1 list=( "${(@)${(M@)${(@f)$(_call windows xwininfo -root -tree)}:#[ ]#0x[0-9a-f]# \"*}##[ ]#}" ) if [[ "$1" = -n ]]; then shift - _all_labels windows expl 'window name' \ + _wanted windows expl 'window name' \ compadd "$@" -d list - "${(@)${(@)list#*\"}%%\"*}" else [[ "$1" = - ]] && shift - _all_labels windows expl 'window ID' compadd "$@" -d list - "${(@)list%% *}" + _wanted windows expl 'window ID' compadd "$@" -d list - "${(@)list%% *}" fi diff --git a/Completion/X/_xmodmap b/Completion/X/_xmodmap index 6595d5adf..5c7fcf3fe 100644 --- a/Completion/X/_xmodmap +++ b/Completion/X/_xmodmap @@ -82,12 +82,14 @@ if [[ -n "$state" ]]; then [[ "$what" = *ksym* ]] && _x_keysym "$suf[@]" && ret=0 else - if _wanted commands; then + _tags commands + while _tags; do while _next_label commands expl command; do compadd "$expl[@]" -S ' ' keycode keysym clear add remove && ret=0 compadd "$expl[@]" -S ' = ' pointer && ret=0 done - fi + (( ret )) || return 0 + done fi fi diff --git a/Completion/X/_xutils b/Completion/X/_xutils index a57f7be36..c0d94a998 100644 --- a/Completion/X/_xutils +++ b/Completion/X/_xutils @@ -55,23 +55,29 @@ xhost) if [[ "$tmp" = *:* ]]; then if compset -P '(#b)(*):'; then type="$match[1]" - _wanted displays && - while _next_label displays expl 'disallow access'; do + _tags displays + while _tags; do + while _next_label displays expl 'disallow access'; do { compadd "$expl[@]" -M 'm:{a-z}={A-Z} r:|[:.]=* r:|=*' - \ ${${(M)tmp:#(#i)$type:*}#(#i)$type:} || - _hosts "$expl[@]" } && return 0 - done + _hosts "$expl[@]" } && ret=0 + done + (( ret )) || return 0 + done else _alternative \ 'types:name family:compadd -S: ${(L)tmp%%:*}' \ 'hosts:host:compadd ${(@)tmp#*:}' && ret=0 fi else - _wanted displays && - while _next_label displays expl 'disallow access'; do - { compadd "$expl[@]" -M 'm:{a-z}={A-Z} r:|[:.]=* r:|=*' - $tmp || - _hosts "$expl[@]" } && return 0 - done + _tags displays + while _tags; do + while _next_label displays expl 'disallow access'; do + { compadd "$expl[@]" -M 'm:{a-z}={A-Z} r:|[:.]=* r:|=*' - $tmp || + _hosts "$expl[@]" } && ret=0 + done + (( ret )) || return 0 + done fi else compset -P + diff --git a/Completion/X/_xwit b/Completion/X/_xwit index 998627869..69b210e5b 100644 --- a/Completion/X/_xwit +++ b/Completion/X/_xwit @@ -17,7 +17,7 @@ _xwit_guard () { _xwit_compopts () { local expl _wanted options expl option compadd - ${(k)no[(R)*~0]} || - _all_labels options expl option compadd - ${(k)no} + _wanted options expl option compadd - ${(k)no} } _regex_arguments _xwit_parse \ diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index 29a259f34..55d2c292d 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -945,15 +945,19 @@ expected by the caller of tt(_files). If the tt(file-patterns) style is set, the default tags are not used. Instead, the value of the style says which tags and which -patterns are to be offered. The strings in the value are of the form -`var(patterns)tt(:)var(tag)'. The var(patterns) gives one or more glob -patterns separated by spaces that are to be used to generate +patterns are to be offered. The strings in the value contain +specifications of the form +`var(patterns)tt(:)var(tag)'; each string may contain any number of +such specifications. The var(patterns) give one or more glob +patterns separated by commas that are to be used to generate filenames. If it contains the sequence `tt(%p)', that is replaced by the pattern(s) given by the calling function. Colons in the pattern have to be preceded by a backslash to make them distinguishable from the colon before the var(tag). The var(tag)s of all strings in the value will be offered by tt(_files) -(again, one after another) and used when looking up other styles. If +(again, one after another) and used when looking up other styles. For +strings containing more than one specification, the filenames for all +specifications will be generated at the same try. If no `tt(:)var(tag)' is given the `tt(files)' tag will be used. The var(tag) may also be followed by an optional second colon and a description. If that is @@ -978,7 +982,7 @@ directories in the first try and all files as the second try. To achieve this, one could do: example(zstyle ':completion:*' file-patterns \ - '%p *(-/):globbed-files' '*:all-files') + '%p:globbed-files *(-/):directories' '*:all-files') Note also that during the execution of completion functions, the tt(EXTENDED_GLOB) option is in effect, so the characters `tt(#)', @@ -2216,22 +2220,12 @@ var(N), complete the var(N)th most recently modified file. Note the completion, if any, is always unique. ) findex(_next_tags) -item(tt(_next_tags))( +item(tt(_next_tags) (^Xn))( This allows to complete types of matches that are not immediately offered because of the setting of the tt(tag-order) style. After a normal completion was tried, invoking this command makes the matches for the next tag (or set of tags) be used. Repeatedly invoking this -command makes the following tags be used. To be able to complete the -matches selected by tt(_next_tags), the tt(completer) style should -contain tt(_next_tags) as its first string. With that, the normal key -binding (normally tt(TAB)) can be used to complete the matches shown -after the call to tt(_next_tags). - -Normally, this command is not bound to a key. To invoke it with, say -`tt(^Xn)', one would use: - -example(zle -C _next_tags complete-word _next_tags -bindkey '^Xn' _next_tags) +command makes the following tags be used. ) findex(_read_comp (^X^R)) item(tt(_read_comp (^X^R)))( @@ -2442,7 +2436,7 @@ user to the tt(tag-order) style is prefered over the one given to tt(_next_label). Note that this function must not be called without a previous call to -tt(_tags), tt(_wanted) or tt(_requested) because it uses the tag label +tt(_tags) or tt(_requested) because it uses the tag label for the current tag found by these functions. A normal use of this function for the tag labels for the tag tt(foo) @@ -2450,12 +2444,13 @@ looks like this: example(local expl ret=1 ... -_wanted foo || return 1 -... -while _next_label foo expl '...'; do - compadd "$expl[@]" ... && ret=0 -done -... +if _requested foo; then + ... + while _next_label foo expl '...'; do + compadd "$expl[@]" ... && ret=0 + done + ... +fi return ret ) ) @@ -2477,9 +2472,10 @@ For example: example(local expl ... -_wanted foo || return 1 -... -_all_labels foo expl '...' compadd ... - $matches) +if _requested foo; then + ... + _all_labels foo expl '...' compadd ... - $matches +fi) Will complete the strings from the tt(matches) parameter, using tt(compadd) with additional options which will take precedence over @@ -2525,7 +2521,7 @@ while _tags; do done) ) findex(_wanted) -item(tt(_wanted) [ tt(-12VJ) ] var(tag) var(name) var(descr) [ var(specs) ... ])( +item(tt(_wanted) [ tt(-12VJ) ] var(tag) var(name) var(descr) var(command) var(args) ...)( In many contexts only one type of matches can be generated but even then it should be tested if the tag representing those matches is requested by the user. This function makes that easier. @@ -2538,6 +2534,10 @@ description built, you can just do: example(_wanted tag expl 'description' \ compadd matches...) + +Unlike tt(_requested), however, tt(_wanted) can not be called without +the var(command). That's because tt(_wanted) also implements the loop +over the tags, not only the one for the labels. ) findex(_alternative) item(tt(_alternative) [ tt(-C) var(name) ] var(specs) ...)( diff --git a/Etc/completion-style-guide b/Etc/completion-style-guide index d57a1a7fb..71b5c9a5c 100644 --- a/Etc/completion-style-guide +++ b/Etc/completion-style-guide @@ -63,12 +63,12 @@ example). Then, before adding the matches, see if matches of that type are requested by the user in the current context. If you will add only one type of matches, this is very simple. You can use the function -`_wanted' for this. Its return value is zero only if the type of -matches is requested by the user, so you can just do: +`_wanted' for this. Well, you can often use it, that is. Use it as in: - _wanted names || return 1 + _wanted names expl 'name' compadd - alice bob - _all_labels names expl 'name' compadd - alice bob +This is like testing if the tag `names' is requested by the user and +then calling `_all_labels' with the same arguments. The `_all_labels' function implements the loop over the tag aliases and handles the user-defined description, using (in the example) the @@ -88,13 +88,6 @@ the last argument. A good example for such a function is And the `-' will be replaced by the options that are to be given to `compadd'. -Since the above sequence of command is used so often, the `_wanted' -function can also accept the same arguments as `_all_labels'. In this -case it will do the test for the requested tag and then just call -`_all_labels', so: - - _wanted names expl 'name' compadd - alice bob - Note that you can also give the `-J' and `-V' options with the optional `1' or `2' preceding them supported by `_description': @@ -332,11 +325,11 @@ often be using the tags function that allows you to give the explanation to the same function that is used to test if the tags are requested (again: see above). Just as a reminder: - _wanted [ -[1,2]V | -[1,2]J ] <tag> expl <descr> + _wanted [ -[1,2]V | -[1,2]J ] <tag> expl <descr> <cmd> ... and - _requested [ -[1,2]V | -[1,2]J ] <tag> expl <descr> + _requested [ -[1,2]V | -[1,2]J ] <tag> expl <descr> [ <cmd> ... ] is all you need to make your function work correctly with both tags and description at the same time. diff --git a/Functions/Zftp/zfcd_match b/Functions/Zftp/zfcd_match index b5902cdde..8e2b6452a 100644 --- a/Functions/Zftp/zfcd_match +++ b/Functions/Zftp/zfcd_match @@ -30,7 +30,7 @@ if [[ $ZFTP_SYSTEM = UNIX* ]]; then rm -f $tmpf [[ -n $dir && $dir != */ ]] && dir="$dir/" if [[ -n $WIDGET ]]; then - _all_labels directories expl 'remote directory' + _wanted directories expl 'remote directory' compadd -S/ -q -P "$dir" - $reply elif [[ -n $dir ]]; then reply=(${dir}$reply) diff --git a/Functions/Zftp/zfget_match b/Functions/Zftp/zfget_match index 0fe2bc06f..1d90bea60 100644 --- a/Functions/Zftp/zfget_match +++ b/Functions/Zftp/zfget_match @@ -17,7 +17,7 @@ if [[ $ZFTP_SYSTEM == UNIX* && $1 == */* ]]; then local reply reply=(${${${(f)"$(<$tmpf)"}##$dir}%\*}) rm -f $tmpf - _all_labels files expl 'remote file' compadd -P $dir - $reply + _wanted files expl 'remote file' compadd -P $dir - $reply else # On the first argument to ls, we usually get away with a glob. zftp ls "$1*$2" >$tmpf @@ -28,7 +28,7 @@ else local fcache_name zffcache if [[ -n $WIDGET ]]; then - _all_labels files expl 'remote file' compadd -F fignore - ${(P)fcache_name} + _wanted files expl 'remote file' compadd -F fignore - ${(P)fcache_name} else reply=(${(P)fcache_name}); fi diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index e73fe8eaf..09746c1bb 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -2291,7 +2291,7 @@ bin_comptags(char *nam, char **args, char *ops, int func) case 'N': min = 0; max = 0; break; case 'R': min = 1; max = 1; break; case 'S': min = 1; max = 1; break; - case 'A': min = 2; max = 2; break; + case 'A': min = 2; max = 3; break; default: zwarnnam(nam, "invalid option: %s", args[0], 0); return 1; @@ -2365,6 +2365,14 @@ bin_comptags(char *nam, char **args, char *ops, int func) } s->ptr = q + 1; setsparam(args[2], ztrdup(*v == '-' ? dyncat(args[1], v) : v)); + if (args[3]) { + char *r = dupstring(*q), *p; + + for (p = r + (v - *q); *p && *p != ':'; p++); + *p = '\0'; + + setsparam(args[3], ztrdup(r)); + } return 0; } return 1; |