diff --git a/Completion/Core/_complete b/Completion/Core/_complete index 06d212a46..2441771bc 100644 --- a/Completion/Core/_complete +++ b/Completion/Core/_complete @@ -12,10 +12,70 @@ oldcontext="$curcontext" # If we have a user-supplied context name, use only that. if [[ -n "$compcontext" ]]; then - ccarray[3]="$compcontext" - comp="$_comps[$compcontext]" - [[ -z "$comp" ]] || "$comp" + if [[ "${(t)compcontext}" = *(array|assoc)* ]]; then + local expl + + _wanted values expl value compadd -a - compcontext + + elif [[ "$compcontext" = *:*:* ]]; then + local tag="${${compcontext%%:*}:-values}" + local descr="${${${compcontext#${tag}:}%%:*}:-value}" + local action="${compcontext#${tag}:${descr}:}" expl ws ret=1 + + case "$action" in + \ #) + _message "$descr";; + + \(\(*\)\)) + eval ws\=\( "${action[3,-3]}" \) + + _describe -t "$tag" "$descr" ws;; + + \(*\)) + eval ws\=\( "${action[2,-2]}" \) + + _wanted "$tag" expl "$descr" compadd -a - ws;; + + \{*\}) + _tags "$tag" + while _tags; do + while _next_label "$tag" expl "$descr"; do + eval "$action[2,-2]" && ret=0 + done + (( ret )) || break + done;; + + \ *) + eval ws\=\( "$action" \) + + _tags "$tag" + while _tags; do + while _next_label "$tag" expl "$descr"; do + "$ws[@]" + done + (( ret )) || break + done;; + + *) + eval ws\=\( "$action" \) + + _tags "$tag" + while _tags; do + while _next_label "$tag" expl "$descr"; do + "$ws[1]" "$expl[@]" "${(@)ws[2,-1]}" + done + (( ret )) || break + done;; + + esac + + else + ccarray[3]="$compcontext" + + comp="$_comps[$compcontext]" + [[ -z "$comp" ]] || "$comp" + fi return fi diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index de30e0ca8..7687dfb7a 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -2313,13 +2313,21 @@ contexts, in most cases named after the context itself named `tt(_tilde)'). Before trying to find a function for a specific context, tt(_complete) -checks if the parameter `tt(compcontext)' is set to a non-empty -value. If it is, the value is taken as the name of the context to use -and the function defined for that context will be called. For this -purpose, there is a special context named tt(-command-line-) that -completes whole command lines (commands and their arguments) and is -not used by the completion system itself, but has a function handling -completion for it. +checks if the parameter `tt(compcontext)' is set. If it is set to an +array, the elements are taken to be the possible matches which will be +completed using the tag `tt(values)' and the description `tt(value)'. +If `tt(compcontext)' to a string containing colons, it should be of +the form `var(tag)tt(:)var(descr)tt(:)var(action)'. In this case the +var(tag) and var(descr) give the tag and description to use and the +var(action) says what should be completed in one of the forms +described for the tt(_arguments) utility function below. + +Finally, if `tt(compcontext)' is set a string without colons, the +value is taken as the name of the context to use and the function +defined for that context will be called. For this purpose, there is a +special context named tt(-command-line-) that completes whole command +lines (commands and their arguments) and is not used by the completion +system itself, but has a function handling completion for it. ) findex(_correct) item(tt(_correct))(