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:
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>
|
||||
|
||||
* 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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue