diff options
-rw-r--r-- | Src/Zle/comp.h | 18 | ||||
-rw-r--r-- | Src/Zle/complist.c | 22 | ||||
-rw-r--r-- | Src/Zle/zle_tricky.c | 198 |
3 files changed, 173 insertions, 65 deletions
diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h index e32a969f3..201469872 100644 --- a/Src/Zle/comp.h +++ b/Src/Zle/comp.h @@ -239,13 +239,14 @@ struct cmatch { int gnum; /* global number */ }; -#define CMF_FILE 1 /* this is a file */ -#define CMF_REMOVE 2 /* remove the suffix */ -#define CMF_ISPAR 4 /* is paramter expansion */ -#define CMF_PARBR 8 /* paramter expansion with a brace */ -#define CMF_PARNEST 16 /* nested paramter expansion */ -#define CMF_NOLIST 32 /* should not be listed */ -#define CMF_DISPLINE 64 /* display strings one per line */ +#define CMF_FILE 1 /* this is a file */ +#define CMF_REMOVE 2 /* remove the suffix */ +#define CMF_ISPAR 4 /* is paramter expansion */ +#define CMF_PARBR 8 /* paramter expansion with a brace */ +#define CMF_PARNEST 16 /* nested paramter expansion */ +#define CMF_NOLIST 32 /* should not be listed */ +#define CMF_DISPLINE 64 /* display strings one per line */ +#define CMF_HIDE 128 /* temporarily hide this one */ /* Stuff for completion matcher control. */ @@ -297,6 +298,8 @@ struct menuinfo { int we; /* non-zero if the cursor was at the end */ int insc; /* length of suffix inserted */ int asked; /* we asked if the list should be shown */ + char *prebr; /* prefix before a brace, if any */ + char *postbr; /* suffix after a brace */ }; /* Flags for compadd and addmatches(). */ @@ -342,6 +345,7 @@ typedef struct cldata *Cldata; struct cldata { int columns; /* screen width */ int lines; /* screen height */ + int menuacc; /* value of global menuacc */ int valid; /* no need to calculate anew */ int nlist; /* number of matches to list */ int nlines; /* number of lines needed */ diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c index 7441db15f..a62a6df48 100644 --- a/Src/Zle/complist.c +++ b/Src/Zle/complist.c @@ -346,11 +346,12 @@ clprintm(Cmgroup g, Cmatch *mp, int mc, int ml, int lastc, int width, mtab[mm] = mp; mgtab[mm] = g; - mmtabp = mtab + mm; - mgtabp = mgtab + mm; } if (m->gnum == mselect) { + int mm = (mcols * ml) + (mcols >> 1); mline = ml; + mmtabp = mtab + mm; + mgtabp = mgtab + mm; cc = COL_MA; } else cc = COL_NO; @@ -377,12 +378,14 @@ clprintm(Cmgroup g, Cmatch *mp, int mc, int ml, int lastc, int width, mtab[mx + mm] = mp; mgtab[mx + mm] = g; - mmtabp = mtab + mx + mm; - mgtabp = mgtab + mx + mm; } if (m->gnum == mselect) { + int mm = mcols * ml; + mcol = mx; mline = ml; + mmtabp = mtab + mx + mm; + mgtabp = mgtab + mx + mm; zcputs(&mcolors, COL_MA); } else if (buf) putcolstr(&mcolors, path, buf->st_mode); @@ -514,6 +517,8 @@ typedef struct menustack *Menustack; struct menustack { Menustack prev; char *line; + char *brbeg; + char *brend; int cs, acc; struct menuinfo info; Cmgroup amatches, pmatches, lmatches; @@ -559,6 +564,7 @@ domenuselect(Hookdef dummy, Chdata dat) } p = mmtabp; pg = mgtabp; + minfo.cur = *p; getk: @@ -579,6 +585,8 @@ domenuselect(Hookdef dummy, Chdata dat) s->pmatches = pmatches; s->lmatches = lmatches; s->acc = menuacc; + s->brbeg = dupstring(brbeg); + s->brend = dupstring(brend); menucmp = menuacc = 0; fixsuffix(); validlist = 0; @@ -604,6 +612,8 @@ domenuselect(Hookdef dummy, Chdata dat) memcpy(&(s->info), &minfo, sizeof(struct menuinfo)); s->amatches = s->pmatches = s->lmatches = NULL; s->acc = menuacc; + s->brbeg = dupstring(brbeg); + s->brend = dupstring(brend); acceptlast(); do_menucmp(0); mselect = (*(minfo.cur))->gnum; @@ -629,6 +639,10 @@ domenuselect(Hookdef dummy, Chdata dat) lmatches = u->lmatches; hasperm = 1; } + zsfree(brbeg); + zsfree(brend); + brbeg = ztrdup(u->brbeg); + brend = ztrdup(u->brend); u = u->prev; clearlist = 1; } else if (cmd == Th(z_redisplay)) { diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 43cb2fe9f..e3b503265 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -112,6 +112,9 @@ static int movetoend; /**/ int menucmp, menuacc; +/**/ +static char *lastprebr, *lastpostbr; + /* Information about menucompletion. */ /**/ @@ -123,7 +126,9 @@ struct menuinfo minfo; * brpcs and brscs hold the positions of the re-inserted string in the * * line. */ -static char *brbeg = NULL, *brend = NULL; +/**/ +char *brbeg = NULL, *brend = NULL; + static int brpl, brsl, brpcs, brscs, qbrpl, qbrsl, hasunqu; /* The list of matches. fmatches contains the matches we first ignore * @@ -540,14 +545,17 @@ reversemenucomplete(char **args) return menucomplete(args); HEAPALLOC { - if (minfo.cur == (minfo.group)->matches) { - do { - if (!(minfo.group = (minfo.group)->prev)) - minfo.group = lmatches; - } while (!(minfo.group)->mcount); - minfo.cur = (minfo.group)->matches + (minfo.group)->mcount - 1; - } else - minfo.cur--; + do { + if (minfo.cur == (minfo.group)->matches) { + do { + if (!(minfo.group = (minfo.group)->prev)) + minfo.group = lmatches; + } while (!(minfo.group)->mcount); + minfo.cur = (minfo.group)->matches + (minfo.group)->mcount - 1; + } else + minfo.cur--; + } while (menuacc && + !hasbrpsfx(*(minfo.cur), minfo.prebr, minfo.postbr)); metafy_line(); do_single(*(minfo.cur)); unmetafy_line(); @@ -563,6 +571,15 @@ reversemenucomplete(char **args) void acceptlast(void) { + if (!menuacc) { + zsfree(minfo.prebr); + minfo.prebr = ztrdup(lastprebr); + zsfree(minfo.postbr); + minfo.postbr = ztrdup(lastpostbr); + + if (listshown) + showinglist = -2; + } menuacc++; if (brbeg && *brbeg) { @@ -1140,13 +1157,16 @@ do_menucmp(int lst) } /* Otherwise go to the next match in the array... */ HEAPALLOC { - if (!*++(minfo.cur)) { - do { - if (!(minfo.group = (minfo.group)->next)) - minfo.group = amatches; - } while (!(minfo.group)->mcount); - minfo.cur = minfo.group->matches; - } + do { + if (!*++(minfo.cur)) { + do { + if (!(minfo.group = (minfo.group)->next)) + minfo.group = amatches; + } while (!(minfo.group)->mcount); + minfo.cur = minfo.group->matches; + } + } while (menuacc && + !hasbrpsfx(*(minfo.cur), minfo.prebr, minfo.postbr)); /* ... and insert it into the command line. */ metafy_line(); do_single(*(minfo.cur)); @@ -7097,6 +7117,9 @@ invalidatelist(void) listshown = 0; minfo.cur = NULL; minfo.asked = 0; + zsfree(minfo.prebr); + zsfree(minfo.postbr); + minfo.postbr = minfo.prebr = NULL; compwidget = NULL; } @@ -7954,7 +7977,11 @@ unambig_data(int *cp) static int instmatch(Cmatch m, int *scs) { - int l, r = 0, ocs, a = cs; + int l, r = 0, ocs, a = cs, brb = 0; + + zsfree(lastprebr); + zsfree(lastpostbr); + lastprebr = lastpostbr = NULL; /* Ignored prefix. */ if (m->ipre) { @@ -7980,6 +8007,9 @@ instmatch(Cmatch m, int *scs) /* Re-insert the brace beginning, if any. */ if (brbeg && *brbeg) { cs = a + m->brpl + (m->pre ? strlen(m->pre) : 0); + lastprebr = (char *) zalloc(cs - a + 1); + memcpy(lastprebr, (char *) line + a, cs - a); + lastprebr[cs - a] = '\0'; l = strlen(brbeg); brpcs = cs; inststrlen(brbeg, 1, l); @@ -7999,12 +8029,14 @@ instmatch(Cmatch m, int *scs) ocs = brscs = cs; l = strlen(brend); inststrlen(brend, 1, l); + brb = cs; r += l; cs = a + l; } else brscs = -1; /* -S suffix */ - *scs = cs; + if (scs) + *scs = cs; if (m->suf) { inststrlen(m->suf, 1, (l = strlen(m->suf))); r += l; @@ -8014,12 +8046,56 @@ instmatch(Cmatch m, int *scs) inststrlen(m->isuf, 1, (l = strlen(m->isuf))); r += l; } + if (brend && *brend) { + lastpostbr = (char *) zalloc(cs - brb + 1); + memcpy(lastpostbr, (char *) line + brb, cs - brb); + lastpostbr[cs - brb] = '\0'; + } lastend = cs; cs = ocs; return r; } +/* Check if the match has the given prefix/suffix before/after the + * braces. */ + +/**/ +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; + + memcpy(oline, line, ll); + + lastprebr = lastpostbr = NULL; + + instmatch(m, NULL); + + cs = 0; + foredel(ll); + spaceinline(oll); + memcpy(line, oline, oll); + cs = ocs; + lastend = ole; + brpcs = opcs; + brscs = oscs; + + ret = (((!op && !lastprebr) || + (op && lastprebr && !strcmp(op, lastprebr))) && + ((!os && !lastpostbr) || + (os && lastpostbr && !strcmp(os, lastpostbr)))); + + zsfree(lastprebr); + zsfree(lastpostbr); + lastprebr = op; + lastpostbr = os; + + return ret; +} + /* Handle the case were we found more than one match. */ /**/ @@ -8539,8 +8615,8 @@ printfmt(char *fmt, int n, int dopr, int doesc) Cmatch * skipnolist(Cmatch *p) { - while (*p && (((*p)->flags & CMF_NOLIST) || - ((*p)->disp && ((*p)->flags & CMF_DISPLINE)))) + while (*p && (((*p)->flags & (CMF_NOLIST | CMF_HIDE)) || + ((*p)->disp && ((*p)->flags & (CMF_DISPLINE | CMF_HIDE))))) p++; return p; @@ -8579,7 +8655,8 @@ calclist(void) int max = 0, i; VARARR(int, mlens, nmatches + 1); - if (listdat.valid && lines == listdat.lines && columns == listdat.columns) + if (listdat.valid && menuacc == listdat.menuacc && + lines == listdat.lines && columns == listdat.columns) return; for (g = amatches; g; g = g->next) { @@ -8625,6 +8702,12 @@ calclist(void) } } else { for (p = g->matches; (m = *p); p++) { + if (menuacc && !hasbrpsfx(m, minfo.prebr, minfo.postbr)) { + m->flags |= CMF_HIDE; + continue; + } + m->flags &= ~CMF_HIDE; + if (m->disp) { if (m->flags & CMF_DISPLINE) { nlines += 1 + printfmt(m->disp, 0, 0, 0); @@ -8704,11 +8787,12 @@ calclist(void) g->width = 0; for (p = g->matches; (m = *p); p++) - if (m->disp) { - if (!(m->flags & CMF_DISPLINE)) - glines += 1 + (mlens[m->gnum] / columns); - } else if (!(m->flags & CMF_NOLIST)) - glines += 1 + ((1 + mlens[m->gnum]) / columns); + if (!(m->flags & CMF_HIDE)) + if (m->disp) { + if (!(m->flags & CMF_DISPLINE)) + glines += 1 + (mlens[m->gnum] / columns); + } else if (!(m->flags & CMF_NOLIST)) + glines += 1 + ((1 + mlens[m->gnum]) / columns); } } g->lins = glines; @@ -8737,7 +8821,8 @@ calclist(void) int x, l = 0, v; for (mm = columns / g->shortest; mm > g->cols; mm--) { - for (j = i = ml = cl = l = v = x = 0, k = g->dcount; + for (j = i = ml = cl = l = v = x = 0, + k = g->dcount; k > 0; k--) { if (ylens[j] > ml) ml = ylens[j]; @@ -8754,7 +8839,7 @@ calclist(void) v = 0; } } - if (j < g->dcount) { + if (j < yl) { ws[x++] = ml; cl += ml; } @@ -8789,31 +8874,34 @@ calclist(void) } else if (g->width) { if (isset(LISTROWSFIRST)) { int x, l = 0, v, al; + Cmatch *q; for (mm = columns / g->shortest; mm > g->cols; mm--) { - for (j = i = ml = cl = l = v = x = 0, k = g->dcount; + p = q = skipnolist(g->matches); + for (i = ml = cl = l = v = x = 0, k = g->dcount; k > 0; k--) { - m = g->matches[j]; - if (!(m->flags & (m->disp ? CMF_DISPLINE : - CMF_NOLIST))) { - al = mlens[m->gnum] + add; - if (al > ml) - ml = al; - j += mm; - v++; - if (j >= g->dcount) { - if ((cl += ml) >= columns) - break; - ws[x++] = ml; - ml = 0; - j = ++i; - if (v > l) - l = v; - v = 0; - } + m = *p; + al = mlens[m->gnum] + add; + if (al > ml) + ml = al; + for (j = mm; j && *p; j--) + p = skipnolist(p + 1); + + v++; + if (!*p) { + if (v > l) + l = v; + v = 0; + + if ((cl += ml) >= columns) + break; + ws[x++] = ml; + ml = 0; + + p = q = skipnolist(q + 1); } } - if (j < g->dcount) { + if (v) { ws[x++] = ml; cl += ml; } @@ -8829,8 +8917,9 @@ calclist(void) i < g->lins; i++) { for (p = g->matches, j = k = cl = ml = mm = 0; (m = *p); p++, j++) { - if (!(m->flags & (m->disp ? CMF_DISPLINE : - CMF_NOLIST))) { + if (!(m->flags & + (m->disp ? (CMF_DISPLINE | CMF_HIDE) : + (CMF_NOLIST | CMF_HIDE)))) { al = mlens[m->gnum] + add; if (al > ml) ml = al; @@ -8858,11 +8947,11 @@ calclist(void) nlines += i - g->lins; g->lins = i; g->cols = mm; + g->totl = cl; + cl -= add; + if (cl > max) + max = cl; } - g->totl = cl; - cl -= add; - if (cl > max) - max = cl; } for (g = amatches; g; g = g->next) { if (g->widths) { @@ -8878,6 +8967,7 @@ calclist(void) listdat.hidden = hidden; listdat.nlist = nlist; listdat.nlines = nlines; + listdat.menuacc = menuacc; } /**/ |