mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-04 10:41:11 +02:00
zsh-workers/8011
This commit is contained in:
parent
2bdcaa9a55
commit
eaafed24ee
3 changed files with 173 additions and 65 deletions
|
@ -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 */
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
|
Loading…
Reference in a new issue