diff options
Diffstat (limited to 'Src/Zle')
-rw-r--r-- | Src/Zle/comp.h | 2 | ||||
-rw-r--r-- | Src/Zle/compcore.c | 83 | ||||
-rw-r--r-- | Src/Zle/complete.c | 5 | ||||
-rw-r--r-- | Src/Zle/complist.c | 4 | ||||
-rw-r--r-- | Src/Zle/compresult.c | 164 |
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); |