zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: option exclusion within current word
@ 2017-01-05  3:15 Oliver Kiddle
  0 siblings, 0 replies; only message in thread
From: Oliver Kiddle @ 2017-01-05  3:15 UTC (permalink / raw)
  To: Zsh workers

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'


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2017-01-05  3:22 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-05  3:15 PATCH: option exclusion within current word Oliver Kiddle

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).