diff options
-rw-r--r-- | Completion/Base/Utility/_alternative | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/Completion/Base/Utility/_alternative b/Completion/Base/Utility/_alternative new file mode 100644 index 000000000..d6aef96b6 --- /dev/null +++ b/Completion/Base/Utility/_alternative @@ -0,0 +1,82 @@ +#autoload + +local tags def expl descr action mesgs nm="$compstate[nmatches]" subopts +local opt curcontext="$curcontext" + +subopts=() +while getopts 'O:C:' opt; do + case "$opt" in + O) subopts=( "${(@P)OPTARG}" ) ;; + C) curcontext="${curcontext%:*}:$OPTARG" ;; + esac +done + +shift OPTIND-1 + +[[ "$1" = -(|-) ]] && shift + +mesgs=() + +_tags "${(@)argv%%:*}" + +while _tags; do + for def; do + if _requested "${def%%:*}"; then + descr="${${def#*:}%%:*}" + action="${def#*:*:}" + + _description "${def%%:*}" 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:|=*' "$subopts[@]" + elif [[ "$action" = \(*\) ]]; then + + # Anything inside `(...)' is added directly. + + _all_labels "${def%%:*}" expl "$descr" \ + compadd "$subopts[@]" - ${=action[2,-2]} + elif [[ "$action" = \{*\} ]]; then + + # A string in braces is evaluated. + + while _next_label "${def%%:*}" expl "$descr"; do + eval "$action[2,-2]" + done + elif [[ "$action" = \ * ]]; then + + # If the action starts with a space, we just call it. + + eval "action=( $action )" + while _next_label "${def%%:*}" expl "$descr"; do + "$action[@]" + done + else + + # Otherwise we call it with the description-arguments built above. + + eval "action=( $action )" + while _next_label "${def%%:*}" expl "$descr"; do + "$action[1]" "$subopts[@]" "$expl[@]" "${(@)action[2,-1]}" + done + fi + fi + done + [[ nm -ne compstate[nmatches] ]] && return 0 +done + +for descr in "$mesgs[@]"; do + _message "$descr" +done + +return 1 |