1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-06-14 20:18:06 +02:00

zsh-workers:6113

This commit is contained in:
Tanaka Akira 1999-04-27 17:33:44 +00:00
parent 8ef649b31e
commit ca7ec1bf02
6 changed files with 178 additions and 133 deletions

View file

@ -83,8 +83,7 @@ while true; do
else
# No exact match, see how many strings match what's on the line.
tmp2=( "${(@)matches%%${sep}*}" )
compadd -O tmp1 - "$tmp2[@]"
compadd -O tmp1 - "${(@)matches%%${sep}*}"
if [[ $#tmp1 -eq 1 ]]; then

View file

@ -230,14 +230,15 @@ for prepath in "$prepaths[@]"; do
if [[ -n "$PREFIX$SUFFIX" ]]; then
# See which of them match what's on the line.
compadd -O tmp2 "$ignore[@]" - "${(@)tmp1##*/}"
tmp2=("$tmp1[@]")
compadd -D tmp1 "$ignore[@]" - "${(@)tmp1##*/}"
# If no file matches, save the expanded path and continue with
# the outer loop.
if [[ $#tmp2 -eq 0 ]]; then
if [[ "$tmp1[1]" = */* ]]; then
tmp2=( "${(@)tmp1#${prepath}${realpath}}" )
if [[ $#tmp1 -eq 0 ]]; then
if [[ "$tmp2[1]" = */* ]]; then
tmp2=( "${(@)tmp2#${prepath}${realpath}}" )
if [[ "$tmp2[1]" = */* ]]; then
exppaths=( "$exppaths[@]" ${^tmp2%/*}/${tpre}${tsuf} )
else
@ -246,14 +247,6 @@ for prepath in "$prepaths[@]"; do
fi
continue 2
fi
# Remove all files that weren't matched.
if [[ "$tmp1[1]" = */* ]]; then
tmp1=( "${(@M)tmp1:#*/(${(j:|:)~${(@)tmp2:q}})}" )
else
tmp1=( "${(@M)tmp1:#(${(j:|:)~${(@)tmp2:q}})}" )
fi
elif (( ! $#tmp1 )); then
continue 2
fi

View file

@ -340,7 +340,7 @@ xitem([ tt(-W) var(file-prefix) ])
xitem([ tt(-J) var(name) ] [ tt(-V) var(name) ] [ tt(-X) var(explanation) ])
xitem([ tt(-r) var(remove-chars) ] [ tt(-R) var(remove-func) ])
xitem([ tt(-M) var(match-spec) ] [ tt(-O) var(array) ] [ tt(-A) var(array) ])
item([ tt(--) ] [ var(words) ... ])(
item([ tt(-D) var(array) ] [ tt(--) ] [ var(words) ... ])(
This builtin command can be used to add matches directly and control
all the information the completion code stores with each possible
@ -518,6 +518,13 @@ on the command line and the string `tt(foo)' as one of the var(words), this
option stores the string `tt(nofoo)' in the array, whereas the tt(-O)
option stores the `tt(foo)' originally given.
)
item(tt(-D) var(array))(
As with tt(-O), the var(words) are not added to the set of possible
completions. Instead, the completion code tests every var(word) if
it matches what is on the line. If the var(n)'th var(word) does not
match, the var(n)'th element of the var(array) is removed. Elements
for which the corresponding var(word) is matched are retained.
)
item(tt(-), tt(--))(
This flag ends the list of flags and options. All arguments after it
will be taken as the words to use as matches even if they begin with

View file

@ -270,6 +270,31 @@ struct cpattern {
#define CAF_ALT 4
#define CAF_MATCH 8
/* Data for compadd and addmatches() */
typedef struct cadata *Cadata;
struct cadata {
char *ipre;
char *isuf;
char *ppre;
char *psuf;
char *prpre;
char *pre;
char *suf;
char *group;
char *rems;
char *remf;
char *ign;
int flags;
int aflags;
Cmatcher match;
char *exp;
char *apar;
char *opar;
char *dpar;
};
/* Flags for special parameters. */
#define CP_WORDS (1 << 0)

View file

@ -1691,17 +1691,22 @@ bin_compgen(char *name, char **argv, char *ops, int func)
static int
bin_compadd(char *name, char **argv, char *ops, int func)
{
char *p, **sp, *e;
char *ipre = NULL, *isuf = NULL, *ppre = NULL, *psuf = NULL, *prpre = NULL;
char *pre = NULL, *suf = NULL, *group = NULL, *m = NULL, *rs = NULL;
char *ign = NULL, *rf = NULL, *expl = NULL, *apar = NULL, *opar = NULL;
int f = 0, a = CAF_MATCH, dm;
struct cadata dat;
char *p, **sp, *e, *m;
int dm;
Cmatcher match = NULL;
if (incompfunc != 1) {
zerrnam(name, "can only be called from completion function", NULL, 0);
return 1;
}
dat.ipre = dat.isuf = dat.ppre = dat.psuf = dat.prpre =
dat.pre = dat.suf = dat.group = dat.rems = dat.remf =
dat.ign = dat.exp = dat.apar = dat.opar = dat.dpar = NULL;
dat.match = NULL;
dat.flags = 0;
dat.aflags = CAF_MATCH;
for (; *argv && **argv == '-'; argv++) {
if (!(*argv)[1]) {
argv++;
@ -1713,64 +1718,64 @@ bin_compadd(char *name, char **argv, char *ops, int func)
dm = 0;
switch (*p) {
case 'q':
f |= CMF_REMOVE;
dat.flags |= CMF_REMOVE;
break;
case 'Q':
a |= CAF_QUOTE;
dat.aflags |= CAF_QUOTE;
break;
case 'f':
f |= CMF_FILE;
dat.flags |= CMF_FILE;
break;
case 'F':
sp = &ign;
sp = &(dat.ign);
e = "string expected after -%c";
break;
case 'n':
f |= CMF_NOLIST;
dat.flags |= CMF_NOLIST;
break;
case 'U':
a &= ~CAF_MATCH;
dat.aflags &= ~CAF_MATCH;
break;
case 'P':
sp = &pre;
sp = &(dat.pre);
e = "string expected after -%c";
break;
case 'S':
sp = &suf;
sp = &(dat.suf);
e = "string expected after -%c";
break;
case 'J':
sp = &group;
sp = &(dat.group);
e = "group name expected after -%c";
break;
case 'V':
if (!group)
a |= CAF_NOSORT;
sp = &group;
if (!dat.group)
dat.aflags |= CAF_NOSORT;
sp = &(dat.group);
e = "group name expected after -%c";
break;
case 'i':
sp = &ipre;
sp = &(dat.ipre);
e = "string expected after -%c";
break;
case 'I':
sp = &isuf;
sp = &(dat.isuf);
e = "string expected after -%c";
break;
case 'p':
sp = &ppre;
sp = &(dat.ppre);
e = "string expected after -%c";
break;
case 's':
sp = &psuf;
sp = &(dat.psuf);
e = "string expected after -%c";
break;
case 'W':
sp = &prpre;
sp = &(dat.prpre);
e = "string expected after -%c";
break;
case 'a':
a |= CAF_ALT;
dat.aflags |= CAF_ALT;
break;
case 'M':
sp = &m;
@ -1778,25 +1783,29 @@ bin_compadd(char *name, char **argv, char *ops, int func)
dm = 1;
break;
case 'X':
sp = &expl;
sp = &(dat.exp);
e = "string expected after -%c";
break;
case 'r':
f |= CMF_REMOVE;
sp = &rs;
dat.flags |= CMF_REMOVE;
sp = &(dat.rems);
e = "string expected after -%c";
break;
case 'R':
f |= CMF_REMOVE;
sp = &rf;
dat.flags |= CMF_REMOVE;
sp = &(dat.remf);
e = "function name expected after -%c";
break;
case 'A':
sp = &apar;
sp = &(dat.apar);
e = "parameter name expected after -%c";
break;
case 'O':
sp = &opar;
sp = &(dat.opar);
e = "parameter name expected after -%c";
break;
case 'D':
sp = &(dat.dpar);
e = "parameter name expected after -%c";
break;
case '-':
@ -1831,11 +1840,10 @@ bin_compadd(char *name, char **argv, char *ops, int func)
return 1;
match = cpcmatcher(match);
a = addmatchesptr(ipre, isuf, ppre, psuf, prpre, pre, suf, group,
rs, rf, ign, f, a, match, expl, apar, opar, argv);
dm = addmatchesptr(&dat, argv);
freecmatcher(match);
return a;
return dm;
}
#define CVT_RANGENUM 0

View file

@ -3472,14 +3472,10 @@ set_param(char *name, LinkList l)
/**/
int
addmatches(char *ipre, char *isuf,
char *ppre, char *psuf, char *prpre, char *pre,
char *suf, char *group, char *rems, char *remf, char *ign,
int flags, int aflags, Cmatcher match, char *exp,
char *apar, char *opar, char **argv)
addmatches(Cadata dat, char **argv)
{
char *s, *ms, *lipre = NULL, *lisuf = NULL, *lpre = NULL, *lsuf = NULL;
char **aign = NULL;
char **aign = NULL, **dparr;
int lpl, lsl, pl, sl, bpl, bsl, llpl = 0, llsl = 0, nm = mnum;
int oisalt = 0, isalt, isexact, doadd;
Cline lc = NULL;
@ -3487,45 +3483,52 @@ addmatches(char *ipre, char *isuf,
struct cmlist mst;
Cmlist oms = mstack;
Comp cp = NULL;
LinkList aparl = NULL, oparl = NULL;
LinkList aparl = NULL, oparl = NULL, dparl = NULL;
/* Switch back to the heap that was used when the completion widget
* was invoked. */
SWITCHHEAPS(compheap) {
HEAPALLOC {
doadd = (!apar && !opar);
if (apar)
doadd = (!dat->apar && !dat->opar && !dat->dpar);
if (dat->apar)
aparl = newlinklist();
if (opar)
if (dat->opar)
oparl = newlinklist();
if (exp) {
if (dat->dpar) {
if (*(dat->dpar) == '(')
dparr = NULL;
else if ((dparr = get_user_var(dat->dpar)) && !*dparr)
dparr = NULL;
dparl = newlinklist();
}
if (dat->exp) {
expl = (Cexpl) zhalloc(sizeof(struct cexpl));
expl->count = expl->fcount = 0;
expl->str = dupstring(exp);
expl->str = dupstring(dat->exp);
} else
expl = NULL;
/* Store the matcher in our stack of matchers. */
if (match) {
if (dat->match) {
mst.next = mstack;
mst.matcher = match;
mst.matcher = dat->match;
mstack = &mst;
if (!mnum)
add_bmatchers(match);
add_bmatchers(dat->match);
addlinknode(matchers, match);
match->refc++;
addlinknode(matchers, dat->match);
dat->match->refc++;
}
if (mnum && (mstack || bmatchers))
update_bmatchers();
/* Get the suffixes to ignore. */
if (ign)
aign = get_user_var(ign);
if (dat->ign)
aign = get_user_var(dat->ign);
/* Get the contents of the completion variables if we have
* to perform matching. */
if (aflags & CAF_MATCH) {
if (dat->aflags & CAF_MATCH) {
lipre = dupstring(compiprefix);
lisuf = dupstring(compisuffix);
lpre = dupstring(compprefix);
@ -3533,8 +3536,8 @@ addmatches(char *ipre, char *isuf,
llpl = strlen(lpre);
llsl = strlen(lsuf);
/* Test if there is an existing -P prefix. */
if (pre && *pre) {
pl = pfxlen(pre, lpre);
if (dat->pre && *dat->pre) {
pl = pfxlen(dat->pre, lpre);
llpl -= pl;
lpre += pl;
}
@ -3557,79 +3560,76 @@ addmatches(char *ipre, char *isuf,
}
}
/* Now duplicate the strings we have from the command line. */
if (ipre)
ipre = (lipre ? dyncat(lipre, ipre) : dupstring(ipre));
if (dat->ipre)
dat->ipre = (lipre ? dyncat(lipre, dat->ipre) :
dupstring(dat->ipre));
else if (lipre)
ipre = lipre;
if (isuf)
isuf = (lisuf ? dyncat(lisuf, isuf) : dupstring(isuf));
dat->ipre = lipre;
if (dat->isuf)
dat->isuf = (lisuf ? dyncat(lisuf, dat->isuf) :
dupstring(dat->isuf));
else if (lisuf)
isuf = lisuf;
if (ppre) {
ppre = dupstring(ppre);
lpl = strlen(ppre);
dat->isuf = lisuf;
if (dat->ppre) {
dat->ppre = dupstring(dat->ppre);
lpl = strlen(dat->ppre);
} else
lpl = 0;
if (psuf) {
psuf = dupstring(psuf);
lsl = strlen(psuf);
if (dat->psuf) {
dat->psuf = dupstring(dat->psuf);
lsl = strlen(dat->psuf);
} else
lsl = 0;
if (aflags & CAF_MATCH) {
s = ppre ? ppre : "";
if (llpl <= lpl && strpfx(lpre, s)) {
llpl = 0;
if (dat->aflags & CAF_MATCH) {
s = dat->ppre ? dat->ppre : "";
if (llpl <= lpl && strpfx(lpre, s))
lpre = "";
} else if (llpl > lpl && strpfx(s, lpre)) {
llpl -= lpl;
else if (llpl > lpl && strpfx(s, lpre))
lpre += lpl;
} else
else
*argv = NULL;
s = psuf ? psuf : "";
if (llsl <= lsl && strsfx(lsuf, s)) {
llsl = 0;
s = dat->psuf ? dat->psuf : "";
if (llsl <= lsl && strsfx(lsuf, s))
lsuf = "";
} else if (llsl > lsl && strsfx(s, lsuf)) {
else if (llsl > lsl && strsfx(s, lsuf))
lsuf[llsl - lsl] = '\0';
llsl -= lsl;
} else
else
*argv = NULL;
}
if (*argv) {
if (pre)
pre = dupstring(pre);
if (suf)
suf = dupstring(suf);
if (!prpre && (prpre = ppre)) {
singsub(&prpre);
untokenize(prpre);
if (dat->pre)
dat->pre = dupstring(dat->pre);
if (dat->suf)
dat->suf = dupstring(dat->suf);
if (!dat->prpre && (dat->prpre = dat->ppre)) {
singsub(&(dat->prpre));
untokenize(dat->prpre);
} else
prpre = dupstring(prpre);
dat->prpre = dupstring(dat->prpre);
/* Select the group in which to store the matches. */
if (group) {
if (dat->group) {
endcmgroup(NULL);
begcmgroup(group, (aflags & CAF_NOSORT));
if (aflags & CAF_NOSORT)
begcmgroup(dat->group, (dat->aflags & CAF_NOSORT));
if (dat->aflags & CAF_NOSORT)
mgroup->flags |= CGF_NOSORT;
} else {
endcmgroup(NULL);
begcmgroup("default", 0);
}
/* Select the set of matches. */
oisalt = (aflags & CAF_ALT);
oisalt = (dat->aflags & CAF_ALT);
if (remf) {
remf = dupstring(remf);
rems = NULL;
} else if (rems)
rems = dupstring(rems);
if (dat->remf) {
dat->remf = dupstring(dat->remf);
dat->rems = NULL;
} else if (dat->rems)
dat->rems = dupstring(dat->rems);
/* Probably quote the prefix and suffix for testing. */
if (!cp && (aflags & CAF_MATCH) && !(aflags & CAF_QUOTE)) {
if (!cp && (dat->aflags & CAF_MATCH) &&
!(dat->aflags & CAF_QUOTE)) {
lpre = quotename(lpre, NULL);
lsuf = quotename(lsuf, NULL);
llpl = strlen(lpre);
llsl = strlen(lsuf);
}
}
/* Walk through the matches given. */
@ -3638,7 +3638,7 @@ addmatches(char *ipre, char *isuf,
bpl = brpl;
bsl = brsl;
isalt = oisalt;
if ((!psuf || !*psuf) && aign) {
if ((!dat->psuf || !*(dat->psuf)) && aign) {
/* Do the suffix-test. If the match has one of the
* suffixes from ign, we put it in the alternate set. */
char **pt = aign;
@ -3649,39 +3649,52 @@ addmatches(char *ipre, char *isuf,
&& !strcmp(*pt, s + sl - filell))
isalt = 1;
if (isalt && !doadd)
if (isalt && !doadd) {
if (dparr && !*++dparr)
dparr = NULL;
continue;
}
}
if (!(aflags & CAF_MATCH)) {
if (!(dat->aflags & CAF_MATCH)) {
ms = dupstring(s);
lc = bld_parts(ms, sl, -1, NULL);
isexact = 0;
} else if (!(ms = comp_match(lpre, lsuf, s, cp, &lc,
!(aflags & CAF_QUOTE),
&bpl, &bsl, &isexact)))
!(dat->aflags & CAF_QUOTE),
&bpl, &bsl, &isexact))) {
if (dparr && !*++dparr)
dparr = NULL;
continue;
}
if (doadd) {
cm = add_match_data(isalt, ms, lc, ipre, ipre, isuf, pre,
prpre, ppre, psuf, suf, bpl, bsl,
flags, isexact);
cm->rems = rems;
cm->remf = remf;
cm = add_match_data(isalt, ms, lc, dat->ipre, dat->ipre,
dat->isuf, dat->pre, dat->prpre,
dat->ppre, dat->psuf, dat->suf,
bpl, bsl, dat->flags, isexact);
cm->rems = dat->rems;
cm->remf = dat->remf;
} else {
if (apar)
if (dat->apar)
addlinknode(aparl, ms);
if (opar)
if (dat->opar)
addlinknode(oparl, s);
if (dat->dpar && dparr) {
addlinknode(dparl, *dparr);
if (!*++dparr)
dparr = NULL;
}
free_cline(lc);
}
}
compnmatches = mnum;
if (exp)
if (dat->exp)
addexpl();
if (apar)
set_param(apar, aparl);
if (opar)
set_param(opar, oparl);
if (dat->apar)
set_param(dat->apar, aparl);
if (dat->opar)
set_param(dat->opar, oparl);
if (dat->dpar)
set_param(dat->dpar, dparl);
} LASTALLOC;
} SWITCHBACKHEAPS;