From e6282df1155e8d9b08b2e518a452c1997973f1ce Mon Sep 17 00:00:00 2001 From: Tanaka Akira Date: Fri, 12 Nov 1999 15:28:24 +0000 Subject: manual/8630 --- Completion/Base/_arguments | 41 ++++-- Completion/Base/_brace_parameter | 2 +- Completion/Base/_command_names | 45 +++---- Completion/Base/_condition | 11 +- Completion/Base/_default | 7 +- Completion/Base/_describe | 12 +- Completion/Base/_equal | 11 +- Completion/Base/_jobs | 18 ++- Completion/Base/_math | 2 +- Completion/Base/_parameter | 2 +- Completion/Base/_subscript | 49 +++++--- Completion/Base/_tilde | 69 +++++----- Completion/Base/_values | 35 ++++-- Completion/Base/_vars | 10 +- Completion/Builtins/_aliases | 7 +- Completion/Builtins/_arrays | 2 + Completion/Builtins/_autoload | 2 + Completion/Builtins/_bindkey | 4 + Completion/Builtins/_builtin | 2 + Completion/Builtins/_cd | 7 +- Completion/Builtins/_command | 2 + Completion/Builtins/_compdef | 4 + Completion/Builtins/_disable | 29 ++--- Completion/Builtins/_echotc | 2 + Completion/Builtins/_enable | 29 ++--- Completion/Builtins/_functions | 2 + Completion/Builtins/_hash | 8 ++ Completion/Builtins/_kill | 4 +- Completion/Builtins/_limits | 2 + Completion/Builtins/_pids | 13 +- Completion/Builtins/_popd | 55 ++++---- Completion/Builtins/_sched | 11 +- Completion/Builtins/_stat | 2 + Completion/Builtins/_trap | 2 + Completion/Builtins/_unhash | 28 ++--- Completion/Builtins/_wait | 2 +- Completion/Builtins/_which | 20 ++- Completion/Builtins/_zftp | 14 ++- Completion/Builtins/_zle | 2 + Completion/Builtins/_zmodload | 3 + Completion/Core/_alternative | 25 ++-- Completion/Core/_complete | 7 +- Completion/Core/_files | 16 +-- Completion/Core/_main_complete | 5 +- Completion/Core/_message | 2 + Completion/Core/_normal | 1 + Completion/Core/_options | 2 + Completion/Core/_parameters | 2 + Completion/Core/_requested | 10 +- Completion/Core/_set_options | 2 + Completion/Core/_sort_tags | 28 +++++ Completion/Core/_style | 55 ++++---- Completion/Core/_tags | 123 +++++++++--------- Completion/Core/_unset_options | 2 + Completion/Core/compinit | 266 +++++++-------------------------------- Completion/Linux/_rpm | 12 +- Completion/User/_archie | 8 +- Completion/User/_flex | 2 +- Completion/User/_gcc | 4 +- Completion/User/_gprof | 6 +- Completion/User/_groups | 2 + Completion/User/_gs | 10 +- Completion/User/_hosts | 2 + Completion/User/_lynx | 2 +- Completion/User/_mount | 29 +++-- Completion/User/_mutt | 23 ++-- Completion/User/_netscape | 71 +++++++---- Completion/User/_nslookup | 14 ++- Completion/User/_pbm | 4 +- Completion/User/_ports | 2 + Completion/User/_rlogin | 19 ++- Completion/User/_socket | 17 ++- Completion/User/_ssh | 115 ++++++++++------- Completion/User/_telnet | 18 +-- Completion/User/_tiff | 4 +- Completion/User/_urls | 19 ++- Completion/User/_user_at_host | 10 +- Completion/User/_users | 2 + Completion/User/_users_on | 2 + Completion/User/_wget | 2 +- Completion/User/_whois | 23 +++- Completion/User/_yp | 33 +++-- Completion/X/_x_color | 2 + Completion/X/_x_cursor | 2 + Completion/X/_x_display | 2 + Completion/X/_x_extension | 2 + Completion/X/_x_font | 2 + Completion/X/_x_keysym | 2 + Completion/X/_x_modifier | 2 + Completion/X/_x_window | 2 + Completion/X/_xmodmap | 10 +- Doc/Zsh/compsys.yo | 20 ++- Src/Zle/computil.c | 64 ++++++++-- 93 files changed, 940 insertions(+), 743 deletions(-) create mode 100644 Completion/Core/_sort_tags diff --git a/Completion/Base/_arguments b/Completion/Base/_arguments index 68b52eef4..fbc7d7875 100644 --- a/Completion/Base/_arguments +++ b/Completion/Base/_arguments @@ -3,7 +3,7 @@ # Complete the arguments of the current command according to the # descriptions given as arguments to this function. -local long cmd="$words[1]" descr mesg +local long cmd="$words[1]" descr mesg subopts long=$argv[(I)--] if (( long )); then @@ -151,17 +151,30 @@ if (( long )); then set -- "$tmpargv[@]" "${(@P)name}" fi +if [[ "$1" = -O?* ]]; then + subopts=( "${(@P)1[3,-1]}" ) + shift +elif [[ "$1" = -O ]]; then + subopts=( "${(@P)1}" ) + shift 2 +else + subopts=() +fi + if comparguments -i "$compconfig[autodescribe_options]" "$@"; then local nm="$compstate[nmatches]" action noargs aret expl local local next direct odirect equal single match matched ws tmp1 tmp2 - local opts + local opts _sub_context oldsc="${_sub_context}" if comparguments -D descr action; then + comparguments -C _sub_context + _sub_context="${oldsc}:${oldsc:+${oldsc}-}${_sub_context}" + if comparguments -O next direct odirect equal; then opts=yes - _tags argument option + _tags "${oldsc}:any" arguments options else - _tags argument + _tags "${oldsc}:any" arguments fi else if comparguments -a; then @@ -172,12 +185,12 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then comparguments -O next direct odirect equal || return 1 opts=yes - _tags option + _tags "${oldsc}:any" options fi while _tags; do while true; do - if [[ -n "$matched" ]] || _requested argument; then + if [[ -n "$matched" ]] || _requested arguments; then _description expl "$descr" if [[ "$action" = -\>* ]]; then @@ -207,13 +220,13 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then eval ws\=\( "${action[3,-3]}" \) - _describe -c "$cmd" "$descr" ws -M "$match" + _describe -c "$cmd" "$descr" ws -M "$match" "$subopts[@]" elif [[ "$action" = \(*\) ]]; then # Anything inside `(...)' is added directly. - compadd "$expl[@]" - ${=action[2,-2]} + compadd "$subopts[@]" "$expl[@]" - ${=action[2,-2]} elif [[ "$action" = \{*\} ]]; then # A string in braces is evaluated. @@ -230,12 +243,13 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then # Otherwise we call it with the description-arguments built above. action=( $=action ) - ${(e)action[1]} "$expl[@]" ${(e)~action[2,-1]} + ${(e)action[1]} "$subopts[@]" "$expl[@]" ${(e)~action[2,-1]} fi fi fi - if [[ -z "$matched" ]] && _requested option && - { ! _style option prefix || [[ "$PREFIX" = [-+]* ]] } ; then + if [[ -z "$matched" ]] && _requested options && + { ! _style options prefix-needed yes || + [[ "$PREFIX" = [-+]* ]] } ; then comparguments -M match if comparguments -s single; then @@ -267,7 +281,7 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then fi if [[ -n "$opts" && -z "$aret$matched" && nm -ne compstate[nmatches] ]] && - _requested argument; then + _requested arguments; then local prefix suffix @@ -282,7 +296,8 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then SUFFIX="$suffix" IPREFIX="${IPREFIX}${equal[1]%%:*}=" matched=yes - comparguments -L "$equal[1]" descr action + comparguments -L "$equal[1]" descr action _sub_context + _sub_context="${oldsc}:${oldsc+${oldsc}-}${_sub_context}" continue fi fi diff --git a/Completion/Base/_brace_parameter b/Completion/Base/_brace_parameter index 9ed4867ef..1d1a48c78 100644 --- a/Completion/Base/_brace_parameter +++ b/Completion/Base/_brace_parameter @@ -1,6 +1,6 @@ #compdef -brace-parameter- -_parameters -e +_tags any parameters && _parameters -e # Without the `-e' option, we would use the following (see the file diff --git a/Completion/Base/_command_names b/Completion/Base/_command_names index 889b330bd..8d8f5630f 100644 --- a/Completion/Base/_command_names +++ b/Completion/Base/_command_names @@ -4,38 +4,27 @@ # complete only external commands and executable files. This and a # `-' as the first argument is then removed from the arguments. -local nm=$compstate[nmatches] ret=1 expl ext +local args defs + +defs=( + 'commands:external command:compadd - ${(@k)commands}' + 'executables:executable file or directory:_path_files -/g \*\(\*\)' +) if [[ "$1" = -e ]]; then - ext=yes - shift -elif [[ "$1" = - ]]; then shift -fi +else + [[ "$1" = - ]] && shift -# Complete jobs in implicit fg and bg -if [[ -z "$ext" && "$PREFIX[1]" = "%" ]]; then - _jobs - [[ nm -ne compstate[nmatches] ]] && return + defs=( "$defs[@]" + 'jobs:: _jobs' + 'builtins:builtin command:compadd - ${(@k)builtins}' + 'functions:shell function:compadd - ${(@k)functions}' + 'aliases:alias:compadd - ${(@k)aliases}' + 'reserved-words:reserved word:compadd - ${(@k)reswords}' + ) fi -_description expl 'external command' -compadd "$expl[@]" "$@" - "${(k@)commands}" && ret=0 +args=( "$@" ) -if [[ -z "$ext" ]]; then - _description expl 'builtin command' - compadd "$expl[@]" "$@" - "${(k@)builtins}" && ret=0 - _description expl 'shell function' - compadd "$expl[@]" "$@" - "${(k@)functions}" && ret=0 - _description expl 'alias' - compadd "$expl[@]" "$@" - "${(k@)aliases}" && ret=0 - _description expl 'reserved word' - compadd "$expl[@]" "$@" - "${(k@)reswords}" && ret=0 -fi - -if [[ nm -eq compstate[nmatches] ]]; then - _description expl 'executable file or directory' - _path_files "$expl[@]" "$@" -/g "*(*)" -else - return ret -fi +_alternative -O args any "$defs[@]" diff --git a/Completion/Base/_condition b/Completion/Base/_condition index 84c9fea20..93bbdc7f4 100644 --- a/Completion/Base/_condition +++ b/Completion/Base/_condition @@ -3,14 +3,13 @@ local prev="$words[CURRENT-1]" if [[ "$prev" = -o ]]; then + _tags - -o options || return 1 + _options elif [[ "$prev" = -([no]t|ef) ]]; then + _tags - "$prev" files || return 1 + _files else - local ret=1 - - _files && ret=0 - _parameters && ret=0 - - return ret + _alternative any 'files:: _files' 'parameters:: _parameters' fi diff --git a/Completion/Base/_default b/Completion/Base/_default index 4fb0b36dd..cf4077d3b 100644 --- a/Completion/Base/_default +++ b/Completion/Base/_default @@ -14,12 +14,13 @@ local expl # compcall || return 0 +_tags any files || return 1 + _description expl file _files "$expl[@]" && return # magicequalsubst allows arguments like =~/foo to do # file name expansion after the =. In that case, it's natural to # allow completion to handle file names after any equals sign. -if [[ -o magicequalsubst ]] && compset -P 1 '*='; then - _files "$expl[@]" -fi + +[[ -o magicequalsubst ]] && compset -P 1 '*=' && _files "$expl[@]" diff --git a/Completion/Base/_describe b/Completion/Base/_describe index 41c2ba8e5..db2011727 100644 --- a/Completion/Base/_describe +++ b/Completion/Base/_describe @@ -2,8 +2,8 @@ # This can be used to add options or values with descriptions as matches. -local cmd opt expl tmps tmpd tmpmd tmpms ret=1 showd _nm hide -local type=value +local cmd opt expl tmps tmpd tmpmd tmpms ret=1 showd _nm hide args +local type=values cmd="$words[1]" @@ -11,7 +11,7 @@ cmd="$words[1]" while getopts 'oc:' opt; do if [[ "$opt" = o ]]; then - type=option + type=options else cmd="$OPTARG" fi @@ -20,9 +20,9 @@ shift OPTIND-1 # Do the tests. `showd' is set if the descriptions should be shown. -_tags -c "$cmd" "$type" || return 1 +_tags -c "$cmd" any "$type" || return 1 -_style "$type" describe && showd=yes +_style "$type" description yes && showd=yes _description expl "$1" shift @@ -33,7 +33,7 @@ else compdescribe -i "$@" fi -[[ "$type" = option ]] && _style option hide && hide=yes +[[ "$type" = options ]] && _style options prefix-hidden yes && hide=yes while compdescribe -g args tmpd tmpmd tmps tmpms; do diff --git a/Completion/Base/_equal b/Completion/Base/_equal index c50741ed4..760f85c68 100644 --- a/Completion/Base/_equal +++ b/Completion/Base/_equal @@ -1,8 +1,9 @@ #compdef -equal- -local expl +local args -_description expl alias -compadd "$@" "$expl[@]" - "${(@k)aliases}" -_description expl command -compadd "$@" "$expl[@]" - "${(k@)commands}" +args=( "$@" ) + +_alternative -O args any \ + 'commands:command:compadd - ${(@k)commands}' \ + 'aliases:alias:compadd - ${(@k)aliases}' diff --git a/Completion/Base/_jobs b/Completion/Base/_jobs index 869aeeb8a..ba83d784e 100644 --- a/Completion/Base/_jobs +++ b/Completion/Base/_jobs @@ -1,6 +1,12 @@ #autoload -local expl disp jobs job jids +local expl disp jobs job jids pfx='%' desc + +_tags any jobs || return 1 + +_style jobs prefix-needed yes && [[ "$PREFIX" != %* ]] && return 1 +_style jobs prefix-hidden yes && pfx='' +_style jobs description yes && desc=yes if [[ "$1" = -r ]]; then jids=( "${(@k)jobstates[(R)running*]}" ) @@ -19,9 +25,13 @@ fi disp=() jobs=() for job in "$jids[@]"; do - disp=( "$disp[@]" "${(l:3:: ::%:)job} -- ${jobtexts[$job]}" ) + [[ -n "$desc" ]] && + disp=( "$disp[@]" "${pfx}${(r:2:: :)job} -- ${(r:COLUMNS-8:: :)jobtexts[$job]}" ) jobs=( "$jobs[@]" "$job" ) done -compadd "$@" "$expl[@]" -ld disp - "%$^jobs[@]" - +if [[ -n "$desc" ]]; then + compadd "$@" "$expl[@]" -ld disp - "%$^jobs[@]" +else + compadd "$@" "$expl[@]" - "%$^jobs[@]" +fi diff --git a/Completion/Base/_math b/Completion/Base/_math index b9743d6b4..77d97acf1 100644 --- a/Completion/Base/_math +++ b/Completion/Base/_math @@ -9,4 +9,4 @@ if [[ "$SUFFIX" = *[^a-zA-Z0-9_]* ]]; then SUFFIX="${SUFFIX%%[^a-zA-Z0-9_]*}" fi -_parameters +_tags any parameters && _parameters diff --git a/Completion/Base/_parameter b/Completion/Base/_parameter index 1ede49e27..3ed91d620 100644 --- a/Completion/Base/_parameter +++ b/Completion/Base/_parameter @@ -1,6 +1,6 @@ #compdef -parameter- -_parameters -e +_tags any parameters && _parameters -e # Without the `-e' option, we would use the following (see the file # Core/_parameters for more enlightenment). diff --git a/Completion/Base/_subscript b/Completion/Base/_subscript index 803893912..c5c6ca7e9 100644 --- a/Completion/Base/_subscript +++ b/Completion/Base/_subscript @@ -3,10 +3,14 @@ local expl if [[ "$PREFIX" = :* ]]; then + _tags any char-classes || return 1 + _description expl 'character class' compadd "$expl[@]" -p: -S ':]' alnum alpha blank cntrl digit graph \ lower print punct space upper xdigit elif [[ ${(Pt)${compstate[parameter]}} = assoc* ]]; then + _tags any association-keys || return 1 + _description expl 'association key' if [[ "$RBUFFER" = \]* ]]; then compadd "$expl[@]" -S '' - "${(@kP)${compstate[parameter]}}" @@ -14,22 +18,39 @@ elif [[ ${(Pt)${compstate[parameter]}} = assoc* ]]; then compadd "$expl[@]" -S ']' - "${(@kP)${compstate[parameter]}}" fi elif [[ ${(Pt)${compstate[parameter]}} = array* ]]; then - local list i j - - _description expl 'array index' - ind=( {1..${#${(P)${compstate[parameter]}}}} ) - list=() - for i in "$ind[@]"; do - [[ "$i" = ${PREFIX}*${SUFFIX} ]] && - list=( "$list[@]" - "${(r:4:: ::):)i} $(print -D ${(P)${compstate[parameter]}[$i]})" ) + local list i j ret=1 disp + + _tags any indexes parameters + + while _tags; do + if _requested indexes; then + _description -V expl 'array index' + ind=( {1..${#${(P)${compstate[parameter]}}}} ) + if _style indexes description yes; then + list=() + for i in "$ind[@]"; do + [[ "$i" = ${PREFIX}*${SUFFIX} ]] && + list=( "$list[@]" + "${i}:$(print -D ${(P)${compstate[parameter]}[$i]})" ) + done + compdisplay list ' -- ' "$list[@]" + disp=( -d list) + else + disp=() + fi + + if [[ "$RBUFFER" = \]* ]]; then + compadd "$expl[@]" -S '' "$disp[@]" - "$ind[@]" && ret=0 + else + compadd "$expl[@]" -S ']' "$disp[@]" - "$ind[@]" && ret=0 + fi + fi + _requested parameters && _parameters && ret=0 + + (( ret )) || return 0 done - if [[ "$RBUFFER" = \]* ]]; then - compadd "$expl[@]" -S '' -V default -d list - "$ind[@]" - else - compadd "$expl[@]" -S ']' -V default -d list - "$ind[@]" - fi + return 1 else _compalso -math- fi diff --git a/Completion/Base/_tilde b/Completion/Base/_tilde index 0b81f75a1..afdca1222 100644 --- a/Completion/Base/_tilde +++ b/Completion/Base/_tilde @@ -4,40 +4,53 @@ # for you or if there are too many of them, you may want to use # `compadd -qS/ - "$friends[@]"' or something like that. -local d s dirs list lines revlines i +local expl suf dirs list lines revlines i ret disp if [[ "$SUFFIX" = */* ]]; then ISUFFIX="/${SUFFIX#*/}$ISUFFIX" SUFFIX="${SUFFIX%%/*}" - s=(-S '') + suf=(-S '') else - s=(-qS/) + suf=(-qS/) fi -if [[ -prefix [-+] ]]; then - lines=("$PWD" "$dirstack[@]") - integer i - if [[ ( -prefix - && ! -o pushdminus ) || - ( -prefix + && -o pushdminus ) ]]; then - revlines=( $lines ) - for (( i = 1; i <= $#lines; i++ )); do - lines[$i]="$((i-1)) -- ${revlines[-$i]}" - done - else - for (( i = 1; i <= $#lines; i++ )); do - lines[$i]="$((i-1)) -- ${lines[$i]}" - done +_tags any users named-directoriess directory-stack + +while _tags; do + _requested users && _users "$suf[@]" "$@" && ret=0 + if _requested named-directories; then + _description expl 'named directory' + compadd "$suf[@]" "$expl[@]" "$@" - "${(@k)nameddirs}" fi - list=(${lines%% *}) - compset -P '[-+]' - _description d 'directory stack' - compadd "$d[@]" -V dirs -S/ -ld lines -Q - "$list[@]" -else - _users "$@" - if (( $# )); then - d=( "$@" ) - else - _description d 'named directory' + + if _requested directory-stack && + { ! _style directory-stack prefix-needed yes || + [[ "$PREFIX" = [-+]* ]] }; then + if _style directory-stack description yes; then + integer i + + lines=("${PWD}" "${dirstack[@]}") + + if [[ ( -prefix - && ! -o pushdminus ) || + ( -prefix + && -o pushdminus ) ]]; then + revlines=( $lines ) + for (( i = 1; i <= $#lines; i++ )); do + lines[$i]="$((i-1)) -- ${revlines[-$i]}" + done + else + for (( i = 1; i <= $#lines; i++ )); do + lines[$i]="$((i-1)) -- ${lines[$i]}" + done + fi + list=( ${PREFIX[1]}${^lines%% *} ) + disp=( -ld lines ) + else + list=( ${PREFIX[1]}{0..${#dirstack}} ) + disp=() + fi + + _description -V expl 'directory stack' + compadd "$expl[@]" "$suf[@]" "$disp[@]" -Q - "$list[@]" && ret=0 fi - compadd "$d[@]" "$s[@]" - "${(@k)nameddirs}" -fi + (( ret )) || return 0 +done diff --git a/Completion/Base/_values b/Completion/Base/_values index aac8b392d..e4d61d288 100644 --- a/Completion/Base/_values +++ b/Completion/Base/_values @@ -1,12 +1,27 @@ #autoload +local subopts + +if [[ "$1" = -O?* ]]; then + subopts=( "${(@P)1[3,-1]}" ) + shift +if [[ "$1" = -O ]]; then + subopts=( "${(@P)1}" ) + shift 2 +else + subopts=() +fi + if compvalues -i "$@"; then - local noargs args opts descr action expl sep + local noargs args opts descr action expl sep _sub_context oldsc="$_sub_context" if ! compvalues -D descr action; then - _tags value || return 1 + compvalues -C _sub_context + _sub_context="${oldsc}:${oldsc+${oldsc}-}${_sub_context}" + + _tags "${_sub_context}" values || return 1 compvalues -V noargs args opts @@ -32,7 +47,8 @@ if compvalues -i "$@"; then PREFIX="$prefix" SUFFIX="$suffix" IPREFIX="${IPREFIX}${args[1]%%:*}=" - compvalues -L "${args[1]%%:*}" descr action + compvalues -L "${args[1]%%:*}" descr action _sub_context + _sub_context="${oldsc}:${oldsc+${oldsc}-}${_sub_context}" fi else compvalues -d descr @@ -49,9 +65,12 @@ if compvalues -i "$@"; then return fi + else + compvalues -C _sub_context + _sub_context="${oldsc}:${oldsc+${oldsc}-}${_sub_context}" fi - _tags argument || return 1 + _tags "${oldsc}:any" arguments || return 1 _description expl "$descr" @@ -85,13 +104,13 @@ if compvalues -i "$@"; then eval ws\=\( "${action[3,-3]}" \) - _describe "$descr" ws -M 'r:|[_-]=* r:|=*' + _describe "$descr" ws -M 'r:|[_-]=* r:|=*' "$subopts[@]" elif [[ "$action" = \(*\) ]]; then # Anything inside `(...)' is added directly. - compadd "$expl[@]" - ${=action[2,-2]} + compadd "$subopts[@]" "$expl[@]" - ${=action[2,-2]} elif [[ "$action" = \{*\} ]]; then # A string in braces is evaluated. @@ -108,13 +127,11 @@ if compvalues -i "$@"; then # Otherwise we call it with the description-arguments built above. action=( $=action ) - ${(e)action[1]} "$expl[@]" ${(e)~action[2,-1]} + ${(e)action[1]} "$subopts[@]" "$expl[@]" ${(e)~action[2,-1]} fi fi [[ nm -ne "$compstate[nmatches]" ]] - return - else return 1; fi diff --git a/Completion/Base/_vars b/Completion/Base/_vars index a81a49f48..43cdf5d2c 100644 --- a/Completion/Base/_vars +++ b/Completion/Base/_vars @@ -4,8 +4,6 @@ # `vared compconfig['. However, in this version the [ must be # added by hand. -local expl - if [[ $PREFIX = *\[* ]]; then local var=${PREFIX%%\[*} local elt="${PREFIX#*\]}${SUFFIX%\]}" @@ -16,9 +14,15 @@ if [[ $PREFIX = *\[* ]]; then addclose=(-S ']') fi if [[ ${(tP)var} = assoc* ]]; then + local expl + + _tags subscript association-keys || return 1 + _description expl 'association key' compadd "$expl[@]" $addclose - ${(kP)var} fi else - _parameter + _tags any parameters || return 1 + + _parameters fi diff --git a/Completion/Builtins/_aliases b/Completion/Builtins/_aliases index 8764f7f66..a097d020e 100644 --- a/Completion/Builtins/_aliases +++ b/Completion/Builtins/_aliases @@ -2,7 +2,6 @@ local expl -_description expl 'regular alias' -compadd "$expl[@]" - "${(@k)aliases}" -_description expl 'global alias' -compadd "$expl[@]" - "${(@k)galiases}" +_alternative any:argument \ + 'aliases:regular alias:compadd - ${(@k)aliases}' \ + 'global-aliases:global alias:compadd - ${(@k)galiases}' diff --git a/Completion/Builtins/_arrays b/Completion/Builtins/_arrays index a2aa813b6..37eb20bf5 100644 --- a/Completion/Builtins/_arrays +++ b/Completion/Builtins/_arrays @@ -2,5 +2,7 @@ local expl +_tags any:argument arrays || return 1 + _description expl array compadd "$expl[@]" - "${(@k)parameters[(R)*array*]}" diff --git a/Completion/Builtins/_autoload b/Completion/Builtins/_autoload index 4a97b2aec..116bb7765 100644 --- a/Completion/Builtins/_autoload +++ b/Completion/Builtins/_autoload @@ -2,5 +2,7 @@ local expl +_tags any:argument functions || return 1 + _description expl 'shell function' compadd "$expl[@]" - ${^fpath}/*(N:t) diff --git a/Completion/Builtins/_bindkey b/Completion/Builtins/_bindkey index b60dafbb2..31215a576 100644 --- a/Completion/Builtins/_bindkey +++ b/Completion/Builtins/_bindkey @@ -10,9 +10,13 @@ local expl if [[ "$words[2]" = -*[DAN]* || "$words[CURRENT-1]" = -*M ]]; then + _tags -M keymaps || return 1 + _description expl keymap compadd "$expl[@]" - "$keymaps[@]" else + _tags any:argument widgets || return 1 + _description expl widget compadd "$expl[@]" -M 'r:|-=* r:|=*' - "${(@k)widgets}" fi diff --git a/Completion/Builtins/_builtin b/Completion/Builtins/_builtin index cf02093bb..fcb20560f 100644 --- a/Completion/Builtins/_builtin +++ b/Completion/Builtins/_builtin @@ -7,6 +7,8 @@ if (( $CURRENT > 2 )); then else local expl + _tags any:command commands || return 1 + _description expl 'builtin command' compadd "$expl[@]" "$@" - "${(k@)builtins}" fi diff --git a/Completion/Builtins/_cd b/Completion/Builtins/_cd index b407b5a85..26846fde2 100644 --- a/Completion/Builtins/_cd +++ b/Completion/Builtins/_cd @@ -22,10 +22,13 @@ if [[ CURRENT -eq 3 ]]; then rep=(${~PWD/$words[2]/*}~$PWD(-/N)) # Now remove all the common parts of $PWD and the completions from this rep=(${${rep#${PWD%%$words[2]*}}%${PWD#*$words[2]}}) - _description expl replacement - (( ! $#rep )) || compadd "$expl[@]" $rep + if (( $#rep )) && _tags replacement strings; then + _description expl replacement + compadd "$expl[@]" $rep + fi elif _popd || [[ $PREFIX != (\~|/|./|../)* && $#cdpath -ne 0 ]]; then local tdir tdir2 + # With cdablevars, we can convert foo/bar/... to ~foo/bar/... if # there is no directory foo. In that case we could also complete # variable names, but it hardly seems worth it. diff --git a/Completion/Builtins/_command b/Completion/Builtins/_command index 9f54aae80..23995dbbe 100644 --- a/Completion/Builtins/_command +++ b/Completion/Builtins/_command @@ -6,6 +6,8 @@ if [[ CURRENT -ge 3 ]]; then else local expl + _tags any:command commands || return 1 + _description expl 'external command' compadd "$expl[@]" "$@" - "${(k@)commands}" fi diff --git a/Completion/Builtins/_compdef b/Completion/Builtins/_compdef index 4208c2689..df25d44de 100644 --- a/Completion/Builtins/_compdef +++ b/Completion/Builtins/_compdef @@ -12,10 +12,14 @@ while [[ $words[base] = -* ]]; do done if [ "$delete" ]; then + _tags any:argument commands || return 1 + _description expl 'completed command' compadd "$expl[@]" - ${(k)_comps} else if [[ CURRENT -eq base ]]; then + _tags any:argument functions || return 1 + _description expl 'completion function' compadd "$expl[@]" - ${^fpath:/.}/_(|*[^~])(N:t) else diff --git a/Completion/Builtins/_disable b/Completion/Builtins/_disable index af4805c25..33c202864 100644 --- a/Completion/Builtins/_disable +++ b/Completion/Builtins/_disable @@ -1,22 +1,15 @@ #compdef disable -local prev="$words[CURRENT-1]" ret=1 expl +local prev="$words[CURRENT-1]" args -if [[ "$prev" = -*a* ]]; then - _description expl alias - compadd "$expl[@]" "$@" - "${(k@)aliases}" && ret=0 -fi -if [[ "$prev" = -*f* ]]; then - _description expl 'shell function' - compadd "$expl[@]" "$@" - "${(k@)functions}" && ret=0 -fi -if [[ "$prev" = -*r* ]]; then - _description expl 'reserved word' - compadd "$expl[@]" "$@" - "${(k@)reswords}" && ret=0 -fi -if [[ "$prev" != -* ]]; then - _description expl 'builtin command' - compadd "$expl[@]" "$@" - "${(k@)builtins}" && ret=0 -fi +args=() +[[ "$prev" = -*a* ]] && + tags=( 'aliases:alias:compadd - ${(@k)aliases} ${(@k)galiases} ) +[[ "$prev" = -*f* ]] && + tags=( "$tags[@]" 'functions:shell function:compadd - ${(@k)functions}' ) +[[ "$prev" = -*r* ]] && + tags=( "$tags[@]" 'reserved-words:reserved word:compadd - ${(@k)reswords}' ) +[[ "$prev" != -* ]] && + tags=( 'builtins:builtin command:compadd - ${(@k)builtins} ) -return ret +_alternative any "$args[@]" diff --git a/Completion/Builtins/_echotc b/Completion/Builtins/_echotc index 46bf38261..2193261a1 100644 --- a/Completion/Builtins/_echotc +++ b/Completion/Builtins/_echotc @@ -2,6 +2,8 @@ local expl +_tags any:argument capabilities || return 1 + _description expl 'terminal capability' compadd "$expl[@]" \ al dc dl do le up al bl cd ce cl cr dc dl do ho is le ma nd nl se so up diff --git a/Completion/Builtins/_enable b/Completion/Builtins/_enable index 7d15e9121..ae2bdc38c 100644 --- a/Completion/Builtins/_enable +++ b/Completion/Builtins/_enable @@ -1,22 +1,15 @@ #compdef enable -local prev="$words[CURRENT-1]" ret=1 expl +local prev="$words[CURRENT-1]" args -if [[ "$prev" = -*a* ]]; then - _description expl alias - compadd "$expl[@]" "$@" - "${(k@)dis_aliases}" "${(k@)dis_galiases}" && ret=0 -fi -if [[ "$prev" = -*f* ]]; then - _description expl 'shell function' - compadd "$expl[@]" "$@" - "${(k@)dis_functions}" && ret=0 -fi -if [[ "$prev" = -*r* ]]; then - _description expl 'reserved word' - compadd "$expl[@]" "$@" - "${(k@)dis_reswords}" && ret=0 -fi -if [[ "$prev" != -* ]]; then - _description expl 'builtin command' - compadd "$expl[@]" "$@" - "${(k@)dis_builtins}" && ret=0 -fi +args=() +[[ "$prev" = -*a* ]] && + tags=( 'aliases:alias:compadd - ${(@k)dis_aliases} ${(@k)dis_galiases} ) +[[ "$prev" = -*f* ]] && + tags=( "$tags[@]" 'functions:shell function:compadd - ${(@k)dis_functions}' ) +[[ "$prev" = -*r* ]] && + tags=( "$tags[@]" 'reserved-words:reserved word:compadd - ${(@k)dis_reswords}' ) +[[ "$prev" != -* ]] && + tags=( 'builtins:builtin command:compadd - ${(@k)dis_builtins} ) -return ret +_alternative any "$args[@]" diff --git a/Completion/Builtins/_functions b/Completion/Builtins/_functions index 81a56eb83..9e6925ce7 100644 --- a/Completion/Builtins/_functions +++ b/Completion/Builtins/_functions @@ -2,5 +2,7 @@ local expl +_tags argument:any functions || return 1 + _description expl 'shell function' compadd "$expl[@]" "$@" - "${(k@)functions}" diff --git a/Completion/Builtins/_hash b/Completion/Builtins/_hash index 4cb72b09c..24a9964b9 100644 --- a/Completion/Builtins/_hash +++ b/Completion/Builtins/_hash @@ -4,15 +4,23 @@ local expl if [[ "$words[2]" = -*d* ]]; then if compset -P 1 '*\='; then + _tags - -d-value files || return 1 + _path_files -g '*(-/)' else + _tags - -d named-directories || return 1 + _description expl 'named directory' compadd "$expl[@]" -q -S '=' - "${(@k)nameddirs}" fi elif compset -P 1 '*\='; then + _tags value executables || return 1 + _description expl 'executable file' _files "$expl[@]" -g '*(*)' else + _tags any:argument commands || return 1 + _description expl command compadd "$expl[@]" -q -S '=' - "${(@k)commands}" fi diff --git a/Completion/Builtins/_kill b/Completion/Builtins/_kill index 43ff40838..e2dc88dac 100644 --- a/Completion/Builtins/_kill +++ b/Completion/Builtins/_kill @@ -4,10 +4,10 @@ local list expl if compset -P 1 -; then - _tags signal || return 1 + _tags - -:signal signals || return 1 _description expl signal compadd "$expl[@]" $signals[1,-3] else - _alternative 'job:: _jobs' 'process:: _pids' + _alternative argument 'jobs:: _jobs' 'processes:: _pids' fi diff --git a/Completion/Builtins/_limits b/Completion/Builtins/_limits index 0072438c3..12e90e96a 100644 --- a/Completion/Builtins/_limits +++ b/Completion/Builtins/_limits @@ -2,5 +2,7 @@ local expl +_tags any:argument limits || return 1 + _description expl 'process limits' compadd "$expl[@]" ${${(f)"$(limit)"}%% *} diff --git a/Completion/Builtins/_pids b/Completion/Builtins/_pids index 0ffda900b..f96c11e2d 100644 --- a/Completion/Builtins/_pids +++ b/Completion/Builtins/_pids @@ -3,7 +3,9 @@ # If given the `-m ' option, this tries to complete only pids # of processes whose command line match the `'. -local list expl match +local list expl match desc + +_tags any processes || return 1 if [[ "$1" = -m ]]; then match="${2}*" @@ -12,7 +14,12 @@ fi _description expl 'process ID' -list=("${(@Mr:COLUMNS-1:)${(f@)$(ps ${=compconfig[ps_listargs]:-$=compconfig[ps_args]} 2>/dev/null)}[2,-1]:#[ ]#${PREFIX}[0-9]#${SUFFIX}[ ]*${~match}}") +if _style processes description yes; then + list=("${(@Mr:COLUMNS-1:)${(f@)$(ps ${=compconfig[ps_listargs]:-$=compconfig[ps_args]} 2>/dev/null)}[2,-1]:#[ ]#${PREFIX}[0-9]#${SUFFIX}[ ]*${~match}}") + desc=(-ld list) +else + desc=() +fi -compadd "$expl[@]" "$@" -ld list - \ +compadd "$expl[@]" "$@" "$desc[@]" - \ ${${${(M)${(f)"$(ps $=compconfig[ps_args] 2>/dev/null)"}[2,-1]:#*${~match}}## #}%% *} diff --git a/Completion/Builtins/_popd b/Completion/Builtins/_popd index 9054befb7..5e4910f48 100644 --- a/Completion/Builtins/_popd +++ b/Completion/Builtins/_popd @@ -5,36 +5,39 @@ # way round if pushdminus is set). Note that this function is also called # from _cd for cd and pushd. -emulate -L zsh setopt extendedglob nonomatch -[[ $PREFIX = [-+]* ]] || return 1 +_tags any directory-stack || return 1 -local expl list lines revlines ret=1 i +! _style directory-stack prefix-needed yes || + [[ $PREFIX = [-+]* ]] || return 1 -IPREFIX=$PREFIX[1] -PREFIX=$PREFIX[2,-1] +local expl list lines revlines disp -# get the list of directories with their canonical number -# and turn the lines into an array, removing the current directory -lines=( ${${(f)"$(dirs -v)"}##0*} ) -if [[ ( $IPREFIX = - && ! -o pushdminus ) || - ( $IPREFIX = + && -o pushdminus ) ]]; then - integer i - revlines=( $lines ) - for (( i = 1; i <= $#lines; i++ )); do - lines[$i]="$((i-1)) -- ${revlines[-$i]##[0-9]#[ ]#}" - done +if _style directory-stack description yes; then + # get the list of directories with their canonical number + # and turn the lines into an array, removing the current directory + lines=("${PWD}" "${dirstack[@]}") + + if [[ ( $PREFIX[1] = - && ! -o pushdminus ) || + ( $PREFIX[1] = + && -o pushdminus ) ]]; then + integer i + revlines=( $lines ) + for (( i = 1; i <= $#lines; i++ )); do + lines[$i]="$((i-1)) -- ${revlines[-$i]##[0-9]#[ ]#}" + done + else + for (( i = 1; i <= $#lines; i++ )); do + lines[$i]="$i -- ${lines[$i]##[0-9]#[ ]#}" + done + fi + # get the array of numbers only + list=( ${PREFIX[1]}${^lines%% *} ) + disp=( -ld lines ) else - for (( i = 1; i <= $#lines; i++ )); do - lines[$i]="$i -- ${lines[$i]##[0-9]#[ ]#}" - done + list=( ${PREFIX[1]}{0..${#dirstack}} ) + disp=() fi -# get the array of numbers only -list=(${lines%% *}) -_description expl 'directory stack index' -compadd "$expl[@]" -ld lines -V dirs -Q - "$list[@]" && ret=0 -[[ -z $compstate[list] ]] && compstate[list]=list && ret=0 -[[ -n $compstate[insert] ]] && compstate[insert]=menu && ret=0 - -return ret + +_description -V expl 'directory stack index' +compadd "$expl[@]" "$@" -qS/ "$disp[@]" -Q - "$list[@]" diff --git a/Completion/Builtins/_sched b/Completion/Builtins/_sched index 38bf44a59..d3245f7ef 100644 --- a/Completion/Builtins/_sched +++ b/Completion/Builtins/_sched @@ -1,12 +1,19 @@ #compdef sched -local expl lines +local expl lines disp if [[ CURRENT -eq 2 ]]; then if compset -P -; then + _tags - - entries || return 1 + lines=(${(f)"$(sched)"}) + if _style entries description yes; then + disp=( -ld lines ) + else + disp=() + fi _description expl 'scheduled jobs' - [[ -z $lines ]] || compadd "$expl[@]" -ld lines - {1..$#lines} + [[ -z $lines ]] || compadd "$expl[@]" "$disp[@]" - {1..$#lines} else _message 'time specification' return 1 diff --git a/Completion/Builtins/_stat b/Completion/Builtins/_stat index 322f042ec..3f1b62ca3 100644 --- a/Completion/Builtins/_stat +++ b/Completion/Builtins/_stat @@ -5,6 +5,8 @@ local expl if [[ "$words[CURRENT-1]" = -[AH] ]]; then _arrays else + _tags any:argument elements || return 1 + _description expl 'inode element' [[ "$PREFIX[1]" = + ]] && compadd "$expl[@]" - +device +inode +mode +nlink +uid +gid +rdev +size \ diff --git a/Completion/Builtins/_trap b/Completion/Builtins/_trap index 0f0209914..5dbb2d284 100644 --- a/Completion/Builtins/_trap +++ b/Completion/Builtins/_trap @@ -6,6 +6,8 @@ if [[ CURRENT -eq 2 ]]; then compset -q _normal else + _tags any:argument signals || return 1 + _description expl signal compadd "$expl[@]" - "$signals[@]" fi diff --git a/Completion/Builtins/_unhash b/Completion/Builtins/_unhash index a23fd9025..6ccbc21a4 100644 --- a/Completion/Builtins/_unhash +++ b/Completion/Builtins/_unhash @@ -1,22 +1,14 @@ #compdef unhash -local fl="$words[2]" ret=1 expl +local fl="$words[2]" args -if [[ "$fl" = -*d* ]]; then - _description expl 'named directory' - compadd "$expl[@]" - "${(@k)nameddirs}" && ret=0 -fi -if [[ "$fl" = -*a* ]]; then - _description expl alias - compadd "$expl[@]" - "${(@k)aliases}" "${(@k)dis_aliases}" \ - "${(@k)galiases}" "${(@k)dis_galiases}" && ret=0 -fi -if [[ "$fl" = -*f* ]]; then - _description expl 'shell function' - compadd "$expl[@]" - "${(@k)functions}" "${(@k)dis_functions}" && ret=0 -fi -if [[ "$fl" != -* ]]; then - _command_names -e && ret=0 -fi +args=() +[[ "$fl" = -*d* ]] && + args=( 'named-directories:named directory:compadd - ${(@k)nameddirs}' ) +[[ "$fl" = -*a* ]] && + args=( "$args[@]" + 'aliases:alias:compadd - ${(@k)aliases} ${(@k)galiases} ${(@k)dis-aliases} ${(@k)dis-galiases}' ) +[[ "$fl != -* ]] && + args=( 'commands:: _command_names -e' ) -return ret +_alternative any:argument "$args[@]" diff --git a/Completion/Builtins/_wait b/Completion/Builtins/_wait index c1022a25f..04ad5e873 100644 --- a/Completion/Builtins/_wait +++ b/Completion/Builtins/_wait @@ -1,3 +1,3 @@ #compdef wait -_alternative 'job:: _jobs' 'process:: _pids' +_alternative argument:any 'jobs:: _jobs' 'processes:: _pids' diff --git a/Completion/Builtins/_which b/Completion/Builtins/_which index 41e7d20fd..6e9e0a460 100644 --- a/Completion/Builtins/_which +++ b/Completion/Builtins/_which @@ -1,14 +1,12 @@ #compdef which whence where type -local expl +local args -_description expl 'external command' -compadd "$expl[@]" "$@" - "${(k@)commands}" && ret=0 -_description expl 'builtin command' -compadd "$expl[@]" "$@" - "${(k@)builtins}" && ret=0 -_description expl 'shell function' -compadd "$expl[@]" "$@" - "${(k@)functions}" && ret=0 -_description expl 'alias' -compadd "$expl[@]" "$@" - "${(k@)aliases}" && ret=0 -_description expl 'reserved word' -compadd "$expl[@]" "$@" - "${(k@)reswords}" && ret=0 +args=( "$@" ) + +_alternative -O args any:argument \ + 'commands:external command:compadd - ${(k@)commands}' \ + 'builtins:builtin command:compadd - ${(k@)builtins}' \ + 'functions:shell function:compadd - ${(k@)functions}' \ + 'aliases:alias:compadd - ${(k@)aliases}' \ + 'reserved-words:reserved word:compadd - ${(k@)reswords}' diff --git a/Completion/Builtins/_zftp b/Completion/Builtins/_zftp index 7aa1d94e8..2728d1747 100644 --- a/Completion/Builtins/_zftp +++ b/Completion/Builtins/_zftp @@ -13,6 +13,8 @@ local subcom expl if [[ $words[1] = zftp ]]; then if [[ $CURRENT -eq 2 ]]; then + _tags command commands || return 1 + _description expl sub-command compadd "$expl[@]" open params user login type ascii binary mode put \ putat get getat append appendat ls dir local remote mkdir rmdir \ @@ -27,26 +29,27 @@ fi case $subcom in *(cd|ls|dir)) # complete remote directories - zfcd_match $PREFIX $SUFFIX + _tags "$subcom" directories && zfcd_match $PREFIX $SUFFIX ;; *(get(|at)|gcp|delete|remote)) # complete remote files - zfget_match $PREFIX $SUFFIX + _tags "$subcom" files && zfget_match $PREFIX $SUFFIX ;; *(put(|at)|pcp)) # complete local files - _files + _tags "$subcom" files && _files ;; *(open|anon|params)) # complete hosts: should do cleverer stuff with user names - _hosts + _tags "$subcom" hosts && _hosts ;; *(goto|mark)) # complete bookmarks. First decide if ncftp mode is go. + _tags "$subcom" bookmarks || return 1 _description expl bookmark if [[ $words[2] = -*n* ]]; then if [[ -f ~/.ncftp/bookmarks ]]; then @@ -61,6 +64,7 @@ case $subcom in *session) # complete sessions, excluding the current one. + _tags "$subcom" sessions || return 1 _description expl 'another FTP session' compadd "$expl[@]" - ${$(zftp session):#$ZFTP_SESSION} ;; @@ -69,6 +73,7 @@ case $subcom in # complete arguments like sess1:file1 sess2:file2 if [[ $PREFIX = *:* ]]; then # complete file in the given session + _tags "$subcom" files || return 1 local sess=${PREFIX%%:*} oldsess=$ZFTP_SESSION compset -p $(( $#sess + 1 )) [[ -n $sess ]] && zftp session $sess @@ -76,6 +81,7 @@ case $subcom in [[ -n $sess && -n $oldsess ]] && zftp session $oldsess else # note here we can complete the current session + _tags "$subcom" sessions || return 1 _description expl 'FTP session' compadd "$expl[@]" -S : - $(zftp session) fi diff --git a/Completion/Builtins/_zle b/Completion/Builtins/_zle index a153aabdd..21997ef62 100644 --- a/Completion/Builtins/_zle +++ b/Completion/Builtins/_zle @@ -3,9 +3,11 @@ local expl if [[ "$words[2]" = -N && CURRENT -eq 3 ]]; then + _tags any:argument functions || return 1 _description expl 'widget shell function' compadd "$expl[@]" "$@" - "${(k@)functions}" && ret=0 else + _tags any:argument widgets || return 1 _description expl widget compadd "$expl[@]" - "${(@k)widgets}" fi diff --git a/Completion/Builtins/_zmodload b/Completion/Builtins/_zmodload index 097911307..1a1097a7a 100644 --- a/Completion/Builtins/_zmodload +++ b/Completion/Builtins/_zmodload @@ -3,12 +3,15 @@ local fl="$words[2]" expl if [[ "$fl" = -*(a*u|u*a)* || "$fl" = -*a* && CURRENT -ge 4 ]]; then + _tags any:argument builtins || return 1 _description expl 'builtin command' compadd "$expl[@]" "$@" - "${(k@)builtins}" && ret=0 elif [[ "$fl" = -*u* ]]; then + _tags any:argument modules || return 1 _description expl module compadd "$expl[@]" - "${(@k)modules}" else + _tags any:argument files || return 1 _description expl 'module file' compadd "$expl[@]" - ${^module_path}/*.s[ol](N:t:r) fi diff --git a/Completion/Core/_alternative b/Completion/Core/_alternative index 158f3a07a..f13fc9e5a 100644 --- a/Completion/Core/_alternative +++ b/Completion/Core/_alternative @@ -1,19 +1,22 @@ #autoload -local tags def expl descr action mesgs nm="$compstack[nmatches]" -local context +local tags def expl descr action mesgs nm="$compstack[nmatches]" subopts -if [[ "$1" = -C?* ]]; then - context="${1[3,-1]}" +if [[ "$1" = -O?* ]]; then + subopts=( "${(@P)1[3,-1]}" ) shift -elif [[ "$1" = -C ]]; then - context="$2" +elif [[ "$1" = -O ]]; then + subopts=( "${(@P)2}" ) shift 2 -fi +else + subopts=() +fi + +[[ "$1" = -(|-) ]] && shift mesgs=() -_tags -C "$context" "${(@)argv%%:*}" +_tags "$1" "${(@)argv[2,-1]%%:*}" while _tags; do for def; do @@ -35,12 +38,12 @@ while _tags; do eval ws\=\( "${action[3,-3]}" \) - _describe "$descr" ws -M 'r:|[_-]=* r:|=*' + _describe "$descr" ws -M 'r:|[_-]=* r:|=*' "$subopts[@]" elif [[ "$action" = \(*\) ]]; then # Anything inside `(...)' is added directly. - compadd "$expl[@]" - ${=action[2,-2]} + compadd "$subopts[@]" "$expl[@]" - ${=action[2,-2]} elif [[ "$action" = \{*\} ]]; then # A string in braces is evaluated. @@ -56,7 +59,7 @@ while _tags; do # Otherwise we call it with the description-arguments built above. action=( $=action ) - ${(e)action[1]} "$expl[@]" ${(e)~action[2,-1]} + ${(e)action[1]} "$subopts[@]" "$expl[@]" ${(e)~action[2,-1]} fi fi done diff --git a/Completion/Core/_complete b/Completion/Core/_complete index 073212d0f..f351c7349 100644 --- a/Completion/Core/_complete +++ b/Completion/Core/_complete @@ -4,7 +4,10 @@ # a normal completion function, but as one possible value for the # compconfig[completer] parameter. -local comp name +local comp name _tag_context="$_tag_context" + +[[ "$compstate[context]" != command || CURRENT -eq 1 ]] && + _tag_context="-${compstate[context]:s/_/-/}-" # If we have a user-supplied context name, use only that. @@ -36,7 +39,7 @@ else # Let's see if we have a special completion definition for the other # possible contexts. - comp="$_comps[-${compstate[context]:s/_/-/}-]" + comp="$_comps[$_tag_context]" # If not, we use default completion, if any. diff --git a/Completion/Core/_files b/Completion/Core/_files index eb1ec3559..973eea69b 100644 --- a/Completion/Core/_files +++ b/Completion/Core/_files @@ -13,22 +13,22 @@ while getopts "P:S:qr:R:W:F:J:V:X:f/g:M:" opt; do done case "$type" in -file) _tags file ;; -dir) _tags path file ;; -*) _tags glob path file ;; +file) _tags any all-files ;; +dir) _tags any directories all-files ;; +*) _tags any globbed-files directories all-files ;; esac while _tags; do - if _requested file; then + if _requested all-files; then _path_files "$opts[@]" -f return - elif _requested path; then - if _requested glob; then + elif _requested directories; then + if _requested globbed-files; then _path_files "$opts[@]" -/g "$type" && return 0 else - _path_files "$opts[@]" -/g "$type" && return 0 + _path_files "$opts[@]" -/ && return 0 fi - elif _requested glob; then + elif _requested globbed-files; then _path_files "$opts[@]" -g "$type" && return 0 fi done diff --git a/Completion/Core/_main_complete b/Completion/Core/_main_complete index e4ee2879b..f9a8a19ad 100644 --- a/Completion/Core/_main_complete +++ b/Completion/Core/_main_complete @@ -17,9 +17,10 @@ # state than the global one for which you are completing. -local comp post ret=1 _compskip _prio_num=1 +local comp post ret=1 _compskip _prio_num=1 _tag_context _cur_contexts +local context state line opt_args val_args typeset -U _offered_tags _tried_tags _failed_tags _used_tags _unused_tags -typeset -A _prio_names _cur_tags +typeset -A _prio_names _prio_contexts _cur_tags _tag_contexts _offered_tags=() _tried_tags=() diff --git a/Completion/Core/_message b/Completion/Core/_message index ab1c67992..ee869d33b 100644 --- a/Completion/Core/_message +++ b/Completion/Core/_message @@ -2,6 +2,8 @@ local format +_tags any messages || return 1 + format="${compconfig[message_format]:-$compconfig[description_format]}" if [[ -n "$format" ]]; then diff --git a/Completion/Core/_normal b/Completion/Core/_normal index 79efaeb97..5d0a18406 100644 --- a/Completion/Core/_normal +++ b/Completion/Core/_normal @@ -1,6 +1,7 @@ #autoload local comp command cmd1 cmd2 pat val name i ret=1 _compskip="$_compskip" +local _sub_context # If we get the option `-s', we don't reset `_compskip'. This ensures # that a value set in the function for the `-first-' context is kept, diff --git a/Completion/Core/_options b/Completion/Core/_options index 0232db857..0dd92cf69 100644 --- a/Completion/Core/_options +++ b/Completion/Core/_options @@ -4,6 +4,8 @@ local expl +_tags any zsh-options || return 1 + _description expl 'zsh option' compadd "$expl[@]" "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - \ "${(@k)options}" diff --git a/Completion/Core/_parameters b/Completion/Core/_parameters index fdb786231..da479097e 100644 --- a/Completion/Core/_parameters +++ b/Completion/Core/_parameters @@ -5,6 +5,8 @@ local pars expl +_tags any parameters || return 1 + _description expl parameter pars=( ${(k)parameters[(R)^*local*]} ) diff --git a/Completion/Core/_requested b/Completion/Core/_requested index 082c45820..09c57ee09 100644 --- a/Completion/Core/_requested +++ b/Completion/Core/_requested @@ -1,9 +1,9 @@ #autoload -local tag tname="$funcstack[2,-1]" +# Reset the current context. -for tag; do - [[ "${_cur_tags[${tname}]}" = *:${tag}(:|\[*\]:)* ]] && return 0 -done +_cur_contexts="${_tag_contexts[$tname]}" -return 1 +# Test if the tag given as argument was requested. + +[[ "${_cur_tags[${funcstack[2,-1]}]}" = *:${1}:* ]] diff --git a/Completion/Core/_set_options b/Completion/Core/_set_options index 947afdeae..55388d0c8 100644 --- a/Completion/Core/_set_options +++ b/Completion/Core/_set_options @@ -6,5 +6,7 @@ local expl +_tags any zsh-options || return 1 + _description expl 'set zsh option' compadd "$expl[@]" "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - $=_set_options diff --git a/Completion/Core/_sort_tags b/Completion/Core/_sort_tags new file mode 100644 index 000000000..f1740511d --- /dev/null +++ b/Completion/Core/_sort_tags @@ -0,0 +1,28 @@ +#autoload + +comptry arguments values +comptry options + +case "$contexts" in +# Some silly examples commented out: +# +# *p[bgpn]m*) # change the order for file-completion +# comptry globbed-files directories +# comptry all-files +# ;; +# *:dvips,-o*) # automatic context set by _arguments +# comptry all-files +# return +# ;; +# *:kill,*) +# comptry processes +# return # this return ensures that we use only processes +# ;; +*) + comptry globbed-files + comptry directories + comptry all-files + ;; +esac + +comptry "$@" diff --git a/Completion/Core/_style b/Completion/Core/_style index b0cbd7b00..a3b54686f 100644 --- a/Completion/Core/_style +++ b/Completion/Core/_style @@ -1,45 +1,50 @@ #autoload -local tags get i +local all get val i + +# Should we return the value? if [[ "$1" = -g ]]; then get=yes shift fi -if (( ${+_cur_tags[${funcstack[2,-1]}]} )); then - tags="${_cur_tags[${funcstack[2,-1]}]}" -else - tags="${_cur_tags[${funcstack[3,-1]}]}" -fi +# Get all styles defined for this context. -if [[ "$tags" = *:${1}\[*\]:* ]]; then +all=() +for i in "${(s.:.)_cur_contexts}"; do + all=("$all[@]" "${(@)_compstyles[(K)${i},${1}]}" ) +done +all=":${(j.:.)${(@o)all:#}##??}:" - tags="${${tags#*:${1}\[}%%\]*}" +if [[ "$all" = *:${2}[:\=]* ]]; then - if [[ $# -eq 2 ]]; then - if [[ -n "$get" ]]; then - eval "${2}=\"$tags\"" - return 0 - fi + # We have a definition for the style. - [[ "$tags" = (|*,)${2}(|,*) ]] - return - fi + if [[ $# -eq 3 ]]; then + if [[ -n "$get" ]]; then - [[ "$tags" = (|*,)${2}(|(\=|,)*) ]] || return 1 + # We have to return the value. - if [[ -n "$get" ]]; then - if [[ "$tags" = (|*,)${2}\=* ]]; then - eval "${3}=\"${${tags#(|*,)${2}\=}%%,*}\"" + if [[ "$all" = *,${2}\=* ]]; then + eval "${3}=\"${${all#*:${2}\=}%%:*}\"" + else + eval "${3}=''" + fi else - eval "${3}=''" + + # We have to test the value. + + if [[ "$all" = *:${2}\=* ]]; then + [[ "${${all#*:${2}\=}%%:*}" = ${~3} ]] + else + [[ '' -eq ${~3} ]] + fi + + return fi - return 0 fi - - [[ "$tags" = (|*,)${2}\=(|[^,]#,)${3}(|,*) ]] - return + return 0 fi return 1 diff --git a/Completion/Core/_tags b/Completion/Core/_tags index 7b1254325..5ed56df6e 100644 --- a/Completion/Core/_tags +++ b/Completion/Core/_tags @@ -1,84 +1,85 @@ #autoload +# We use the funcstack names to communicate to neighboring functions. + local tname="$funcstack[2,-1]" if (( $# )); then - local cmd="$words[1]" defs i ttags tag pat style prio context opt - while getopts 'c:C:' opt; do - if [[ "$opt" = c ]]; then - cmd="$OPTARG" - else - context="$OPTARG" - fi - done - shift OPTIND-1 + # We have arguments: the tags supported in this context. + + local command="${_tag_context:-${words[1]}}" _tags contexts name + + # We are given the `-c command-name' option. + + if [[ "$1" = -c?* ]]; then + command="${1[3,-1]}" + shift + elif [[ "$1" = -c ]]; then + command="$2" + shift 2 + fi + + [[ "$1" = -(|-) ]] && shift + + # Get the context names. - [[ -n "$context" ]] && context="/$context" + if [[ -n "$_sub_context" ]]; then + contexts="${1}:${_sub_context}" + else + contexts="${1}" + fi + contexts=":${command},${${contexts//::/:}//:/:${command},}:" + shift - defs=( "${(@M)argv:#${(kj:|:)~override_tags[(R)(|+*)]}}" ) - (( $#defs )) && set -- "$defs[@]" + _tags=() + + # Remember offered tags. _offered_tags=( "$_offered_tags[@]" "$@" ) _last_tags=() - defs=() - for i; do - if [[ -n ${override_tags[$i]} && ${override_tags[$i]} != (\[|+\[)* ]]; then - if [[ ${override_tags[$i]} = *\[* ]]; then - prio=( "${i}:*=${override_tags[$i]#+}" ) - else - prio=( "${i}:${(@v)^comptags[(I)(|*:)${i}(|:*)]}" ) - (( $#prio )) || prio=( "${i}:${comptags[any]}" ) - prio="${${${prio[(r)(|*:)\*=[^:]#\[*\](|:*)]}##(|*:)\*}%%:*}" - prio=( "${i}:*=${override_tags[$i]#+}${(M)prio%%\[*\]}" ) - fi - else - prio=( "${i}:${(@v)^comptags[(I)(|*:)${i}(|:*)]}" ) - (( $#prio )) || prio=( "${i}:${comptags[any]}" ) - fi - defs=( "$defs[@]" "$prio[@]" ) - done - - ttags=() - for i in "$defs[@]"; do - tag="${i%%:*}" - for pat in "${(s.:.)i#*:}"; do - if [[ "$cmd$context" = ${~pat%%\=*} ]]; then - prio="${pat#*\=}" - [[ "$prio" = -* ]] && continue 2 - - if [[ "$prio" = *\[*\] ]]; then - style="${(M)prio%%\[*}" - prio="${prio%%\[*}" - else - style='' - fi - [[ ${override_tags[$tag]} = (|+)\[* ]] && - style="${override_tags[$tag]#+}" - - (( prio++ )) - - ttags[$prio]="${ttags[$prio]}:${tag}${style}" - break - fi - done - done - - prio="_prio_arr$(( _prio_num++ ))" - _prio_names[$tname]="$prio" - ttags=( "${(@)ttags:#}" ) - eval "${prio}=( \"\$ttags[@]\" )" - - return \!$#ttags + # Call the function that sorts the tags into sets. + + "${_sort_tags:-_sort_tags}" "$@" + + # The sets are reported in $_tags, one element per set. Remove + # tags that weren't requested. + + _tags=( "${(M@)_tags:#*:(${(j:|:)~argv}):*}" ) + + # Store the sets in a `hidden' array. + + name="_prio_arr$(( _prio_num++ ))" + _prio_names[$tname]="$name" + eval "${name}=( \"\$_tags[@]\" )" + + # Also store the context (used below and in _requested). + + _cur_contexts="$contexts[2,-2]" + _tag_contexts[$tname]="$_cur_contexts" + + # Return non-zero if at least one set of tags should be used. + + return \!$#_tags fi +# The other mode: switch to the next set of tags. + local prios="$_prio_names[$tname]" +# Reset the current context. + +_cur_contexts="${_tag_contexts[$tname]}" + _failed_tags=( "$_failed_tags[@]" "$_last_tags" ) +# Return failure if no sets remaining. + (( ${(P)#prios} )) || return 1 +# Otherwise get the next tags. + _cur_tags[$tname]="${(@)${(@P)prios}[1]}:" _last_tags=( "${(@)${(@s.:.)${(@P)prios}[1]}:#}" ) diff --git a/Completion/Core/_unset_options b/Completion/Core/_unset_options index f6a1c58f0..0c7b91b7a 100644 --- a/Completion/Core/_unset_options +++ b/Completion/Core/_unset_options @@ -6,5 +6,7 @@ local expl +_tags any zsh-options || return 1 + _description expl 'unset zsh option' compadd "$expl[@]" "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - $=_unset_options diff --git a/Completion/Core/compinit b/Completion/Core/compinit index 1b88cc8f0..0f614f322 100644 --- a/Completion/Core/compinit +++ b/Completion/Core/compinit @@ -108,13 +108,9 @@ fi compconfig[correct_prompt]='correct to:' (( ${+compconfig[completer]} )) || compconfig[completer]=_complete -# This holds the tag/priority definitions. +# This holds the style definitions. -typeset -gA comptags - -(( ${+comptags[any]} )) || comptags[any]='*=100' - -typeset -gA override_tags +typeset -gA _compstyles # This can hold names of functions that are to be called after all # matches have been generated. @@ -378,243 +374,65 @@ compconf() { fi } -# Function to set tags and priorities. - -comptag() { - local i opt list tag val - - while getopts "lL" opt; do - if [[ "$opt" = l ]]; then - [[ -z "$list" ]] && list=yes - else - list=long - fi - done - shift OPTIND-1 - - if (( $# )); then - if [[ -n $list ]]; then - for i; do - if [[ $list = long ]]; then - (( ${+comptags[$i]} )) && print "comptag $i='$comptags[$i]'" - else - print $comptags[$i] - fi - done - else - for i; do - tag="${i%%([-+]|)\=*}" - val="${${i#*(|[-+])\=}#+}" - case "$i" in - *+\=*) - if [[ -n "$comptags[$tag]" ]]; then - comptags[$tag]="${val}:${comptags[$tag]}" - else - comptags[$tag]="$val" - fi - ;; - *\=+*) - if [[ -n "$comptags[$tag]" ]]; then - comptags[$tag]="${comptags[$tag]}:${val}" - else - comptags[$tag]="$val" - fi - ;; - *-\=*) - if [[ -n "$comptags[$tag]" ]]; then - comptags[$tag]="${${${comptags[$tag]//:${val}\=[^:]##}#${val}\=*:}%:${val}\=[^:]##}" - [[ "$comptags[$tag]" = ${val}\=* ]] && unset "comptags[$tag]" - fi - ;; - *\=*) - comptags[${i%%\=*}]="${i#*\=}" - ;; - *) - unset "compconfig[$i]" - ;; - esac - done - fi - else - for i in ${(ok)comptags}; do - if [[ $list = long ]]; then - print "comptag $i='$comptags[$i]'" - else - print ${(r:25:)i} "$comptags[$i]" - fi - done - fi -} - -# First suggested function for new configuration interface. +# Very simple interface for setting styles: # -# Example: +# compstyle context -styles... context -styles ... # -# conf1 \ -# argument = 1 \ -# value = 1 with describe \ -# option = 2 with describe and hide \ -# file = 3 \ -# path in '*dvi*' = 1 \ -# else = 2 \ -# glob = 1 \ -# job = never - -conf1() { - local tag pat prio - - while (( $# )); do +# Where context is of the form cmd-pat:ctxt-pat:tag-pat. +# +# This will be improved if needed. Promised. - tag="$1" - shift +compstyle() { + if (( ! $# )); then + local pat - while (( $# )); do + for pat in "${(@k)_compstyles}"; do + print -- "${(r:20:: :)pat} -- ${_compstyles[$pat]#??}" + done - if [[ "$1" = in ]]; then - pat="$2" - shift 2 - else - pat='*' - [[ "$1" = else ]] && shift - fi + return 0 + fi - style='' + local sep pat test + typeset -Z 2 num - if [[ "$1" = is ]]; then - prio=0 - style="[${2}]" - shift 2 - elif [[ "$1" = \= ]]; then - if [[ "$2" = n(o|ever) ]]; then - prio=-1 - shift 2 - else - prio="$2" - shift 2 - - if [[ "$1" = with ]]; then - while [[ "$1" = (with|and) ]]; do - style="${style},${2}" - shift 2 - done - style="[${style[2,-1]}]" - fi - fi - else - echo "$0: missing priority: $1" - return 1 - fi - if [[ -n "$comptags[$tag]" ]]; then - comptags[$tag]="${comptags[$tag]}:${pat}=${prio}${style}" - else - comptags[$tag]="${pat}=${prio}${style}" + while (( $# )); do + num=0 + for pat in "${(s:,:)1}"; do + if [[ "$pat" = \* ]]; then + (( num += 3 )) + elif [[ "$pat" = any ]]; then + (( num += 2 )) + elif [[ "$pat" != "$pat:q" ]]; then + (( num++ )) fi - - [[ "$1" = (in|else|\=) ]] || break - done - done - return 0 -} + pat="$1" + shift -# Second suggested function for new configuration interface. -# -# Example: -# -# conf2 \ -# for '*dvi*' do \ -# glob and path or \ -# file \ -# else do \ -# glob or \ -# path or \ -# file \ -# for '*p[bgpn]m*' do \ -# argument and option with describe and with hide \ -# else do \ -# argument or \ -# value with describe or \ -# option with describe \ -# for 'kill' do \ -# no job but \ -# process \ -# else do \ -# process and job - -conf2() { - local pat prio tag style + sep=$argv[(I)[^-]*] - while (( $# )); do - - if [[ "$1" = for ]]; then - pat="$2" - shift 2 - elif [[ "$1" = (else|always) ]]; then - pat="*" - shift + if (( sep )); then + _compstyles[$pat]="${num}${(j.:.)${(@)argv[1,sep-1]#-}}" + shift sep-1 else - echo "$0: missing context: $1" - return 1 + _compstyles[$pat]="${num}${(j.:.)${(@)argv#-}}" + break fi + done - shift 1 - - prio=1 - - while (( $# )); do - - if [[ "$1" = no ]]; then - while [[ "$1" != (but|for|else|always) ]]; do - if [[ -n "$comptags[$2]" ]]; then - comptags[$2]="${comptags[$2]}:${pat}=-1" - else - comptags[$2]="${pat}=-1" - fi - - shift 2 - done - - [[ "$1" != but ]] && break - - shift - fi - - while (( $# )); do - - tag="$1" - shift - - style='' - if [[ "$1" = with ]]; then - shift - while true; do - style="${style},${1}" - [[ "$2" != and || "$3" != with ]] && break - shift 3 - done - shift - fi - - [[ -n "$style" ]] && style="[${style[2,-1]}]" - - if [[ -n "$comptags[$tag]" ]]; then - comptags[$tag]="${comptags[$tag]}:${pat}=${prio}${style}" - else - comptags[$tag]="${pat}=${prio}${style}" - fi + return 0 +} - [[ "$1" != and ]] && break +# Default styles. - shift - done +compstyle '*,*,*' -description=yes -prefix-needed=yes -prefix-hidden=no - [[ "$1" != or ]] && break +# Helper function for `_tags'. Will be moved into C-code. - (( prio++ )) - shift - done - done +comptry() { + _tags=( "$_tags[@]" ":${(j.:.)argv}:" ) } # Utility function to call a function if it exists. diff --git a/Completion/Linux/_rpm b/Completion/Linux/_rpm index 5b59f1d2b..15f154db9 100644 --- a/Completion/Linux/_rpm +++ b/Completion/Linux/_rpm @@ -43,7 +43,7 @@ local ret=1 tmp expl # Used by `_arguments', made local here. -local state lstate line +local context state lstate line typeset -A opt_args state='' @@ -187,13 +187,19 @@ while [[ -n "$state" ]]; do state=package_file ;& package) + _tags "$context" packages || return 1 + _description expl 'RPM package' compadd "$expl[@]" -M 'r:|-=* r:|=*' - $(rpm -qa) && ret=0 ;; package_file) if compset -P ftp://; then + _tags "$context" hosts || return 1 + _hosts -S/ && ret=0 else + _tags "$context" files || return 1 + _description expl 'RPM package file' _files "$expl[@]" -g '*.(#i)rpm' && ret=0 _description expl 'ftp URL prefix' @@ -202,6 +208,8 @@ while [[ -n "$state" ]]; do ;; tags) if compset -P '*\{'; then + _tags "$context" tags || return 1 + _description expl 'RPM tag' compadd "$expl[@]" -M 'm:{a-z}={A-Z}' -S '}' - \ "${(@)${(@f)$(rpm --querytags)}#RPMTAG_}" && ret=0 @@ -219,6 +227,8 @@ while [[ -n "$state" ]]; do _description expl 'old path' fi + _tags "$context" directories || return 1 + _files "$expl[@]" -/ && ret=0 ;; esac diff --git a/Completion/User/_archie b/Completion/User/_archie index 1e0eb71be..640fbc4ed 100644 --- a/Completion/User/_archie +++ b/Completion/User/_archie @@ -1,6 +1,6 @@ #compdef archie -local state line +local context state line expl typeset -A opt_args _arguments -s \ @@ -25,6 +25,10 @@ _arguments -s \ case "$state" in serverhost) : ${(A)archie_servers:=${(M)$(archie -L):#archie.*}} - compadd $archie_servers + + _tags "${context}:server" hosts || return 1 + + _description expl 'archie servers' + compadd "$expl[@]" - $archie_servers ;; esac diff --git a/Completion/User/_flex b/Completion/User/_flex index ef998c3cf..5d5d55f7a 100644 --- a/Completion/User/_flex +++ b/Completion/User/_flex @@ -1,6 +1,6 @@ #compdef flex -local state line ret=1 +local context state line ret=1 typeset -A opt_args _arguments -s \ diff --git a/Completion/User/_gcc b/Completion/User/_gcc index 2fa29df8c..88f70ad52 100644 --- a/Completion/User/_gcc +++ b/Completion/User/_gcc @@ -1,6 +1,6 @@ #compdef gcc -local state line ret=1 expl args +local context state line ret=1 expl args typeset -A opt_args args=() @@ -273,6 +273,8 @@ dump) 'p[annotate assembler output]' && ret=0 ;; library) + _tags "${context}" libraries || return 1 + _description expl library compadd "$expl[@]" - ${^=LD_LIBRARY_PATH:-/usr/lib /usr/local/lib}/lib*.(a|so*)(:t:fr:s/lib//) && ret=0 ;; diff --git a/Completion/User/_gprof b/Completion/User/_gprof index 211a7a15f..cbc362331 100644 --- a/Completion/User/_gprof +++ b/Completion/User/_gprof @@ -1,6 +1,6 @@ #compdef gprof -local state line ret=1 +local context state line ret=1 typeset -A opt_args _arguments -s -{a,b,c,D,h,i,l,L,s,T,v,w,x,y,z} \ @@ -17,6 +17,8 @@ _arguments -s -{a,b,c,D,h,i,l,L,s,T,v,w,x,y,z} \ if [[ -n "$state" ]]; then local cmd pair expl + _tags "${context}" functions || return 1 + [[ "$state" = pair ]] && pair=yes if [[ $#line -gt 1 ]]; then @@ -46,7 +48,7 @@ if [[ -n "$state" ]]; then else _description expl function fi - compadd -M 'r:|_=* r:|=*' - "$_gprof_funcs[@]" && ret=0 + compadd "$expl[@]" -M 'r:|_=* r:|=*' - "$_gprof_funcs[@]" && ret=0 else return 1 fi diff --git a/Completion/User/_groups b/Completion/User/_groups index b867634c0..bc955a8d2 100644 --- a/Completion/User/_groups +++ b/Completion/User/_groups @@ -2,6 +2,8 @@ local expl +_tags any groups || return 1 + if (( ! $+groups )); then if whence -p ypcat > /dev/null; then : ${(A)groups:=${${(s: :)$(ypcat group.byname)}%%:*}} # If you use NIS diff --git a/Completion/User/_gs b/Completion/User/_gs index 55dc4f8f7..0c9c11e10 100644 --- a/Completion/User/_gs +++ b/Completion/User/_gs @@ -8,7 +8,7 @@ if compset -N --; then return 1 fi else - local state line ret=1 + local context state line ret=1 typeset -A opt_args _x_arguments \ @@ -25,6 +25,8 @@ else if [[ "$PREFIX" = *\=* ]]; then _message 'systemdict definition value' else + _tags "$context" names || return 1 + _description expl 'systemdict definition name' compadd "$expl[@]" -M 'm:{a-z}={A-Z}' - \ DISKFONTS NOCACHE NOBIND NODISPLAY NOPAUSE PLATFONTS SAFER \ @@ -35,10 +37,14 @@ else if compset -P '*\='; then case "$IPREFIX" in *DEVICE\=) + _tags "$context" devices || return 1 + _description expl 'ghostscript device' compadd "$expl[@]" - "${(@)${=${$(gs -h)##* devices:}%%Search path:*}:#}" && ret=0 ;; *OutputFile\=) + _tags "$context" files || return 1 + _description expl 'output file' _files && ret=0 ;; @@ -47,6 +53,8 @@ else return 1 esac else + _tags "$context" names || return 1 + _description expl 'systemdict name' compadd "$expl[@]" -S\= -M 'm:{a-z}={A-Z}' - DEVICE OutputFile && ret=0 fi diff --git a/Completion/User/_hosts b/Completion/User/_hosts index 00150f9b7..d577c83ab 100644 --- a/Completion/User/_hosts +++ b/Completion/User/_hosts @@ -2,6 +2,8 @@ local expl +_tags any hosts || return 1 + : ${(A)hosts:=${(s: :)${(ps:\t:)${${(f)"$(userhost' \ @@ -25,15 +25,16 @@ local state line muttrc="~/.muttrc" ret=1 '-Z+:open first mailbox with new mail:' && ret=0 if [[ "$state" = userhost ]]; then - if compset -P '*@'; then - _description expl 'remote host name' - _hosts "$expl[@]" -q -S, - return - else - _description expl 'login name' - _users "$expl[@]" -q -S@ && ret=0 - fi - fi + _tags "$context" hosts || return 1 -return ret + if compset -P '*@'; then + _description expl 'remote host name' + _hosts "$expl[@]" -q -S, && return 0 + else + _description expl 'login name' + _users "$expl[@]" -q -S@ && return 0 + fi + fi fi + +return ret diff --git a/Completion/User/_netscape b/Completion/User/_netscape index 11f583dd5..3caaad05e 100644 --- a/Completion/User/_netscape +++ b/Completion/User/_netscape @@ -1,6 +1,6 @@ #compdef netscape -local state line +local context state line ret=1 typeset -A opt_args _x_arguments \ @@ -22,56 +22,75 @@ _x_arguments \ -{,no-}{,irix-}session-management \ -{done-save,ignore}-geometry-prefs \ -{component-bar,composer,edit,messenger,mail,discussions,news} \ - '*:location:->urls' + '*:location:->urls' && ret=0 + +[[ "$state" = "urls" ]] && + _tags "$context" files && _files "$@" && return 0 -[ "$state" = "urls" ] && _files "$@" && return # Handle netscape remote commands -if [ "$state" = "remote" ]; then +if [[ "$state" = "remote" ]]; then local -a remote_commands remote_commands=(openURL openFile saveAs mailto addBookmark) [[ $compstate[quoting] = (double|single) ]] && compset -q compset -P '*\(' case $IPREFIX in - openURL*|addBookmark* ) state=urls;; - openFile* ) _files -W ~;; - saveAs* ) + openURL*|addBookmark*) state=urls;; + openFile*) _files -W ~;; + saveAs*) if compset -P "*,"; then - compadd -s")" -M 'm:{a-zA-Z}={A-Za-z}' HTML Text PostScript + if _tags "$context" types; then + _description expl 'data type' + compadd -s")" -M 'm:{a-zA-Z}={A-Za-z}' HTML Text PostScript && + ret=0 + fi else - _path_files -W ~ + _tags "$context" files && _path_files -W ~ && ret=0 fi ;; - mailto* ) + mailto*) compset -P "*," if compset -P '*@'; then - _description expl 'remote host name' - _hosts "$expl[@]" -q -S, + if _tags "$context" hosts; then + _description expl 'remote host name' + _hosts "$expl[@]" -q -S, && ret=0 + fi else - _description expl 'login name' - _users "$expl[@]" -q -S@ + if _tags "$context" users; then + _description expl 'login name' + _users "$expl[@]" -q -S@ && ret=0 + fi fi ;; - * ) - if [ "$QIPREFIX" ]; then - compadd -q -S '(' -M 'm:{a-zA-Z}={A-Za-z}' $remote_commands - else - compadd -s'(' -S '' -M 'm:{a-zA-Z}={A-Za-z}' $remote_commands + *) + if _tags "$context" commands; then + if [[ "$QIPREFIX" ]]; then + compadd -q -S '(' -M 'm:{a-zA-Z}={A-Za-z}' $remote_commands && ret=0 + else + compadd -s'(' -S '' -M 'm:{a-zA-Z}={A-Za-z}' $remote_commands && ret=0 + fi fi ;; esac fi -if [ "$state" = "urls" ]; then +if [[ "$state" = "urls" ]]; then # Complete netscape urls if [[ -prefix about: ]]; then - compset -P about: - compadd authors blank cache document fonts global hype image-cache \ - license logo memory-cache mozilla plugins + if _tags "$context" values; then + _description expl 'about what' + compset -P about: + compadd authors blank cache document fonts global hype image-cache \ + license logo memory-cache mozilla plugins && ret=0 + fi else - _description expl 'URL prefix' - compadd "$expl[@]" -S '' about: mocha: javascript: - _urls "$@" + if _tags "$context" prefixes; then + _description expl 'URL prefix' + compadd "$expl[@]" -S '' about: mocha: javascript: + _urls "$@" && ret=0 + fi fi fi + +return ret diff --git a/Completion/User/_nslookup b/Completion/User/_nslookup index 7bf97a8ad..f3e290505 100644 --- a/Completion/User/_nslookup +++ b/Completion/User/_nslookup @@ -19,7 +19,7 @@ # other characters than lower case letters, we try to call the function # `_nslookup_host'. -local state expl ret=1 setopts +local context state expl ret=1 setopts setopts=( 'all[print current values]' \ @@ -52,6 +52,8 @@ if [[ -n "$compcontext" ]]; then funcall ret _nslookup_command && return ret + _tags any commands || return 1 + _description expl 'command' compadd "$expl[@]" - server lserver root finger ls view help set && ret=0 _hosts && ret=0 @@ -60,6 +62,8 @@ if [[ -n "$compcontext" ]]; then funcall ret _nslookup_redirect && return ret + _tags redirection files || return 1 + if [[ "$words[1]" != (finger|ls) ]]; then _message "redirection not allowed for command \`$words[1]'" return 1 @@ -84,6 +88,8 @@ if [[ -n "$compcontext" ]]; then case "$words[1]" in (|l)server) + _tags argument hosts || return 1 + _description expl 'new default server' _hosts "$expl[@]" return @@ -106,6 +112,8 @@ if [[ -n "$compcontext" ]]; then return ;; view) + _tags argument files || return 1 + _description expl 'view file' _files "$expl[@]" return @@ -118,6 +126,8 @@ if [[ -n "$compcontext" ]]; then [[ -z "$state" ]] && return ret ;; *) + _tags argument hosts || return 1 + _description expl 'server' _hosts "$expl[@]" return @@ -141,6 +151,8 @@ fi # This is completion after `srchlist' for both types. if [[ -n "$state" ]]; then + _tags "$context" hosts || return 1 + if compset -P '*/'; then _description expl 'search list entry' else diff --git a/Completion/User/_pbm b/Completion/User/_pbm index 77af9b23b..c697ebaa6 100644 --- a/Completion/User/_pbm +++ b/Completion/User/_pbm @@ -21,7 +21,7 @@ if [[ $# -ne 0 || $+_in_pbm -ne 0 ]]; then _description expl 'picture file' set -- "$expl[@]" fi - _path_files "$@" -g "$pat" || _files "$@" -g '*.(#i)p[bgp]m' + _files "$@" -g "$pat" || _files "$@" -g '*.(#i)p[bgp]m' return fi @@ -775,5 +775,5 @@ zeisstopnm) *) _description expl 'picture file' - _path_files "$expl[@]" -g "$pat" || _files "$expl[@]" -g '*.(#i)p[bgp]m' + _files "$expl[@]" -g "$pat" || _files "$expl[@]" -g '*.(#i)p[bgp]m' esac diff --git a/Completion/User/_ports b/Completion/User/_ports index 950212832..9012dfd5e 100644 --- a/Completion/User/_ports +++ b/Completion/User/_ports @@ -2,6 +2,8 @@ local expl +_tags any ports || return 1 + : ${(A)ports:=${${(M)${${(f)"$(/dev/null; then _description expl 'users logged on' compadd "$@" "$expl[@]" - $(users) && return 0 diff --git a/Completion/User/_wget b/Completion/User/_wget index c9b671194..3a15d3867 100644 --- a/Completion/User/_wget +++ b/Completion/User/_wget @@ -1,6 +1,6 @@ #compdef wget -local state line +local context state line typeset -A opt_args local tmp1 tmp2 diff --git a/Completion/User/_whois b/Completion/User/_whois index 2043cbd4e..1e0f7707c 100644 --- a/Completion/User/_whois +++ b/Completion/User/_whois @@ -112,7 +112,7 @@ _whois_setup () { } _whois_single () { - local state line expl + local context state line expl typeset -A opt_args local tmp host @@ -189,19 +189,25 @@ _whois_fwhois () { } _whois_hosts () { - compadd "$@" \ - -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' \ - - ${_whois_servers%:?} || _hosts "$@" + _tags any hosts && + compadd "$@" \ + -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' \ + - ${_whois_servers%:?} || _hosts "$@" } _whois_ports () { - compadd "$@" - whois || _ports "$@" + _tags any ports && compadd "$@" - whois || _ports "$@" } (( $+functions[_whois:whois.internic.net] )) || _whois:whois.internic.net () { if (( CURRENT == 1 )); then - compadd HELP DOMAIN HOST + local expl + + _tags any string || return 1 + + _description expl string + compadd "$expl[@]" HELP DOMAIN HOST else _message 'string' fi @@ -210,6 +216,11 @@ _whois:whois.internic.net () { (( $+functions[_whois:whois.nic.ad.jp] )) || _whois:whois.nic.ad.jp () { if (( CURRENT == 1 )); then + local expl + + _tags any string || return 1 + + _description expl string compadd HELP DOM NET HOST PERSON CONN COM else _message 'string' diff --git a/Completion/User/_yp b/Completion/User/_yp index e06f42a29..d0876f6dd 100644 --- a/Completion/User/_yp +++ b/Completion/User/_yp @@ -1,6 +1,6 @@ #compdef ypcat ypmatch yppasswd ypwhich ypset ypserv ypbind yppush yppoll ypxfr domainname -local line state ret=1 +local context line state ret=1 typeset -A opt_args if (( ! $+_yp_cache_maps )); then @@ -87,20 +87,31 @@ esac if [[ "$state" = map* ]]; then local expl - _description expl 'map name' - - # The `-M ...' allows `pa.n' to complete to `passwd.byname'. - - compadd "$expl[@]" -M 'l:.|by=by l:.|=by r:|.=* r:|=*' - \ - "$_yp_cache_maps[@]" && ret=0 if [[ $+opt_args[-t] -eq 0 && "$state" != maponly ]]; then - _description expl 'nicknames' - compadd "$expl[@]" - "$_yp_cache_nicks[@]" && ret=0 + _tags "$context" maps nicknames + else + _tags "$context" maps fi + + while _tags; do + if _requested maps; then + # The `-M ...' allows `pa.n' to complete to `passwd.byname'. + + _description expl 'map name' + compadd "$expl[@]" -M 'l:.|by=by l:.|=by r:|.=* r:|=*' - \ + "$_yp_cache_maps[@]" && ret=0 + fi + if _requested nicknames; then + _description expl 'nicknames' + compadd "$expl[@]" - "$_yp_cache_nicks[@]" && ret=0 + fi + done elif [[ "$state" = servers ]]; then if compset -P '*,'; then - _description expl 'server' - _hosts -qS, && ret=0 + if _tags "$context" hosts; then + _description expl 'server' + _hosts -qS, && ret=0 + fi else _message 'domain name' fi diff --git a/Completion/X/_x_color b/Completion/X/_x_color index 0cbcdf0eb..4c1c73bf4 100644 --- a/Completion/X/_x_color +++ b/Completion/X/_x_color @@ -29,6 +29,8 @@ if (( ! $+_color_cache )); then (( $#_color_cache )) || _color_cache=(white black gray red blue green) fi +_tags any colors || return 1 + _description expl 'color specification' compadd "$@" "$expl[@]" -M 'm:{a-z}={A-Z} m:-=\ r:|[ A-Z0-9]=* r:|=*' - \ "$_color_cache[@]" diff --git a/Completion/X/_x_cursor b/Completion/X/_x_cursor index 59ecb5976..a22189f9d 100644 --- a/Completion/X/_x_cursor +++ b/Completion/X/_x_cursor @@ -14,5 +14,7 @@ if (( ! $+_cursor_cache )); then fi fi +_tags any cursors || return 1 + _description expl 'cursor name' compadd "$@" "$expl[@]" -M 'm:-=_ r:|_=*' - "$_cursor_cache[@]" diff --git a/Completion/X/_x_display b/Completion/X/_x_display index e3f9af479..7b9fbab9a 100644 --- a/Completion/X/_x_display +++ b/Completion/X/_x_display @@ -1,3 +1,5 @@ #autoload +_tags any displays || return 1 + _hosts -S ':0 ' -r : diff --git a/Completion/X/_x_extension b/Completion/X/_x_extension index 967938e28..44e47d956 100644 --- a/Completion/X/_x_extension +++ b/Completion/X/_x_extension @@ -2,6 +2,8 @@ local expl +_tags any extensions || return 1 + (( $+_xe_cache )) || _xe_cache=( "${(@)${(@f)$(xdpyinfo)}[(r)number of extensions:*,-1][2,(r)default screen number:*][1,-2]//[ ]}" ) _description expl 'X extension' diff --git a/Completion/X/_x_font b/Completion/X/_x_font index 4ba21ddff..f4dfef79c 100644 --- a/Completion/X/_x_font +++ b/Completion/X/_x_font @@ -2,6 +2,8 @@ local expl +_tags any fonts || return 1 + # This *has* to be improved some day... if (( ! $+_font_cache )); then diff --git a/Completion/X/_x_keysym b/Completion/X/_x_keysym index 6b031014a..fc2847c57 100644 --- a/Completion/X/_x_keysym +++ b/Completion/X/_x_keysym @@ -2,6 +2,8 @@ local expl +_tags any keysyms || return 1 + if (( ! $+_keysym_cache )); then local file diff --git a/Completion/X/_x_modifier b/Completion/X/_x_modifier index a9276ab71..345243835 100644 --- a/Completion/X/_x_modifier +++ b/Completion/X/_x_modifier @@ -2,6 +2,8 @@ local expl +_tags any modifiers || return 1 + _description expl modifier compadd "$@" "$expl[@]" -M 'm:{a-z}={A-Z}' - \ Shift Lock Control Mod1 Mod2 Mod3 Mod4 Mod5 diff --git a/Completion/X/_x_window b/Completion/X/_x_window index 65d2b72e2..6d6e3112e 100644 --- a/Completion/X/_x_window +++ b/Completion/X/_x_window @@ -2,6 +2,8 @@ local list expl +_tags any windows || return 1 + list=( "${(@)${(M@)${(@f)$(xwininfo -root -tree)}:#[ ]#0x[0-9a-f]# \"*}##[ ]#}" ) if [[ "$1" = -n ]]; then diff --git a/Completion/X/_xmodmap b/Completion/X/_xmodmap index 4e7a8bfc8..d8ba420ce 100644 --- a/Completion/X/_xmodmap +++ b/Completion/X/_xmodmap @@ -1,6 +1,6 @@ #compdef xmodmap -local state line ret=1 +local context state line ret=1 typeset -A opt_args _x_arguments \ @@ -82,9 +82,11 @@ if [[ -n "$state" ]]; then [[ "$what" = *ksym* ]] && _x_keysym "$suf[@]" && ret=0 else - _description expl command - compadd "$expl[@]" -S ' ' keycode keysym clear add remove && ret=0 - compadd "$expl[@]" -S ' = ' pointer && ret=0 + if _tags any commands; then + _description expl command + compadd "$expl[@]" -S ' ' keycode keysym clear add remove && ret=0 + compadd "$expl[@]" -S ' = ' pointer && ret=0 + fi fi fi diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index e30586238..ed19df233 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -878,14 +878,14 @@ that implement a state machine. In this case, the `var(string)' (with all leading and trailing spaces and tabs removed) will be stored in the global parameter tt(state) and the function returns with a return value of 300 (to make it distinguishable from other return values) -after setting the global `tt(line)' and `tt(opt_args)' +after setting the global `tt(context)', `tt(line)' and `tt(opt_args)' parameters as described below and without resetting any changes made to the special parameters such as tt(PREFIX) and tt(words). Note that this means that a function calling tt(_arguments) with at least one action containing such a `tt(->)var(string)' has to declare appropriate local parameters as in: -example(local state line +example(local context state line typeset -A opt_args) This will ensure that tt(_arguments) does not create unused global @@ -921,7 +921,12 @@ and their arguments. These are stored in the associative array `tt(opt_args)', using the option names as keys and their arguments as the values. For options that have more than one argument these are given as one string, separated by colons. All colons in the original -arguments are preceded with backslashes. +arguments are preceded with backslashes. The parameter `tt(context)' +will be set to the automatically created context name. This is either +a string of the form `var(-opt)tt(-)var(n)' for the var(n)'th argument +of the option var(-opt), or a string of the form `tt(argument-)var(n)' +for the var(n)'th argument (for rest arguments the var(n) is the +string `tt(rest)'). Normally the option names are taken as multi-character names and a word from the line is considered to contain only one option (or @@ -1073,12 +1078,15 @@ One last difference is that this function uses the associative array tt(val_args) to report values and their arguments (but otherwise this is the same as the tt(opt_args) association used by tt(_arguments)). This also means that the function calling tt(_values) -should declare the tt(state) and tt(val_args) parameters as in: +should declare the tt(state), tt(line), tt(context) and tt(val_args) +parameters as in: -example(local state line +example(local context state line typeset -A val_args) -when using an action of the form `tt(->)var(string)'. +when using an action of the form `tt(->)var(string)'. With this +function the tt(context) parameter will be set to the name of the +value whose argument is to be completed. ) item(tt(_regex_arguments))( This function is a compiler to generate a completion function. The diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index 22a8f7656..b5b09e732 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -357,6 +357,7 @@ struct caarg { char *action; int type; char *end; + char *opt; int num; }; @@ -395,6 +396,7 @@ free_caargs(Caarg a) zsfree(a->descr); zsfree(a->action); zsfree(a->end); + zsfree(a->opt); zfree(a, sizeof(*a)); } } @@ -442,7 +444,7 @@ rembslashcolon(char *s) } static Caarg -parse_caarg(int mult, int type, int num, char **def) +parse_caarg(int mult, int type, int num, char *oname, char **def) { Caarg ret = (Caarg) zalloc(sizeof(*ret)); char *p = *def, *d, sav; @@ -451,6 +453,7 @@ parse_caarg(int mult, int type, int num, char **def) ret->descr = ret->action = ret->end = NULL; ret->num = num; ret->type = type; + ret->opt = ztrdup(oname); for (d = p; *p && *p != ':'; p++) if (*p == '\\' && p[1]) @@ -647,7 +650,7 @@ parse_cadef(char *nam, char **args) } if (c == ':') { Caarg *oargp = &oargs; - int atype, rest; + int atype, rest, oanum = 1; char *end; while (c == ':') { @@ -681,7 +684,7 @@ parse_cadef(char *nam, char **args) rest = 1; } else atype = CAA_NORMAL; - *oargp = parse_caarg(!rest, atype, 0, &p); + *oargp = parse_caarg(!rest, atype, oanum++, name, &p); oargp = &((*oargp)->next); if (rest) break; @@ -739,7 +742,7 @@ parse_cadef(char *nam, char **args) } else type = CAA_RARGS; } - ret->rest = parse_caarg(0, type, -1, &p); + ret->rest = parse_caarg(0, type, -1, NULL, &p); } else { int type = CAA_NORMAL; Caarg arg, tmp, pre; @@ -763,7 +766,7 @@ parse_cadef(char *nam, char **args) type = CAA_OPT; p++; } - arg = parse_caarg(0, type, anum - 1, &p); + arg = parse_caarg(0, type, anum - 1, NULL, &p); for (tmp = ret->args, pre = NULL; tmp && tmp->num < anum - 1; @@ -1191,8 +1194,9 @@ bin_comparguments(char *nam, char **args, char *ops, int func) switch (args[0][1]) { case 'i': min = 2; max = -1; break; case 'D': min = 2; max = 2; break; + case 'C': min = 1; max = 1; break; case 'O': min = 4; max = 4; break; - case 'L': min = 3; max = 3; break; + case 'L': min = 3; max = 4; break; case 's': min = 1; max = 1; break; case 'M': min = 1; max = 1; break; case 'a': min = 0; max = 0; break; @@ -1248,6 +1252,24 @@ bin_comparguments(char *nam, char **args, char *ops, int func) } return 1; } + case 'C': + { + Caarg arg = ca_laststate.def; + + if (arg) { + char buf[20]; + + if (arg->num > 0) + sprintf(buf, "%d", arg->num); + else + strcpy(buf, "rest"); + + setsparam(args[1], (arg->opt ? tricat(arg->opt, "-", buf) : + tricat("argument-", buf, ""))); + return 0; + } + return 1; + } case 'O': if (ca_laststate.opt) { LinkList next = newlinklist(); @@ -1283,8 +1305,8 @@ bin_comparguments(char *nam, char **args, char *ops, int func) set_list_array(args[4], equal); return 0; - } else - return 1; + } + return 1; case 'L': { Caopt opt = ca_get_opt(ca_laststate.d, args[1], 1, NULL); @@ -1293,6 +1315,9 @@ bin_comparguments(char *nam, char **args, char *ops, int func) setsparam(args[2], ztrdup(opt->args->descr)); setsparam(args[3], ztrdup(opt->args->action)); + if (args[4]) + setsparam(args[4], tricat(opt->name, "-1", NULL)); + return 0; } return 1; @@ -1306,8 +1331,8 @@ bin_comparguments(char *nam, char **args, char *ops, int func) (ca_laststate.ddef->type == CAO_EQUAL ? "equal" : "next")) : "")); return 0; - } else - return 1; + } + return 1; case 'M': setsparam(args[1], ztrdup(ca_laststate.d->match)); return 0; @@ -1533,7 +1558,7 @@ parse_cvdef(char *nam, char **args) vtype = CVV_OPT; } else vtype = CVV_ARG; - arg = parse_caarg(0, 0, 0, &p); + arg = parse_caarg(0, 0, 0, name, &p); } else { vtype = CVV_NOARG; arg = NULL; @@ -1758,10 +1783,11 @@ bin_compvalues(char *nam, char **args, char *ops, int func) switch (args[0][1]) { case 'i': min = 2; max = -1; break; case 'D': min = 2; max = 2; break; + case 'C': min = 1; max = 1; break; case 'V': min = 3; max = 3; break; case 's': min = 1; max = 1; break; case 'd': min = 1; max = 1; break; - case 'L': min = 3; max = 3; break; + case 'L': min = 3; max = 4; break; case 'v': min = 1; max = 1; break; default: zerrnam(nam, "invalid option: %s", args[0], 0); @@ -1806,6 +1832,17 @@ bin_compvalues(char *nam, char **args, char *ops, int func) } return 1; } + case 'C': + { + Caarg arg = cv_laststate.def; + + if (arg) { + setsparam(args[1], ztrdup(arg->opt)); + + return 0; + } + return 1; + } case 'V': { LinkList noarg = newlinklist(); @@ -1861,6 +1898,9 @@ bin_compvalues(char *nam, char **args, char *ops, int func) setsparam(args[2], val->arg->descr); setsparam(args[3], val->arg->action); + if (args[4]) + setsparam(args[4], ztrdup(val->name)); + return 0; } return 1; -- cgit 1.4.1