summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>1999-11-09 13:14:59 +0000
committerTanaka Akira <akr@users.sourceforge.net>1999-11-09 13:14:59 +0000
commitc615397157e5efd7a81c8ce11b3f77fd7ccb5a19 (patch)
tree9f6e9081024370574ae18b5808ebedf6d653d672
parentzsh-workers/8599 (diff)
downloadzsh-c615397157e5efd7a81c8ce11b3f77fd7ccb5a19.tar
zsh-c615397157e5efd7a81c8ce11b3f77fd7ccb5a19.tar.gz
zsh-c615397157e5efd7a81c8ce11b3f77fd7ccb5a19.tar.bz2
zsh-c615397157e5efd7a81c8ce11b3f77fd7ccb5a19.tar.lz
zsh-c615397157e5efd7a81c8ce11b3f77fd7ccb5a19.tar.xz
zsh-c615397157e5efd7a81c8ce11b3f77fd7ccb5a19.tar.zst
zsh-c615397157e5efd7a81c8ce11b3f77fd7ccb5a19.zip
zsh-workers/8603
-rw-r--r--Completion/Base/_arguments26
-rw-r--r--Completion/Base/_describe15
-rw-r--r--Completion/Base/_values10
-rw-r--r--Completion/Builtins/_kill16
-rw-r--r--Completion/Builtins/_wait12
-rw-r--r--Completion/Core/_alternative70
-rw-r--r--Completion/Core/_files23
-rw-r--r--Completion/Core/_main_complete4
-rw-r--r--Completion/Core/_requested9
-rw-r--r--Completion/Core/_style45
-rw-r--r--Completion/Core/_tags41
-rw-r--r--Completion/Core/compinit171
12 files changed, 363 insertions, 79 deletions
diff --git a/Completion/Base/_arguments b/Completion/Base/_arguments
index 31713750f..68b52eef4 100644
--- a/Completion/Base/_arguments
+++ b/Completion/Base/_arguments
@@ -154,14 +154,14 @@ fi
if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
local nm="$compstate[nmatches]" action noargs aret expl local
local next direct odirect equal single match matched ws tmp1 tmp2
- local tags opts
+ local opts
if comparguments -D descr action; then
if comparguments -O next direct odirect equal; then
opts=yes
- _tags -f "$funcstack[2]" argument option
+ _tags argument option
else
- _tags -f "$funcstack[2]" argument
+ _tags argument
fi
else
if comparguments -a; then
@@ -172,12 +172,12 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
comparguments -O next direct odirect equal || return 1
opts=yes
- _tags -f "$funcstack[2]" option
+ _tags option
fi
while _tags; do
while true; do
- if [[ "$tags" = *:argument* ]]; then
+ if [[ -n "$matched" ]] || _requested argument; then
_description expl "$descr"
if [[ "$action" = -\>* ]]; then
@@ -207,7 +207,7 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
eval ws\=\( "${action[3,-3]}" \)
- _describe -c "$cmd" -f "$funcstack[2]" "$descr" ws -M "$match"
+ _describe -c "$cmd" "$descr" ws -M "$match"
elif [[ "$action" = \(*\) ]]; then
@@ -234,8 +234,8 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
fi
fi
fi
- if [[ "$tags" = *:option* &&
- ( "$tags" != *\[*prefix*\]* || "$PREFIX" = [-+]* ) ]]; then
+ if [[ -z "$matched" ]] && _requested option &&
+ { ! _style option prefix || [[ "$PREFIX" = [-+]* ]] } ; then
comparguments -M match
if comparguments -s single; then
@@ -253,20 +253,21 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
tmp1=( "${(M@)tmp1:#[-+]?(|:*)}" )
tmp2=( "${PREFIX}${(@M)^${(@)${(@)tmp1%%:*}#[-+]}:#?}" )
- _describe -o -c "$cmd" -f "$funcstack[2]" option \
+ _describe -o -c "$cmd" option \
tmp1 tmp2 -Q -S ''
fi
single=yes
else
next=( "$next[@]" "$odirect[@]" )
- _describe -o -c "$cmd" -f "$funcstack[2]" option \
+ _describe -o -c "$cmd" option \
next -Q -M "$match" -- \
direct -QS '' -M "$match" -- \
equal -QqS= -M "$match"
fi
fi
- if [[ -n "$opts" && -z "$aret$matched" && nm -ne compstate[nmatches] &&
- "$tags" = *:argument* ]]; then
+ if [[ -n "$opts" && -z "$aret$matched" &&
+ nm -ne compstate[nmatches] ]] &&
+ _requested argument; then
local prefix suffix
@@ -282,7 +283,6 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
IPREFIX="${IPREFIX}${equal[1]%%:*}="
matched=yes
comparguments -L "$equal[1]" descr action
- tags=argument
continue
fi
fi
diff --git a/Completion/Base/_describe b/Completion/Base/_describe
index ddd35f0e7..41c2ba8e5 100644
--- a/Completion/Base/_describe
+++ b/Completion/Base/_describe
@@ -2,19 +2,16 @@
# This can be used to add options or values with descriptions as matches.
-local cmd func opt expl tmps tmpd tmpmd tmpms ret=1 showd _nm hide
-local tags type=value
+local cmd opt expl tmps tmpd tmpmd tmpms ret=1 showd _nm hide
+local type=value
cmd="$words[1]"
-func="$funcstack[2]"
# Get the options.
-while getopts 'oc:f:' opt; do
+while getopts 'oc:' opt; do
if [[ "$opt" = o ]]; then
type=option
- elif [[ "$opt" = f ]]; then
- func="$OPTARG"
else
cmd="$OPTARG"
fi
@@ -23,9 +20,9 @@ shift OPTIND-1
# Do the tests. `showd' is set if the descriptions should be shown.
-_tags -i -c "$cmd" -f "$func" "$type" || return 1
+_tags -c "$cmd" "$type" || return 1
-[[ "$tags" = *:${type}\[*describe*\]* ]] && showd=yes
+_style "$type" describe && showd=yes
_description expl "$1"
shift
@@ -36,7 +33,7 @@ else
compdescribe -i "$@"
fi
-[[ "$type" = option && "$tags" = *:option\[*hide*\]* ]] && hide=yes
+[[ "$type" = option ]] && _style option hide && hide=yes
while compdescribe -g args tmpd tmpmd tmps tmpms; do
diff --git a/Completion/Base/_values b/Completion/Base/_values
index 9d89c7ea9..aac8b392d 100644
--- a/Completion/Base/_values
+++ b/Completion/Base/_values
@@ -2,11 +2,11 @@
if compvalues -i "$@"; then
- local tags noargs args opts descr action expl sep
+ local noargs args opts descr action expl sep
if ! compvalues -D descr action; then
- _tags -i value || return 1
+ _tags value || return 1
compvalues -V noargs args opts
@@ -42,7 +42,7 @@ if compvalues -i "$@"; then
sep=()
fi
- _describe -f "$funcstack[2]" "$descr" \
+ _describe "$descr" \
noargs "$sep[@]" -M 'r:|[_-]=* r:|=*' -- \
args -S= -M 'r:|[_-]=* r:|=*' -- \
opts -qS= -M 'r:|[_-]=* r:|=*'
@@ -51,7 +51,7 @@ if compvalues -i "$@"; then
fi
fi
- _tags -i argument || return 1
+ _tags argument || return 1
_description expl "$descr"
@@ -85,7 +85,7 @@ if compvalues -i "$@"; then
eval ws\=\( "${action[3,-3]}" \)
- _describe -f "$funcstack[2]" "$descr" ws -M 'r:|[_-]=* r:|=*'
+ _describe "$descr" ws -M 'r:|[_-]=* r:|=*'
elif [[ "$action" = \(*\) ]]; then
diff --git a/Completion/Builtins/_kill b/Completion/Builtins/_kill
index bb198b7a4..43ff40838 100644
--- a/Completion/Builtins/_kill
+++ b/Completion/Builtins/_kill
@@ -1,23 +1,13 @@
#compdef kill
-local tags list expl
+local list expl
if compset -P 1 -; then
- _tags -i signal || return 1
+ _tags signal || return 1
_description expl signal
compadd "$expl[@]" $signals[1,-3]
else
- local ret=1
-
- _tags job process
-
- while _tags; do
- [[ "$tags" = *:job:* ]] && _jobs && ret=0
- [[ "$tags" = *:process:* ]] && _pids && ret=0
- (( ret )) || break
- done
-
- return ret
+ _alternative 'job:: _jobs' 'process:: _pids'
fi
diff --git a/Completion/Builtins/_wait b/Completion/Builtins/_wait
index b03aac6e0..c1022a25f 100644
--- a/Completion/Builtins/_wait
+++ b/Completion/Builtins/_wait
@@ -1,13 +1,3 @@
#compdef wait
-local tags ret=1
-
-_tags job process
-
-while _tags; do
- [[ "$tags" = *:job:* ]] && _jobs && ret=0
- [[ "$tags" = *:process:* ]] && _pids && ret=0
- (( ret )) || break
-done
-
-return ret
+_alternative 'job:: _jobs' 'process:: _pids'
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/_files b/Completion/Core/_files
index 4adae0f73..eb1ec3559 100644
--- a/Completion/Core/_files
+++ b/Completion/Core/_files
@@ -1,6 +1,6 @@
#autoload
-local opts opt type=file tags
+local opts opt type=file
opts=()
while getopts "P:S:qr:R:W:F:J:V:X:f/g:M:" opt; do
@@ -13,15 +13,24 @@ while getopts "P:S:qr:R:W:F:J:V:X:f/g:M:" opt; do
done
case "$type" in
-file) _tags -f "$funcstack[2]" file ;;
-dir) _tags -f "$funcstack[2]" path file ;;
-*) _tags -f "$funcstack[2]" glob path file ;;
+file) _tags file ;;
+dir) _tags path file ;;
+*) _tags glob path file ;;
esac
while _tags; do
- [[ "$tags" = *:file:* ]] && { _path_files "$opts[@]" -f ; return }
- [[ "$tags" = *:path:* ]] && _path_files "$opts[@]" -/ && return 0
- [[ "$tags" = *:glob:* ]] && _path_files "$opts[@]" -g "$type" && return 0
+ if _requested file; then
+ _path_files "$opts[@]" -f
+ return
+ elif _requested path; then
+ if _requested glob; then
+ _path_files "$opts[@]" -/g "$type" && return 0
+ else
+ _path_files "$opts[@]" -/g "$type" && return 0
+ fi
+ elif _requested glob; then
+ _path_files "$opts[@]" -g "$type" && return 0
+ fi
done
return 1
diff --git a/Completion/Core/_main_complete b/Completion/Core/_main_complete
index d1d75de7f..e4ee2879b 100644
--- a/Completion/Core/_main_complete
+++ b/Completion/Core/_main_complete
@@ -17,9 +17,9 @@
# state than the global one for which you are completing.
-local comp post ret=1 _compskip tags _prio_num=1
+local comp post ret=1 _compskip _prio_num=1
typeset -U _offered_tags _tried_tags _failed_tags _used_tags _unused_tags
-typeset -A _prio_names
+typeset -A _prio_names _cur_tags
_offered_tags=()
_tried_tags=()
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
diff --git a/Completion/Core/_tags b/Completion/Core/_tags
index 9b9ce96b4..7b1254325 100644
--- a/Completion/Core/_tags
+++ b/Completion/Core/_tags
@@ -1,19 +1,21 @@
#autoload
+local tname="$funcstack[2,-1]"
+
if (( $# )); then
- local cmd="$words[1]" func="$funcstack[2]" defs i ttags tag pat style prio
- local trynow
+ local cmd="$words[1]" defs i ttags tag pat style prio context opt
- while getopts 'c:f:i' i; do
- case "$i" in
- c) cmd="$OPTARG" ;;
- f) func="$OPTARG" ;;
- i) trynow=yes ;;
- esac
+ while getopts 'c:C:' opt; do
+ if [[ "$opt" = c ]]; then
+ cmd="$OPTARG"
+ else
+ context="$OPTARG"
+ fi
done
-
shift OPTIND-1
+ [[ -n "$context" ]] && context="/$context"
+
defs=( "${(@M)argv:#${(kj:|:)~override_tags[(R)(|+*)]}}" )
(( $#defs )) && set -- "$defs[@]"
@@ -42,8 +44,7 @@ if (( $# )); then
for i in "$defs[@]"; do
tag="${i%%:*}"
for pat in "${(s.:.)i#*:}"; do
- if [[ ( "$pat" = _* && "$func" = ${~pat%%\=*} ) ||
- "$cmd" = ${~pat%%\=*} ]]; then
+ if [[ "$cmd$context" = ${~pat%%\=*} ]]; then
prio="${pat#*\=}"
[[ "$prio" = -* ]] && continue 2
@@ -65,22 +66,24 @@ if (( $# )); then
done
prio="_prio_arr$(( _prio_num++ ))"
- _prio_names[$funcstack]="$prio"
- eval "${prio}=( \"\${(@)ttags:#}\" )"
+ _prio_names[$tname]="$prio"
+ ttags=( "${(@)ttags:#}" )
+ eval "${prio}=( \"\$ttags[@]\" )"
- [[ -z "$trynow" ]] && return 0
+ return \!$#ttags
fi
-local prios="$_prio_names[$funcstack]"
+local prios="$_prio_names[$tname]"
-_failed_tags=( "$_failed_tags[@]" "$_last_tags[@]" )
+_failed_tags=( "$_failed_tags[@]" "$_last_tags" )
(( ${(P)#prios} )) || return 1
-tags="${${(@P)prios}[1]}:"
-shift 1 "$prios"
+_cur_tags[$tname]="${(@)${(@P)prios}[1]}:"
-_last_tags=( "${(@s.:.)${${tags#:}%:}}" )
+_last_tags=( "${(@)${(@s.:.)${(@P)prios}[1]}:#}" )
_tried_tags=( "$_tried_tags[@]" "$_last_tags[@]" )
+shift 1 "$prios"
+
return 0
diff --git a/Completion/Core/compinit b/Completion/Core/compinit
index 3d316fac8..1b88cc8f0 100644
--- a/Completion/Core/compinit
+++ b/Completion/Core/compinit
@@ -446,6 +446,177 @@ comptag() {
fi
}
+# First suggested function for new configuration interface.
+#
+# Example:
+#
+# conf1 \
+# argument = 1 \
+# value = 1 with describe \
+# option = 2 with describe and hide \
+# file = 3 \
+# path in '*dvi*' = 1 \
+# else = 2 \
+# glob = 1 \
+# job = never
+
+conf1() {
+ local tag pat prio
+
+ while (( $# )); do
+
+ tag="$1"
+ shift
+
+ while (( $# )); do
+
+ if [[ "$1" = in ]]; then
+ pat="$2"
+ shift 2
+ else
+ pat='*'
+ [[ "$1" = else ]] && shift
+ fi
+
+ style=''
+
+ if [[ "$1" = is ]]; then
+ prio=0
+ style="[${2}]"
+ shift 2
+ elif [[ "$1" = \= ]]; then
+ if [[ "$2" = n(o|ever) ]]; then
+ prio=-1
+ shift 2
+ else
+ prio="$2"
+ shift 2
+
+ if [[ "$1" = with ]]; then
+ while [[ "$1" = (with|and) ]]; do
+ style="${style},${2}"
+ shift 2
+ done
+ style="[${style[2,-1]}]"
+ fi
+ fi
+ else
+ echo "$0: missing priority: $1"
+ return 1
+ fi
+ if [[ -n "$comptags[$tag]" ]]; then
+ comptags[$tag]="${comptags[$tag]}:${pat}=${prio}${style}"
+ else
+ comptags[$tag]="${pat}=${prio}${style}"
+ fi
+
+ [[ "$1" = (in|else|\=) ]] || break
+
+ done
+ done
+
+ return 0
+}
+
+# Second suggested function for new configuration interface.
+#
+# Example:
+#
+# conf2 \
+# for '*dvi*' do \
+# glob and path or \
+# file \
+# else do \
+# glob or \
+# path or \
+# file \
+# for '*p[bgpn]m*' do \
+# argument and option with describe and with hide \
+# else do \
+# argument or \
+# value with describe or \
+# option with describe \
+# for 'kill' do \
+# no job but \
+# process \
+# else do \
+# process and job
+
+conf2() {
+ local pat prio tag style
+
+ while (( $# )); do
+
+ if [[ "$1" = for ]]; then
+ pat="$2"
+ shift 2
+ elif [[ "$1" = (else|always) ]]; then
+ pat="*"
+ shift
+ else
+ echo "$0: missing context: $1"
+ return 1
+ fi
+
+ shift 1
+
+ prio=1
+
+ while (( $# )); do
+
+ if [[ "$1" = no ]]; then
+ while [[ "$1" != (but|for|else|always) ]]; do
+ if [[ -n "$comptags[$2]" ]]; then
+ comptags[$2]="${comptags[$2]}:${pat}=-1"
+ else
+ comptags[$2]="${pat}=-1"
+ fi
+
+ shift 2
+ done
+
+ [[ "$1" != but ]] && break
+
+ shift
+ fi
+
+ while (( $# )); do
+
+ tag="$1"
+ shift
+
+ style=''
+ if [[ "$1" = with ]]; then
+ shift
+ while true; do
+ style="${style},${1}"
+ [[ "$2" != and || "$3" != with ]] && break
+ shift 3
+ done
+ shift
+ fi
+
+ [[ -n "$style" ]] && style="[${style[2,-1]}]"
+
+ if [[ -n "$comptags[$tag]" ]]; then
+ comptags[$tag]="${comptags[$tag]}:${pat}=${prio}${style}"
+ else
+ comptags[$tag]="${pat}=${prio}${style}"
+ fi
+
+ [[ "$1" != and ]] && break
+
+ shift
+ done
+
+ [[ "$1" != or ]] && break
+
+ (( prio++ ))
+ shift
+ done
+ done
+}
+
# Utility function to call a function if it exists.
#
# Usage: funcall <return> <name> [ <args> ... ]