From 8e7e17237ea013a271ec41471bfcd40a2e39584a Mon Sep 17 00:00:00 2001 From: Sven Wischnowsky Date: Thu, 11 May 2000 08:54:47 +0000 Subject: allow internally-mutually exclusive sets in _argument_sets; fixes for _argument_sets and the C-code for it (11320) --- ChangeLog | 5 +++++ Completion/Base/_argument_sets | 32 +++++++++++++++++++++++++++--- Completion/Base/_arguments | 33 +++++++++++++++++++++++-------- Doc/Zsh/compsys.yo | 14 ++++++++++++++ Src/Zle/computil.c | 44 ++++++++++++++++++++++++++++++------------ 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 + * 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 || -- cgit 1.4.1