mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-25 17:20:25 +02:00
49528: allow multiple -D options to compadd
This commit is contained in:
parent
0b6e73d477
commit
632fee7cdf
7 changed files with 68 additions and 25 deletions
|
|
@ -1,5 +1,9 @@
|
||||||
2021-10-30 Oliver Kiddle <opk@zsh.org>
|
2021-10-30 Oliver Kiddle <opk@zsh.org>
|
||||||
|
|
||||||
|
* 49528: Src/Zle/comp.h, Src/Zle/compcore.c, Src/Zle/complete.c,
|
||||||
|
Completion/X/Command/_xinput, Completion/Zsh/Command/_compadd,
|
||||||
|
Doc/Zsh/compwid.yo: allow multiple -D options to compadd
|
||||||
|
|
||||||
* unposted (c.f. Bart: 49531): Test/Y02compmatch.ztst: fix test
|
* unposted (c.f. Bart: 49531): Test/Y02compmatch.ztst: fix test
|
||||||
|
|
||||||
2021-10-27 Matthew Martin <phy1729@gmail.com>
|
2021-10-27 Matthew Martin <phy1729@gmail.com>
|
||||||
|
|
|
||||||
|
|
@ -106,8 +106,7 @@ case $state in
|
||||||
|
|
||||||
if [[ $PREFIX$SUFFIX = [^-]*[^0-9]* ]]; then
|
if [[ $PREFIX$SUFFIX = [^-]*[^0-9]* ]]; then
|
||||||
# match based on the names but insert IDs
|
# match based on the names but insert IDs
|
||||||
compadd "$expl[@]" -M 'b:=* m:{[:lower:]}={[:upper:]}' -D ids -a names
|
compadd "$expl[@]" -M 'b:=* m:{[:lower:]}={[:upper:]}' -D ids -D disp -a names
|
||||||
compadd "$expl[@]" -M 'b:=* m:{[:lower:]}={[:upper:]}' -D disp -a names
|
|
||||||
compadd "$expl[@]" -U -ld disp -a ids && ret=0
|
compadd "$expl[@]" -U -ld disp -a ids && ret=0
|
||||||
|
|
||||||
zstyle -s ":completion:${curcontext}:input-devices" insert-ids out || out=menu
|
zstyle -s ":completion:${curcontext}:input-devices" insert-ids out || out=menu
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ args=(
|
||||||
'-n[hide matches in completion listing]'
|
'-n[hide matches in completion listing]'
|
||||||
'-O+[populate array with matches instead of adding them]:array:_parameters -g "*array*"'
|
'-O+[populate array with matches instead of adding them]:array:_parameters -g "*array*"'
|
||||||
'-A+[populate array with expanded matches instead of adding them]:array:_parameters -g "*array*"'
|
'-A+[populate array with expanded matches instead of adding them]:array:_parameters -g "*array*"'
|
||||||
'-D+[delete elements from array corresponding to non-matching candidates]:array:_parameters -g "*array*"'
|
'*-D+[delete elements from array corresponding to non-matching candidates]:array:_parameters -g "*array*"'
|
||||||
)
|
)
|
||||||
|
|
||||||
case $service in
|
case $service in
|
||||||
|
|
|
||||||
|
|
@ -725,6 +725,8 @@ As with tt(-O), the var(completions) are not added to the set of matches.
|
||||||
Instead, whenever the var(n)th var(completion) does not
|
Instead, whenever the var(n)th var(completion) does not
|
||||||
match, the var(n)th element of the var(array) is removed. Elements
|
match, the var(n)th element of the var(array) is removed. Elements
|
||||||
for which the corresponding var(completion) matches are retained.
|
for which the corresponding var(completion) matches are retained.
|
||||||
|
This option can be used more than once to remove elements from multiple
|
||||||
|
arrays.
|
||||||
)
|
)
|
||||||
item(tt(-C))(
|
item(tt(-C))(
|
||||||
This option adds a special match which expands to all other matches
|
This option adds a special match which expands to all other matches
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,7 @@ struct cadata {
|
||||||
char *exp; /* explanation (-X) */
|
char *exp; /* explanation (-X) */
|
||||||
char *apar; /* array to store matches in (-A) */
|
char *apar; /* array to store matches in (-A) */
|
||||||
char *opar; /* array to store originals in (-O) */
|
char *opar; /* array to store originals in (-O) */
|
||||||
char *dpar; /* array to delete non-matches in (-D) */
|
char **dpar; /* arrays to delete non-matches in (-D) */
|
||||||
char *disp; /* array with display lists (-d) */
|
char *disp; /* array with display lists (-d) */
|
||||||
char *mesg; /* message to show unconditionally (-x) */
|
char *mesg; /* message to show unconditionally (-x) */
|
||||||
int dummies; /* add that many dummy matches */
|
int dummies; /* add that many dummy matches */
|
||||||
|
|
|
||||||
|
|
@ -2081,10 +2081,10 @@ addmatches(Cadata dat, char **argv)
|
||||||
/* ms: "match string" - string to use as completion.
|
/* ms: "match string" - string to use as completion.
|
||||||
* Overloaded at one place as a temporary. */
|
* Overloaded at one place as a temporary. */
|
||||||
char *s, *ms, *lipre = NULL, *lisuf = NULL, *lpre = NULL, *lsuf = NULL;
|
char *s, *ms, *lipre = NULL, *lisuf = NULL, *lpre = NULL, *lsuf = NULL;
|
||||||
char **aign = NULL, **dparr = NULL, *oaq = autoq, *oppre = dat->ppre;
|
char **aign = NULL, ***dparr = NULL, *oaq = autoq, *oppre = dat->ppre;
|
||||||
char *oqp = qipre, *oqs = qisuf, qc, **disp = NULL, *ibuf = NULL;
|
char *oqp = qipre, *oqs = qisuf, qc, **disp = NULL, *ibuf = NULL;
|
||||||
char **arrays = NULL;
|
char **arrays = NULL;
|
||||||
int lpl, lsl, bcp = 0, bcs = 0, bpadd = 0, bsadd = 0;
|
int dind, lpl, lsl, bcp = 0, bcs = 0, bpadd = 0, bsadd = 0;
|
||||||
int ppl = 0, psl = 0, ilen = 0;
|
int ppl = 0, psl = 0, ilen = 0;
|
||||||
int llpl = 0, llsl = 0, nm = mnum, gflags = 0, ohp = haspattern;
|
int llpl = 0, llsl = 0, nm = mnum, gflags = 0, ohp = haspattern;
|
||||||
int isexact, doadd, ois = instring, oib = inbackt;
|
int isexact, doadd, ois = instring, oib = inbackt;
|
||||||
|
|
@ -2092,7 +2092,7 @@ addmatches(Cadata dat, char **argv)
|
||||||
struct cmlist mst;
|
struct cmlist mst;
|
||||||
Cmlist oms = mstack;
|
Cmlist oms = mstack;
|
||||||
Patprog cp = NULL, *pign = NULL;
|
Patprog cp = NULL, *pign = NULL;
|
||||||
LinkList aparl = NULL, oparl = NULL, dparl = NULL;
|
LinkList aparl = NULL, oparl = NULL, *dparl = NULL;
|
||||||
Brinfo bp, bpl = brbeg, obpl, bsl = brend, obsl;
|
Brinfo bp, bpl = brbeg, obpl, bsl = brend, obsl;
|
||||||
Heap oldheap;
|
Heap oldheap;
|
||||||
|
|
||||||
|
|
@ -2186,11 +2186,24 @@ addmatches(Cadata dat, char **argv)
|
||||||
if (dat->opar)
|
if (dat->opar)
|
||||||
oparl = newlinklist();
|
oparl = newlinklist();
|
||||||
if (dat->dpar) {
|
if (dat->dpar) {
|
||||||
if (*(dat->dpar) == '(')
|
int darr = 0, dparlen = arrlen(dat->dpar);
|
||||||
dparr = NULL;
|
char **tail = dat->dpar + dparlen;
|
||||||
else if ((dparr = get_user_var(dat->dpar)) && !*dparr)
|
|
||||||
dparr = NULL;
|
dparr = (char ***)hcalloc((1 + dparlen) * sizeof(char **));
|
||||||
dparl = newlinklist();
|
dparl = (LinkList *)hcalloc((1 + dparlen) * sizeof(LinkList));
|
||||||
|
queue_signals();
|
||||||
|
while (darr < dparlen) {
|
||||||
|
if ((dparr[darr] = getaparam(dat->dpar[darr])) && *dparr[darr]) {
|
||||||
|
dparr[darr] = arrdup(dparr[darr]);
|
||||||
|
dparl[darr++] = newlinklist();
|
||||||
|
} else {
|
||||||
|
/* swap in the last -D argument if we didn't get a non-empty array */
|
||||||
|
dat->dpar[darr] = *--tail;
|
||||||
|
*tail = NULL;
|
||||||
|
--dparlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unqueue_signals();
|
||||||
}
|
}
|
||||||
/* Store the matcher in our stack of matchers. */
|
/* Store the matcher in our stack of matchers. */
|
||||||
if (dat->match) {
|
if (dat->match) {
|
||||||
|
|
@ -2507,8 +2520,10 @@ addmatches(Cadata dat, char **argv)
|
||||||
}
|
}
|
||||||
if (!addit) {
|
if (!addit) {
|
||||||
compignored++;
|
compignored++;
|
||||||
if (dparr && !*++dparr)
|
for (dind = 0; dparl && dparl[dind]; dind++) {
|
||||||
dparr = NULL;
|
if (dparr[dind] && !*++dparr[dind])
|
||||||
|
dparr[dind] = NULL;
|
||||||
|
}
|
||||||
goto next_array;
|
goto next_array;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2525,8 +2540,10 @@ addmatches(Cadata dat, char **argv)
|
||||||
!(dat->flags & CMF_FILE) ? 1 : 2) : 0),
|
!(dat->flags & CMF_FILE) ? 1 : 2) : 0),
|
||||||
&bpl, bcp, &bsl, bcs,
|
&bpl, bcp, &bsl, bcs,
|
||||||
&isexact))) {
|
&isexact))) {
|
||||||
if (dparr && !*++dparr)
|
for (dind = 0; dparl && dparl[dind]; dind++) {
|
||||||
dparr = NULL;
|
if (dparr[dind] && !*++dparr[dind])
|
||||||
|
dparr[dind] = NULL;
|
||||||
|
}
|
||||||
goto next_array;
|
goto next_array;
|
||||||
}
|
}
|
||||||
if (doadd) {
|
if (doadd) {
|
||||||
|
|
@ -2553,10 +2570,14 @@ addmatches(Cadata dat, char **argv)
|
||||||
addlinknode(aparl, ms);
|
addlinknode(aparl, ms);
|
||||||
if (dat->opar)
|
if (dat->opar)
|
||||||
addlinknode(oparl, s);
|
addlinknode(oparl, s);
|
||||||
if (dat->dpar && dparr) {
|
if (dat->dpar) {
|
||||||
addlinknode(dparl, *dparr);
|
for (dind = 0; dparl[dind]; dind++) {
|
||||||
if (!*++dparr)
|
if (dparr[dind]) {
|
||||||
dparr = NULL;
|
addlinknode(dparl[dind], *dparr[dind]);
|
||||||
|
if (!*++dparr[dind])
|
||||||
|
dparr[dind] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free_cline(lc);
|
free_cline(lc);
|
||||||
}
|
}
|
||||||
|
|
@ -2584,8 +2605,10 @@ addmatches(Cadata dat, char **argv)
|
||||||
set_list_array(dat->apar, aparl);
|
set_list_array(dat->apar, aparl);
|
||||||
if (dat->opar)
|
if (dat->opar)
|
||||||
set_list_array(dat->opar, oparl);
|
set_list_array(dat->opar, oparl);
|
||||||
if (dat->dpar)
|
if (dat->dpar) {
|
||||||
set_list_array(dat->dpar, dparl);
|
for (dind = 0; dparl[dind]; dind++)
|
||||||
|
set_list_array(dat->dpar[dind], dparl[dind]);
|
||||||
|
}
|
||||||
if (dat->exp)
|
if (dat->exp)
|
||||||
addexpl(0);
|
addexpl(0);
|
||||||
if (!hasallmatch && (dat->aflags & CAF_ALL)) {
|
if (!hasallmatch && (dat->aflags & CAF_ALL)) {
|
||||||
|
|
|
||||||
|
|
@ -607,6 +607,7 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
|
||||||
char *oarg = NULL; /* argument of -o option */
|
char *oarg = NULL; /* argument of -o option */
|
||||||
int added; /* return value */
|
int added; /* return value */
|
||||||
Cmatcher match = NULL;
|
Cmatcher match = NULL;
|
||||||
|
size_t dparlen = 0, dparsize = 0; /* no. of -D options and array size */
|
||||||
|
|
||||||
if (incompfunc != 1) {
|
if (incompfunc != 1) {
|
||||||
zwarnnam(name, "can only be called from completion function");
|
zwarnnam(name, "can only be called from completion function");
|
||||||
|
|
@ -614,7 +615,8 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
|
||||||
}
|
}
|
||||||
dat.ipre = dat.isuf = dat.ppre = dat.psuf = dat.prpre = dat.mesg =
|
dat.ipre = dat.isuf = dat.ppre = dat.psuf = dat.prpre = dat.mesg =
|
||||||
dat.pre = dat.suf = dat.group = dat.rems = dat.remf = dat.disp =
|
dat.pre = dat.suf = dat.group = dat.rems = dat.remf = dat.disp =
|
||||||
dat.ign = dat.exp = dat.apar = dat.opar = dat.dpar = NULL;
|
dat.ign = dat.exp = dat.apar = dat.opar = NULL;
|
||||||
|
dat.dpar = NULL;
|
||||||
dat.match = NULL;
|
dat.match = NULL;
|
||||||
dat.flags = 0;
|
dat.flags = 0;
|
||||||
dat.aflags = CAF_MATCH;
|
dat.aflags = CAF_MATCH;
|
||||||
|
|
@ -741,7 +743,12 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
|
||||||
e = "parameter name expected after -%c";
|
e = "parameter name expected after -%c";
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
sp = &(dat.dpar);
|
if (dparsize <= dparlen + 1) {
|
||||||
|
dparsize = (dparsize + 1) * 2;
|
||||||
|
dat.dpar = (char **)zrealloc(dat.dpar, sizeof(char *) * dparsize);
|
||||||
|
}
|
||||||
|
sp = dat.dpar + dparlen++;
|
||||||
|
*sp = dat.dpar[dparlen] = NULL;
|
||||||
e = "parameter name expected after -%c";
|
e = "parameter name expected after -%c";
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
|
|
@ -768,11 +775,13 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
|
||||||
} else {
|
} else {
|
||||||
zwarnnam(name, "number expected after -%c", *p);
|
zwarnnam(name, "number expected after -%c", *p);
|
||||||
zsfree(mstr);
|
zsfree(mstr);
|
||||||
|
zfree(dat.dpar, dparsize);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (dat.dummies < 0) {
|
if (dat.dummies < 0) {
|
||||||
zwarnnam(name, "invalid number: %d", dat.dummies);
|
zwarnnam(name, "invalid number: %d", dat.dummies);
|
||||||
zsfree(mstr);
|
zsfree(mstr);
|
||||||
|
zfree(dat.dpar, dparsize);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -782,6 +791,7 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
|
||||||
default:
|
default:
|
||||||
zwarnnam(name, "bad option: -%c", *p);
|
zwarnnam(name, "bad option: -%c", *p);
|
||||||
zsfree(mstr);
|
zsfree(mstr);
|
||||||
|
zfree(dat.dpar, dparsize);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (sp) {
|
if (sp) {
|
||||||
|
|
@ -802,6 +812,7 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
|
||||||
/* Missing argument: argv[N] == "-X", argv[N+1] == NULL. */
|
/* Missing argument: argv[N] == "-X", argv[N+1] == NULL. */
|
||||||
zwarnnam(name, e, *p);
|
zwarnnam(name, e, *p);
|
||||||
zsfree(mstr);
|
zsfree(mstr);
|
||||||
|
zfree(dat.dpar, dparsize);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (m) {
|
if (m) {
|
||||||
|
|
@ -820,17 +831,21 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
|
||||||
|
|
||||||
if (mstr && (match = parse_cmatcher(name, mstr)) == pcm_err) {
|
if (mstr && (match = parse_cmatcher(name, mstr)) == pcm_err) {
|
||||||
zsfree(mstr);
|
zsfree(mstr);
|
||||||
|
zfree(dat.dpar, dparsize);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
zsfree(mstr);
|
zsfree(mstr);
|
||||||
|
|
||||||
if (!*argv && !dat.group && !dat.mesg &&
|
if (!*argv && !dat.group && !dat.mesg &&
|
||||||
!(dat.aflags & (CAF_NOSORT|CAF_UNIQALL|CAF_UNIQCON|CAF_ALL)))
|
!(dat.aflags & (CAF_NOSORT|CAF_UNIQALL|CAF_UNIQCON|CAF_ALL))) {
|
||||||
|
zfree(dat.dpar, dparsize);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
dat.match = match = cpcmatcher(match);
|
dat.match = match = cpcmatcher(match);
|
||||||
added = addmatches(&dat, argv);
|
added = addmatches(&dat, argv);
|
||||||
freecmatcher(match);
|
freecmatcher(match);
|
||||||
|
zfree(dat.dpar, dparsize);
|
||||||
|
|
||||||
return added;
|
return added;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue