diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Doc/Zsh/compsys.yo | 11 | ||||
-rw-r--r-- | Src/Zle/computil.c | 122 |
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; } |