summaryrefslogtreecommitdiff
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)