diff options
-rw-r--r-- | Completion/Core/_alternative | 70 | ||||
-rw-r--r-- | Completion/Core/_requested | 9 | ||||
-rw-r--r-- | Completion/Core/_style | 45 |
3 files changed, 124 insertions, 0 deletions
diff --git a/Completion/Core/_alternative b/Completion/Core/_alternative new file mode 100644 index 000000000..158f3a07a --- /dev/null +++ b/Completion/Core/_alternative @@ -0,0 +1,70 @@ +#autoload + +local tags def expl descr action mesgs nm="$compstack[nmatches]" +local context + +if [[ "$1" = -C?* ]]; then + context="${1[3,-1]}" + shift +elif [[ "$1" = -C ]]; then + context="$2" + shift 2 +fi + +mesgs=() + +_tags -C "$context" "${(@)argv%%:*}" + +while _tags; do + for def; do + if _requested "${def%%:*}"; then + descr="${${def#*:}%%:*}" + action="${def#*:*:}" + + _description expl "$descr" + + if [[ "$action" = \ # ]]; then + + # An empty action means that we should just display a message. + + mesgs=( "$mesgs[@]" "$descr") + elif [[ "$action" = \(\(*\)\) ]]; then + local ws + + # ((...)) contains literal strings with descriptions. + + eval ws\=\( "${action[3,-3]}" \) + + _describe "$descr" ws -M 'r:|[_-]=* r:|=*' + elif [[ "$action" = \(*\) ]]; then + + # Anything inside `(...)' is added directly. + + compadd "$expl[@]" - ${=action[2,-2]} + elif [[ "$action" = \{*\} ]]; then + + # A string in braces is evaluated. + + eval "$action[2,-2]" + elif [[ "$action" = \ * ]]; then + + # If the action starts with a space, we just call it. + + ${(e)=~action} + else + + # Otherwise we call it with the description-arguments built above. + + action=( $=action ) + ${(e)action[1]} "$expl[@]" ${(e)~action[2,-1]} + fi + fi + done + [[ nm -ne compstate[nmatches] ]] && return 0 +done + +for descr in "$mesgs[@]"; do + _message "$descr" +done + +return 1 diff --git a/Completion/Core/_requested b/Completion/Core/_requested new file mode 100644 index 000000000..082c45820 --- /dev/null +++ b/Completion/Core/_requested @@ -0,0 +1,9 @@ +#autoload + +local tag tname="$funcstack[2,-1]" + +for tag; do + [[ "${_cur_tags[${tname}]}" = *:${tag}(:|\[*\]:)* ]] && return 0 +done + +return 1 diff --git a/Completion/Core/_style b/Completion/Core/_style new file mode 100644 index 000000000..b0cbd7b00 --- /dev/null +++ b/Completion/Core/_style @@ -0,0 +1,45 @@ +#autoload + +local tags get i + +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 + +if [[ "$tags" = *:${1}\[*\]:* ]]; then + + tags="${${tags#*:${1}\[}%%\]*}" + + if [[ $# -eq 2 ]]; then + if [[ -n "$get" ]]; then + eval "${2}=\"$tags\"" + return 0 + fi + + [[ "$tags" = (|*,)${2}(|,*) ]] + return + fi + + [[ "$tags" = (|*,)${2}(|(\=|,)*) ]] || return 1 + + if [[ -n "$get" ]]; then + if [[ "$tags" = (|*,)${2}\=* ]]; then + eval "${3}=\"${${tags#(|*,)${2}\=}%%,*}\"" + else + eval "${3}=''" + fi + return 0 + fi + + [[ "$tags" = (|*,)${2}\=(|[^,]#,)${3}(|,*) ]] + return +fi + +return 1 |