From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17247 invoked from network); 13 Jun 2000 13:41:51 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 13 Jun 2000 13:41:51 -0000 Received: (qmail 29480 invoked by alias); 13 Jun 2000 13:40:45 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 11876 Received: (qmail 28980 invoked from network); 13 Jun 2000 13:39:50 -0000 Date: Tue, 13 Jun 2000 14:07:40 +0200 (MET DST) Message-Id: <200006131207.OAA32732@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@sunsite.auc.dk Subject: PATCH: _arguments 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 (-), 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@informatik.hu-berlin.de