about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSven Wischnowsky <wischnow@users.sourceforge.net>2000-05-09 09:05:34 +0000
committerSven Wischnowsky <wischnow@users.sourceforge.net>2000-05-09 09:05:34 +0000
commit125dc0d4f2a3c1c4efe942e4d92c412583582f9d (patch)
tree7440be739687f4275c365d00f050418537461019
parente5eb094bf3c031f07f7e9ab152fe63a120dd3821 (diff)
downloadzsh-125dc0d4f2a3c1c4efe942e4d92c412583582f9d.tar.gz
zsh-125dc0d4f2a3c1c4efe942e4d92c412583582f9d.tar.xz
zsh-125dc0d4f2a3c1c4efe942e4d92c412583582f9d.zip
new -A and -S options to _arguments; `-opt=-' specs for options whose argument has to come after the `=' (11270)
-rw-r--r--ChangeLog6
-rw-r--r--Doc/Zsh/compsys.yo11
-rw-r--r--Src/Zle/computil.c122
3 files changed, 100 insertions, 39 deletions
diff --git a/ChangeLog b/ChangeLog
index 7b05d9e57..57197469b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2000-05-09  Sven Wischnowsky  <wischnow@zsh.org>
+
+	* 11270: Doc/Zsh/compsys.yo, Src/Zle/computil.c: new -A and -S
+ 	options to _arguments; `-opt=-' specs for options whose argument
+ 	has to come after the `='
+	
 2000-05-08  Oliver Kiddle  <opk@zsh.org>
 
 	* 11268: Doc/Zsh/compsys.yo, Doc/Zsh/builtins.yo: minor typo fixes
diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo
index ed7de1411..fae8961b7 100644
--- a/Doc/Zsh/compsys.yo
+++ b/Doc/Zsh/compsys.yo
@@ -2951,7 +2951,10 @@ in one string with the option name, but may also be given as a
 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
@@ -3093,6 +3096,12 @@ letter. However, strings beginning with two hyphens (like
 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
 functions called to generate matches when executing the
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index 79e18b002..7f743492a 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -305,8 +305,12 @@ struct cadef {
     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 @@ struct caopt {
 #define CAO_DIRECT  2
 #define CAO_ODIRECT 3
 #define CAO_EQUAL   4
+#define CAO_OEQUAL  5
 
 /* Description for an argument */
 
@@ -515,7 +520,7 @@ parse_cadef(char *nam, char **args, int multi)
     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 @@ parse_cadef(char *nam, char **args, int multi)
     } 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 @@ parse_cadef(char *nam, char **args, int multi)
     } else
 	ret->single = NULL;
     ret->match = ztrdup(match);
+    ret->flags = flags;
 
     /* Get the definitions. */
 
@@ -659,8 +682,10 @@ parse_cadef(char *nam, char **args, int multi)
 
 	    /* 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 @@ parse_cadef(char *nam, char **args, int multi)
 		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 @@ parse_cadef(char *nam, char **args, int multi)
 	    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 @@ ca_get_opt(Cadef d, char *line, int full, char **end)
 		    /* 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 @@ ca_get_sopt(Cadef d, char *line, int full, char **end)
 		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 @@ ca_get_arg(Cadef d, int n)
 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 @@ ca_inactive(Cadef d, char **xor, int cur)
 		    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 @@ ca_parse_line(Cadef d, int multi)
 	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 @@ ca_parse_line(Cadef d, int multi)
 	/* 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 @@ ca_parse_line(Cadef d, int multi)
 
 	    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 @@ ca_parse_line(Cadef d, int multi)
 		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 @@ ca_parse_line(Cadef d, int multi)
 	    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 @@ bin_comparguments(char *nam, char **args, char *ops, int func)
 		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 @@ bin_comparguments(char *nam, char **args, char *ops, int func)
 		      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;
 	}