1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-23 04:30:24 +02:00

49528: allow multiple -D options to compadd

This commit is contained in:
Oliver Kiddle 2021-10-30 23:27:29 +02:00
parent 0b6e73d477
commit 632fee7cdf
7 changed files with 68 additions and 25 deletions

View file

@ -1,5 +1,9 @@
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
2021-10-27 Matthew Martin <phy1729@gmail.com>

View file

@ -106,8 +106,7 @@ case $state in
if [[ $PREFIX$SUFFIX = [^-]*[^0-9]* ]]; then
# 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 disp -a names
compadd "$expl[@]" -M 'b:=* m:{[:lower:]}={[:upper:]}' -D ids -D disp -a names
compadd "$expl[@]" -U -ld disp -a ids && ret=0
zstyle -s ":completion:${curcontext}:input-devices" insert-ids out || out=menu

View file

@ -31,7 +31,7 @@ args=(
'-n[hide matches in completion listing]'
'-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*"'
'-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

View file

@ -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
match, the var(n)th element of the var(array) is removed. Elements
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))(
This option adds a special match which expands to all other matches

View file

@ -329,7 +329,7 @@ struct cadata {
char *exp; /* explanation (-X) */
char *apar; /* array to store matches in (-A) */
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 *mesg; /* message to show unconditionally (-x) */
int dummies; /* add that many dummy matches */

View file

@ -2081,10 +2081,10 @@ addmatches(Cadata dat, char **argv)
/* ms: "match string" - string to use as completion.
* Overloaded at one place as a temporary. */
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 **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 llpl = 0, llsl = 0, nm = mnum, gflags = 0, ohp = haspattern;
int isexact, doadd, ois = instring, oib = inbackt;
@ -2092,7 +2092,7 @@ addmatches(Cadata dat, char **argv)
struct cmlist mst;
Cmlist oms = mstack;
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;
Heap oldheap;
@ -2186,11 +2186,24 @@ addmatches(Cadata dat, char **argv)
if (dat->opar)
oparl = newlinklist();
if (dat->dpar) {
if (*(dat->dpar) == '(')
dparr = NULL;
else if ((dparr = get_user_var(dat->dpar)) && !*dparr)
dparr = NULL;
dparl = newlinklist();
int darr = 0, dparlen = arrlen(dat->dpar);
char **tail = dat->dpar + dparlen;
dparr = (char ***)hcalloc((1 + dparlen) * sizeof(char **));
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. */
if (dat->match) {
@ -2507,8 +2520,10 @@ addmatches(Cadata dat, char **argv)
}
if (!addit) {
compignored++;
if (dparr && !*++dparr)
dparr = NULL;
for (dind = 0; dparl && dparl[dind]; dind++) {
if (dparr[dind] && !*++dparr[dind])
dparr[dind] = NULL;
}
goto next_array;
}
}
@ -2525,8 +2540,10 @@ addmatches(Cadata dat, char **argv)
!(dat->flags & CMF_FILE) ? 1 : 2) : 0),
&bpl, bcp, &bsl, bcs,
&isexact))) {
if (dparr && !*++dparr)
dparr = NULL;
for (dind = 0; dparl && dparl[dind]; dind++) {
if (dparr[dind] && !*++dparr[dind])
dparr[dind] = NULL;
}
goto next_array;
}
if (doadd) {
@ -2553,10 +2570,14 @@ addmatches(Cadata dat, char **argv)
addlinknode(aparl, ms);
if (dat->opar)
addlinknode(oparl, s);
if (dat->dpar && dparr) {
addlinknode(dparl, *dparr);
if (!*++dparr)
dparr = NULL;
if (dat->dpar) {
for (dind = 0; dparl[dind]; dind++) {
if (dparr[dind]) {
addlinknode(dparl[dind], *dparr[dind]);
if (!*++dparr[dind])
dparr[dind] = NULL;
}
}
}
free_cline(lc);
}
@ -2584,8 +2605,10 @@ addmatches(Cadata dat, char **argv)
set_list_array(dat->apar, aparl);
if (dat->opar)
set_list_array(dat->opar, oparl);
if (dat->dpar)
set_list_array(dat->dpar, dparl);
if (dat->dpar) {
for (dind = 0; dparl[dind]; dind++)
set_list_array(dat->dpar[dind], dparl[dind]);
}
if (dat->exp)
addexpl(0);
if (!hasallmatch && (dat->aflags & CAF_ALL)) {

View file

@ -607,6 +607,7 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
char *oarg = NULL; /* argument of -o option */
int added; /* return value */
Cmatcher match = NULL;
size_t dparlen = 0, dparsize = 0; /* no. of -D options and array size */
if (incompfunc != 1) {
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.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.flags = 0;
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";
break;
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";
break;
case 'd':
@ -768,11 +775,13 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
} else {
zwarnnam(name, "number expected after -%c", *p);
zsfree(mstr);
zfree(dat.dpar, dparsize);
return 1;
}
if (dat.dummies < 0) {
zwarnnam(name, "invalid number: %d", dat.dummies);
zsfree(mstr);
zfree(dat.dpar, dparsize);
return 1;
}
break;
@ -782,6 +791,7 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
default:
zwarnnam(name, "bad option: -%c", *p);
zsfree(mstr);
zfree(dat.dpar, dparsize);
return 1;
}
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. */
zwarnnam(name, e, *p);
zsfree(mstr);
zfree(dat.dpar, dparsize);
return 1;
}
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) {
zsfree(mstr);
zfree(dat.dpar, dparsize);
return 1;
}
zsfree(mstr);
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;
}
dat.match = match = cpcmatcher(match);
added = addmatches(&dat, argv);
freecmatcher(match);
zfree(dat.dpar, dparsize);
return added;
}