summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Completion/Base/_argument_sets32
-rw-r--r--Completion/Base/_arguments33
-rw-r--r--Doc/Zsh/compsys.yo14
-rw-r--r--Src/Zle/computil.c44
5 files changed, 105 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index e01c4b999..8dd744148 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2000-05-11 Sven Wischnowsky <wischnow@zsh.org>
+ * 11320: Completion/Base/_argument_sets, Completion/Base/_arguments,
+ Doc/Zsh/compsys.yo, Src/Zle/computil.c: allow internally-mutually
+ exclusive sets in _argument_sets; fixes for _argument_sets and the
+ C-code forit
+
* 11319: Completion/Core/_main_complete, Doc/Zsh/compsys.yo,
Doc/Zsh/mod_complist.yo, Src/Zle/compcore.c, Src/Zle/complist.c:
make ^G in menu-selection restore the old command line; add
diff --git a/Completion/Base/_argument_sets b/Completion/Base/_argument_sets
index 5218fef69..d9c771051 100644
--- a/Completion/Base/_argument_sets
+++ b/Completion/Base/_argument_sets
@@ -1,10 +1,20 @@
#autoload
local all ret=1 end xor has_args had_args ostate ocontext oopt_args r
+local nm="$compstate[nmatches]"
local opre="$PREFIX" oipre="$IPREFIX" ocur="$CURRENT"
local osuf="$SUFFIX" oisuf="$ISUFFIX" owords
+local _ms_match _ms_opt _ms_soptmid _ms_soptmidadd _ms_soptend
+local _ms_optnext _ms_optdirect _ms_optequal
-owords="$words[@]"
+_ms_soptmid=()
+_ms_soptmidadd=()
+_ms_soptend=()
+_ms_optnext=()
+_ms_optdirect=()
+_ms_optequal=()
+
+owords=("$words[@]")
end=$argv[(i)-]
[[ end -gt $# ]] && return 1
@@ -16,14 +26,22 @@ shift end
xor=()
ostate=()
ocontext=()
+oopt_args=()
while true; do
end=$argv[(i)-]
- _arguments -m xor "$1" "$all[@]" "${(@)argv[2,end-1]}"
+ if [[ "$1" = \(*\) ]]; then
+ _arguments -m xor "${1[2,-2]}" "$all[@]" \
+ "$1${(@)^argv[2,end-1]:#\(*}" \
+ "${1[1,-2]} ${(@)${(@M)^argv[2,end-1]:#\(*}#?}"
+ else
+ _arguments -m xor "$1" "$all[@]" "${(@)argv[2,end-1]}"
+ fi
+
r=$?
- oopt_args=( "$oopt_args[@]" "${(kv)opt_args}" )
+ oopt_args=( "$oopt_args[@]" "${(@kv)opt_args}" )
if [[ r -eq 300 ]]; then
ret=300
ostate=( "$ostate[@]" "$state[@]" )
@@ -40,6 +58,14 @@ while true; do
shift end
done
+[[ -n "$_ms_opt" ]] &&
+ _describe -o option \
+ _ms_soptmid _ms_soptmidadd -Q -S '' -- \
+ _ms_soptend -Q -- \
+ _ms_optnext -Q -M "$_ms_match" -- \
+ _ms_optdirect -QS '' -M "$_ms_match" -- \
+ _ms_optequal -QqS= -M "$_ms_match" && [[ ret -eq 1 ]] && ret=0
+
opt_args=( "$oopt_args[@]" )
if [[ ret -eq 300 ]]; then
diff --git a/Completion/Base/_arguments b/Completion/Base/_arguments
index 0637b2cd5..ed7bd98d7 100644
--- a/Completion/Base/_arguments
+++ b/Completion/Base/_arguments
@@ -163,11 +163,13 @@ done
zstyle -s ":completion:${curcontext}:options" auto-description autod
if (( $# )) && comparguments "$multi[@]" "$autod" "$@"; then
- local nm="$compstate[nmatches]" action noargs aret expl local
+ local action noargs aret expl local
local next direct odirect equal single match matched ws tmp1 tmp2 tmp3
local opts subc tc prefix suffix descrs actions subcs
local origpre="$PREFIX" origipre="$IPREFIX"
+ [[ -z "$ismulti" ]] && local nm="$compstate[nmatches]"
+
if comparguments -D descrs actions subcs; then
if comparguments -O next direct odirect equal; then
opts=yes
@@ -314,17 +316,32 @@ if (( $# )) && comparguments "$multi[@]" "$autod" "$@"; then
tmp1=( "${(M@)tmp1:#[-+]?(|:*)}" )
tmp2=( "${PREFIX}${(@M)^${(@)${(@)tmp1%%:*}#[-+]}:#?}" )
- _describe -o option \
- tmp1 tmp2 -Q -S '' -- \
- tmp3 -Q
+ if [[ -n "$ismulti" ]]; then
+ _ms_opt=yes
+ _ms_soptmid=( "$_ms_soptmid[@]" "$tmp1[@]" )
+ _ms_soptmidadd=( "$_ms_soptmidadd[@]" "$tmp2[@]" )
+ _ms_soptend=( "$_ms_soptend[@]" "$tmp3[@]" )
+ else
+ _describe -o option \
+ tmp1 tmp2 -Q -S '' -- \
+ tmp3 -Q
+ fi
fi
single=yes
else
next=( "$next[@]" "$odirect[@]" )
- _describe -o option \
- next -Q -M "$match" -- \
- direct -QS '' -M "$match" -- \
- equal -QqS= -M "$match"
+ if [[ -n "$ismulti" ]]; then
+ _ms_opt=yes
+ _ms_match="$_ms_match $match"
+ _ms_optnext=( "$_ms_optnext[@]" "$next[@]" )
+ _ms_optdirect=( "$_ms_optdirect[@]" "$direct[@]" )
+ _ms_optequal=( "$_ms_optequal[@]" "$equal[@]" )
+ else
+ _describe -o option \
+ next -Q -M "$match" -- \
+ direct -QS '' -M "$match" -- \
+ equal -QqS= -M "$match"
+ fi
fi
PREFIX="$prevpre"
IPREFIX="$previpre"
diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo
index 4c7e6dd6b..8834fd489 100644
--- a/Doc/Zsh/compsys.yo
+++ b/Doc/Zsh/compsys.yo
@@ -3252,6 +3252,20 @@ option `tt(-c)' will not be completed any more, but if `tt(-a)' is
given, both sets will still be considered valid, because it appears
before the first hyphen, so both sets contain this option.
+If the name-string is of the form `tt(LPAR())var(name)tt(RPAR())' then
+all specifications in the set have an implicit exclusion list
+containing the name of the set, i.e. all specifications are mutual
+exclusive with all other specifications in the same set. This is
+useful for defining multiple sets of options which are mutual
+exclusive and in which the options are aliases for each other. E.g.:
+
+example(_argument_sets \
+ -a -b \
+ - '(compress)' \
+ {-c,--compress}'[compress]' \
+ - '(uncompress)' \
+ {-d,--decompress}'[decompress]')
+
Don't expect too much with complicated options that get their
arguments in the same string and `tt(->)var(state)' actions or with
the tt(-C) option that is given to tt(_arguments), otherwise most
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index b72132895..c47914db7 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -1058,26 +1058,46 @@ ca_inactive(Cadef d, char **xor, int cur, int opts)
if ((xor || opts) && cur <= compcurrent) {
Caopt opt;
char *x;
- int sl = (d->set ? strlen(d->set) : -1);
+ int sl = (d->set ? strlen(d->set) : -1), set = 0;
for (; (x = (opts ? "-" : *xor)); xor++) {
if (ca_xor)
addlinknode(ca_xor, x);
+ set = 0;
if (sl > 0) {
- if (strpfx(d->set, x))
+ if (strpfx(d->set, x)) {
x += sl;
- else if (!strncmp(d->set, x, sl - 1))
- return 1;
+ set = 1;
+ } else if (!strncmp(d->set, x, sl - 1)) {
+ Caopt p;
+
+ for (p = d->opts; p; p = p->next)
+ if (p->set)
+ p->active = 0;
+
+ x = ":";
+ set = 1;
+ }
}
- if (x[0] == ':' && !x[1])
- d->argsactive = 0;
- else if (x[0] == '-' && !x[1]) {
+ if (x[0] == ':' && !x[1]) {
+ if (set) {
+ Caarg a;
+
+ for (a = d->args; a; a = a->next)
+ if (a->set)
+ a->active = 0;
+ if (d->rest && (!set || d->rest->set))
+ d->rest->active = 0;
+ } else
+ d->argsactive = 0;
+ } else if (x[0] == '-' && !x[1]) {
Caopt p;
for (p = d->opts; p; p = p->next)
- p->active = 0;
+ if (!set || p->set)
+ p->active = 0;
} else if (x[0] == '*' && !x[1]) {
- if (d->rest)
+ if (d->rest && (!set || d->rest->set))
d->rest->active = 0;
} else if (x[0] >= '0' && x[0] <= '9') {
int n = atoi(x);
@@ -1086,9 +1106,9 @@ ca_inactive(Cadef d, char **xor, int cur, int opts)
while (a && a->num < n)
a = a->next;
- if (a && a->num == n)
+ if (a && a->num == n && (!set || a->set))
a->active = 0;
- } else if ((opt = ca_get_opt(d, x, 1, NULL)))
+ } else if ((opt = ca_get_opt(d, x, 1, NULL)) && (!set || opt->set))
opt->active = 0;
if (opts)
@@ -1319,7 +1339,7 @@ ca_parse_line(Cadef d, int multi)
state.nargbeg = cur - 1;
state.argend = argend;
}
- if (!d->args && !d->rest)
+ if (!d->args && !d->rest && *line != '-' && *line != '+')
return 1;
if ((adef = state.def = ca_get_arg(d, state.nth)) &&
(state.def->type == CAA_RREST ||