Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: _arguments
- X-seq: zsh-workers 11876
- From: Sven Wischnowsky <wischnow@xxxxxxxxxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxxxxxx
- Subject: PATCH: _arguments
- Date: Tue, 13 Jun 2000 14:07:40 +0200 (MET DST)
- Mailing-list: contact zsh-workers-help@xxxxxxxxxxxxxx; run by ezmlm
Ok, here's the patch for _arguments. To repeat:
- -A now takes a pattern as argument. All words matching that pattern
are *not* taken to be normal arguments and hence don't keep it from
completing options (i.e. it will often be called as `-A "-*"').
- -s with option strings that contain more than one option with
arguments in the next word should work now.
- The unrecognised option bug from 11801 should be fixed now. Those
tests were very restrictive, and if I remember correctly, I did that
because of some ugly interaction between _arguments and
_argument_sets when that was still a separate function.
If anyone sees weird results when completing options from multiple
sets, please tell me.
Bye
Sven
Index: Doc/Zsh/compsys.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/compsys.yo,v
retrieving revision 1.63
diff -u -r1.63 compsys.yo
--- Doc/Zsh/compsys.yo 2000/06/13 11:55:07 1.63
+++ Doc/Zsh/compsys.yo 2000/06/13 12:06:46
@@ -2931,10 +2931,15 @@
{-d,--decompress}'[decompress]')
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.
+parsing, the options tt(-S) and tt(-A) may be given. With tt(-S), no
+option will be completed after a `tt(-)tt(-)' on the line and this
+argument will otherwise be ignored. With tt(-A), no options will be
+completed after the first non-option argument on the line. The tt(-A)
+has to be followed by a pattern matching all strings which are not to
+be taken as arguemnts. For example, to make tt(_arguments) stop
+completing options after the first normal argument, but ignoring all
+strings starting with a hyphen even if they are not described by one
+of the var(optspec)s, one would use: `tt(-A "-*")'.
Note that using multiple sets will be slower than using only one set
because the completion code has to parse the command line once for
Index: Src/Zle/computil.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/computil.c,v
retrieving revision 1.28
diff -u -r1.28 computil.c
--- Src/Zle/computil.c 2000/06/13 09:05:37 1.28
+++ Src/Zle/computil.c 2000/06/13 12:06:47
@@ -308,10 +308,10 @@
char *set; /* set name prefix (<name>-), shared */
char *sname; /* set name */
int flags; /* see CDF_* below */
+ char *nonarg; /* pattern for non-args (-A argument) */
};
#define CDF_SEP 1
-#define CDF_ARG 2
/* Description for an option. */
@@ -423,6 +423,7 @@
}
freecaargs(d->args);
freecaargs(d->rest);
+ zsfree(d->nonarg);
if (d->single)
zfree(d->single, 256 * sizeof(Caopt));
zfree(d, sizeof(*d));
@@ -518,7 +519,7 @@
}
static Cadef
-alloc_cadef(char **args, int single, char *match, int flags)
+alloc_cadef(char **args, int single, char *match, char *nonarg, int flags)
{
Cadef ret;
@@ -526,6 +527,7 @@
ret->next = ret->snext = NULL;
ret->opts = NULL;
ret->args = ret->rest = NULL;
+ ret->nonarg = ztrdup(nonarg);
if (args) {
ret->defs = zarrdup(args);
ret->ndefs = arrlen(args);
@@ -569,6 +571,7 @@
Caopt *optp;
char **oargs = args, *p, *q, *match = "r:|[_-]=* r:|=*", **xor, **sargs;
char *adpre, *adsuf, *axor = NULL, *doset = NULL, **setp = NULL;
+ char *nonarg = NULL;
int single = 0, anum = 1, xnum, nopts, ndopts, nodopts, flags = 0;
int state = 0;
@@ -591,10 +594,10 @@
args++;
while ((p = *args) && *p == '-' && p[1]) {
for (q = ++p; *q; q++)
- if (*q == 'M') {
+ if (*q == 'M' || *q == 'A') {
q = "";
break;
- } else if (*q != 's' && *q != 'S' && *q != 'A')
+ } else if (*q != 's' && *q != 'S')
break;
if (*q)
@@ -605,10 +608,16 @@
single = 1;
else if (*p == 'S')
flags |= CDF_SEP;
- else if (*p == 'A')
- flags |= CDF_ARG;
- else if (*p == 'M') {
+ else if (*p == 'A') {
if (p[1]) {
+ nonarg = p + 1;
+ p = "" - 1;
+ } else if (args[1])
+ nonarg = *++args;
+ else
+ break;
+ } else if (*p == 'M') {
+ if (p[1]) {
match = p + 1;
p = "" - 1;
} else if (args[1])
@@ -625,9 +634,12 @@
if (!*args)
return NULL;
+ if (nonarg)
+ tokenize(nonarg = dupstring(nonarg));
+
/* Looks good. Optimistically allocate the cadef structure. */
- all = ret = alloc_cadef(oargs, single, match, flags);
+ all = ret = alloc_cadef(oargs, single, match, nonarg, flags);
optp = &(ret->opts);
anum = 1;
@@ -662,7 +674,7 @@
ret->ndopts = ndopts;
ret->nodopts = nodopts;
set_cadef_opts(ret);
- ret = ret->snext = alloc_cadef(NULL, single, NULL, flags);
+ ret = ret->snext = alloc_cadef(NULL, single, NULL, nonarg, flags);
optp = &(ret->opts);
nopts = ndopts = nodopts = 0;
anum = 1;
@@ -1064,21 +1076,21 @@
/* Same as above, only for single-letter-style. */
static Caopt
-ca_get_sopt(Cadef d, char *line, int full, char **end)
+ca_get_sopt(Cadef d, char *line, char **end, LinkList *lp)
{
Caopt p;
char pre = *line++;
+ LinkList l = NULL;
- if (full) {
- for (p = NULL; *line; line++)
- if (!(p = d->single[STOUC(*line)]) || !p->active ||
- (line[1] && p->args))
- return NULL;
- return p;
- } else {
- for (p = NULL; *line; line++)
- if ((p = d->single[STOUC(*line)]) && p->active &&
- p->args && p->type != CAO_NEXT && p->name[0] == pre) {
+ *lp = NULL;
+ for (p = NULL; *line; line++)
+ if ((p = d->single[STOUC(*line)]) && p->active &&
+ p->args && p->name[0] == pre) {
+ if (p->type == CAO_NEXT) {
+ if (!l)
+ *lp = l = newlinklist();
+ addlinknode(l, p);
+ } else {
if (end) {
line++;
if ((p->type == CAO_OEQUAL || p->type == CAO_EQUAL) &&
@@ -1087,14 +1099,12 @@
*end = line;
}
break;
- } else if (!p || !p->active || (line[1] && p->args) ||
- p->name[0] != pre)
- return NULL;
- if (p && end)
- *end = line;
- return p;
- }
- return NULL;
+ }
+ } else if (!p || (!p->active && p->name[0] != pre))
+ return NULL;
+ if (p && end)
+ *end = line;
+ return p;
}
/* Return the n'th argument definition. */
@@ -1228,7 +1238,8 @@
struct castate state;
char *line, *pe, **argxor = NULL;
int cur, doff, argend, arglast;
- Patprog endpat = NULL;
+ Patprog endpat = NULL, napat = NULL;
+ LinkList sopts = NULL;
/* Free old state. */
@@ -1279,6 +1290,9 @@
goto end;
}
+ if (d->nonarg)
+ napat = patcompile(d->nonarg, 0, NULL);
+
/* Loop over the words from the line. */
for (line = compwords[1], cur = 2, state.curopt = NULL, state.def = NULL;
@@ -1315,6 +1329,15 @@
} else if ((state.def = state.def->next)) {
state.argbeg = cur;
state.argend = argend;
+ } else if (sopts && nonempty(sopts)) {
+ state.curopt = (Caopt) uremnode(sopts, firstnode(sopts));
+ state.def = state.curopt->args;
+ state.opt = 0;
+ state.argbeg = state.optbeg = state.inopt = cur;
+ state.argend = argend;
+ doff = state.doff = 0;
+ state.singles = 1;
+ goto cont;
} else {
state.curopt = NULL;
state.opt = 1;
@@ -1378,12 +1401,16 @@
state.curopt = NULL;
}
} else if (state.opt == 2 && d->single &&
- (state.curopt = ca_get_sopt(d, line, 0, &pe))) {
+ ((state.curopt = ca_get_sopt(d, line, &pe, &sopts)) ||
+ (sopts && nonempty(sopts)))) {
/* Or maybe it's a single-letter option? */
char *p;
Caopt tmpopt;
+ if (sopts && nonempty(sopts))
+ state.curopt = (Caopt) uremnode(sopts, firstnode(sopts));
+
ddef = state.def = state.curopt->args;
dopt = state.curopt;
doff = pe - line;
@@ -1419,9 +1446,9 @@
state.curopt = NULL;
} else if (multi && (*line == '-' || *line == '+') && cur != compcurrent)
return 1;
- else if (state.arg) {
+ else if (state.arg && (!napat || !pattry(napat, line))) {
/* Otherwise it's a normal argument. */
- if ((d->flags & CDF_ARG) && ca_inactive(d, NULL, cur + 1, 1))
+ if (napat && ca_inactive(d, NULL, cur + 1, 1))
return 1;
arglast = 1;
@@ -1438,9 +1465,7 @@
state.inrest = 0;
state.opt = (cur == state.nargbeg + 1 &&
(!multi || !*line ||
- ((*line == '-' || *line == '+') &&
- (!line[1] ||
- (*line == '-' && line[1] == '-' && !line[2])))));
+ *line == '-' || *line == '+'));
state.optbeg = state.nargbeg;
state.argbeg = cur - 1;
state.argend = argend;
@@ -1517,9 +1542,7 @@
} else {
ca_laststate.def = adef;
ca_laststate.opt = (!arglast || !multi || !*line ||
- ((*line == '-' || *line == '+') &&
- (!line[1] ||
- (*line == '-' && line[1] == '-' && !line[2]))));
+ *line == '-' || *line == '+');
ca_laststate.ddef = NULL;
ca_laststate.dopt = NULL;
ca_laststate.optbeg = state.nargbeg;
--
Sven Wischnowsky wischnow@xxxxxxxxxxxxxxxxxxxxxxx
Messages sorted by:
Reverse Date,
Date,
Thread,
Author