zsh-workers
 help / color / mirror / code / Atom feed
* Menu selection
@ 2002-06-18  7:57 Sven Wischnowsky
  2002-06-18  9:51 ` Oliver Kiddle
  0 siblings, 1 reply; 21+ messages in thread
From: Sven Wischnowsky @ 2002-06-18  7:57 UTC (permalink / raw)
  To: zsh-workers


Hi

Here is the next version, now including real incremental search
(started by history-incremental-search-{for,back}ward). And patches
for the docs.

Should I commit it?


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	Mon Jun 17 23:44:32 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


^ permalink raw reply	[flat|nested] 21+ messages in thread
[parent not found: <15642.49846.468542.689062@wischnow.berkom.de>]
* Menu selection
@ 2002-05-28  8:31 Sven Wischnowsky
  2002-05-28 10:44 ` Oliver Kiddle
                   ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Sven Wischnowsky @ 2002-05-28  8:31 UTC (permalink / raw)
  To: zsh-workers


Hi

I can't find the message now, but Bart said that searching in menu
selection would be nice to have. This patch doesn't do that, but...

I had been thinking about that, too, and, if it's going to be
incremental searching -- which it should -- it's not entirely trivial
to implement. The patch below (not committed and not to be committed
in its current form) is not intended to be a replacement for a patch
that implements searching in menu selection, but I think it's a nice
little patch (when improved to its final form).

It makes completion be re-tried after every selfinsert-key. This is a
bit like incremental searchin, only that the whole completion list
changes to include only the set of possible matches. As always, undo
can be used to go back to previous lists. For easier testing, the
patch makes every selfinsert-key show this behaviour unconditionally.
In a final patch I think there should be a key to toggle between this
behaviour and the usual one (leaving menu selection, inserting the
character into the line). And probably a way to set the default
behaviour (i.e. when menu selection is first entered).

Also, the behaviour of send-break (^G) after one has inserted some
more characters is arguable. Currently it leaves the additional
characters on the line. Maybe the line should go back to the state
when menu selection was entered. Or maybe a undo should remove all
characters added during menu selection.

And the output in the status line is a bit ugly. I think there should
be some visual feedback, though.

Anyway, what does everybody think? And do you have any suggestions
for the things I mentioned or any other ideas?


Bye
  Sven

diff -ur -r ../oz/Src/Zle/complist.c ./Src/Zle/complist.c
--- ../oz/Src/Zle/complist.c	Sun May 26 19:55:10 2002
+++ ./Src/Zle/complist.c	Mon May 27 22:59:51 2002
@@ -1711,8 +1711,11 @@
     Cmgroup amatches, pmatches, lastmatches, lastlmatches;
     char *origline;
     int origcs, origll;
+    char *status;
 };
 
+#define MAX_STATUS 128
+
 static int
 domenuselect(Hookdef dummy, Chdata dat)
 {
@@ -1725,7 +1728,9 @@
     int space, lbeg = 0, step = 1, wrap, pl = nlnct, broken = 0, first = 1;
     int nolist = 0;
     char *s;
+    char status[MAX_STATUS];
 
+    status[0] = '\0';
     queue_signals();
     if (fdat || (dummy && (!(s = getsparam("MENUSELECT")) ||
 			   (dat && dat->num < atoi(s))))) {
@@ -1822,7 +1827,16 @@
         if (first && !listshown && isset(LISTBEEP))
             zbeep();
         first = 0;
+        if (status[0]) {
+            statusline = status;
+            statusll = strlen(status);
+        } else {
+            statusline = NULL;
+            statusll = 0;
+        }
         zrefresh();
+        statusline = NULL;
+        statusll = 0;
         inselect = 1;
         if (noselect) {
             broken = 1;
@@ -1865,7 +1879,9 @@
 	} else if (cmd == Th(z_acceptline)) {
 	    acc = 1;
 	    break;
-	} else if (cmd == Th(z_acceptandinfernexthistory)) {
+	} else if (cmd == Th(z_acceptandinfernexthistory) ||
+                   cmd == Th(z_selfinsert) ||
+                   cmd == Th(z_selfinsertunmeta)) {
 	    Menustack s = (Menustack) zhalloc(sizeof(*s));
 
 	    s->prev = u;
@@ -1888,6 +1904,7 @@
 	    s->origline = origline;
 	    s->origcs = origcs;
 	    s->origll = origll;
+            s->status = dupstring(status);
 	    menucmp = menuacc = hasoldlist = 0;
 	    minfo.cur = NULL;
 	    fixsuffix();
@@ -1897,9 +1914,45 @@
 	    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);
+            }
 	    menucomplete(zlenoargs);
 	    iforcemenu = 0;
 
+            if (cmd != Th(z_acceptandinfernexthistory)) {
+                int pl = strlen(compprefix), sl = strlen(compsuffix);
+                int 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, compprefix + pl - h - 3);
+                    } else
+                        strcat(status, compprefix);
+
+                    strcat(status, "[]");
+                    if (sl > h - 3) {
+                        strncat(status, compsuffix, h - 3);
+                        strcat(status, "...");
+                    } else
+                        strcat(status, compsuffix);
+                }
+            }
 	    if (dat->num < 1 || !minfo.cur || !*(minfo.cur)) {
 		nolist = 1;
 		if (dat->nmesg || nmessages) {
@@ -1949,6 +2002,7 @@
 	    s->origline = origline;
 	    s->origcs = origcs;
 	    s->origll = origll;
+            s->status = dupstring(status);
 	    accept_last();
 	    handleundo();
 	    comprecursive = 1;
@@ -2013,6 +2067,7 @@
 	    origline = u->origline;
 	    origcs = u->origcs;
 	    origll = u->origll;
+            strcpy(status, u->status);
 
 	    u = u->prev;
 	    clearlist = 1;

-- 
Sven Wischnowsky                          wischnow@berkom.de


^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2002-07-30  7:46 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-06-18  7:57 Menu selection Sven Wischnowsky
2002-06-18  9:51 ` Oliver Kiddle
2002-06-19  7:49   ` Sven Wischnowsky
2002-06-20 15:52     ` Oliver Kiddle
2002-06-20 15:58       ` Bart Schaefer
2002-06-20 16:22         ` Oliver Kiddle
2002-06-21  9:27       ` Sven Wischnowsky
2002-06-26 10:18         ` Sven Wischnowsky
     [not found] <15642.49846.468542.689062@wischnow.berkom.de>
     [not found] ` <20020627182621.70670.qmail@web10405.mail.yahoo.com>
2002-07-03  7:58   ` Sven Wischnowsky
2002-07-04  9:27     ` Sven Wischnowsky
2002-07-04 17:56       ` Felix Rosencrantz
2002-07-05  8:09         ` Sven Wischnowsky
2002-07-24 23:01           ` Felix Rosencrantz
2002-07-30  7:47             ` Sven Wischnowsky
  -- strict thread matches above, loose matches on Subject: below --
2002-05-28  8:31 Sven Wischnowsky
2002-05-28 10:44 ` Oliver Kiddle
2002-05-28 11:24   ` Sven Wischnowsky
2002-05-28 12:08 ` Peter Stephenson
2002-05-29 11:23   ` Sven Wischnowsky
2002-05-29 11:30     ` Peter Stephenson
2002-05-29 16:44 ` Felix Rosencrantz

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).