mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-02 22:11:54 +02:00
two new modes for menu selection: incremental search and interactive (17366)
This commit is contained in:
parent
03105a5d6e
commit
d28f67623f
8 changed files with 502 additions and 47 deletions
|
@ -1,3 +1,11 @@
|
|||
2002-06-26 Sven Wischnowsky <wischnow@zsh.org>
|
||||
|
||||
* 17366: Completion/Base/Core/_main_complete,
|
||||
Completion/Zsh/Command/_zstyle, Doc/Zsh/compsys.yo,
|
||||
Doc/Zsh/mod_complist.yo, Src/Zle/compcore.c, Src/Zle/complist.c,
|
||||
Src/Zle/compresult.c: two new modes for menu selection:
|
||||
incremental search and interactive
|
||||
|
||||
2002-06-24 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* 17361: Src/zle_hist.c: Be safer about NULL returns from
|
||||
|
|
|
@ -267,6 +267,19 @@ if [[ $compstate[old_list] = keep || nm -gt 1 ]]; then
|
|||
unset MENUSELECT
|
||||
fi
|
||||
fi
|
||||
if [[ -n "$MENUSELECT" ]]; then
|
||||
if [[ -n "$_menu_style[(r)interactive*]" ]]; then
|
||||
MENUMODE=interactive
|
||||
elif [[ -n "$_menu_style[(r)search*]" ]]; then
|
||||
if [[ -n "$_menu_style[(r)*backward*]" ]]; then
|
||||
MENUMODE=search-backward
|
||||
else
|
||||
MENUMODE=search-forward
|
||||
fi
|
||||
else
|
||||
unset MENUMODE
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
elif [[ nm -lt 1 && -n "$_comp_mesg" ]]; then
|
||||
compstate[insert]=''
|
||||
|
|
|
@ -206,7 +206,8 @@ while (( $#state )); do
|
|||
;;
|
||||
|
||||
boolauto)
|
||||
_wanted values expl boolean compadd true false auto select
|
||||
_wanted values expl boolean \
|
||||
compadd true false auto select search search-backward interactive
|
||||
;;
|
||||
|
||||
cmdorcont)
|
||||
|
|
|
@ -1824,6 +1824,13 @@ To turn on menu completion or menu selection when a certain number of
|
|||
matches is generated em(or) the list of matches does not fit onto the
|
||||
screen, both of `tt(yes=)' and `tt(select=)' can be given twice, once
|
||||
with a number and once with `tt(long)' or `tt(long-list)'.
|
||||
|
||||
Finally, the two special modes of menu selection, namely interactive
|
||||
mode and incremental search can be pre-selected with this style. By
|
||||
including the word `tt(interactive)' in the value, interactive mode
|
||||
will be entered immediately when menu selection is started and the
|
||||
string `tt(search)' does the same for incremental search. To select
|
||||
backward incremental search, include the string `tt(search-backward)'.
|
||||
)
|
||||
kindex(muttrc, completion style)
|
||||
item(tt(muttrc))(
|
||||
|
|
|
@ -332,6 +332,22 @@ moves the mark to the next match
|
|||
item(tt(reverse-menu-complete))(
|
||||
moves the mark to the previous match
|
||||
)
|
||||
item(tt(viinsert))(
|
||||
this toggles between normal and interactive mode; in interactive mode
|
||||
the keys bound to tt(self-insert) and tt(self-insert-unmeta) insert
|
||||
into the command line as in normal editing mode but without leaving
|
||||
menu selection; after each character completion is tried again and the
|
||||
list changes to contain only the new matches; the completion widgets
|
||||
make the longest unambiguous string be inserted in the command line
|
||||
and tt(undo) and tt(backward-delete-char) go back to the previous set
|
||||
of matches
|
||||
)
|
||||
item(tt(history-incremental-search-forward),
|
||||
tt(history-incremental-search-backward))(
|
||||
this starts incremental searches in the list of completions displayed;
|
||||
in this mode, tt(accept-line) only leaves incremental search, going
|
||||
back to the normal menu selection mode
|
||||
)
|
||||
enditem()
|
||||
|
||||
All movement functions wrap around at the edges; any other zle function not
|
||||
|
|
|
@ -360,7 +360,7 @@ do_completion(Hookdef dummy, Compldat dat)
|
|||
haspattern = 1;
|
||||
if (iforcemenu) {
|
||||
if (nmatches)
|
||||
do_ambig_menu();
|
||||
do_ambig_menu();
|
||||
ret = !nmatches;
|
||||
} else if (useline < 0)
|
||||
ret = selfinsert(zlenoargs);
|
||||
|
|
|
@ -400,8 +400,12 @@ static struct listcols mcolors;
|
|||
|
||||
/* Used in mtab/mgtab, for explanations. */
|
||||
|
||||
#define mtexpl ((Cmatch *) 1)
|
||||
#define mgexpl ((Cmgroup) 1)
|
||||
#define MMARK ((unsigned long) 1)
|
||||
#define mmarked(v) (((unsigned long) (v)) & MMARK)
|
||||
#define mtmark(v) ((Cmatch *) (((unsigned long) (v)) | MMARK))
|
||||
#define mtunmark(v) ((Cmatch *) (((unsigned long) (v)) & ~MMARK))
|
||||
#define mgmark(v) ((Cmgroup) (((unsigned long) (v)) | MMARK))
|
||||
#define mgunmark(v) ((Cmgroup) (((unsigned long) (v)) & ~MMARK))
|
||||
|
||||
/* Information for in-string colours. */
|
||||
|
||||
|
@ -1065,8 +1069,8 @@ compprintlist(int showall)
|
|||
int mm = (mcols * ml), i;
|
||||
|
||||
for (i = mcols; i--; ) {
|
||||
mtab[mm + i] = mtexpl;
|
||||
mgtab[mm + i] = mgexpl;
|
||||
mtab[mm + i] = mtmark(NULL);
|
||||
mgtab[mm + i] = mgmark(NULL);
|
||||
}
|
||||
}
|
||||
if (stop)
|
||||
|
@ -1381,13 +1385,20 @@ clprintm(Cmgroup g, Cmatch *mp, int mc, int ml, int lastc, int width)
|
|||
|
||||
mlastm = m->gnum;
|
||||
if (m->disp && (m->flags & CMF_DISPLINE)) {
|
||||
if (mselect >= 0 && !(m->flags & CMF_DUMMY)) {
|
||||
if (mselect >= 0) {
|
||||
int mm = (mcols * ml), i;
|
||||
|
||||
for (i = mcols; i--; ) {
|
||||
mtab[mm + i] = mp;
|
||||
mgtab[mm + i] = g;
|
||||
}
|
||||
if (m->flags & CMF_DUMMY) {
|
||||
for (i = mcols; i--; ) {
|
||||
mtab[mm + i] = mtmark(mp);
|
||||
mgtab[mm + i] = mgmark(g);
|
||||
}
|
||||
} else {
|
||||
for (i = mcols; i--; ) {
|
||||
mtab[mm + i] = mp;
|
||||
mgtab[mm + i] = g;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!dolist(ml)) {
|
||||
mlprinted = printfmt(m->disp, 0, 0, 0) / columns;
|
||||
|
@ -1428,13 +1439,20 @@ clprintm(Cmgroup g, Cmatch *mp, int mc, int ml, int lastc, int width)
|
|||
} else
|
||||
mx = mc * g->width;
|
||||
|
||||
if (mselect >= 0 && !(m->flags & CMF_DUMMY)) {
|
||||
if (mselect >= 0) {
|
||||
int mm = mcols * ml, i;
|
||||
|
||||
for (i = (width ? width : mcols); i--; ) {
|
||||
mtab[mx + mm + i] = mp;
|
||||
mgtab[mx + mm + i] = g;
|
||||
}
|
||||
if (m->flags & CMF_DUMMY) {
|
||||
for (i = (width ? width : mcols); i--; ) {
|
||||
mtab[mx + mm + i] = mtmark(mp);
|
||||
mgtab[mx + mm + i] = mgmark(g);
|
||||
}
|
||||
} else {
|
||||
for (i = (width ? width : mcols); i--; ) {
|
||||
mtab[mx + mm + i] = mp;
|
||||
mgtab[mx + mm + i] = g;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!dolist(ml)) {
|
||||
mlprinted = niceztrlen(m->disp ? m->disp : m->str) / columns;
|
||||
|
@ -1675,8 +1693,8 @@ adjust_mcol(int wish, Cmatch ***tabp, Cmgroup **grp)
|
|||
|
||||
tab -= mcol;
|
||||
|
||||
for (p = wish; p >= 0 && (!tab[p] || tab[p] == mtexpl); p--);
|
||||
for (n = wish; n < mcols && (!tab[n] || tab[n] == mtexpl); n++);
|
||||
for (p = wish; p >= 0 && (!tab[p] || mmarked(tab[p])); p--);
|
||||
for (n = wish; n < mcols && (!tab[n] || mmarked(tab[n])); n++);
|
||||
if (n == mcols)
|
||||
n = -1;
|
||||
|
||||
|
@ -1711,21 +1729,222 @@ struct menustack {
|
|||
Cmgroup amatches, pmatches, lastmatches, lastlmatches;
|
||||
char *origline;
|
||||
int origcs, origll;
|
||||
char *status;
|
||||
int mode;
|
||||
};
|
||||
|
||||
typedef struct menusearch *Menusearch;
|
||||
|
||||
struct menusearch {
|
||||
Menusearch prev;
|
||||
char *str;
|
||||
int line;
|
||||
int col;
|
||||
int back;
|
||||
int state;
|
||||
Cmatch **ptr;
|
||||
};
|
||||
|
||||
#define MS_OK 0
|
||||
#define MS_FAILED 1
|
||||
#define MS_WRAPPED 2
|
||||
|
||||
#define MAX_STATUS 128
|
||||
|
||||
static char *
|
||||
setmstatus(char *status, int *csp, int *llp, int *lenp)
|
||||
{
|
||||
char *p, *s, *ret = NULL;
|
||||
int pl, sl, max;
|
||||
|
||||
if (csp) {
|
||||
*csp = cs;
|
||||
*llp = ll;
|
||||
*lenp = lastend - wb;
|
||||
|
||||
ret = dupstring((char *) line);
|
||||
|
||||
p = (char *) zhalloc(cs - wb + 1);
|
||||
strncpy(p, (char *) line + wb, cs - wb);
|
||||
p[cs - wb] = '\0';
|
||||
s = (char *) zhalloc(lastend - cs + 1);
|
||||
strncpy(s, (char *) line + cs, lastend - cs);
|
||||
s[lastend - cs] = '\0';
|
||||
|
||||
cs = wb;
|
||||
foredel(lastend - wb);
|
||||
pl = strlen(compprefix);
|
||||
sl = strlen(compsuffix);
|
||||
spaceinline(pl + sl);
|
||||
strncpy(line + wb, compprefix, pl);
|
||||
strncpy(line + wb + pl, compsuffix, sl);
|
||||
cs = wb + pl;
|
||||
} else {
|
||||
p = compprefix;
|
||||
s = compsuffix;
|
||||
}
|
||||
pl = strlen(p);
|
||||
sl = strlen(s);
|
||||
max = (columns < MAX_STATUS ? columns : MAX_STATUS) - 14;
|
||||
|
||||
if (max > 12) {
|
||||
int h = (max - 2) >> 1;
|
||||
|
||||
strcpy(status, "interactive: ");
|
||||
if (pl > h - 3) {
|
||||
strcat(status, "...");
|
||||
strcat(status, p + pl - h - 3);
|
||||
} else
|
||||
strcat(status, p);
|
||||
|
||||
strcat(status, "[]");
|
||||
if (sl > h - 3) {
|
||||
strncat(status, s, h - 3);
|
||||
strcat(status, "...");
|
||||
} else
|
||||
strcat(status, s);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Menusearch msearchstack;
|
||||
static char *msearchstr = NULL;
|
||||
static int msearchstate;
|
||||
|
||||
static void
|
||||
msearchpush(Cmatch **p, int back)
|
||||
{
|
||||
Menusearch s = (Menusearch) zhalloc(sizeof(struct menusearch));
|
||||
|
||||
s->prev = msearchstack;
|
||||
msearchstack = s;
|
||||
s->str = dupstring(msearchstr);
|
||||
s->line = mline;
|
||||
s->col = mcol;
|
||||
s->back = back;
|
||||
s->state = msearchstate;
|
||||
s->ptr = p;
|
||||
}
|
||||
|
||||
static Cmatch **
|
||||
msearchpop(int *backp)
|
||||
{
|
||||
Menusearch s = msearchstack;
|
||||
|
||||
if (s->prev)
|
||||
msearchstack = s->prev;
|
||||
|
||||
msearchstr = s->str;
|
||||
mline = s->line;
|
||||
mcol = s->col;
|
||||
msearchstate = s->state;
|
||||
|
||||
*backp = s->back;
|
||||
|
||||
return s->ptr;
|
||||
}
|
||||
|
||||
static Cmatch **
|
||||
msearch(Cmatch **ptr, int ins, int back, int rep, int *wrapp)
|
||||
{
|
||||
char s[2];
|
||||
Cmatch **p, *l = NULL, m;
|
||||
int x = mcol, y = mline;
|
||||
int ex, ey, wrap = 0, owrap = (msearchstate & MS_WRAPPED);
|
||||
|
||||
msearchpush(ptr, back);
|
||||
|
||||
if (ins) {
|
||||
s[0] = c;
|
||||
s[1] = '\0';
|
||||
|
||||
msearchstr = dyncat(msearchstr, s);
|
||||
}
|
||||
if (back) {
|
||||
ex = mcols - 1;
|
||||
ey = -1;
|
||||
} else {
|
||||
ex = 0;
|
||||
ey = listdat.nlines;
|
||||
}
|
||||
p = mtab + (mline * mcols) + mcol;
|
||||
if (rep)
|
||||
l = *p;
|
||||
while (1) {
|
||||
if (!rep && mtunmark(*p) && *p != l) {
|
||||
l = *p;
|
||||
m = *mtunmark(*p);
|
||||
|
||||
if (strstr((m->disp ? m->disp : m->str), msearchstr)) {
|
||||
mcol = x;
|
||||
mline = y;
|
||||
|
||||
return p;
|
||||
}
|
||||
}
|
||||
rep = 0;
|
||||
|
||||
if (back) {
|
||||
p--;
|
||||
if (--x < 0) {
|
||||
x = mcols - 1;
|
||||
y--;
|
||||
}
|
||||
} else {
|
||||
p++;
|
||||
if (++x == mcols) {
|
||||
x = 0;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
if (x == ex && y == ey) {
|
||||
if (wrap) {
|
||||
msearchstate = MS_FAILED | owrap;
|
||||
break;
|
||||
}
|
||||
msearchstate |= MS_WRAPPED;
|
||||
|
||||
if (back) {
|
||||
x = mcols - 1;
|
||||
y = listdat.nlines - 1;
|
||||
p = mtab + (y * mcols) + x;
|
||||
} else {
|
||||
x = y = 0;
|
||||
p = mtab;
|
||||
}
|
||||
ex = mcol;
|
||||
ey = mline;
|
||||
wrap = 1;
|
||||
*wrapp = 1;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define MM_INTER 1
|
||||
#define MM_FSEARCH 2
|
||||
#define MM_BSEARCH 3
|
||||
|
||||
static int
|
||||
domenuselect(Hookdef dummy, Chdata dat)
|
||||
{
|
||||
static Chdata fdat = NULL;
|
||||
static char *lastsearch = NULL;
|
||||
Cmatch **p;
|
||||
Cmgroup *pg;
|
||||
Thingy cmd;
|
||||
Menustack u = NULL;
|
||||
int i = 0, acc = 0, wishcol = 0, setwish = 0, oe = onlyexpl, wasnext = 0;
|
||||
int space, lbeg = 0, step = 1, wrap, pl = nlnct, broken = 0, first = 1;
|
||||
int nolist = 0;
|
||||
int nolist = 0, mode = 0, modecs, modell, modelen;
|
||||
char *s;
|
||||
char status[MAX_STATUS], *modeline;
|
||||
|
||||
msearchstack = NULL;
|
||||
msearchstr = "";
|
||||
msearchstate = MS_OK;
|
||||
|
||||
status[0] = '\0';
|
||||
queue_signals();
|
||||
if (fdat || (dummy && (!(s = getsparam("MENUSELECT")) ||
|
||||
(dat && dat->num < atoi(s))))) {
|
||||
|
@ -1744,6 +1963,21 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
if ((step += lines - nlnct) < 0)
|
||||
step = 1;
|
||||
}
|
||||
if ((s = getsparam("MENUMODE"))) {
|
||||
if (!strcmp(s, "interactive")) {
|
||||
int l = strlen(origline);
|
||||
|
||||
mode = MM_INTER;
|
||||
cs = 0;
|
||||
foredel(ll);
|
||||
spaceinline(l);
|
||||
strncpy((char *) line, origline, l);
|
||||
cs = origcs;
|
||||
setmstatus(status, NULL, NULL, NULL);
|
||||
} else if (strpfx("search", s)) {
|
||||
mode = (strstr(s, "back") ? MM_BSEARCH : MM_FSEARCH);
|
||||
}
|
||||
}
|
||||
if ((mstatus = dupstring(getsparam("MENUPROMPT"))) && !*mstatus)
|
||||
mstatus = "%SScrolling active: current selection at %p%s";
|
||||
unqueue_signals();
|
||||
|
@ -1770,7 +2004,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
|
||||
for (y = 0; y < mlines; y++) {
|
||||
for (x = mcols; x; x--, p++)
|
||||
if (*p && *p != mtexpl && **p && mselect == (**p)->gnum)
|
||||
if (*p && !mmarked(*p) && **p && mselect == (**p)->gnum)
|
||||
break;
|
||||
if (x) {
|
||||
mcol = mcols - x;
|
||||
|
@ -1790,7 +2024,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
|
||||
while (mlbeg) {
|
||||
for (q = p, c = columns; c; q++, c--)
|
||||
if (*q && *q != mtexpl)
|
||||
if (*q && !mmarked(*q))
|
||||
break;
|
||||
if (c)
|
||||
break;
|
||||
|
@ -1821,8 +2055,33 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
showinglist = -2;
|
||||
if (first && !listshown && isset(LISTBEEP))
|
||||
zbeep();
|
||||
if (first) {
|
||||
modeline = dyncat(compprefix, compsuffix);
|
||||
modecs = cs;
|
||||
modell = ll;
|
||||
modelen = minfo.len;
|
||||
}
|
||||
first = 0;
|
||||
if (mode == MM_INTER) {
|
||||
statusline = status;
|
||||
statusll = strlen(status);
|
||||
} else if (mode) {
|
||||
int l = sprintf(status, "%s%sisearch%s: ",
|
||||
((msearchstate & MS_FAILED) ? "failed " : ""),
|
||||
((msearchstate & MS_WRAPPED) ? "wrapped " : ""),
|
||||
(mode == MM_FSEARCH ? "" : " backward"));
|
||||
|
||||
strncat(status, msearchstr, MAX_STATUS - l - 1);
|
||||
|
||||
statusline = status;
|
||||
statusll = strlen(status);
|
||||
} else {
|
||||
statusline = NULL;
|
||||
statusll = 0;
|
||||
}
|
||||
zrefresh();
|
||||
statusline = NULL;
|
||||
statusll = 0;
|
||||
inselect = 1;
|
||||
if (noselect) {
|
||||
broken = 1;
|
||||
|
@ -1859,13 +2118,36 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
zbeep();
|
||||
molbeg = -1;
|
||||
break;
|
||||
} else if (nolist && cmd != Th(z_undo)) {
|
||||
} else if (nolist && cmd != Th(z_undo) &&
|
||||
(!mode || cmd != Th(z_backwarddeletechar))) {
|
||||
ungetkeycmd();
|
||||
break;
|
||||
} else if (cmd == Th(z_acceptline)) {
|
||||
if (mode == MM_FSEARCH || mode == MM_BSEARCH) {
|
||||
mode = 0;
|
||||
continue;
|
||||
}
|
||||
acc = 1;
|
||||
break;
|
||||
} else if (cmd == Th(z_acceptandinfernexthistory)) {
|
||||
} else if (cmd == Th(z_viinsert)) {
|
||||
if (mode == MM_INTER)
|
||||
mode = 0;
|
||||
else {
|
||||
int l = strlen(origline);
|
||||
|
||||
mode = MM_INTER;
|
||||
cs = 0;
|
||||
foredel(ll);
|
||||
spaceinline(l);
|
||||
strncpy((char *) line, origline, l);
|
||||
cs = origcs;
|
||||
setmstatus(status, NULL, NULL, NULL);
|
||||
|
||||
continue;
|
||||
}
|
||||
} else if (cmd == Th(z_acceptandinfernexthistory) ||
|
||||
(mode == MM_INTER && (cmd == Th(z_selfinsert) ||
|
||||
cmd == Th(z_selfinsertunmeta)))) {
|
||||
Menustack s = (Menustack) zhalloc(sizeof(*s));
|
||||
|
||||
s->prev = u;
|
||||
|
@ -1888,6 +2170,8 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
s->origline = origline;
|
||||
s->origcs = origcs;
|
||||
s->origll = origll;
|
||||
s->status = dupstring(status);
|
||||
s->mode = mode;
|
||||
menucmp = menuacc = hasoldlist = 0;
|
||||
minfo.cur = NULL;
|
||||
fixsuffix();
|
||||
|
@ -1897,6 +2181,23 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
invalidate_list();
|
||||
iforcemenu = 1;
|
||||
comprecursive = 1;
|
||||
if (cmd != Th(z_acceptandinfernexthistory)) {
|
||||
int l = strlen(origline);
|
||||
|
||||
cs = 0;
|
||||
foredel(ll);
|
||||
spaceinline(l);
|
||||
strncpy((char *) line, origline, l);
|
||||
cs = origcs;
|
||||
|
||||
if (cmd == Th(z_selfinsert))
|
||||
selfinsert(zlenoargs);
|
||||
else
|
||||
selfinsertunmeta(zlenoargs);
|
||||
|
||||
iforcemenu = -1;
|
||||
} else
|
||||
mode = 0;
|
||||
menucomplete(zlenoargs);
|
||||
iforcemenu = 0;
|
||||
|
||||
|
@ -1920,6 +2221,9 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
}
|
||||
goto getk;
|
||||
}
|
||||
if (cmd != Th(z_acceptandinfernexthistory))
|
||||
modeline = setmstatus(status, &modecs, &modell, &modelen);
|
||||
|
||||
clearlist = listshown = 1;
|
||||
mselect = (*(minfo.cur))->gnum;
|
||||
setwish = wasnext = 1;
|
||||
|
@ -1931,6 +2235,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
Menustack s = (Menustack) zhalloc(sizeof(*s));
|
||||
int ol;
|
||||
|
||||
mode = 0;
|
||||
s->prev = u;
|
||||
u = s;
|
||||
s->line = dupstring((char *) line);
|
||||
|
@ -1949,6 +2254,8 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
s->origline = origline;
|
||||
s->origcs = origcs;
|
||||
s->origll = origll;
|
||||
s->status = dupstring(status);
|
||||
s->mode = mode;
|
||||
accept_last();
|
||||
handleundo();
|
||||
comprecursive = 1;
|
||||
|
@ -1977,7 +2284,8 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
}
|
||||
setwish = 1;
|
||||
continue;
|
||||
} else if (cmd == Th(z_undo)) {
|
||||
} else if (cmd == Th(z_undo) ||
|
||||
(mode == MM_INTER && cmd == Th(z_backwarddeletechar))) {
|
||||
int l;
|
||||
|
||||
if (!u)
|
||||
|
@ -2013,12 +2321,17 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
origline = u->origline;
|
||||
origcs = u->origcs;
|
||||
origll = u->origll;
|
||||
strcpy(status, u->status);
|
||||
mode = u->mode;
|
||||
|
||||
u = u->prev;
|
||||
clearlist = 1;
|
||||
setwish = 1;
|
||||
listdat.valid = 0;
|
||||
molbeg = -42;
|
||||
|
||||
if (mode)
|
||||
continue;
|
||||
} else if (cmd == Th(z_redisplay)) {
|
||||
redisplay(zlenoargs);
|
||||
molbeg = -42;
|
||||
|
@ -2034,6 +2347,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
int omline;
|
||||
Cmatch **op;
|
||||
|
||||
mode = 0;
|
||||
wrap = 0;
|
||||
|
||||
down:
|
||||
|
@ -2057,7 +2371,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
}
|
||||
if (adjust_mcol(wishcol, &p, NULL))
|
||||
continue;
|
||||
} while (!*p || *p == mtexpl);
|
||||
} while (!*p || mmarked(*p));
|
||||
|
||||
if (wrap == 1)
|
||||
goto right;
|
||||
|
@ -2068,6 +2382,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
int omline;
|
||||
Cmatch **op;
|
||||
|
||||
mode = 0;
|
||||
wrap = 0;
|
||||
|
||||
up:
|
||||
|
@ -2091,7 +2406,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
}
|
||||
if (adjust_mcol(wishcol, &p, NULL))
|
||||
continue;
|
||||
} while (!*p || *p == mtexpl);
|
||||
} while (!*p || mmarked(*p));
|
||||
|
||||
if (wrap == 1) {
|
||||
if (mcol == wishcol)
|
||||
|
@ -2106,6 +2421,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
int i = lines - pl - 1, oi = i, ll = 0;
|
||||
Cmatch **lp = NULL;
|
||||
|
||||
mode = 0;
|
||||
if (mline == mlines - 1)
|
||||
goto top;
|
||||
while (i > 0) {
|
||||
|
@ -2119,7 +2435,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
}
|
||||
if (adjust_mcol(wishcol, &p, NULL))
|
||||
continue;
|
||||
if (*p && *p != mtexpl) {
|
||||
if (*p && !mmarked(*p)) {
|
||||
i--;
|
||||
lp = p;
|
||||
ll = mline;
|
||||
|
@ -2133,6 +2449,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
int i = lines - pl - 1, oi = i, ll = 0;
|
||||
Cmatch **lp = NULL;
|
||||
|
||||
mode = 0;
|
||||
if (!mline)
|
||||
goto bottom;
|
||||
while (i > 0) {
|
||||
|
@ -2146,7 +2463,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
}
|
||||
if (adjust_mcol(wishcol, &p, NULL))
|
||||
continue;
|
||||
if (*p || *p != mtexpl) {
|
||||
if (*p || !mmarked(*p)) {
|
||||
i--;
|
||||
lp = p;
|
||||
ll = mline;
|
||||
|
@ -2158,6 +2475,8 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
int ll;
|
||||
Cmatch **lp;
|
||||
|
||||
mode = 0;
|
||||
|
||||
top:
|
||||
|
||||
ll = mline;
|
||||
|
@ -2167,7 +2486,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
p -= mcols;
|
||||
if (adjust_mcol(wishcol, &p, NULL))
|
||||
continue;
|
||||
if (*p && *p != mtexpl) {
|
||||
if (*p && !mmarked(*p)) {
|
||||
lp = p;
|
||||
ll = mline;
|
||||
}
|
||||
|
@ -2178,6 +2497,8 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
int ll;
|
||||
Cmatch **lp;
|
||||
|
||||
mode = 0;
|
||||
|
||||
bottom:
|
||||
|
||||
ll = mline;
|
||||
|
@ -2187,7 +2508,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
p += mcols;
|
||||
if (adjust_mcol(wishcol, &p, NULL))
|
||||
continue;
|
||||
if (*p && *p != mtexpl) {
|
||||
if (*p && !mmarked(*p)) {
|
||||
lp = p;
|
||||
ll = mline;
|
||||
}
|
||||
|
@ -2198,6 +2519,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
int omcol;
|
||||
Cmatch **op;
|
||||
|
||||
mode = 0;
|
||||
wrap = 0;
|
||||
|
||||
right:
|
||||
|
@ -2219,7 +2541,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
mcol++;
|
||||
p++;
|
||||
}
|
||||
} while (!*p || *p == mtexpl || (mcol != omcol && *p == *op));
|
||||
} while (!*p || mmarked(*p) || (mcol != omcol && *p == *op));
|
||||
wishcol = mcol;
|
||||
|
||||
if (wrap == 2)
|
||||
|
@ -2228,6 +2550,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
int omcol;
|
||||
Cmatch **op;
|
||||
|
||||
mode = 0;
|
||||
wrap = 0;
|
||||
|
||||
left:
|
||||
|
@ -2249,7 +2572,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
mcol--;
|
||||
p--;
|
||||
}
|
||||
} while (!*p || *p == mtexpl || (mcol != omcol && *p == *op));
|
||||
} while (!*p || mmarked(*p) || (mcol != omcol && *p == *op));
|
||||
wishcol = mcol;
|
||||
|
||||
if (wrap == 2) {
|
||||
|
@ -2262,9 +2585,10 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
cmd == Th(z_beginningofline) ||
|
||||
cmd == Th(z_beginningoflinehist) ||
|
||||
cmd == Th(z_vibeginningofline)) {
|
||||
mode = 0;
|
||||
p -= mcol;
|
||||
mcol = 0;
|
||||
while (!*p || *p == mtexpl) {
|
||||
while (!*p || mmarked(*p)) {
|
||||
mcol++;
|
||||
p++;
|
||||
}
|
||||
|
@ -2273,9 +2597,10 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
cmd == Th(z_endofline) ||
|
||||
cmd == Th(z_endoflinehist) ||
|
||||
cmd == Th(z_viendofline)) {
|
||||
mode = 0;
|
||||
p += mcols - mcol - 1;
|
||||
mcol = mcols - 1;
|
||||
while (!*p || *p == mtexpl) {
|
||||
while (!*p || mmarked(*p)) {
|
||||
mcol--;
|
||||
p--;
|
||||
}
|
||||
|
@ -2285,6 +2610,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
Cmgroup g = *pg;
|
||||
int ol = mline;
|
||||
|
||||
mode = 0;
|
||||
do {
|
||||
if (mline == mlines - 1) {
|
||||
p -= mline * mcols;
|
||||
|
@ -2297,11 +2623,12 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
}
|
||||
if (adjust_mcol(wishcol, &p, &pg))
|
||||
continue;
|
||||
} while (ol != mline && (*pg == g || !*pg || *pg == mgexpl));
|
||||
} while (ol != mline && (*pg == g || !*pg || mmarked(*pg)));
|
||||
} else if (cmd == Th(z_vibackwardblankword)) {
|
||||
Cmgroup g = *pg;
|
||||
int ol = mline;
|
||||
|
||||
mode = 0;
|
||||
do {
|
||||
if (!mline) {
|
||||
mline = mlines - 1;
|
||||
|
@ -2314,7 +2641,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
}
|
||||
if (adjust_mcol(wishcol, &p, &pg))
|
||||
continue;
|
||||
} while (ol != mline && (*pg == g || !*pg || *pg == mgexpl));
|
||||
} while (ol != mline && (*pg == g || !*pg || mmarked(*pg)));
|
||||
} else if (cmd == Th(z_completeword) ||
|
||||
cmd == Th(z_expandorcomplete) ||
|
||||
cmd == Th(z_expandorcompleteprefix) ||
|
||||
|
@ -2326,21 +2653,99 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
!strcmp(cmd->nam, "expand-or-complete-prefix") ||
|
||||
!strcmp(cmd->nam, "menu-complete") ||
|
||||
!strcmp(cmd->nam, "menu-expand-or-complete")) {
|
||||
comprecursive = 1;
|
||||
do_menucmp(0);
|
||||
mselect = (*(minfo.cur))->gnum;
|
||||
setwish = 1;
|
||||
mline = -1;
|
||||
if (mode == MM_INTER) {
|
||||
origline = modeline;
|
||||
origcs = modecs;
|
||||
origll = modell;
|
||||
cs = 0;
|
||||
foredel(ll);
|
||||
spaceinline(origll);
|
||||
strncpy((char *) line, origline, origll);
|
||||
cs = origcs;
|
||||
minfo.len = modelen;
|
||||
} else {
|
||||
mode = 0;
|
||||
comprecursive = 1;
|
||||
do_menucmp(0);
|
||||
mselect = (*(minfo.cur))->gnum;
|
||||
setwish = 1;
|
||||
mline = -1;
|
||||
}
|
||||
continue;
|
||||
} else if (cmd == Th(z_reversemenucomplete) ||
|
||||
!strcmp(cmd->nam, "reverse-menu-complete")) {
|
||||
mode = 0;
|
||||
comprecursive = 1;
|
||||
reversemenucomplete(zlenoargs);
|
||||
mselect = (*(minfo.cur))->gnum;
|
||||
setwish = 1;
|
||||
mline = -1;
|
||||
continue;
|
||||
} else if (cmd == Th(z_historyincrementalsearchforward) ||
|
||||
cmd == Th(z_historyincrementalsearchbackward) ||
|
||||
((mode == MM_FSEARCH || mode == MM_BSEARCH) &&
|
||||
(cmd == Th(z_selfinsert) ||
|
||||
cmd == Th(z_selfinsertunmeta)))) {
|
||||
Cmatch **np, **op = p;
|
||||
int was = (mode == MM_FSEARCH || mode == MM_BSEARCH);
|
||||
int ins = (cmd == Th(z_selfinsert) || cmd == Th(z_selfinsertunmeta));
|
||||
int back = (cmd == Th(z_historyincrementalsearchbackward));
|
||||
int wrap;
|
||||
|
||||
do {
|
||||
if (was) {
|
||||
p += wishcol - mcol;
|
||||
mcol = wishcol;
|
||||
}
|
||||
if (!ins) {
|
||||
if (was) {
|
||||
if (!*msearchstr && lastsearch) {
|
||||
msearchstr = dupstring(lastsearch);
|
||||
mode = 0;
|
||||
}
|
||||
} else {
|
||||
msearchstr = "";
|
||||
msearchstack = NULL;
|
||||
}
|
||||
}
|
||||
if (cmd == Th(z_selfinsertunmeta)) {
|
||||
c &= 0x7f;
|
||||
if (c == '\r')
|
||||
c = '\n';
|
||||
}
|
||||
wrap = 0;
|
||||
np = msearch(p, ins, (ins ? (mode == MM_BSEARCH) : back),
|
||||
(was && !ins), &wrap);
|
||||
|
||||
if (!ins)
|
||||
mode = (back ? MM_BSEARCH : MM_FSEARCH);
|
||||
|
||||
if (*msearchstr) {
|
||||
zsfree(lastsearch);
|
||||
lastsearch = ztrdup(msearchstr);
|
||||
}
|
||||
if (np) {
|
||||
wishcol = mcol;
|
||||
p = np;
|
||||
}
|
||||
adjust_mcol(wishcol, &p, NULL);
|
||||
|
||||
} while ((back || cmd == Th(z_historyincrementalsearchforward)) &&
|
||||
np && !wrap && was && **p == **op);
|
||||
|
||||
} else if ((mode == MM_FSEARCH || mode == MM_BSEARCH) &&
|
||||
cmd == Th(z_backwarddeletechar)) {
|
||||
int back;
|
||||
Cmatch **np = msearchpop(&back);
|
||||
|
||||
mode = (back ? MM_BSEARCH : MM_FSEARCH);
|
||||
wishcol = mcol;
|
||||
if (np) {
|
||||
p = np;
|
||||
adjust_mcol(wishcol, &p, NULL);
|
||||
}
|
||||
} else if (cmd == Th(z_undefinedkey)) {
|
||||
mode = 0;
|
||||
continue;
|
||||
} else {
|
||||
ungetkeycmd();
|
||||
|
|
|
@ -744,8 +744,9 @@ do_ambiguous(void)
|
|||
* unambiguous prefix. */
|
||||
lastambig = 1;
|
||||
|
||||
if (usemenu || (haspattern && comppatinsert &&
|
||||
!strcmp(comppatinsert, "menu"))) {
|
||||
if (iforcemenu != -1 &&
|
||||
(usemenu || (haspattern && comppatinsert &&
|
||||
!strcmp(comppatinsert, "menu")))) {
|
||||
/* We are in a position to start using menu completion due to one *
|
||||
* of the menu completion options, or due to the menu-complete- *
|
||||
* word command, or due to using GLOB_COMPLETE which does menu- *
|
||||
|
@ -961,9 +962,10 @@ do_single(Cmatch m)
|
|||
cs = minfo.pos;
|
||||
foredel(l);
|
||||
|
||||
if (m->flags & CMF_ALL)
|
||||
if (m->flags & CMF_ALL) {
|
||||
do_allmatches(0);
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
/* And then we insert the new string. */
|
||||
minfo.len = instmatch(m, &scs);
|
||||
|
@ -1136,7 +1138,6 @@ 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 *
|
||||
|
@ -1283,6 +1284,9 @@ do_ambig_menu(void)
|
|||
{
|
||||
Cmatch *mc;
|
||||
|
||||
if (iforcemenu == -1)
|
||||
do_ambiguous();
|
||||
|
||||
if (usemenu != 3) {
|
||||
menucmp = 1;
|
||||
menuacc = 0;
|
||||
|
@ -1324,7 +1328,8 @@ do_ambig_menu(void)
|
|||
}
|
||||
#endif
|
||||
mc = (minfo.group)->matches + insmnum;
|
||||
do_single(*mc);
|
||||
if (iforcemenu != -1)
|
||||
do_single(*mc);
|
||||
minfo.cur = mc;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue