From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8370 invoked by alias); 5 Jan 2017 03:22:07 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 40269 Received: (qmail 9390 invoked from network); 5 Jan 2017 03:22:07 -0000 X-Qmail-Scanner-Diagnostics: from nm40-vm7.bullet.mail.ir2.yahoo.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.99.2/21882. spamassassin: 3.4.1. Clear:RC:0(212.82.97.175):SA:0(-1.8/5.0):. Processed in 1.218995 secs); 05 Jan 2017 03:22:07 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H2,SPF_PASS,T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.1 X-Envelope-From: okiddle@yahoo.co.uk X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | Received-SPF: pass (ns1.primenet.com.au: SPF record at _spf.mail.yahoo.com designates 212.82.97.175 as permitted sender) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.co.uk; s=s2048; t=1483586133; bh=6NgUHE5BHB5VupiGPxIKVrSgRzWCRfpsD+YuHhox3ZA=; h=From:To:Subject:Date:From:Subject; b=AkxaBaea4tEKDq7+U6kRhoJUgwO9QZ+eekLoLtimtr5MoLSndTvXfHnK2mAEvJ+EXdTzNLrgtao7dK9br9DGaEZYkduXlWVnKeW0+UNaoxtHn8SvSc72csEm6NcAMMFBPNMSTMxOmzptJpOAw6/wU6ANsSNb2SUoSXTnRSJOmH2fcRIgNgj1enOvC+V3u6wLmVRj1tG1mdJdcwX9nknqs306YTX538B9OgnG/Q3H2gnPnp4z7HJqxyiaHK9FvC5JMEobzMxQGxB4TphL8XaFheFYcvmoERBRtZunloqkkTB8mgueCfMI+XPZ2I2xVVIpXPWRx/+Jm76Fvla7jMC0Og== X-Yahoo-Newman-Id: 219932.36142.bm@smtp104.mail.ir2.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: OlGmq00VM1mEC0v0vWkgT0r0Qfcv4VBfKa4q48TEvYCH5d8 iU3rTnidlCWWwK2ZdVPoa9ui9HtxAzvEfQNMZs0f189YapM.5umvD_h5rCwn iFvUFEuOil5tVcaKTzdvEh23drEn.UK.gtne2YCuOItTgXvEOE3nKZR2Ge0R NcNB6KFZWlcDqAF19nWSTJgpjeNT1mdLnrVi94PY1ztpBwKFqma28lQKOiYj eTVvobOTaUIGGF4.nOMxST64i_7t8YfDcsUwFExUTY79nrGrxXfpOImtpq1p SvBDFndAlp6cds2zrp.JxRfoiHi8DXpL7CuX3uvEygk8QkHB_wRp77w1lTJb ByTUx_xmn0WAcHE82LcNv6IWXjLaxsyT74WlJyultHmruXgHS40PRJXm2tWL BLPn4QwEc39OTZgDM15xQvfXULhJZ9Uk0OW054WZY_w1BiQu1ssEBbD5ueDp 3ZmF5hB9u0saXtSciNLAqnw1gmPmeUDLDmg2.F0tSwDPEOAA0aDxRpZqgKz8 NHWrXDnQjT6RO2d.aKe.WxEfnTJ69LCbJvrEzIzfl X-Yahoo-SMTP: opAkk_CswBAce_kJ3nIPlH80cJI- From: Oliver Kiddle To: Zsh workers Subject: PATCH: option exclusion within current word MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <37341.1483586115.1@hydra.kiddle.eu> Date: Thu, 05 Jan 2017 04:15:15 +0100 Message-ID: <37342.1483586115@hydra.kiddle.eu> With _arguments, exclusions don't apply for options within the current word. This mainly affects clumped options (_arguments -s). So, e.g. with _arguments -s : '(-b)-a' -b -c completion directly after -a offers both -b and -c. The reasoning for this is specific handling added in 13999 to prevent an option being excluded by an option that is a prefix of it: things like -c excluding -conf or --long excluding --longer. This patch replaces 13999 with a different, more indirect approach. Within the current word, only exclusions to short options are applied. The old code explicitly checks for prefixes. There may be some case I've not thought of that this approach doesn't handle (any ideas?) but we're right at the start of the release so I'd prefer to try this to see and at least kill the known issue. Oliver diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index 8214465..12aa895 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -1790,16 +1790,17 @@ ca_get_arg(Cadef d, int n) * opts: if set, all options excluded leaving only nornal/rest arguments */ static void -ca_inactive(Cadef d, char **xor, int cur, int opts, char *optname) +ca_inactive(Cadef d, char **xor, int cur, int opts) { if ((xor || opts) && cur <= compcurrent) { Caopt opt; char *x; int sl = (d->set ? (int)strlen(d->set) : -1), set = 0; + /* current word could be a prefix of a longer one so only do + * exclusions for single-letter options (for option clumping) */ + int single = (cur == compcurrent); for (; (x = (opts ? "-" : *xor)); xor++) { - if (optname && optname[0] == x[0] && strcmp(optname, x)) - continue; set = 0; if (sl > 0) { if (strpfx(d->set, x)) { @@ -1809,7 +1810,7 @@ ca_inactive(Cadef d, char **xor, int cur, int opts, char *optname) Caopt p; for (p = d->opts; p; p = p->next) - if (p->set) + if (p->set && !(single && *p->name && p->name[1] && p->name[2])) p->active = 0; x = ":"; @@ -1831,7 +1832,7 @@ ca_inactive(Cadef d, char **xor, int cur, int opts, char *optname) Caopt p; for (p = d->opts; p; p = p->next) - if (!set || p->set) + if ((!set || p->set) && !(single && *p->name && p->name[1] && p->name[2])) p->active = 0; } else if (x[0] == '*' && !x[1]) { if (d->rest && (!set || d->rest->set)) @@ -1845,7 +1846,8 @@ ca_inactive(Cadef d, char **xor, int cur, int opts, char *optname) if (a && a->num == n && (!set || a->set)) a->active = 0; - } else if ((opt = ca_get_opt(d, x, 1, NULL)) && (!set || opt->set)) + } else if ((opt = ca_get_opt(d, x, 1, NULL)) && (!set || opt->set) && + !(single && *opt->name && opt->name[1] && opt->name[2])) opt->active = 0; if (opts) @@ -2029,9 +2031,9 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first) remnulargs(line); untokenize(line); - ca_inactive(d, argxor, cur, 0, NULL); + ca_inactive(d, argxor, cur, 0); if ((d->flags & CDF_SEP) && cur != compcurrent && !strcmp(line, "--")) { - ca_inactive(d, NULL, cur, 1, NULL); + ca_inactive(d, NULL, cur, 1); continue; } @@ -2107,8 +2109,7 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first) if (!state.oargs[state.curopt->num]) state.oargs[state.curopt->num] = znewlinklist(); - ca_inactive(d, state.curopt->xor, cur, 0, - (cur == compcurrent ? state.curopt->name : NULL)); + ca_inactive(d, state.curopt->xor, cur, 0); /* Collect the argument strings. Maybe. */ @@ -2161,8 +2162,7 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first) if (!state.oargs[tmpopt->num]) state.oargs[tmpopt->num] = znewlinklist(); - ca_inactive(d, tmpopt->xor, cur, 0, - (cur == compcurrent ? tmpopt->name : NULL)); + ca_inactive(d, tmpopt->xor, cur, 0); } } if (state.def && @@ -2190,7 +2190,7 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first) (!napat || cur <= compcurrent || !pattry(napat, line))) { /* Otherwise it's a normal argument. */ if (napat && cur <= compcurrent) - ca_inactive(d, NULL, cur + 1, 1, NULL); + ca_inactive(d, NULL, cur + 1, 1); arglast = 1; /* if this is the first normal arg after an option, may have been diff --git a/Test/Y03arguments.ztst b/Test/Y03arguments.ztst index 47f4747..5957bc3 100644 --- a/Test/Y03arguments.ztst +++ b/Test/Y03arguments.ztst @@ -479,12 +479,9 @@ F:shouldn't offer -b as it is already on the command-line tst_arguments -s : '(-d)-a' -b -c -d - comptest $'tst -ab\t -\t\eb\eb \C-b-\t' + comptest $'tst -ab\t\C-h -\t\eb\eb \C-b-\t' 0:exclusion with clumped options, in, after and before ->line: {tst -ab}{} ->DESCRIPTION:{option} ->NO:{-c} ->NO:{-d} +>line: {tst -abc}{} >line: {tst -ab -c }{} >line: {tst -}{ -ab -c} >DESCRIPTION:{option} @@ -492,7 +489,23 @@ F:shouldn't offer -b as it is already on the command-line >NO:{-b} >NO:{-c} >NO:{-d} -F:the first tab press shouldn't offer -d since -a is on the command line + + tst_arguments -s '(-conf)-c' '-conf' '-f' '(-)--long' --longer + comptest $'tst -c\t\C-h-long\t' +0:don't prematurely exclude option that current word is a prefix of +>line: {tst -c}{} +>DESCRIPTION:{option} +>NO:{-conf} +>NO:{-f} +>line: {tst --long}{} +>DESCRIPTION:{option} +>NO:{--long} +>NO:{--longer} + + tst_arguments -s '(set)-c' - set '-conf' '-f' + comptest $'tst -c\t' +0:don't prematurely exclude option that current word is a prefix of (with sets) +>line: {tst -conf }{} tst_arguments -s : -ad '(-d)-a' -b -ca -d comptest $'tst -ad\t-b\t'