summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--Src/Zle/computil.c32
-rw-r--r--Test/Y03arguments.ztst8
3 files changed, 28 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 168886d5d..916087cb9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2017-10-07  Oliver Kiddle  <opk@zsh.org>
 
+	* 41824: Src/Zle/computil.c, Test/Y03arguments.ztst: fix to
+	not complete rest args from an _arguments set alongside
+	the argument to and option in a separate set
+
 	* 41823: Completion/Unix/Command/_expand,
 	Completion/Unix/Command/_mv, Completion/Unix/Command/_numfmt,
 	Completion/Unix/Command/_seq, Completion/Unix/Command/_split,
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index 0368a07d0..70cea9f27 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -1933,7 +1933,6 @@ struct castate {
     int inopt;		/* set to current word pos if word is a recognised option */
     int inarg;          /* in a normal argument */
     int nth;		/* number of current normal arg */
-    int doff;		/* length of current option */
     int singles;	/* argument consists of clumped options */
     int oopt;
     int actopts;	/* count of active options */
@@ -1943,6 +1942,7 @@ struct castate {
 
 static struct castate ca_laststate;
 static int ca_parsed = 0, ca_alloced = 0;
+static int ca_doff; /* no. of chars of ignored prefix (for clumped options or arg to an option) */
 
 static void
 freecastate(Castate s)
@@ -2033,7 +2033,7 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first)
     state.argbeg = state.optbeg = state.nargbeg = state.restbeg = state.actopts =
 	state.nth = state.inopt = state.inarg = state.opt = state.arg = 1;
     state.argend = argend = arrlen(compwords) - 1;
-    state.doff = state.singles = state.oopt = 0;
+    state.singles = state.oopt = 0;
     state.curpos = compcurrent;
     state.args = znewlinklist();
     state.oargs = (LinkList *) zalloc(d->nopts * sizeof(LinkList));
@@ -2057,7 +2057,7 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first)
 	 line; line = compwords[cur++]) {
 	ddef = adef = NULL;
 	dopt = NULL;
-	doff = state.singles = arglast = 0;
+	state.singles = arglast = 0;
 
         oline = line;
 #if 0
@@ -2114,7 +2114,7 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first)
 		state.opt = 0;
 		state.argbeg = state.optbeg = state.inopt = cur;
 		state.argend = argend;
-		doff = state.doff = 0;
+		doff = 0;
 		state.singles = 1;
 		if (!state.oargs[state.curopt->num])
 		    state.oargs[state.curopt->num] = znewlinklist();
@@ -2287,7 +2287,6 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first)
 		memcpy(&ca_laststate, &state, sizeof(state));
 		ca_laststate.ddef = NULL;
 		ca_laststate.dopt = NULL;
-		ca_laststate.doff = 0;
 		break;
 	    }
 	    zaddlinknode(state.args, ztrdup(line));
@@ -2324,7 +2323,6 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first)
 
 		ca_laststate.ddef = NULL;
 		ca_laststate.dopt = NULL;
-		ca_laststate.doff = 0;
 		break;
 	    }
 	} else if (state.def && state.def->end)
@@ -2338,7 +2336,6 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first)
 	    memcpy(&ca_laststate, &state, sizeof(state));
 	    ca_laststate.ddef = NULL;
 	    ca_laststate.dopt = NULL;
-	    ca_laststate.doff = 0;
 	} else if (cur == compcurrent && !ca_laststate.def) {
 	    if ((ca_laststate.def = ddef)) {
 		ca_laststate.singles = state.singles;
@@ -2349,7 +2346,7 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first)
 		    ca_laststate.opt = 1;
 		    state.curopt->active = 1;
 		} else {
-		    ca_laststate.doff = doff;
+		    ca_doff = doff;
 		    ca_laststate.opt = 0;
 		}
 	    } else {
@@ -2452,11 +2449,16 @@ ca_set_data(LinkList descr, LinkList act, LinkList subc,
 		!strcmp((char *) getdata(anode), arg->action))
 		break;
 
+	/* with an ignored prefix, we're not completing any normal arguments */
+	if (single && !arg->opt)
+	    return;
+
 	if (!dnode) {
 	    addlinknode(descr, arg->descr);
 	    addlinknode(act, arg->action);
 
 	    if (!restr) {
+
 		if ((restr = (arg->type == CAA_RARGS)))
 		    restrict_range(ca_laststate.optbeg, ca_laststate.argend);
 		else if ((restr = (arg->type == CAA_RREST)))
@@ -2493,6 +2495,7 @@ ca_set_data(LinkList descr, LinkList act, LinkList subc,
 	if (arg->type == CAA_NORMAL &&
 	    opt && optdef && optdef->type == CAO_NEXT)
 	    return;
+
 	if (single)
 	    break;
 
@@ -2521,7 +2524,6 @@ ca_set_data(LinkList descr, LinkList act, LinkList subc,
     if (!single && opt && (lopt || ca_laststate.oopt)) {
 	opt = NULL;
 	arg = ca_get_arg(ca_laststate.d, ca_laststate.nth);
-
 	goto rec;
     }
     if (!opt && oopt > 0) {
@@ -2590,6 +2592,7 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 
 	    multi = !!def->snext; /* if we have sets */
 	    ca_parsed = cap;
+	    ca_doff = 0;
 
 	    while (def) { /* for each set */
 		use = !ca_parse_line(def, all, multi, first);
@@ -2629,23 +2632,20 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	{
 	    LinkList descr, act, subc;
 	    Caarg arg;
-	    int ign = 0, ret = 1;
+	    int ret = 1;
 
 	    descr = newlinklist();
 	    act = newlinklist();
 	    subc = newlinklist();
 
+	    ignore_prefix(ca_doff);
 	    while (lstate) {
 		arg = lstate->def;
 
 		if (arg) {
 		    ret = 0;
-		    if (!ign && lstate->doff > 0) {
-			ign = 1;
-			ignore_prefix(lstate->doff);
-		    }
 		    ca_set_data(descr, act, subc, arg->opt, arg,
-				lstate->curopt, (lstate->doff > 0));
+				lstate->curopt, (ca_doff > 0));
 		}
 		lstate = lstate->snext;
 	    }
@@ -2673,7 +2673,7 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 
 	    for (; lstate; lstate = lstate->snext) {
 		if (lstate->actopts &&
-		    (lstate->opt || (lstate->doff && lstate->def) ||
+		    (lstate->opt || lstate->def ||
 		     (lstate->def && lstate->def->opt &&
 		      (lstate->def->type == CAA_OPT ||
 		       (lstate->def->type >= CAA_RARGS &&
diff --git a/Test/Y03arguments.ztst b/Test/Y03arguments.ztst
index 94ce8361e..de495ee6c 100644
--- a/Test/Y03arguments.ztst
+++ b/Test/Y03arguments.ztst
@@ -364,6 +364,14 @@
 0:repeatable options
 >line: {tst -v -v }{}
 
+ tst_arguments - set1 '--label=:arg:(a b)' - set2 ':rest:(rest args --label=not)'
+ comptest $'tst --label=\t'
+0:rest arguments from another set not completed after option from first set
+>line: {tst --label=}{}
+>DESCRIPTION:{arg}
+>NO:{a}
+>NO:{b}
+
  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)