From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20776 invoked from network); 20 Jun 2002 10:22:19 -0000 Received: from sunsite.dk (130.225.247.90) by ns1.primenet.com.au with SMTP; 20 Jun 2002 10:22:19 -0000 Received: (qmail 20505 invoked by alias); 20 Jun 2002 10:21:47 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 17335 Received: (qmail 17258 invoked from network); 20 Jun 2002 10:18:16 -0000 From: Sven Wischnowsky MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <15632.14247.959681.905916@wischnow.berkom.de> Date: Wed, 19 Jun 2002 09:49:59 +0200 To: zsh-workers@sunsite.dk Subject: Re: Menu selection In-Reply-To: References: <15630.59397.643329.80093@wischnow.berkom.de> X-Mailer: VM 7.03 under 21.5 (patch 5) "beets" XEmacs Lucid Oliver Kiddle wrote: > On 18 Jun, you wrote: > > > > Here is the next version, now including real incremental search > > (started by history-incremental-search-{for,back}ward). And patches > > for the docs. > > Looks good. I get a seg fault though when I try a failing search when > there are descriptions for the completion matches. Not always though. > I can reproduce it with ls -xy That was a rather stupid bug, ahem. It happened only when the prefix string was found in a description. The code made that description be selected, which wasn't possible. > It would also be nice if this could be invoked when scrolling a > completion list, i.e. from the listscroll keymap. Nothing for this yet, it's a whole lot more complicated, because listscroll is done while the completion list is being printed (and while the internal variables which are needed by searching are being set). Below is an improved patch, still not committed. Bye Sven diff -ur -r ../oz/Completion/Base/Core/_main_complete ./Completion/Base/Core/_main_complete --- ../oz/Completion/Base/Core/_main_complete Sun Jun 9 16:03:38 2002 +++ ./Completion/Base/Core/_main_complete Mon Jun 17 23:37:03 2002 @@ -267,6 +267,19 @@ 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]='' diff -ur -r ../oz/Doc/Zsh/compsys.yo ./Doc/Zsh/compsys.yo --- ../oz/Doc/Zsh/compsys.yo Sun Jun 9 16:03:36 2002 +++ ./Doc/Zsh/compsys.yo Mon Jun 17 23:54:42 2002 @@ -1824,6 +1824,13 @@ 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))( diff -ur -r ../oz/Doc/Zsh/mod_complist.yo ./Doc/Zsh/mod_complist.yo --- ../oz/Doc/Zsh/mod_complist.yo Sun Jun 9 16:03:36 2002 +++ ./Doc/Zsh/mod_complist.yo Mon Jun 17 23:52:21 2002 @@ -332,6 +332,22 @@ 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 in +the same way as normally but without leaving menu selection; instead, +the set of matches will be reduced to contain only those matches the +changed command line by calling completion again; the completion +widgets make the longest unabiguous 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 diff -ur -r ../oz/Src/Zle/compcore.c ./Src/Zle/compcore.c --- ../oz/Src/Zle/compcore.c Sun Jun 9 16:03:37 2002 +++ ./Src/Zle/compcore.c Sun Jun 9 16:03:48 2002 @@ -360,7 +360,7 @@ haspattern = 1; if (iforcemenu) { if (nmatches) - do_ambig_menu(); + do_ambig_menu(); ret = !nmatches; } else if (useline < 0) ret = selfinsert(zlenoargs); diff -ur -r ../oz/Src/Zle/complist.c ./Src/Zle/complist.c --- ../oz/Src/Zle/complist.c Sun Jun 9 16:03:37 2002 +++ ./Src/Zle/complist.c Tue Jun 18 19:14:01 2002 @@ -400,8 +400,12 @@ /* 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 @@ 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 @@ 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 @@ } 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 @@ 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,221 @@ 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) +{ + 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; + } + } + 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 +1962,21 @@ 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 +2003,7 @@ 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 +2023,7 @@ while (mlbeg) { for (q = p, c = columns; c; q++, c--) - if (*q && *q != mtexpl) + if (*q && !mmarked(*q)) break; if (c) break; @@ -1821,8 +2054,33 @@ 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 +2117,36 @@ 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 +2169,8 @@ 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 +2180,23 @@ 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 +2220,9 @@ } 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 +2234,7 @@ Menustack s = (Menustack) zhalloc(sizeof(*s)); int ol; + mode = 0; s->prev = u; u = s; s->line = dupstring((char *) line); @@ -1949,6 +2253,8 @@ s->origline = origline; s->origcs = origcs; s->origll = origll; + s->status = dupstring(status); + s->mode = mode; accept_last(); handleundo(); comprecursive = 1; @@ -1977,7 +2283,8 @@ } 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 +2320,17 @@ 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 +2346,7 @@ int omline; Cmatch **op; + mode = 0; wrap = 0; down: @@ -2057,7 +2370,7 @@ } if (adjust_mcol(wishcol, &p, NULL)) continue; - } while (!*p || *p == mtexpl); + } while (!*p || mmarked(*p)); if (wrap == 1) goto right; @@ -2068,6 +2381,7 @@ int omline; Cmatch **op; + mode = 0; wrap = 0; up: @@ -2091,7 +2405,7 @@ } if (adjust_mcol(wishcol, &p, NULL)) continue; - } while (!*p || *p == mtexpl); + } while (!*p || mmarked(*p)); if (wrap == 1) { if (mcol == wishcol) @@ -2106,6 +2420,7 @@ 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 +2434,7 @@ } if (adjust_mcol(wishcol, &p, NULL)) continue; - if (*p && *p != mtexpl) { + if (*p && !mmarked(*p)) { i--; lp = p; ll = mline; @@ -2133,6 +2448,7 @@ int i = lines - pl - 1, oi = i, ll = 0; Cmatch **lp = NULL; + mode = 0; if (!mline) goto bottom; while (i > 0) { @@ -2146,7 +2462,7 @@ } if (adjust_mcol(wishcol, &p, NULL)) continue; - if (*p || *p != mtexpl) { + if (*p || !mmarked(*p)) { i--; lp = p; ll = mline; @@ -2158,6 +2474,8 @@ int ll; Cmatch **lp; + mode = 0; + top: ll = mline; @@ -2167,7 +2485,7 @@ p -= mcols; if (adjust_mcol(wishcol, &p, NULL)) continue; - if (*p && *p != mtexpl) { + if (*p && !mmarked(*p)) { lp = p; ll = mline; } @@ -2178,6 +2496,8 @@ int ll; Cmatch **lp; + mode = 0; + bottom: ll = mline; @@ -2187,7 +2507,7 @@ p += mcols; if (adjust_mcol(wishcol, &p, NULL)) continue; - if (*p && *p != mtexpl) { + if (*p && !mmarked(*p)) { lp = p; ll = mline; } @@ -2198,6 +2518,7 @@ int omcol; Cmatch **op; + mode = 0; wrap = 0; right: @@ -2219,7 +2540,7 @@ 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 +2549,7 @@ int omcol; Cmatch **op; + mode = 0; wrap = 0; left: @@ -2249,7 +2571,7 @@ 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 +2584,10 @@ 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 +2596,10 @@ 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 +2609,7 @@ Cmgroup g = *pg; int ol = mline; + mode = 0; do { if (mline == mlines - 1) { p -= mline * mcols; @@ -2297,11 +2622,12 @@ } 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 +2640,7 @@ } 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 +2652,91 @@ !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; + int was = (mode == MM_FSEARCH || mode == MM_BSEARCH); + int ins = (cmd == Th(z_selfinsert) || cmd == Th(z_selfinsertunmeta)); + int back = (cmd == Th(z_historyincrementalsearchbackward)); + + 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'; + } + np = msearch(p, ins, (ins ? (mode == MM_BSEARCH) : back), was); + + 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); + } 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(); diff -ur -r ../oz/Src/Zle/compresult.c ./Src/Zle/compresult.c --- ../oz/Src/Zle/compresult.c Sun Jun 9 16:03:37 2002 +++ ./Src/Zle/compresult.c Sun Jun 9 16:03:49 2002 @@ -744,8 +744,9 @@ * 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 @@ 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 @@ 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 @@ { Cmatch *mc; + if (iforcemenu == -1) + do_ambiguous(); + if (usemenu != 3) { menucmp = 1; menuacc = 0; @@ -1324,7 +1328,8 @@ } #endif mc = (minfo.group)->matches + insmnum; - do_single(*mc); + if (iforcemenu != -1) + do_single(*mc); minfo.cur = mc; } -- Sven Wischnowsky wischnow@berkom.de