zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: Re: Assorted _arguments arguments
@ 2000-05-09  9:02 Sven Wischnowsky
  0 siblings, 0 replies; 4+ messages in thread
From: Sven Wischnowsky @ 2000-05-09  9:02 UTC (permalink / raw)
  To: zsh-workers


Bart Schaefer wrote:

> On May 8, 11:00am, Sven Wischnowsky wrote:
> 
> ...
> 
> } But before I start writing it: should the default for _arguments be
> } changed? And would someone be willing to check all uses of _arguments
> } and add the option to the calls that need them?
> 
> I don't think it makes a lot of difference which way the default goes;
> do whatever would require the fewest changes to _arguments and to all
> the other functions that call it.

I didn't have much time yesterday and won't have any time today, so
this is only the change to _arguments. It adds the `-A' and `-S'
options (I couldn't think of better characters, but that's easy to
change). `-A' means: no options after the first argument and `-S'
means no options after the `--' separator. As with `-s' they can be
given to _arguments before the specs.

Changing the default behaviour would be implemented in _arguments
(this patch mostly changes the builtin behind it).


Then there is a change for this option-equal thing. I've chosen the
syntax `-opt=-' to mean: the option has to come after the equal sign,
not in a separate word. I didn't use `-opt=?' because, at least to me, 
this looks like making the `=' optional, i.e. the old behaviour, which 
is still the default. This, too, would be easy to change if we find
out that we will have to change more `-opt='s (to `-opt=-') than we
can leave untouched. I haven't had a look at the completion functions
to see which we have to change and I preferred to not change the
default behaviour.

No patches for the other two things, yet...

> ...
>
> } Exactly, the existence of `=' is the criteria used by getopt_long.  So
> } it's good.  But I vote `-opt=?' instead of `-opt=='.
> 
> I think we should try to make the syntax consistent with `getopts' and
> `zparseopts' if possible.  Maybe that _isn't_ possible do to conflicting
> use of colons ... and maybe we should have thought of that before we used
> colons everywhere, but ...

Maybe, I hope we (ok, I) can be excused for not making this more
consistent because _arguments does a whole lot more than getopts and
because of that I didn't think of getopts at that time.
 
> } Note that another common criteria is that a optional argument must be
> } some set of strings: `yes' or `no' for example.  At least, xset
> } handles optional arguments in this way.  If we can specify a pattern
> } addition to the current optional argument syntax, it can be handled.
> 
> If there's a known set of strings that can be the optional argument, then
> I think this can be handled with state changes and/or alternation and we
> don't need any more patterns jammed into the opt-spec.

I was thinking the same yesterday. Maybe someone can think of a nice
utility function that plays together with _arguments in such cases
(this is not entirely trivial because the optional option-argument
that's causing the trouble is *not* returned by the builtin, but maybe 
we could make... or something).

> ...
> 
> Returning to the original topic, perhaps a better way to think of this
> is that -i and --ignore-case are synonyms and should get the same
> treatment and description.  E.g. your suggestion does not help with
> a case like
> 
> _bzip2:    '(--decompress --compress -z --test -t)-d[decompress]' \
> _bzip2:    '(-d --compress -z --test -t)--decompress[decompress]' \
> _bzip2:    '(--compress --decompress -d --test -t)-z[compress]' \
> _bzip2:    '(-z --decompress -d --test -t)--compress[compress]' \
> 
> where you have both options that have alternate names for each other and
> are mutually exclusive with other options.  Much better would be, say,
> 
> 	'-d(--decompress)' '-z(--compress)' '-t(--test)' \
> 	'(-z -t)-d[decompress]' \
> 	'(-d -t)-z[compress]' \
> 	'(-z -d)-t[test compressed file integrity]' \
> 
> It might even be able to compute this automatically from the comma-lists
> in --help output, or some such.  (No, I don't really like the `-x(--xxx)'
> syntax, but I haven't time to think harder about it just now.)

When thinking about this yesterday, I was reminded of _argument_sets.
This does something entirely different, but the point is that this
already works with `sets'. For _argument_sets they are mutually
exclusive, but maybe we could get something similar (a wrapper
function for _arguments) with the opposite meaning, i.e. you define
multiple sets of options and the options in each set are mutually
exclusive. That with some sharing of descriptions, arguments
etc. should be enough. And even easier to read than the possibly
longish comma lists. I've got to think some more about this (and look
at the code), but it sounds promising.


Bye
 Sven

Index: Doc/Zsh/compsys.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/compsys.yo,v
retrieving revision 1.38
diff -u -r1.38 compsys.yo
--- Doc/Zsh/compsys.yo	2000/05/08 18:14:46	1.38
+++ Doc/Zsh/compsys.yo	2000/05/09 08:42:13
@@ -2951,7 +2951,10 @@
 separate argument after the option, a plus sign should be used
 instead. If the argument may be given as the next string or in same
 string as the option name but separated from it by an equal sign, a
-`tt(=)' should be used instead of the minus or plus sign.
+`tt(=)' should be used instead of the minus or plus sign and if the
+argument to the option has to be given in the same string after an
+equal sign and may not be given in the next argument, `tt(=-)' should
+be used.
 
 Note that this and the shortcut syntax with a leading tt(-+) or tt(+-) 
 means that for options like tt(-+) the second character has to be
@@ -3092,6 +3095,12 @@
 `tt(-)tt(-prefix)') are still considered to contain only one option
 name. This allows the use of the `tt(-s)' option to describe
 single-letter options together with such long option names.
+
+To simplify the specifications for commands with standard option
+parsing, the options tt(-A) and tt(-S) may be given. With tt(-A) no
+options will be completed after the first non-option argument on the
+line. With tt(-S), no option will be completed after a `tt(-)tt(-)' on 
+the line and this argument will otherwise be ignored.
 
 Another option supported is `tt(-O) var(name)'. The var(name) will be
 taken as the name of an array and its elements will be given to
Index: Src/Zle/computil.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/computil.c,v
retrieving revision 1.14
diff -u -r1.14 computil.c
--- Src/Zle/computil.c	2000/05/08 10:37:58	1.14
+++ Src/Zle/computil.c	2000/05/09 08:42:14
@@ -305,8 +305,12 @@
     int argsactive;		/* if arguments are still allowed */
 				/* used while parsing a command line */
     char *set;			/* set name, shared */
+    int flags;			/* see CDF_* below */
 };
 
+#define CDF_SEP 1
+#define CDF_ARG 2
+
 /* Description for an option. */
 
 struct caopt {
@@ -325,6 +329,7 @@
 #define CAO_DIRECT  2
 #define CAO_ODIRECT 3
 #define CAO_EQUAL   4
+#define CAO_OEQUAL  5
 
 /* Description for an argument */
 
@@ -515,7 +520,7 @@
     Caarg argp;
     char **oargs = args, *p, *q, *match = "r:|[_-]=* r:|=*", **xor;
     char *adpre, *adsuf, *set = NULL, *doset = NULL;
-    int single = 0, anum = 1, xnum, nopts, ndopts, nodopts;
+    int single = 0, anum = 1, xnum, nopts, ndopts, nodopts, flags = 0;
 
     nopts = ndopts = nodopts = 0;
 
@@ -536,23 +541,40 @@
     } else
 	adpre = adsuf = NULL;
 
-    /* Now get the -s and -M options. */
+    /* Now get the -s, -A, -S and -M options. */
 
     args++;
-    while ((p = *args)) {
-	if (!strcmp(p, "-s"))
-	    single = 1;
-	else if (p[0] == '-' && p[1] == 'M') {
-	    if (p[2])
-		match = p + 2;
-	    else if (args[1])
-		match = *++args;
-	    else {
-		args++;
+    while ((p = *args) && *p == '-') {
+	for (q = ++p; *q; q++)
+	    if (*q == 'M') {
+		q = "";
+		break;
+	    } else if (*q != 's' && *q != 'S' && *q != 'A')
 		break;
+
+	if (*q)
+	    break;
+
+	for (; *p; p++) {
+	    if (*p == 's')
+		single = 1;
+	    else if (*p == 'S')
+		flags |= CDF_SEP;
+	    else if (*p == 'A')
+		flags |= CDF_ARG;
+	    else if (*p == 'M') {
+		if (p[1]) {
+		    match = p + 1;
+		    p = "" - 1;
+		} else if (args[1])
+		    match = *++args;
+		else
+		    break;
 	    }
-	} else
+	}
+	if (*p)
 	    break;
+
 	args++;
     }
     if (!*args)
@@ -574,6 +596,7 @@
     } else
 	ret->single = NULL;
     ret->match = ztrdup(match);
+    ret->flags = flags;
 
     /* Get the definitions. */
 
@@ -659,8 +682,10 @@
 
 	    /* Skip over the name. */
 	    for (p++; *p && *p != ':' && *p != '[' &&
-		     ((*p != '-' && *p != '+' && *p != '=') ||
-		      (p[1] != ':' && p[1] != '[')); p++)
+		     ((*p != '-' && *p != '+') ||
+		      (p[1] != ':' && p[1] != '[')) &&
+		     (*p != '=' ||
+		      (p[1] != ':' && p[1] != '[' && p[1] != '-')); p++)
 		if (*p == '\\' && p[1])
 		    p++;
 
@@ -674,8 +699,11 @@
 		otype = CAO_ODIRECT;
 		c = *++p;
 	    } else if (c == '=') {
-		otype = CAO_EQUAL;
-		c = *++p;
+		otype = CAO_OEQUAL;
+		if ((c = *++p) == '-') {
+		    otype = CAO_EQUAL;
+		    c = *++p;
+		}
 	    }
 	    /* Get the optional description, if any. */
 	    if (c == '[') {
@@ -797,9 +825,9 @@
 	    opt->args = oargs;
 	    opt->num = nopts++;
 
-	    if (otype == CAO_DIRECT)
+	    if (otype == CAO_DIRECT || otype == CAO_EQUAL)
 		ndopts++;
-	    else if (otype == CAO_ODIRECT || otype == CAO_EQUAL)
+	    else if (otype == CAO_ODIRECT || otype == CAO_OEQUAL)
 		nodopts++;
 
 	    /* If this is for single-letter option we also store a
@@ -952,7 +980,8 @@
 		    /* Return a pointer to the end of the option. */
 		    int l = strlen(p->name);
 
-		    if (p->type == CAO_EQUAL && line[l] == '=')
+		    if ((p->type == CAO_OEQUAL || p->type == CAO_EQUAL) &&
+			line[l] == '=')
 			l++;
 
 		    *end = line + l;
@@ -983,7 +1012,8 @@
 		p->args && p->type != CAO_NEXT && p->name[0] == pre) {
 		if (end) {
 		    line++;
-		    if (p->type == CAO_EQUAL && *line == '=')
+		    if ((p->type == CAO_OEQUAL || p->type == CAO_EQUAL) &&
+			*line == '=')
 			line++;
 		    *end = line;
 		}
@@ -1022,14 +1052,14 @@
 static LinkList ca_xor;
 
 static int
-ca_inactive(Cadef d, char **xor, int cur)
+ca_inactive(Cadef d, char **xor, int cur, int opts)
 {
-    if (xor && cur <= compcurrent) {
+    if ((xor || opts) && cur <= compcurrent) {
 	Caopt opt;
 	char *x;
 	int sl = (d->set ? strlen(d->set) : -1);
 
-	for (; (x = *xor); xor++) {
+	for (; (x = (opts ? "-" : *xor)); xor++) {
 	    if (ca_xor)
 		addlinknode(ca_xor, x);
 	    if (sl > 0) {
@@ -1059,6 +1089,9 @@
 		    a->active = 0;
 	    } else if ((opt = ca_get_opt(d, x, 1, NULL)))
 		opt->active = 0;
+
+	    if (opts)
+		break;
 	}
     }
     return 0;
@@ -1145,10 +1178,13 @@
 	ddef = adef = NULL;
 	doff = state.singles = 0;
 
-	if (ca_inactive(d, argxor, cur))
-	    return 1;
-
-	/* We've a definition for an argument, skip to the next. */
+	if (ca_inactive(d, argxor, cur, 0) ||
+	    ((d->flags & CDF_SEP) && !strcmp(line, "--"))) {
+	    if (ca_inactive(d, NULL, cur, 1))
+		return 1;
+	    continue;
+	}
+	/* We've got a definition for an argument, skip to the next. */
 
 	if (state.def) {
 	    state.arg = 0;
@@ -1186,10 +1222,14 @@
 	/* See if it's an option. */
 
 	if (state.opt == 2 && (state.curopt = ca_get_opt(d, line, 0, &pe)) &&
-	    (state.curopt->type != CAO_EQUAL || 
-	     compwords[cur] || pe[-1] == '=')) {
-
-	    ddef = state.def = state.curopt->args;
+	    (state.curopt->type == CAO_OEQUAL ?
+	     (compwords[cur] || pe[-1] == '=') :
+	     (state.curopt->type == CAO_EQUAL ?
+	      (pe[-1] == '=' || !pe[0]) : 1))) {
+
+	    ddef = state.def = ((state.curopt->type != CAO_EQUAL ||
+				 pe[-1] == '=') ?
+				state.curopt->args : NULL);
 	    doff = pe - line;
 	    state.optbeg = state.argbeg = state.inopt = cur;
 	    state.singles = (d->single && (!pe || !*pe) &&
@@ -1197,15 +1237,16 @@
 
 	    state.oargs[state.curopt->num] = znewlinklist();
 
-	    if (ca_inactive(d, state.curopt->xor, cur))
+	    if (ca_inactive(d, state.curopt->xor, cur, 0))
 		return 1;
 
 	    /* Collect the argument strings. Maybe. */
 
 	    if (state.def &&
 		(state.curopt->type == CAO_DIRECT ||
+		 state.curopt->type == CAO_EQUAL ||
 		 (state.curopt->type == CAO_ODIRECT && pe[0]) ||
-		 (state.curopt->type == CAO_EQUAL &&
+		 (state.curopt->type == CAO_OEQUAL &&
 		  (pe[0] || pe[-1] == '=')))) {
 		if (state.def->type != CAA_REST &&
 		    state.def->type != CAA_RARGS &&
@@ -1237,14 +1278,15 @@
 		if ((tmpopt = d->single[STOUC(*p)])) {
 		    state.oargs[tmpopt->num] = znewlinklist();
 
-		    if (ca_inactive(d, tmpopt->xor, cur))
+		    if (ca_inactive(d, tmpopt->xor, cur, 0))
 			return 1;
 		}
 	    }
 	    if (state.def &&
 		(state.curopt->type == CAO_DIRECT ||
+		 state.curopt->type == CAO_EQUAL ||
 		 (state.curopt->type == CAO_ODIRECT && pe[0]) ||
-		 (state.curopt->type == CAO_EQUAL &&
+		 (state.curopt->type == CAO_OEQUAL &&
 		  (pe[0] || pe[-1] == '=')))) {
 		if (state.def->type != CAA_REST &&
 		    state.def->type != CAA_RARGS &&
@@ -1261,6 +1303,9 @@
 	    return 1;
 	else if (state.arg) {
 	    /* Otherwise it's a normal argument. */
+	    if ((d->flags & CDF_ARG) && ca_inactive(d, NULL, cur + 1, 1))
+		return 1;
+
 	    if (state.inopt) {
 		state.inopt = 0;
 		state.nargbeg = cur - 1;
@@ -1541,7 +1586,7 @@
 		ca_xor = newlinklist();
 		if ((xor = getaparam(args[1]))) {
 		    if (arrcontains(xor, args[2], 0) ||
-			ca_inactive(def, xor, compcurrent)) {
+			ca_inactive(def, xor, compcurrent, 0)) {
 			ca_xor = cax;
 			return 1;
 		    }
@@ -1645,7 +1690,8 @@
 		      ztrdup(ca_laststate.ddef ?
 			     (ca_laststate.ddef->type == CAO_DIRECT ?
 			      "direct" :
-			      (ca_laststate.ddef->type == CAO_EQUAL ?
+			      ((ca_laststate.ddef->type == CAO_OEQUAL ||
+				ca_laststate.ddef->type == CAO_EQUAL) ?
 			       "equal" : "next")) : ""));
 	    return 0;
 	}

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: PATCH: Re: Assorted _arguments arguments
@ 2000-05-12  7:35 Sven Wischnowsky
  0 siblings, 0 replies; 4+ messages in thread
From: Sven Wischnowsky @ 2000-05-12  7:35 UTC (permalink / raw)
  To: zsh-workers


Bart Schaefer wrote:

> ...
> 
> I haven't really worked at understanding _argument_sets very much, but:
> 
> As I understand it, _argument_sets only works for fairly simple option
> combinations.  As soon as you start needing ->state and the like, it's
> necessary to revert to using _arguments directly.  Is it possible to
> combine the two in some useful way so that it isn't necessary to give
> up the above convenience in order to do more complex parsing?

The only real problem _argument_sets currently has with `->state'
actions is when there are more than one state returned at the same
time. Especially for actions defined in the common options/args part:
you'll get the state/context more than once in $state and $context
(and just using `typeset -U' doesn't work, because the contexts may be 
different, including the set-name).

However, _argument_sets was mostly written to give us a way to play
with this, test it. The syntax (the `-' to separate sets) was chosen
because `-' currently makes comparguments/_arguments report an invalid 
argument. So... we could try to put the whole functionality of
_argument_sets into _arguments, implement it (mostly) in C. I would
then write it there as we have it in shell code now: as a wrapper
around the existing code. That was the problem that led to the
implementation we have now: changing all of comparguments to support
multiple sets is extremly complicated (and error-prone).

Bye
 Sven


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: PATCH: Re: Assorted _arguments arguments
  2000-05-11  8:52 Sven Wischnowsky
@ 2000-05-12  2:53 ` Bart Schaefer
  0 siblings, 0 replies; 4+ messages in thread
From: Bart Schaefer @ 2000-05-12  2:53 UTC (permalink / raw)
  To: zsh-workers

On May 11, 10:52am, Sven Wischnowsky wrote:
} Subject: PATCH: Re: Assorted _arguments arguments
}
} I said that I was thinking about using something like _argument_sets
} for this. But, why not use _argument_sets itself? This allows the
} set-strings be given as `(name)' meaning that all specifications in
} that set are mutually exclusive with all other specs in the set. They
} are mutually exclusive with the set in which they are, so to say.
} 
} Example:
} 
}   _argument_sets \
}       -common -options ':and:(arguments)' \
}     - '(compress)' \
}       {-c,--compress}'[compress]' \
}     - '(decompress)' \
}       {-d,--decompress}'[decompress]'
} 
} Is that convenient enough?

I haven't really worked at understanding _argument_sets very much, but:

As I understand it, _argument_sets only works for fairly simple option
combinations.  As soon as you start needing ->state and the like, it's
necessary to revert to using _arguments directly.  Is it possible to
combine the two in some useful way so that it isn't necessary to give
up the above convenience in order to do more complex parsing?

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


^ permalink raw reply	[flat|nested] 4+ messages in thread

* PATCH: Re: Assorted _arguments arguments
@ 2000-05-11  8:52 Sven Wischnowsky
  2000-05-12  2:53 ` Bart Schaefer
  0 siblings, 1 reply; 4+ messages in thread
From: Sven Wischnowsky @ 2000-05-11  8:52 UTC (permalink / raw)
  To: zsh-workers


Bart Schaefer wrote:

> ...
> 
> Returning to the original topic, perhaps a better way to think of this
> is that -i and --ignore-case are synonyms and should get the same
> treatment and description.  E.g. your suggestion does not help with
> a case like
> 
> _bzip2:    '(--decompress --compress -z --test -t)-d[decompress]' \
> _bzip2:    '(-d --compress -z --test -t)--decompress[decompress]' \
> _bzip2:    '(--compress --decompress -d --test -t)-z[compress]' \
> _bzip2:    '(-z --decompress -d --test -t)--compress[compress]' \
> 
> where you have both options that have alternate names for each other and
> are mutually exclusive with other options.  Much better would be, say,
> 
> 	'-d(--decompress)' '-z(--compress)' '-t(--test)' \
> 	'(-z -t)-d[decompress]' \
> 	'(-d -t)-z[compress]' \
> 	'(-z -d)-t[test compressed file integrity]' \
> 
> It might even be able to compute this automatically from the comma-lists
> in --help output, or some such.  (No, I don't really like the `-x(--xxx)'
> syntax, but I haven't time to think harder about it just now.)

I said that I was thinking about using something like _argument_sets
for this. But, why not use _argument_sets itself? This allows the
set-strings be given as `(name)' meaning that all specifications in
that set are mutually exclusive with all other specs in the set. They
are mutually exclusive with the set in which they are, so to say.

Example:

  _argument_sets \
      -common -options ':and:(arguments)' \
    - '(compress)' \
      {-c,--compress}'[compress]' \
    - '(decompress)' \
      {-d,--decompress}'[decompress]'

Is that convenient enough? It is a bit slower than a only-_arguments-based
solution would have been, though. If nobody likes it, I can take it
out again (it is only a small part of the patch below).

The patch also contains some fixes in the C-code for this and in the
shell code -- to make listing of options defined by different sets
nicer.


Bye
 Sven

Index: Completion/Base/_argument_sets
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Base/_argument_sets,v
retrieving revision 1.2
diff -u -r1.2 _argument_sets
--- Completion/Base/_argument_sets	2000/05/09 09:52:27	1.2
+++ Completion/Base/_argument_sets	2000/05/11 08:52:00
@@ -1,11 +1,21 @@
 #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 @@
 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[@]" )
@@ -39,6 +57,14 @@
 
   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[@]" )
 
Index: Completion/Base/_arguments
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Base/_arguments,v
retrieving revision 1.14
diff -u -r1.14 _arguments
--- Completion/Base/_arguments	2000/05/09 09:52:27	1.14
+++ Completion/Base/_arguments	2000/05/11 08:52:01
@@ -163,11 +163,13 @@
 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 @@
 	    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"
Index: Doc/Zsh/compsys.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/compsys.yo,v
retrieving revision 1.44
diff -u -r1.44 compsys.yo
--- Doc/Zsh/compsys.yo	2000/05/11 08:40:10	1.44
+++ Doc/Zsh/compsys.yo	2000/05/11 08:52:08
@@ -3252,6 +3252,20 @@
 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
Index: Src/Zle/computil.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/computil.c,v
retrieving revision 1.18
diff -u -r1.18 computil.c
--- Src/Zle/computil.c	2000/05/10 11:53:06	1.18
+++ Src/Zle/computil.c	2000/05/11 08:52:11
@@ -1058,26 +1058,46 @@
     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 @@
 		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 @@
 		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 ||

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2000-05-12  7:36 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-05-09  9:02 PATCH: Re: Assorted _arguments arguments Sven Wischnowsky
2000-05-11  8:52 Sven Wischnowsky
2000-05-12  2:53 ` Bart Schaefer
2000-05-12  7:35 Sven Wischnowsky

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).