about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSven Wischnowsky <wischnow@users.sourceforge.net>2000-05-11 08:54:47 +0000
committerSven Wischnowsky <wischnow@users.sourceforge.net>2000-05-11 08:54:47 +0000
commit8e7e17237ea013a271ec41471bfcd40a2e39584a (patch)
tree5babcfb8dbd029bb11b63ea0c2c30a66a29e4b9c
parentd3620a02dfad71562320a90315175855b44ed4de (diff)
downloadzsh-8e7e17237ea013a271ec41471bfcd40a2e39584a.tar.gz
zsh-8e7e17237ea013a271ec41471bfcd40a2e39584a.tar.xz
zsh-8e7e17237ea013a271ec41471bfcd40a2e39584a.zip
allow internally-mutually exclusive sets in _argument_sets; fixes for _argument_sets and the C-code for it (11320)
-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 ||