summaryrefslogtreecommitdiff
path: root/Src/Zle
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle')
-rw-r--r--Src/Zle/comp.h2
-rw-r--r--Src/Zle/compcore.c83
-rw-r--r--Src/Zle/complete.c5
-rw-r--r--Src/Zle/complist.c4
-rw-r--r--Src/Zle/compresult.c164
5 files changed, 195 insertions, 63 deletions
diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h
index 57091c744..b18947064 100644
--- a/Src/Zle/comp.h
+++ b/Src/Zle/comp.h
@@ -124,6 +124,7 @@ struct cmatch {
#define CMF_ROWS (1<<10) /* prefer LIST_ROWS_FIRST */
#define CMF_MULT (1<<11) /* string appears more than once */
#define CMF_FMULT (1<<12) /* first of multiple equal strings */
+#define CMF_ALL (1<<13) /* a match representing all other matches */
/* Stuff for completion matcher control. */
@@ -236,6 +237,7 @@ struct menuinfo {
#define CAF_UNIQALL 16
#define CAF_ARRAYS 32
#define CAF_KEYS 64
+#define CAF_ALL 128
/* Data for compadd and addmatches() */
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 6941dbfe2..fa8104169 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -143,6 +143,11 @@ mod_export Cmgroup lastmatches, pmatches, amatches, lmatches, lastlmatches;
/**/
mod_export int hasoldlist, hasperm;
+/* Non-zero if we have a match representing all other matches. */
+
+/**/
+int hasallmatch;
+
/* Non-zero if we have newly added matches. */
/**/
@@ -331,6 +336,7 @@ do_completion(Hookdef dummy, Compldat dat)
maxmlen = -1;
compignored = 0;
nmessages = 0;
+ hasallmatch = 0;
/* Make sure we have the completion list and compctl. */
if (makecomplist(s, incmd, lst)) {
@@ -366,41 +372,8 @@ do_completion(Hookdef dummy, Compldat dat)
cs = origcs;
showinglist = -2;
} else if (useline == 2 && nmatches > 1) {
- int first = 1, nm = nmatches;
- Cmatch *mc;
-
- menucmp = 1;
- menuacc = 0;
-
- for (minfo.group = amatches;
- minfo.group && !(minfo.group)->mcount;
- minfo.group = (minfo.group)->next);
+ do_allmatches(1);
- mc = (minfo.group)->matches;
-
- while (1) {
- if (!first)
- accept_last();
- first = 0;
-
- if (!--nm)
- menucmp = 0;
-
- do_single(*mc);
- minfo.cur = mc;
-
- if (!*++(minfo.cur)) {
- do {
- if (!(minfo.group = (minfo.group)->next))
- break;
- } while (!(minfo.group)->mcount);
- if (!minfo.group)
- break;
- minfo.cur = minfo.group->matches;
- }
- mc = minfo.cur;
- }
- menucmp = 0;
minfo.cur = NULL;
if (forcelist)
@@ -1604,7 +1577,7 @@ addmatches(Cadata dat, char **argv)
Brinfo bp, bpl = brbeg, obpl, bsl = brend, obsl;
Heap oldheap;
- if (!*argv) {
+ if (!*argv && !(dat->aflags & CAF_ALL)) {
SWITCHHEAPS(oldheap, compheap) {
/* Select the group in which to store the matches. */
gflags = (((dat->aflags & CAF_NOSORT ) ? CGF_NOSORT : 0) |
@@ -2042,6 +2015,36 @@ addmatches(Cadata dat, char **argv)
set_list_array(dat->dpar, dparl);
if (dat->exp)
addexpl();
+ if (!hasallmatch && (dat->aflags & CAF_ALL)) {
+ Cmatch cm = (Cmatch) zhalloc(sizeof(struct cmatch));
+
+ memset(cm, 0, sizeof(struct cmatch));
+ cm->str = dupstring("<all>");
+ cm->flags = (dat->flags | CMF_ALL |
+ (complist ?
+ ((strstr(complist, "packed") ? CMF_PACKED : 0) |
+ (strstr(complist, "rows") ? CMF_ROWS : 0)) : 0));
+ if (disp) {
+ if (!*++disp)
+ disp = NULL;
+ if (disp)
+ cm->disp = dupstring(*disp);
+ } else {
+ cm->disp = dupstring("");
+ cm->flags |= CMF_DISPLINE;
+ }
+ mnum++;
+ ainfo->count++;
+ if (curexpl)
+ curexpl->count++;
+
+ addlinknode(matches, cm);
+
+ newmatches = 1;
+ mgroup->new = 1;
+
+ hasallmatch = 1;
+ }
} SWITCHBACKHEAPS(oldheap);
/* We switched back to the current heap, now restore the stack of
@@ -2695,7 +2698,7 @@ dupmatch(Cmatch m, int nbeg, int nend)
r->pre = ztrdup(m->pre);
r->suf = ztrdup(m->suf);
r->flags = m->flags;
- if (nbeg) {
+ if (m->brpl) {
int *p, *q, i;
r->brpl = (int *) zalloc(nbeg * sizeof(int));
@@ -2704,7 +2707,7 @@ dupmatch(Cmatch m, int nbeg, int nend)
*p = *q;
} else
r->brpl = NULL;
- if (nend) {
+ if (m->brsl) {
int *p, *q, i;
r->brsl = (int *) zalloc(nend * sizeof(int));
@@ -2888,8 +2891,10 @@ freematch(Cmatch m, int nbeg, int nend)
zsfree(m->remf);
zsfree(m->disp);
zsfree(m->autoq);
- zfree(m->brpl, nbeg * sizeof(int));
- zfree(m->brsl, nend * sizeof(int));
+ if (m->brpl)
+ zfree(m->brpl, nbeg * sizeof(int));
+ if (m->brsl)
+ zfree(m->brsl, nend * sizeof(int));
zfree(m, sizeof(m));
}
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index 20da967ef..df9faed7a 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -452,6 +452,9 @@ bin_compadd(char *name, char **argv, char *ops, int func)
case 'Q':
dat.aflags |= CAF_QUOTE;
break;
+ case 'C':
+ dat.aflags |= CAF_ALL;
+ break;
case 'f':
dat.flags |= CMF_FILE;
break;
@@ -604,7 +607,7 @@ bin_compadd(char *name, char **argv, char *ops, int func)
ca_args:
if (!*argv && !dat.group && !dat.mesg &&
- !(dat.aflags & (CAF_NOSORT|CAF_UNIQALL|CAF_UNIQCON)))
+ !(dat.aflags & (CAF_NOSORT|CAF_UNIQALL|CAF_UNIQCON|CAF_ALL)))
return 1;
dat.match = match = cpcmatcher(match);
diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index a7dbf6412..2334a2612 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -1375,6 +1375,10 @@ clprintm(Cmgroup g, Cmatch *mp, int mc, int ml, int lastc, int width,
return 0;
}
m = *mp;
+
+ if ((m->flags & CMF_ALL) && (!m->disp || !m->disp[0]))
+ bld_all_str(m);
+
mlastm = m->gnum;
if (m->disp && (m->flags & CMF_DISPLINE)) {
if (mselect >= 0) {
diff --git a/Src/Zle/compresult.c b/Src/Zle/compresult.c
index 924cf3dcd..cce06d1e3 100644
--- a/Src/Zle/compresult.c
+++ b/Src/Zle/compresult.c
@@ -570,36 +570,40 @@ instmatch(Cmatch m, int *scs)
mod_export int
hasbrpsfx(Cmatch m, char *pre, char *suf)
{
- char *op = lastprebr, *os = lastpostbr;
- VARARR(char, oline, ll);
- int oll = ll, ocs = cs, ole = lastend, opcs = brpcs, oscs = brscs, ret;
+ if (m->flags & CMF_ALL)
+ return 1;
+ else {
+ char *op = lastprebr, *os = lastpostbr;
+ VARARR(char, oline, ll);
+ int oll = ll, ocs = cs, ole = lastend, opcs = brpcs, oscs = brscs, ret;
- memcpy(oline, line, ll);
+ memcpy(oline, line, ll);
- lastprebr = lastpostbr = NULL;
+ lastprebr = lastpostbr = NULL;
- instmatch(m, NULL);
+ instmatch(m, NULL);
- cs = 0;
- foredel(ll);
- spaceinline(oll);
- memcpy(line, oline, oll);
- cs = ocs;
- lastend = ole;
- brpcs = opcs;
- brscs = oscs;
+ cs = 0;
+ foredel(ll);
+ spaceinline(oll);
+ memcpy(line, oline, oll);
+ cs = ocs;
+ lastend = ole;
+ brpcs = opcs;
+ brscs = oscs;
- ret = (((!pre && !lastprebr) ||
- (pre && lastprebr && !strcmp(pre, lastprebr))) &&
- ((!suf && !lastpostbr) ||
- (suf && lastpostbr && !strcmp(suf, lastpostbr))));
+ ret = (((!pre && !lastprebr) ||
+ (pre && lastprebr && !strcmp(pre, lastprebr))) &&
+ ((!suf && !lastpostbr) ||
+ (suf && lastpostbr && !strcmp(suf, lastpostbr))));
- zsfree(lastprebr);
- zsfree(lastpostbr);
- lastprebr = op;
- lastpostbr = os;
+ zsfree(lastprebr);
+ zsfree(lastpostbr);
+ lastprebr = op;
+ lastpostbr = os;
- return ret;
+ return ret;
+ }
}
/* Handle the case were we found more than one match. */
@@ -748,6 +752,65 @@ ztat(char *nam, struct stat *buf, int ls)
}
}
+/* Insert all matches in the command line. */
+
+/**/
+void
+do_allmatches(int end)
+{
+ int first = 1, nm = nmatches - 1, omc = menucmp, oma = menuacc, e;
+ Cmatch *mc;
+ struct menuinfo mi;
+ char *p = (brbeg ? ztrdup(lastbrbeg->str) : NULL);
+
+ memcpy(&mi, &minfo, sizeof(struct menuinfo));
+ menucmp = 1;
+ menuacc = 0;
+
+ for (minfo.group = amatches;
+ minfo.group && !(minfo.group)->mcount;
+ minfo.group = (minfo.group)->next);
+
+ mc = (minfo.group)->matches;
+
+ while (1) {
+ if (!((*mc)->flags & CMF_ALL)) {
+ if (!first)
+ accept_last();
+ first = 0;
+
+ if (!omc && !--nm)
+ menucmp = 0;
+
+ do_single(*mc);
+ }
+ minfo.cur = mc;
+
+ if (!*++(minfo.cur)) {
+ do {
+ if (!(minfo.group = (minfo.group)->next))
+ break;
+ } while (!(minfo.group)->mcount);
+ if (!minfo.group)
+ break;
+ minfo.cur = minfo.group->matches;
+ }
+ mc = minfo.cur;
+ }
+ menucmp = omc;
+ menuacc = oma;
+
+ e = minfo.end;
+ memcpy(&minfo, &mi, sizeof(struct menuinfo));
+ minfo.end = e;
+ minfo.len = e - minfo.pos;
+
+ if (p) {
+ zsfree(lastbrbeg->str);
+ lastbrbeg->str = p;
+ }
+}
+
/* Insert a single match in the command line. */
/**/
@@ -785,6 +848,10 @@ do_single(Cmatch m)
cs = minfo.pos;
foredel(l);
+ if (m->flags & CMF_ALL)
+ do_allmatches(0);
+ else {
+
/* And then we insert the new string. */
minfo.len = instmatch(m, &scs);
minfo.end = cs;
@@ -956,6 +1023,7 @@ do_single(Cmatch m)
runhookdef(INSERTMATCHHOOK, (void *) &dat);
minfo.cur = om;
}
+ }
}
/* Do completion, given that we are in the middle of a menu completion. We *
@@ -1886,6 +1954,54 @@ printlist(int over, CLPrintFunc printm, int showall)
}
/**/
+mod_export void
+bld_all_str(Cmatch all)
+{
+ Cmgroup g;
+ Cmatch *mp, m;
+ int len = columns - 5, t, add = 0;
+ VARARR(char, buf, columns + 1);
+
+ buf[0] = '\0';
+
+ for (g = amatches; g && !g->mcount; g = g->next);
+
+ mp = g->matches;
+ while (1) {
+ m = *mp;
+ if (!(m->flags & (CMF_ALL | CMF_HIDE)) && m->str) {
+ t = strlen(m->str) + add;
+ if (len >= t) {
+ if (add)
+ strcat(buf, " ");
+ strcat(buf, m->str);
+ len -= t;
+ add = 1;
+ } else {
+ if (len > add + 2) {
+ if (add)
+ strcat(buf, " ");
+ strncat(buf, m->str, len);
+ }
+ strcat(buf, " ...");
+ break;
+ }
+ }
+ if (!*++mp) {
+ do {
+ if (!(g = g->next))
+ break;
+ } while (!g->mcount);
+ if (!g)
+ break;
+ mp = g->matches;
+ }
+ }
+ zsfree(all->disp);
+ all->disp = ztrdup(buf);
+}
+
+/**/
static void
iprintm(Cmgroup g, Cmatch *mp, int mc, int ml, int lastc, int width,
char *path, struct stat *buf)
@@ -1897,6 +2013,8 @@ iprintm(Cmgroup g, Cmatch *mp, int mc, int ml, int lastc, int width,
return;
m = *mp;
+ if ((m->flags & CMF_ALL) && (!m->disp || !m->disp[0]))
+ bld_all_str(m);
if (m->disp) {
if (m->flags & CMF_DISPLINE) {
printfmt(m->disp, 0, 1, 0);