summaryrefslogtreecommitdiff
path: root/Completion/Base
diff options
context:
space:
mode:
Diffstat (limited to 'Completion/Base')
-rw-r--r--Completion/Base/_arguments571
-rw-r--r--Completion/Base/_default30
-rw-r--r--Completion/Base/_describe164
-rw-r--r--Completion/Base/_jobs80
-rw-r--r--Completion/Base/_subscript58
-rw-r--r--Completion/Base/_tilde55
-rw-r--r--Completion/Base/_values383
7 files changed, 575 insertions, 766 deletions
diff --git a/Completion/Base/_arguments b/Completion/Base/_arguments
index 5170acb84..bf263d6e9 100644
--- a/Completion/Base/_arguments
+++ b/Completion/Base/_arguments
@@ -3,386 +3,345 @@
# Complete the arguments of the current command according to the
# descriptions given as arguments to this function.
-local long args rest ws cur nth def nm expl descr action opt arg tmp
+local long cmd="$words[1]" descr mesg subopts opt usecc autod
+local oldcontext="$curcontext" hasopts
-# Associative arrays used to collect information about the options.
+long=$argv[(I)--]
+if (( long )); then
+ local name tmp tmpargv
-typeset -A opts mopts dopts dmopts odopts odmopts
-
-# See if we support long options, too.
+ if [[ long -eq 1 ]]; then
+ tmpargv=()
+ else
+ tmpargv=( "${(@)argv[1,long-1]}" )
+ fi
-nth=$argv[(I)--]
-if (( nth )); then
- long=( "${(@)argv[nth+1,-1]}" )
- argv=("${(@)argv[1,nth-1]}")
-else
- long=()
-fi
+ name=${~words[1]}
+ [[ "$name" != /* ]] && tmp="$PWD/$name"
-# Now parse the arguments...
+ name="_args_cache_${name}"
+ name="${name//[^a-zA-Z0-9_]/_}"
-args=()
-nth=1
-while (( $# )); do
+ if (( ! ${(P)+name} )); then
+ local iopts sopts pattern tmpo cur cache
+ typeset -U lopts
- # This describes a one-shot option.
+ cache=()
- if [[ "$1" = [-+]* ]]; then
- if [[ "$1" = *:* ]]; then
+ # We have to build a new long-option cache, get the `-i' and
+ # `-s' options.
- # If the option name ends in a `-', the first argument comes
- # directly after the option, if it ends in a `+', the first
- # argument *may* come directly after the option, otherwise it
- # is in the next word.
+ set -- "${(@)argv[long+1,-1]}"
- if [[ "$1" = [^:]##-:* ]]; then
- dopts[${${1%%:*}[1,-2]}]="${1#*:}"
- elif [[ "$1" = [^:]##+:* ]]; then
- odopts[${${1%%:*}[1,-2]}]="${1#*:}"
+ iopts=()
+ sopts=()
+ while [[ "$1" = -[is]* ]]; do
+ if [[ "$1" = -??* ]]; then
+ tmp="${1[3,-1]}"
+ cur=1
else
- opts[${1%%:*}]="${1#*:}"
+ tmp="$2"
+ cur=2
fi
- else
- opts[$1]=''
- fi
- elif [[ "$1" = \*[-+]* ]]; then
-
- # The same for options that may appear more than once.
-
- if [[ "$1" = *:* ]]; then
- if [[ "$1" = [^:]##-:* ]]; then
- dmopts[${${1[2,-1]%%:*}[1,-2]}]="${1#*:}"
- elif [[ "$1" = [^:]##+:* ]]; then
- odmopts[${${1[2,-1]%%:*}[1,-2]}]="${1#*:}"
+ if [[ "$tmp[1]" = '(' ]]; then
+ tmp=( ${=tmp[2,-2]} )
else
- mopts[${1[2,-1]%%:*}]="${1#*:}"
+ tmp=( "${(@P)tmp}" )
fi
- else
- mopts[${1[2,-1]}]=''
- fi
- elif [[ "$1" = \*:* ]]; then
+ if [[ "$1" = -i* ]]; then
+ iopts=( "$iopts[@]" "$tmp[@]" )
+ else
+ sopts=( "$sopts[@]" "$tmp[@]" )
+ fi
+ shift cur
+ done
- # This is `*:...', describing `all other arguments'.
+ # Now get the long option names by calling the command with `--help'.
+ # The parameter expansion trickery first gets the lines as separate
+ # array elements. Then we select all lines whose first non-blank
+ # character is a hyphen. Since some commands document more than one
+ # option per line, separated by commas, we convert commas int
+ # newlines and then split the result again at newlines after joining
+ # the old array elements with newlines between them. Then we select
+ # those elements that start with two hyphens, remove anything up to
+ # those hyphens and anything from the space or comma after the
+ # option up to the end.
- rest="${1[3,-1]}"
- elif [[ "$1" = :* ]]; then
+ lopts=("--${(@)^${(@)${(@)${(@M)${(@ps:\n:j:\n:)${(@)${(@M)${(@f)$(_call options ${~words[1]} --help 2>&1)//\[--/
+--}:#[ ]#-*}//,/
+}}:#[ ]#--*}#*--}%%[], ]*}:#}")
+ lopts=( "${(@)lopts:#--}" )
- # This is `:...', describing `the next argument'.
+ # Now remove all ignored options ...
- args[nth++]="${1#*:}"
- else
+ while (( $#iopts )); do
+ lopts=( ${lopts:#$~iopts[1]} )
+ shift iopts
+ done
- # And this is `n:...', describing the `n'th argument.
+ # ... and add "same" options
- args[${1%%:*}]="${1#*:}"
- nth=$(( ${1%%:*} + 1 ))
- fi
- shift
-done
+ while (( $#sopts )); do
+ lopts=( $lopts ${lopts/$sopts[1]/$sopts[2]} )
+ shift 2 sopts
+ done
-if [[ $#long -ne 0 && "$PREFIX" = --* ]]; then
+ # Then we walk through the descriptions plus a few builtin ones.
- # If the current words starts with `--' and we should use long
- # options, just call...
+ set -- "$@" '*=FILE*:file:_files' \
+ '*=(DIR|PATH)*:directory:_files -/' '*: :'
- _long_options "$long[@]"
-else
+ while (( $# )); do
- # Otherwise parse the command line...
+ # First, we get the pattern and the action to use and take them
+ # from the positional parameters.
- ws=( "${(@)words[2,-1]}" )
- cur=$(( CURRENT-2 ))
- nth=1
+ pattern="${${${(M)1#*[^\\]:}[1,-2]}//\\\\:/:}"
+ descr="${1#${pattern}}"
+ shift
- # ...until the current word is reached.
+ # We get all options matching the pattern and take them from the
+ # list we have built. If no option matches the pattern, we
+ # continue with the next.
- while [[ cur -gt 0 ]]; do
+ tmp=("${(@M)lopts:##$~pattern}")
+ lopts=("${(@)lopts:##$~pattern}")
- # `def' holds the description for the option we are currently after.
- # Check if the next argument for the option is optional.
+ (( $#tmp )) || continue
- if [[ "$def" = :* ]]; then
- opt=yes
- else
opt=''
- fi
- arg=''
-
- # Remove one description/action pair from `def' if that isn't empty.
- if [[ -n "$def" ]]; then
- if [[ "$def" = ?*:*:* ]]; then
- def="${def#?*:*:}"
- else
- def=''
- fi
- else
+ # If there are option strings with a `[=', we take these get an
+ # optional argument.
- # If it is empty, and the word starts with `--' and we should
- # complete long options, just ignore this word, otherwise make sure
- # we test for options below and handle normal arguments.
+ tmpo=("${(@M)tmp:#*\[\=*}")
+ if (( $#tmpo )); then
+ tmp=("${(@)tmp:#*\[\=*}")
+ tmpo=("${(@)${(@)tmpo%%\=*}//[^a-z0-9-]}")
- if [[ $#long -eq 0 || "$ws[1]" != --* ]]; then
- opt=yes
- arg=yes
- else
- def=''
+ if [[ "$descr" = ::* ]]; then
+ cache=( "$cache[@]" "${(@)^tmpo}=${descr}" )
+ else
+ cache=( "$cache[@]" "${(@)^tmpo}=:${descr}" )
+ fi
fi
- fi
-
- if [[ -n "$opt" ]]; then
-
- # `opt' was set above if we have to test if the word is an option.
- # We first test for the simple options -- those without arguments or
- # those whose arguments have to be given as separate words.
-
- if (( $+opts[$ws[1]] )); then
-
- # Options that may only be given once are removed from the
- # associative array so that we are not offered them again.
- def="$opts[$ws[1]]"
- unset "opts[$ws[1]]"
- elif (( $+mopts[$ws[1]] )); then
- def="$mopts[$ws[1]]"
- else
+ # Descriptions with `=': mandatory argument.
- # If the word is none of the simple options, test for those
- # whose first argument has to or may come directly after the
- # option. This is done in four loops looking very much alike.
+ tmpo=("${(@M)tmp:#*\=*}")
+ if (( $#tmpo )); then
+ tmp=("${(@)tmp:#*\=*}")
+ tmpo=("${(@)${(@)tmpo%%\=*}//[^a-z0-9-]}")
- if (( $#dopts )); then
+ cache=( "$cache[@]" "${(@)^tmpo}=${descr}" )
+ fi
- # First we get the option names.
+ # Everything else is just added as a option without arguments.
- tmp=( "${(@k)dopts}" )
+ if (( $#tmp )); then
+ tmp=("${(@)tmp//[^a-zA-Z0-9-]}")
+ cache=( "$cache[@]" "$tmp[@]" )
+ fi
+ done
+ eval "${name}=( \"\${(@)cache:# #}\" )"
+ fi
+ set -- "$tmpargv[@]" "${(@P)name}"
+fi
- # Then we loop over them and see if the current word begins
- # with one of the option names.
+subopts=()
+while [[ "$1" = -(O*|C) ]]; do
+ case "$1" in
+ -C) usecc=yes; shift ;;
+ -O) subopts=( "${(@P)2}" ); shift 2 ;;
+ *) subopts=( "${(@P)1[3,-1]}" ); shift ;;
+ esac
+done
- while (( $#tmp )); do
- [[ "$ws[1]" = ${tmp[1]}* ]] && break
- shift 1 tmp
- done
+zstyle -s ":completion:${curcontext}:options" auto-description autod
- if (( $#tmp )); then
+if (( $# )) && comparguments -i "$autod" "$@"; then
+ local nm="$compstate[nmatches]" action noargs aret expl local
+ local next direct odirect equal single match matched ws tmp1 tmp2 tmp3
+ local opts subc prefix suffix
+ local origpre="$PREFIX" origipre="$IPREFIX"
- # It does. So use the description for it, but only from
- # the second argument on, because we are searching the
- # description for the next command line argument.
+ if comparguments -D descr action; then
+ comparguments -C subc
+ curcontext="${oldcontext%:*}:$subc"
- opt=''
- def="$dopts[$tmp[1]]"
- unset "dopts[$tmp[1]]"
- if [[ "$def" = ?*:*:* ]]; then
- def="${def#?*:*:}"
- else
- def=''
- fi
- fi
- fi
- if [[ -n "$opt" && $#dmopts -ne 0 ]]; then
- tmp=( "${(@k)dmopts}" )
- while (( $#tmp )); do
- [[ "$ws[1]" = ${tmp[1]}* ]] && break
- shift 1 tmp
- done
-
- if (( $#tmp )); then
- opt=''
- def="$dmopts[$tmp[1]]"
- if [[ "$def" = ?*:*:* ]]; then
- def="${def#?*:*:}"
- else
- def=''
- fi
- fi
- fi
- if [[ -n "$opt" && $#odopts -ne 0 ]]; then
- tmp=( "${(@k)odopts}" )
- while (( $#tmp )); do
- [[ "$ws[1]" = ${tmp[1]}* ]] && break
- shift 1 tmp
- done
-
- if (( $#tmp )); then
- opt=''
- def="$odopts[$tmp[1]]"
- unset "odopts[$tmp[1]]"
-
- # For options whose first argument *may* come after the
- # option, we skip over the first description only if there
- # is something after the option name on the line.
-
- if [[ "$ws[1]" != "$tmp[1]" ]]; then
- if [[ "$def" = ?*:*:* ]]; then
- def="${def#?*:*:}"
- else
- def=''
- fi
- fi
- fi
- fi
- if [[ -n "$opt" && $#odmopts -ne 0 ]]; then
- tmp=( "${(@k)odmopts}" )
- while (( $#tmp )); do
- [[ "$ws[1]" = ${tmp[1]}* ]] && break
- shift 1 tmp
- done
-
- if (( $#tmp )); then
- opt=''
- def="$odmopts[$tmp[1]]"
- if [[ "$ws[1]" != "$tmp[1]" ]]; then
- if [[ "$def" = ?*:*:* ]]; then
- def="${def#?*:*:}"
- else
- def=''
- fi
- fi
- fi
- fi
-
- # If we didn't find a matching option description and we were
- # told to use normal argument descriptions, just increase
- # our counter `nth'.
-
- if [[ -n "$opt" && -n "$arg" ]]; then
- def=''
- (( nth++ ))
- fi
- fi
+ if comparguments -O next direct odirect equal; then
+ opts=yes
+ _tags arguments options
+ else
+ _tags arguments
+ fi
+ else
+ if comparguments -a; then
+ noargs='no more arguments'
+ else
+ noargs='no arguments'
fi
+ comparguments -O next direct odirect equal || return 1
- shift 1 ws
- (( cur-- ))
- done
+ opts=yes
+ _tags options
+ fi
- # Now generate the matches.
+ while true; do
+ while _tags; do
+ if [[ -n "$matched" ]] || _requested arguments; then
+ _description arguments expl "$descr"
+
+ if [[ "$action" = -\>* ]]; then
+ comparguments -W line opt_args
+ state="${${action[3,-1]##[ ]#}%%[ ]#}"
+ if [[ -n "$usecc" ]]; then
+ curcontext="${oldcontext%:*}:$subc"
+ else
+ context="$subc"
+ fi
+ compstate[restore]=''
+ aret=yes
+ else
+ if [[ -z "$local" ]]; then
+ local line
+ typeset -A opt_args
+ local=yes
+ fi
- nm="$compstate[nmatches]"
+ comparguments -W line opt_args
- if [[ -z "$def" || "$def" = :* ]]; then
+ if [[ "$action" = \ # ]]; then
- # We either don't have a description for an argument of an option
- # or we have a description for a optional argument.
+ # An empty action means that we should just display a message.
- if [[ -z "$def" ]]; then
+ [[ -n "$matched" ]] && compadd -n -Q -S '' -s "$SUFFIX" - "$PREFIX"
+ mesg="$descr"
- # If we have none at all, use the one for this argument position.
+ elif [[ "$action" = \(\(*\)\) ]]; then
- def="$args[nth]"
- [[ -z "$def" ]] && def="$rest"
- fi
+ # ((...)) contains literal strings with descriptions.
- # In any case, we have to complete option names here, but we may
- # be in a string that starts with an option names and continues with
- # the first argument, test that (again, four loops).
+ eval ws\=\( "${action[3,-3]}" \)
- opt=yes
- if (( $#dopts )); then
+ _describe "$descr" ws -M "$match" "$subopts[@]"
- # Get the option names.
+ elif [[ "$action" = \(*\) ]]; then
- tmp=( "${(@k)dopts}" )
- while (( $#tmp )); do
- if compset -P "$tmp[1]"; then
+ # Anything inside `(...)' is added directly.
- # The current string starts with the option name, so ignore
- # that and complete the rest of the string.
+ _all_labels arguments expl "$descr" \
+ compadd "$subopts[@]" - ${=action[2,-2]}
+ elif [[ "$action" = \{*\} ]]; then
- def="$dopts[$tmp[1]]"
- opt=''
- break
- fi
- shift 1 tmp
- done
- fi
- if [[ -n "$opt" && $#dmopts -ne 0 ]]; then
- tmp=( "${(@k)dmopts}" )
- while (( $#tmp )); do
- if compset -P "$tmp[1]"; then
- def="$dmopts[$tmp[1]]"
- opt=''
- break
- fi
- shift 1 tmp
- done
- fi
- if [[ -n "$opt" && $#odopts -ne 0 ]]; then
- tmp=( "${(@k)odopts}" )
- while (( $#tmp )); do
- if compset -P "$tmp[1]"; then
- def="$odopts[$tmp[1]]"
- opt=''
- break
- fi
- shift 1 tmp
- done
- fi
- if [[ -n "$opt" && $#odmopts -ne 0 ]]; then
- tmp=( "${(@k)odmopts}" )
- while (( $#tmp )); do
- if compset -P "$tmp[1]"; then
- def="$odmopts[$tmp[1]]"
- opt=''
- break
- fi
- shift 1 tmp
- done
- fi
- if [[ -n "$opt" ]]; then
-
- # We aren't in an argument directly after a option name, so
- # all option names are possible matches.
-
- _description expl option
- compadd "$expl[@]" - "${(@k)opts}" "${(@k)mopts}" \
- "${(@k)dopts}" "${(@k)dmopts}" \
- "${(@k)odopts}" "${(@k)odmopts}"
- fi
- fi
+ # A string in braces is evaluated.
- # Now add the matches from the description, if any.
+ while _next_label arguments expl "$descr"; do
+ eval "$action[2,-2]"
+ done
+ elif [[ "$action" = \ * ]]; then
- if [[ -n "$def" ]]; then
+ # If the action starts with a space, we just call it.
- # Ignore the leading colon describing optional arguments.
+ eval "action=( $action )"
+ while _next_label arguments expl "$descr"; do
+ "$action[@]"
+ done
+ else
- [[ "$def" = :* ]] && def="$def[2,-1]"
+ # Otherwise we call it with the description-arguments.
- # Get the description and the action.
+ eval "action=( $action )"
+ _all_labels arguments expl "$descr" \
+ "$action[1]" "$subopts[@]" "${(@)action[2,-1]}"
+ fi
+ fi
+ fi
- descr="${def%%:*}"
- action="${${def#*:}%%:*}"
+ if [[ -z "$matched$hasopts" ]] && _requested options &&
+ { ! zstyle -T ":completion:${curcontext}:options" prefix-needed ||
+ [[ "$origpre" = [-+]* ||
+ ( -z "$aret$mesg" && nm -eq compstate[nmatches] ) ]] } ; then
+ local prevpre="$PREFIX" previpre="$IPREFIX"
+
+ hasopts=yes
+
+ PREFIX="$origpre"
+ IPREFIX="$origipre"
+
+ comparguments -M match
+
+ if comparguments -s single; then
+
+ _description options expl option
+
+ if [[ "$single" = direct ]]; then
+ compadd "$expl[@]" -QS '' - "${PREFIX}${SUFFIX}"
+ elif [[ "$single" = next ]]; then
+ compadd "$expl[@]" -Q - "${PREFIX}${SUFFIX}"
+ elif [[ "$single" = equal ]]; then
+ compadd "$expl[@]" -QqS= - "${PREFIX}${SUFFIX}"
+ else
+ tmp1=( "$next[@]" "$direct[@]" "$odirect[@]" "$equal[@]" )
+ tmp3=( "${(M@)tmp1:#[-+]?[^:]*}" )
+ tmp1=( "${(M@)tmp1:#[-+]?(|:*)}" )
+ tmp2=( "${PREFIX}${(@M)^${(@)${(@)tmp1%%:*}#[-+]}:#?}" )
+
+ _describe -o option \
+ tmp1 tmp2 -Q -S '' -- \
+ tmp3 -Q
+ fi
+ single=yes
+ else
+ next=( "$next[@]" "$odirect[@]" )
+ _describe -o option \
+ next -Q -M "$match" -- \
+ direct -QS '' -M "$match" -- \
+ equal -QqS= -M "$match"
+ fi
+ PREFIX="$prevpre"
+ IPREFIX="$previpre"
+ fi
+ done
+ if [[ -n "$opts" && -z "$aret$matched$mesg" &&
+ nm -eq compstate[nmatches] ]]; then
- _description expl "$descr"
+ PREFIX="$origpre"
+ IPREFIX="$origipre"
- if [[ -z "$action" ]]; then
+ prefix="${PREFIX#*\=}"
+ suffix="$SUFFIX"
+ PREFIX="${PREFIX%%\=*}"
+ SUFFIX=''
+ compadd -M "$match" -D equal - "${(@)equal%%:*}"
- # An empty action means that we should just display a message.
- _message "$descr"
- return 1
- elif [[ "$action[1]" = \( ]]; then
+ if [[ $#equal -eq 1 ]]; then
+ PREFIX="$prefix"
+ SUFFIX="$suffix"
+ IPREFIX="${IPREFIX}${equal[1]%%:*}="
+ matched=yes
- # Anything inside `(...)' is added directly.
+ comparguments -L "${equal[1]%%:*}" descr action subc
+ curcontext="${oldcontext%:*}:$subc"
- compadd "$expl[@]" - ${=action[2,-2]}
- elif [[ "$action" = \ * ]]; then
+ _tags arguments
- # If the action starts with a space, we just call it.
+ continue
+ fi
+ fi
+ break
+ done
- $=action
- else
+ [[ -z "$aret" || -z "$usecc" ]] && curcontext="$oldcontext"
- # Otherwise we call it with the description-arguments built above.
+ [[ -n "$aret" ]] && return 300
- action=( $=action )
- "$action[1]" "$expl[@]" "${(@)action[2,-1]}"
- fi
- fi
+ [[ -n "$mesg" ]] && _message "$mesg"
+ [[ -n "$noargs" ]] && _message "$noargs"
# Set the return value.
- [[ nm -ne "$compstate[nmatches]" ]]
+ [[ nm -ne "$compstate[nmatches]" ]]
+else
+ return 1
fi
diff --git a/Completion/Base/_default b/Completion/Base/_default
index 8bcf14f6a..fd5869e2e 100644
--- a/Completion/Base/_default
+++ b/Completion/Base/_default
@@ -1,13 +1,23 @@
-#defcomp -default-
+#compdef -default-
-# We first try the `compctl's. This is without first (-T) and default (-D)
-# completion. If you want them add `-T' and/or `-D' to this command.
-# If there is a `compctl' for the command we are working on, we return
-# immediatly. If you want to use new style completion anyway, remove the
-# `|| return'. Also, you may want to use new style completion if the
-# `compctl' didn't produce any matches. In that case remove the `|| return'
-# and at the line `[[ -nmatches 0 ]] || return' after `compcall'.
+local ctl
-compcall || return
+if { zstyle -s ":completion:${curcontext}:" use-compctl ctl ||
+ zmodload -e zsh/compctl } && [[ "$ctl" != (no|false|0|off) ]]; then
+ local opt
-_files
+ opt=()
+ [[ "$ctl" = *first* ]] && opt=(-T)
+ [[ "$ctl" = *default* ]] && opt=("$opt[@]" -D)
+ compcall "$opt[@]" || return 0
+fi
+
+_wanted files || return 1
+
+_files && return 0
+
+# magicequalsubst allows arguments like <any-old-stuff>=~/foo to do
+# file name expansion after the =. In that case, it's natural to
+# allow completion to handle file names after any equals sign.
+
+[[ -o magicequalsubst ]] && compset -P 1 '*=' && _files
diff --git a/Completion/Base/_describe b/Completion/Base/_describe
index e01c77509..6e6f4f4a9 100644
--- a/Completion/Base/_describe
+++ b/Completion/Base/_describe
@@ -2,154 +2,52 @@
# This can be used to add options or values with descriptions as matches.
-setopt localoptions extendedglob
+local _opt _expl _tmps _tmpd _tmpmd _tmpms _ret=1 _showd _nm _hide _args
+local _type=values _descr
-local gdescr isopt cmd opt nsets tmp descr match descrs matches adescr i
-local disps disp expl tmps tmpd tmpmd tmpms name ret=1 showd _nm
+# Get the option.
-cmd="$words[1]"
-
-# Get the options.
-
-while getopts 'oc:' opt; do
- if [[ "$opt" = o ]]; then
- isopt=yes
- else
- cmd="$OPTARG"
- fi
-done
-shift OPTIND-1
+if [[ "$1" = -o ]]; then
+ _type=options
+ shift
+fi
# Do the tests. `showd' is set if the descriptions should be shown.
-if [[ -n "$isopt" ]]; then
-
- # We take the value to test the number of patches from a non-local
- # parameter `nm' if that exists and contains only digits. It's a hack.
-
- if [[ "$nm" = [0-9]## ]]; then
- _nm="$nm"
- else
- _nm=0
- fi
- [[ -n "$compconfig[option_prefix]" &&
- "$compconfig[option_prefix]" != *\!${cmd}* &&
- "$PREFIX" != [-+]* &&
- ( "$compconfig[option_prefix]" = *nodefault* ||
- _nm -ne compstate[nmatches] ) ]] && return 1
+_wanted "$_type" || return 1
- [[ -n "$compconfig[describe_options]" &&
- "$compconfig[describe_options]" != *\!${cmd}* ]] && showd=yes
-else
- [[ -n "$compconfig[describe_values]" &&
- "$compconfig[describe_values]" != *\!${cmd}* ]] && showd=yes
-fi
+zstyle -T ":completion:${curcontext}:$_type" verbose && _showd=yes
-gdescr="$1"
+_descr="$1"
shift
-# Now interpret the arguments.
+[[ "$_type" = options ]] &&
+ zstyle -t ":completion:${curcontext}:options" prefix-hidden && _hide=yes
-nsets=0
-adescr=()
-descrs=()
-matches=()
-while (( $# )); do
- (( nsets++ ))
- descr="$1"
- [[ -n "$showd" ]] && adescr=( "$adescr[@]" "${(@PM)^descr:#*:?*},$nsets" )
- if [[ "$2" = -* ]]; then
- match=''
- shift
- else
- match="$2"
- shift 2
- fi
- tmp=$argv[(i)--]
- if [[ tmp -eq 1 ]]; then
- opt=()
- else
- opt=( "${(@)argv[1,tmp-1]}" )
- fi
- if [[ tmp -gt $# ]]; then
- argv=()
+while _next_label "$_type" _expl "$_descr"; do
+
+ if [[ -n "$_showd" ]]; then
+ compdescribe -I ' -- ' "$@"
else
- shift tmp
+ compdescribe -i "$@"
fi
- # `descr' and `matches' collect the names of the arrays containing the
- # possible matches with descriptions and the matches to add.
- # The options to give to `compadd' are stored in local arrays.
+ while compdescribe -g _args _tmpd _tmpmd _tmps _tmpms; do
- descrs[nsets]="$descr"
- matches[nsets]="$match"
- typeset -a _descr_opts_$nsets
- eval "_descr_opts_${nsets}=( \"\$opt[@]\" )"
-done
-
-(( nsets )) || return 1
-
-# Build the display strings if needed.
-
-[[ -n "$showd" ]] && _display disps "$adescr[@]"
-_description expl "$gdescr"
+ # See if we should remove the option prefix characters.
-# Loop through the array/option sets we have.
-
-i=0
-while [[ ++i -le nsets ]]; do
- name=_descr_opts_$i
- [[ -n "$showd" ]] && disp=( "${(@)${(@M)disps:#*,${i}}%,*}" )
- descr=( "${(@P)descrs[i]}" )
-
- # We collect the strings to display in `tmpd' (one string per line)
- # and `tmps' (in columns) and the matches to add in `tmpmd' and `tmpms'.
-
- tmpd=()
- tmps=()
- tmpmd=()
- tmpms=()
- if [[ -n "$matches[i]" ]]; then
- match=( "${(@P)matches[i]}" )
- while (( $#match )); do
- if [[ -n "$showd" && "$descr[1]" = *:?* ]]; then
- tmpd=( "$tmpd[@]" "$disp[1]" )
- tmpmd=( "$tmpmd[@]" "$match[1]" )
- shift 1 disp
- else
- tmps=( "$tmps[@]" "${descr[1]%%:*}" )
- tmpms=( "$tmpms[@]" "$match[1]" )
+ if [[ -n "$_hide" ]]; then
+ if [[ "$PREFIX" = --* ]]; then
+ _tmpd=( "${(@)_tmpd#--}" )
+ _tmps=( "${(@)_tmps#--}" )
+ elif [[ "$PREFIX" = [-+]* ]]; then
+ _tmpd=( "${(@)_tmpd#[-+]}" )
+ _tmps=( "${(@)_tmps#[-+]}" )
fi
- shift 1 match
- shift 1 descr
- done
- else
- while (( $#descr )); do
- if [[ -n "$showd" && "$descr[1]" = *:?* ]]; then
- tmpd=( "$tmpd[@]" "$disp[1]" )
- tmpmd=( "$tmpmd[@]" "${descr[1]%%:*}" )
- shift 1 disp
- else
- tmps=( "$tmps[@]" "${descr[1]%%:*}" )
- tmpms=( "$tmpms[@]" "${descr[1]%%:*}" )
- fi
- shift 1 descr
- done
- fi
-
- # See if we should remove the option prefix characters.
-
- if [[ -n "$isopt" && "$compconfig[option_prefix]" = hide* ]]; then
- if [[ "$PREFIX" = --* ]]; then
- tmpd=( "${(@)tmpd#--}" )
- tmps=( "${(@)tmps#--}" )
- elif [[ "$PREFIX" = [-+]* ]]; then
- tmpd=( "${(@)tmpd#[-+]}" )
- tmps=( "${(@)tmps#[-+]}" )
fi
- fi
- compadd "${(@P)name}" "$expl[@]" -ld tmpd - "$tmpmd[@]" && ret=0
- compadd "${(@P)name}" "$expl[@]" -d tmps - "$tmpms[@]" && ret=0
-done
-return ret
+ compadd "$_args[@]" "$_expl[@]" -ld _tmpd - "$_tmpmd[@]" && _ret=0
+ compadd "$_args[@]" "$_expl[@]" -d _tmps - "$_tmpms[@]" && _ret=0
+ done
+done
+return _ret
diff --git a/Completion/Base/_jobs b/Completion/Base/_jobs
index 869aeeb8a..45983ad16 100644
--- a/Completion/Base/_jobs
+++ b/Completion/Base/_jobs
@@ -1,27 +1,85 @@
#autoload
-local expl disp jobs job jids
+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
+ shift
+fi
+zstyle -t ":completion:${curcontext}:jobs" prefix-hidden && pfx=''
+zstyle -T ":completion:${curcontext}:jobs" verbose && desc=yes
if [[ "$1" = -r ]]; then
jids=( "${(@k)jobstates[(R)running*]}" )
shift
- _description expl 'running job'
+ expls='running job'
elif [[ "$1" = -s ]]; then
jids=( "${(@k)jobstates[(R)running*]}" )
shift
- _description expl 'suspended job'
+ expls='suspended job'
else
[[ "$1" = - ]] && shift
jids=( "${(@k)jobtexts}" )
- _description expl job
+ expls=job
fi
-disp=()
-jobs=()
-for job in "$jids[@]"; do
- disp=( "$disp[@]" "${(l:3:: ::%:)job} -- ${jobtexts[$job]}" )
- jobs=( "$jobs[@]" "$job" )
-done
+if [[ -n "$desc" ]]; then
+ disp=()
+ for job in "$jids[@]"; do
+ [[ -n "$desc" ]] &&
+ disp=( "$disp[@]" "${pfx}${(r:2:: :)job} -- ${(r:COLUMNS-8:: :)jobtexts[$job]}" )
+ done
+fi
+
+zstyle -s ":completion:${curcontext}:jobs" numbers how
+
+if [[ "$how" = (yes|true|on|1) ]]; then
+ jobs=( "$jids[@]" )
+else
+ local texts i text str tmp num max=0
-compadd "$@" "$expl[@]" -ld disp - "%$^jobs[@]"
+ # Find shortest unambiguous strings.
+ texts=( "$jobtexts[@]" )
+ jobs=()
+ for i in "$jids[@]"; do
+ text="$jobtexts[$i]"
+ str="${text%% *}"
+ if [[ "$text" = *\ * ]]; then
+ text="${text#* }"
+ else
+ text=""
+ fi
+ tmp=( "${(@M)texts:#${str}*}" )
+ num=1
+ while [[ -n "$text" && $#tmp -ge 2 ]]; do
+ str="${str} ${text%% *}"
+ if [[ "$text" = *\ * ]]; then
+ text="${text#* }"
+ else
+ text=""
+ fi
+ tmp=( "${(@M)texts:#${str}*}" )
+ (( num++ ))
+ done
+
+ [[ num -gt max ]] && max="$num"
+
+ jobs=( "$jobs[@]" "$str" )
+ done
+
+ if [[ "$how" = [0-9]## && max -gt how ]]; then
+ jobs=( "$jids[@]" )
+ else
+ [[ -z "$pfx" && -n "$desc" ]] && disp=( "${(@)disp#%}" )
+ fi
+fi
+
+if [[ -n "$desc" ]]; then
+ _all_labels jobs expl "$expls" compadd "$@" -ld disp - "%$^jobs[@]"
+else
+ _all_labels jobs expl "$expls" compadd "$@" - "%$^jobs[@]"
+fi
diff --git a/Completion/Base/_subscript b/Completion/Base/_subscript
index 2b827a117..60d45370b 100644
--- a/Completion/Base/_subscript
+++ b/Completion/Base/_subscript
@@ -1,4 +1,56 @@
-#defcomp -subscript-
+#compdef -subscript-
-_compalso -math- "$@"
-[[ ${(Pt)${COMMAND}} = assoc* ]] && complist -k "( ${(kP)${COMMAND}} )"
+local expl
+
+if [[ "$PREFIX" = :* ]]; then
+ _wanted characters expl 'character class' \
+ compadd -p: -S ':]' alnum alpha blank cntrl digit graph \
+ lower print punct space upper xdigit
+elif [[ ${(Pt)${compstate[parameter]}} = assoc* ]]; then
+ local suf
+
+ [[ "$RBUFFER" != \]* ]] && suf=']'
+
+ _wanted association-keys expl 'association key' \
+ compadd -S "$suf" - "${(@kP)${compstate[parameter]}}"
+elif [[ ${(Pt)${compstate[parameter]}} = array* ]]; then
+ local list i j ret=1 disp
+
+ _tags indexes parameters
+
+ while _tags; do
+ if _requested indexes; then
+ ind=( {1..${#${(P)${compstate[parameter]}}}} )
+ if zstyle -T ":completion:${curcontext}:indexes" verbose; then
+ list=()
+ for i in "$ind[@]"; do
+ if [[ "$i" = ${PREFIX}*${SUFFIX} ]]; then
+ list=( "$list[@]"
+ "${i}:$(print -D ${(P)${compstate[parameter]}[$i]})" )
+ else
+ list=( "$list[@]" '' )
+ fi
+ done
+ zformat -a list ' -- ' "$list[@]"
+ disp=( -d list)
+ else
+ disp=()
+ fi
+
+ if [[ "$RBUFFER" = \]* ]]; then
+ _all_labels -V indexes expl 'array index' \
+ compadd -S '' "$disp[@]" - "$ind[@]" && ret=0
+ else
+ _all_labels -V indexes expl 'array index' \
+ compadd -S ']' "$disp[@]" - "$ind[@]" && ret=0
+ fi
+ fi
+ _requested parameters && _parameters && ret=0
+
+ (( ret )) || return 0
+ done
+
+ return 1
+else
+ _compalso -math-
+fi
diff --git a/Completion/Base/_tilde b/Completion/Base/_tilde
index aef575e19..7ab058e01 100644
--- a/Completion/Base/_tilde
+++ b/Completion/Base/_tilde
@@ -1,10 +1,53 @@
-#defcomp -tilde-
+#compdef -tilde-
# We use all named directories and user names here. If this is too slow
# for you or if there are too many of them, you may want to use
-# `compgen -k friends -qS/' or something like that. To get all user names
-# if there are no matches in the `friends' array, add
-# `(( compstate[nmatches] )) || compgen -nu -qS/'
-# below that.
+# `compadd -qS/ - "$friends[@]"' or something like that.
-compgen -nu -qS/
+local expl suf dirs list lines revlines i ret disp nm="$compstate[nmatches]"
+
+if [[ "$SUFFIX" = */* ]]; then
+ ISUFFIX="/${SUFFIX#*/}$ISUFFIX"
+ SUFFIX="${SUFFIX%%/*}"
+ suf=(-S '')
+else
+ suf=(-qS/)
+fi
+
+_tags users named-directories directory-stack
+
+while _tags; do
+ _requested users && _users "$suf[@]" "$@" && ret=0
+ _requested named-directories expl 'named directory' \
+ compadd "$suf[@]" "$@" - "${(@k)nameddirs}"
+
+ if _requested directory-stack &&
+ { ! zstyle -T ":completion:${curcontext}:directory-stack" prefix-needed ||
+ [[ "$PREFIX" = [-+]* || nm -eq compstate[nmatches] ]] }; then
+ if zstyle -T ":completion:${curcontext}:directory-stack" verbose; 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
+ _all_labels -V directory-stack expl 'directory stack' \
+ compadd "$suf[@]" "$disp[@]" -Q - "$list[@]" && ret=0
+ fi
+ (( ret )) || return 0
+done
diff --git a/Completion/Base/_values b/Completion/Base/_values
index 4be3e8203..62cf0e409 100644
--- a/Completion/Base/_values
+++ b/Completion/Base/_values
@@ -1,322 +1,103 @@
#autoload
-setopt localoptions extendedglob
+local subopts opt usecc
-local name arg def descr xor str tmp ret=1 expl nm="$compstate[nmatches]"
-local snames odescr gdescr sep
-typeset -A names onames xors _values
+subopts=()
+while [[ "$1" = -(O*|C) ]]; do
+ case "$1" in
+ -C) usecc=yes; shift ;;
+ -O) subopts=( "${(@P)2}" ); shift 2 ;;
+ *) subopts=( "${(@P)1[3,-1]}" ); shift ;;
+ esac
+done
-# Probably fill our cache.
+if compvalues -i "$@"; then
-if [[ "$*" != "$_vals_cache_args" ]]; then
- _vals_cache_args="$*"
+ local noargs args opts descr action expl sep subc
+ local oldcontext="$curcontext"
- unset _vals_cache_{sep,descr,names,onames,snames,xors,odescr}
+ if ! compvalues -D descr action; then
- typeset -gA _vals_cache_{names,onames,xors}
- _vals_cache_snames=()
- _vals_cache_odescr=()
+ _wanted values || return 1
- # Get the separator, if any.
+ curcontext="${oldcontext%:*}:values"
- if [[ "$1" = -s ]]; then
- _vals_cache_sep="$2"
- shift 2
- fi
-
- # This is the description string for the values.
-
- _vals_cache_descr="$1"
- shift
-
- # Now parse the descriptions.
-
- while (( $# )); do
-
- # Get the `name', anything before an unquoted colon.
-
- if [[ "$1" = *[^\\]:* ]]; then
- name="${${${(M)1#*[^\\]:}[1,-2]}//\\\\:/:}"
- else
- name="$1"
- fi
-
- descr=''
- xor=''
-
- # Get a description, if any.
-
- if [[ "$name" = *\[*\] ]]; then
- descr="${${name#*\[}[1,-2]}"
- name="${name%%\[*}"
- fi
-
- # Get the names of other values that are mutually exclusive with
- # this one.
-
- if [[ "$name" = \(*\)* ]]; then
- xor="${${name[2,-1]}%%\)*}"
- name="${name#*\)}"
- fi
-
- # Finally see if this value may appear more than once.
-
- if [[ "$name" = \** ]]; then
- name="$name[2,-1]"
- else
- xor="$xor $name"
- fi
-
- # Store the information in the cache.
-
- _vals_cache_odescr=( "$_vals_cache_odescr[@]" "${name}:$descr" )
- [[ -n "$xor" ]] && _vals_cache_xors[$name]="${${xor##[ ]#}%%[ ]#}"
-
- # Get the description and store that.
-
- if [[ "$1" = *[^\\]:* ]]; then
- descr=":${1#*[^\\]:}"
- else
- descr=''
- fi
-
- if [[ "$descr" = ::* ]]; then
+ compvalues -V noargs args opts
- # Optional argument.
-
- _vals_cache_onames[$name]="$descr[3,-1]"
- elif [[ "$descr" = :* ]]; then
-
- # Mandatory argument.
-
- _vals_cache_names[$name]="$descr[2,-1]"
- else
-
- # No argument.
-
- _vals_cache_snames=( "$_vals_cache_snames[@]" "$name" )
- fi
- shift
- done
-fi
-
-snames=( "$_vals_cache_snames[@]" )
-names=( "${(@kv)_vals_cache_names}" )
-onames=( "${(@kv)_vals_cache_onames}" )
-xors=( "${(@kv)_vals_cache_xors}" )
-odescr=( "$_vals_cache_odescr[@]" )
-gdescr="$_vals_cache_descr"
-sep="$_vals_cache_sep"
-
-if [[ -n "$sep" ]]; then
-
- # We have a separator character. We parse the PREFIX and SUFFIX to
- # see if any of the values that must not appear more than once are
- # already on the line.
-
- while [[ "$PREFIX" = *${sep}* ]]; do
-
- # Get one part, remove it from PREFIX and put it into IPREFIX.
-
- tmp="${PREFIX%%${sep}*}"
- PREFIX="${PREFIX#*${sep}}"
- IPREFIX="${IPREFIX}${tmp}${sep}"
-
- # Get the value `name'.
-
- name="${tmp%%\=*}"
-
- if [[ "$tmp" = *\=* ]]; then
- _values[$name]="${tmp#*\=}"
- else
- _values[$name]=''
- fi
-
- # And remove the descriptions for the values this one makes
- # superfluous.
-
- if [[ -n "$xors[$name]" ]]; then
- snames=( "${(@)snames:#(${(j:|:)~${=xors[$name]}})}" )
- odescr=( "${(@)odescr:#(${(j:|:)~${=xors[$name]}}):*}" )
- unset {names,onames,xors}\[${^=tmp}\]
- fi
- done
- if [[ "$SUFFIX" = *${sep}* ]]; then
-
- # The same for the suffix.
+ if [[ "$PREFIX" = *\=* ]]; then
+ local name
- str="${SUFFIX%%${sep}*}"
- SUFFIX="${SUFFIX#*${sep}}"
- while [[ -n "$SUFFIX" ]]; do
- tmp="${PREFIX%%${sep}*}"
- if [[ "$SUFFIX" = *${sep}* ]]; then
- SUFFIX="${SUFFIX#*${sep}}"
+ name="${PREFIX%%\=*}"
+ if compvalues -L "$name" descr action; then
+ IPREFIX="${IPREFIX}${name}="
+ PREFIX="${PREFIX#*\=}"
else
- SUFFIX=''
+ local prefix suffix
+
+ prefix="${PREFIX#*\=}"
+ suffix="$SUFFIX"
+ PREFIX="$name"
+ SUFFIX=''
+ args=( "$args[@]" "$opts[@]" )
+ compadd -M 'r:|[_-]=* r:|=*' -D args - "${(@)args[@]%%:*}"
+
+ [[ $#args -ne 1 ]] && return 1
+
+ PREFIX="$prefix"
+ SUFFIX="$suffix"
+ IPREFIX="${IPREFIX}${args[1]%%:*}="
+ compvalues -L "${args[1]%%:*}" descr action subc
+ curcontext="${oldcontext%:*}:$subc"
fi
- PREFIX="${PREFIX#*${sep}}"
- IPREFIX="${IPREFIX}${tmp}${sep}"
-
- name="${tmp%%\=*}"
-
- if [[ "$tmp" = *\=* ]]; then
- _values[$name]="${tmp#*\=}"
+ else
+ compvalues -d descr
+ if [[ ${#noargs}+${#args}+${#opts} -ne 1 ]] && compvalues -s sep; then
+ sep=( "-qQS" "$sep" )
else
- _values[$name]=''
+ sep=()
fi
- if [[ -n "$xors[$name]" ]]; then
- snames=( "${(@)snames:#(${(j:|:)~${=xors[$name]}})}" )
- odescr=( "${(@)odescr:#(${(j:|:)~${=xors[$name]}}):*}" )
- unset {names,onames,xors}\[${^=tmp}\]
- fi
- done
- SUFFIX="$str"
- fi
-fi
-
-descr=''
-str="$PREFIX$SUFFIX"
-
-if [[ "$str" = *\=* ]]; then
-
- # The string from the line contains a `=', so we get the stuff before
- # it and after it and see what we can do here...
-
- name="${str%%\=*}"
- arg="${str#*\=}"
-
- if (( $snames[(I)${name}] )); then
-
- # According to our information, the value doesn't get an argument,
- # so give up.
-
- _message "\`${name}' gets no value"
- return 1
- elif (( $+names[$name] )); then
-
- # It has to get an argument, we skip over the name and complete
- # the argument (below).
-
- def="$names[$name]"
- if ! compset -P '*\='; then
- IPREFIX="${IPREFIX}${name}="
- PREFIX="$arg"
- SUFFIX=''
- fi
- elif (( $+onames[$name] )); then
+ _describe "$descr" \
+ noargs "$sep[@]" -M 'r:|[_-]=* r:|=*' -- \
+ args -S= -M 'r:|[_-]=* r:|=*' -- \
+ opts -qS= -M 'r:|[_-]=* r:|=*'
- # Gets an optional argument, same as previous case.
+ curcontext="$oldcontext"
- def="$onames[$name]"
- if ! compset -P '*\='; then
- IPREFIX="${IPREFIX}${name}="
- PREFIX="$arg"
- SUFFIX=''
+ return
fi
else
- local pre="$PREFIX" suf="$SUFFIX"
-
- # The part before the `=' isn't a known value name, so we see if
- # it matches only one of the known names.
-
- if [[ "$PREFIX" = *\=* ]]; then
- PREFIX="${PREFIX%%\=*}"
- pre="${pre#*\=}"
- SUFFIX=''
- else
- SUFFIX="${SUFFIX%%\=*}"
- pre="${suf#*\=}"
- suf=''
- fi
-
- tmp=( "${(@k)names}" "${(@k)onames}" )
- compadd -M 'r:|[-_]=* r:|=*' -D tmp - "$tmp[@]"
-
- if [[ $#tmp -eq 1 ]]; then
-
- # It does, so we use that name and immediatly start completing
- # the argument for it.
-
- IPREFIX="${IPREFIX}${tmp[1]}="
- PREFIX="$pre"
- SUFFIX="$suf"
-
- def="$names[$tmp[1]]"
- [[ -z "$def" ]] && def="$onames[$tmp[1]]"
- elif (( $#tmp )); then
- _message "ambiguous option \`${PREFIX}${SUFFIX}'"
- return 1
- else
- _message "unknown option \`${PREFIX}${SUFFIX}'"
- return 1
- fi
+ compvalues -C subc
+ curcontext="${oldcontext%:*}:$subc"
fi
-else
-
- # No `=', just complete value names.
-
- _description expl "$gdescr"
- [[ -n "$sep" && ${#snames}+${#names}+${#onames} -ne 1 ]] &&
- expl=( "-qS$sep" "$expl[@]" )
-
- tmp=''
- if [[ -n "$compconfig[describe_values]" &&
- "$compconfig[describe_values]" != *\!${words[1]}* ]]; then
- if _display tmp odescr -M 'r:|[_-]=* r:|=*'; then
- if (( $#snames )); then
- compadd "$expl[@]" -y tmp -M 'r:|[_-]=* r:|=*' - \
- "$snames[@]" && ret=0
- compadd -n -S= -J "_$gdescr" -M 'r:|[_-]=* r:|=*' - \
- "${(@k)names}" && ret=0
- compadd -n -qS= -J "_$gdescr" -M 'r:|[_-]=* r:|=*' - \
- "${(@k)onames}" && ret=0
- elif (( $#names )); then
- compadd -n -S= "$expl[@]" -y tmp -M 'r:|[_-]=* r:|=*' - \
- "${(@k)names}" && ret=0
- compadd -n -qS= -J "_$gdescr" -M 'r:|[_-]=* r:|=*' - \
- "${(@k)onames}" && ret=0
- else
- compadd -n -qS= "$expl[@]" -y tmp -M 'r:|[_-]=* r:|=*' - \
- "${(@k)onames}" && ret=0
- fi
- fi
- fi
- if [[ -z "$tmp" ]]; then
- compadd "$expl[@]" -M 'r:|[_-]=* r:|=*' - "$snames[@]" && ret=0
- compadd -S= "$expl[@]" -M 'r:|[_-]=* r:|=*' - "${(@k)names}" && ret=0
- compadd -qS= "$expl[@]" -M 'r:|[_-]=* r:|=*' - "${(@k)onames}" && ret=0
+ if ! _tags arguments; then
+ curcontext="$oldcontext"
+ return 1
fi
- return ret
-fi
-
-if [[ -z "$def" ]]; then
- _message 'no value'
- return 1
-else
- local action
-
- descr="${${${(M)def#*[^\\]:}[1,-2]}//\\\\:/:}"
- action="${${def#*[^\\]:}//\\\\:/:}"
- _description expl "$descr"
+ _description arguments expl "$descr"
# We add the separator character as a autoremovable suffix unless
# we have only one possible value left.
- [[ -n "$sep" && ${#snames}+${#names}+${#onames} -ne 1 ]] &&
+ [[ ${#snames}+${#names}+${#onames} -ne 1 ]] && compvalues -s sep &&
expl=( "-qS$sep" "$expl[@]" )
if [[ "$action" = -\>* ]]; then
- values=( "${(@kv)_values}" )
+ compvalues -v val_args
state="${${action[3,-1]##[ ]#}%%[ ]#}"
+ if [[ -n "$usecc" ]]; then
+ curcontext="${oldcontext%:*}:$subc"
+ else
+ context="$subc"
+ fi
compstate[restore]=''
return 1
else
- typeset -A values
+ typeset -A val_args
- values=( "${(@kv)_values}" )
+ compvalues -v val_args
if [[ "$action" = \ # ]]; then
@@ -332,36 +113,44 @@ else
eval ws\=\( "${action[3,-3]}" \)
- if _display tmp ws; then
- compadd "$expl[@]" -y tmp - "${(@)ws%%:*}"
- else
- _message "$descr"
- return 1
- fi
+ _describe "$descr" ws -M 'r:|[_-]=* r:|=*' "$subopts[@]"
+
elif [[ "$action" = \(*\) ]]; then
# Anything inside `(...)' is added directly.
- compadd "$expl[@]" - ${=action[2,-2]}
+ _all_labels arguments expl "$descr" \
+ compadd "$subopts[@]" - ${=action[2,-2]}
elif [[ "$action" = \{*\} ]]; then
# A string in braces is evaluated.
- eval "$action[2,-2]"
-
+ while _next_label arguments expl "$descr"; do
+ eval "$action[2,-2]"
+ done
elif [[ "$action" = \ * ]]; then
# If the action starts with a space, we just call it.
- ${(e)=~action}
+ eval "action=( $action )"
+ while _next_label arguments expl "$descr"; do
+ "$action[@]"
+ done
else
# Otherwise we call it with the description-arguments built above.
- action=( $=action )
- ${(e)action[1]} "$expl[@]" ${(e)~action[2,-1]}
+ eval "action=( $action )"
+ _all_labels arguments expl "$descr" \
+ "$action[1]" "$subopts[@]" "${(@)action[2,-1]}"
fi
fi
-fi
-[[ nm -ne "$compstate[nmatches]" ]]
+ curcontext="$oldcontext"
+
+ [[ nm -ne "$compstate[nmatches]" ]]
+else
+ curcontext="$oldcontext"
+
+ return 1;
+fi