summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Completion/Core/_alternative70
-rw-r--r--Completion/Core/_requested9
-rw-r--r--Completion/Core/_style45
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