From 8be732cbcc248abfa82ee1b4d0031f684e79aa8b Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 4 Jan 2017 14:50:56 +0100 Subject: 40227: handle _arguments sets and rest arguments starting with a dash This is a new approach to the problem first covered by 39611: checking to see if an option-like argument belongs to one of the other sets. --- ChangeLog | 3 +++ Src/Zle/computil.c | 37 ++++++++++++++++++++++++++----------- Test/Y03arguments.ztst | 16 +++++++--------- 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2f6023fdc..dee6ad7dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2017-01-04 Oliver Kiddle + * 40227: Src/Zle/computil.c, Test/Y03arguments.ztst: new approach + to 39611 (_arguments sets and rest arguments starting with a dash) + * 40226: Src/Zle/computil.c, Test/Y03arguments.ztst: tidy up some of the _arguments set code diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index cc879c445..82144656d 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -1741,6 +1741,27 @@ ca_get_sopt(Cadef d, char *line, char **end, LinkList *lp) return pp; } +/* Search for an option in all sets except the current one. + * Return true if found */ + +static int +ca_foreign_opt(Cadef curset, Cadef all, char *option) +{ + Cadef d; + Caopt p; + + for (d = all; d; d = d->snext) { + if (d == curset) + continue; + + for (p = d->opts; p; p = p->next) { + if (!strcmp(p->name, option)) + return 1; + } + } + return 0; +} + /* Return the n'th argument definition. */ static Caarg @@ -1917,7 +1938,7 @@ ca_opt_arg(Caopt opt, char *line) * existing options on the line. */ static int -ca_parse_line(Cadef d, int multi, int first) +ca_parse_line(Cadef d, Cadef all, int multi, int first) { Caarg adef, ddef; Caopt ptr, wasopt = NULL, dopt; @@ -2163,13 +2184,7 @@ ca_parse_line(Cadef d, int multi, int first) else state.curopt = NULL; } else if (multi && (*line == '-' || *line == '+') && cur != compcurrent -#if 0 - /**** Ouch. Using this will disable the mutual exclusion - of different sets. Not using it will make the -A - pattern be effectively ignored with multiple sets. */ - && (!napat || !pattry(napat, line)) -#endif - ) + && (ca_foreign_opt(d, all, line))) return 1; else if (state.arg && (!napat || cur <= compcurrent || !pattry(napat, line))) { @@ -2515,20 +2530,20 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) * auto-description string, the optional -s, -S, -A and -M options * given to _arguments and the specs. */ if (compcurrent > 1 && compwords[0]) { - Cadef def; + Cadef def, all; int cap = ca_parsed, multi, first = 1, use, ret = 0; Castate states = NULL, sp; ca_parsed = 0; - if (!(def = get_cadef(nam, args + 1))) + if (!(def = all = get_cadef(nam, args + 1))) return 1; multi = !!def->snext; /* if we have sets */ ca_parsed = cap; while (def) { /* for each set */ - use = !ca_parse_line(def, multi, first); + use = !ca_parse_line(def, all, multi, first); def = def->snext; if (use && def) { /* entry needed so save it into list */ diff --git a/Test/Y03arguments.ztst b/Test/Y03arguments.ztst index 0b797ac03..47f4747b8 100644 --- a/Test/Y03arguments.ztst +++ b/Test/Y03arguments.ztst @@ -358,26 +358,24 @@ 0:repeatable options >line: {tst -v -v }{} -# necessary to exclude the rest arguments for the other set because -# it is currently any unknown option rather than options from another -# set that causes a set to be excluded tst_arguments -A '-*' - help -h -V - other -a '*: :(-x more)' comptest $'tst -a -x m\t' 0:continue completion after rest argument that looks like an option (with sets) ->line: {tst -a -x m}{} -#>line: {tst -a -x more }{} +>line: {tst -a -x more }{} tst_arguments - '(help)' -h -V - other -a '*:rest:(1 2 3)' - comptest $'tst -h \t' -0:unknown option disables whole set (without -A) + comptest $'tst -h \t-a \t' +0:foreign option disables whole set (without -A) >line: {tst -h }{} >MESSAGE:{no arguments} +>line: {tst -h -a }{} tst_arguments -A "-*" - '(help)' -h -V - other -a '*:rest:(1 2 3)' - comptest $'tst -h \t' -0:unknown option disables whole set (with -A) + comptest $'tst -h \t-a \t' +0:foreign option disables whole set (with -A) >line: {tst -h }{} >MESSAGE:{no arguments} +>line: {tst -h -a }{} tst_arguments '(-C)-a' - set1 -C -v - set2 '(-a)-C' -w comptest $'tst -a -\t' $'\C-w\C-w-C -\t' -- cgit 1.4.1