Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Menu selection, interactive mode



Hi

Here's the newest version. Now one can use `vi-insert' to toggle in
and out of the `interactive' mode (there must be a better name, btw,
right?). And the command and status line display should be better, on
the command line one sees the stuff that was typed, in the status line
one sees the smallest unambiguous string (normal-completion like). The
cursor placement on the command line is not yet optimal, I think,
problem is that this is partially controlled by styles. Hrmpf.

Well, self-inserting characters in `interactive' mode make the listing
shorter again, TAB `accepts' the currently smallest unambiguous
string, backward-delete-char (backspace) does undo (but only while in
interactive mode) and other keys leave interactive mode.

And one can include the word `interactive' in the value of the menu
style to make menu selection start in interactive mode.


Bye
  Sven

diff -ur -r ../oz/Completion/Base/Core/_main_complete ./Completion/Base/Core/_main_complete
--- ../oz/Completion/Base/Core/_main_complete	Tue Jun  4 20:03:16 2002
+++ ./Completion/Base/Core/_main_complete	Tue Jun  4 20:34:53 2002
@@ -267,6 +267,13 @@
         unset MENUSELECT
       fi
     fi
+    if [[ -n "$MENUSELECT" ]]; then
+      if [[ -n "$_menu_style[(r)interactive*]" ]]; then
+        MENUMODE=interactive
+      else
+        unset MENUMODE
+      fi
+    fi
   fi
 elif [[ nm -lt 1 && -n "$_comp_mesg" ]]; then
   compstate[insert]=''
diff -ur -r ../oz/Src/Zle/compcore.c ./Src/Zle/compcore.c
--- ../oz/Src/Zle/compcore.c	Tue Jun  4 20:03:16 2002
+++ ./Src/Zle/compcore.c	Tue Jun  4 20:34:53 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	Tue Jun  4 20:03:16 2002
+++ ./Src/Zle/complist.c	Tue Jun  4 21:46:06 2002
@@ -1711,8 +1711,68 @@
     Cmgroup amatches, pmatches, lastmatches, lastlmatches;
     char *origline;
     int origcs, origll;
+    char *status;
+    int inter;
 };
 
+#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 int
 domenuselect(Hookdef dummy, Chdata dat)
 {
@@ -1723,9 +1783,11 @@
     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, inter = 0, intercs, interll, interlen;
     char *s;
+    char status[MAX_STATUS], *interline;
 
+    status[0] = '\0';
     queue_signals();
     if (fdat || (dummy && (!(s = getsparam("MENUSELECT")) ||
 			   (dat && dat->num < atoi(s))))) {
@@ -1744,6 +1806,19 @@
 	    if ((step += lines - nlnct) < 0)
 		step = 1;
     }
+    if ((s = getsparam("MENUMODE"))) {
+        if (!strcmp(s, "interactive")) {
+            int l = strlen(origline);
+
+            inter = 1;
+            cs = 0;
+            foredel(ll);
+            spaceinline(l);
+            strncpy((char *) line, origline, l);
+            cs = origcs;
+            setmstatus(status, NULL, NULL, NULL);
+        }
+    }
     if ((mstatus = dupstring(getsparam("MENUPROMPT"))) && !*mstatus)
 	mstatus = "%SScrolling active: current selection at %p%s";
     unqueue_signals();
@@ -1821,8 +1896,23 @@
         showinglist = -2;
         if (first && !listshown && isset(LISTBEEP))
             zbeep();
+        if (first) {
+            interline = dyncat(compprefix, compsuffix);
+            intercs = cs;
+            interll = ll;
+            interlen = minfo.len;
+        }
         first = 0;
+        if (inter) {
+            statusline = status;
+            statusll = strlen(status);
+        } else {
+            statusline = NULL;
+            statusll = 0;
+        }
         zrefresh();
+        statusline = NULL;
+        statusll = 0;
         inselect = 1;
         if (noselect) {
             broken = 1;
@@ -1859,13 +1949,29 @@
 	    zbeep();
             molbeg = -1;
 	    break;
-	} else if (nolist && cmd != Th(z_undo)) {
+	} else if (nolist && cmd != Th(z_undo) &&
+                   (!inter || cmd != Th(z_backwarddeletechar))) {
 	    ungetkeycmd();
 	    break;
 	} else if (cmd == Th(z_acceptline)) {
 	    acc = 1;
 	    break;
-	} else if (cmd == Th(z_acceptandinfernexthistory)) {
+        } else if (cmd == Th(z_viinsert)) {
+            if ((inter = !inter)) {
+                int l = strlen(origline);
+
+                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) ||
+                   (inter && (cmd == Th(z_selfinsert) ||
+                              cmd == Th(z_selfinsertunmeta)))) {
 	    Menustack s = (Menustack) zhalloc(sizeof(*s));
 
 	    s->prev = u;
@@ -1888,6 +1994,8 @@
 	    s->origline = origline;
 	    s->origcs = origcs;
 	    s->origll = origll;
+            s->status = dupstring(status);
+            s->inter = inter;
 	    menucmp = menuacc = hasoldlist = 0;
 	    minfo.cur = NULL;
 	    fixsuffix();
@@ -1897,6 +2005,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
+                inter = 0;
 	    menucomplete(zlenoargs);
 	    iforcemenu = 0;
 
@@ -1920,6 +2045,9 @@
 		}
 		goto getk;
 	    }
+            if (cmd != Th(z_acceptandinfernexthistory))
+                interline = setmstatus(status, &intercs, &interll, &interlen);
+
 	    clearlist = listshown = 1;
 	    mselect = (*(minfo.cur))->gnum;
 	    setwish = wasnext = 1;
@@ -1931,6 +2059,7 @@
 	    Menustack s = (Menustack) zhalloc(sizeof(*s));
 	    int ol;
 
+            inter = 0;
 	    s->prev = u;
 	    u = s;
 	    s->line = dupstring((char *) line);
@@ -1949,6 +2078,8 @@
 	    s->origline = origline;
 	    s->origcs = origcs;
 	    s->origll = origll;
+            s->status = dupstring(status);
+            s->inter = inter;
 	    accept_last();
 	    handleundo();
 	    comprecursive = 1;
@@ -1977,7 +2108,8 @@
 	    }
 	    setwish = 1;
 	    continue;
-	} else if (cmd == Th(z_undo)) {
+	} else if (cmd == Th(z_undo) ||
+                   (inter && cmd == Th(z_backwarddeletechar))) {
 	    int l;
 
 	    if (!u)
@@ -2013,12 +2145,17 @@
 	    origline = u->origline;
 	    origcs = u->origcs;
 	    origll = u->origll;
+            strcpy(status, u->status);
+            inter = u->inter;
 
 	    u = u->prev;
 	    clearlist = 1;
 	    setwish = 1;
 	    listdat.valid = 0;
             molbeg = -42;
+
+            if (inter)
+                continue;
 	} else if (cmd == Th(z_redisplay)) {
 	    redisplay(zlenoargs);
             molbeg = -42;
@@ -2034,6 +2171,7 @@
 	    int omline;
 	    Cmatch **op;
 
+            inter = 0;
 	    wrap = 0;
 
 	down:
@@ -2068,6 +2206,7 @@
 	    int omline;
 	    Cmatch **op;
 
+            inter = 0;
 	    wrap = 0;
 
 	up:
@@ -2106,6 +2245,7 @@
 	    int i = lines - pl - 1, oi = i, ll = 0;
 	    Cmatch **lp = NULL;
 
+            inter = 0;
 	    if (mline == mlines - 1)
 		goto top;
 	    while (i > 0) {
@@ -2133,6 +2273,7 @@
 	    int i = lines - pl - 1, oi = i, ll = 0;
 	    Cmatch **lp = NULL;
 
+            inter = 0;
 	    if (!mline)
 		goto bottom;
 	    while (i > 0) {
@@ -2158,6 +2299,8 @@
 	    int ll;
 	    Cmatch **lp;
 
+            inter = 0;
+
 	top:
 
 	    ll = mline;
@@ -2178,6 +2321,8 @@
 	    int ll;
 	    Cmatch **lp;
 
+            inter = 0;
+
 	bottom:
 
 	    ll = mline;
@@ -2198,6 +2343,7 @@
 	    int omcol;
 	    Cmatch **op;
 
+            inter = 0;
 	    wrap = 0;
 
 	right:
@@ -2228,6 +2374,7 @@
 	    int omcol;
 	    Cmatch **op;
 
+            inter = 0;
 	    wrap = 0;
 
 	left:
@@ -2262,6 +2409,7 @@
 		   cmd == Th(z_beginningofline) ||
 		   cmd == Th(z_beginningoflinehist) ||
 		   cmd == Th(z_vibeginningofline)) {
+            inter = 0;
 	    p -= mcol;
 	    mcol = 0;
 	    while (!*p || *p == mtexpl) {
@@ -2273,6 +2421,7 @@
 		   cmd == Th(z_endofline) ||
 		   cmd == Th(z_endoflinehist) ||
 		   cmd == Th(z_viendofline)) {
+            inter = 0;
 	    p += mcols - mcol - 1;
 	    mcol = mcols - 1;
 	    while (!*p || *p == mtexpl) {
@@ -2285,6 +2434,7 @@
 	    Cmgroup g = *pg;
 	    int ol = mline;
 
+            inter = 0;
 	    do {
 		if (mline == mlines - 1) {
 		    p -= mline * mcols;
@@ -2302,6 +2452,7 @@
 	    Cmgroup g = *pg;
 	    int ol = mline;
 
+            inter = 0;
 	    do {
 		if (!mline) {
 		    mline = mlines - 1;
@@ -2326,14 +2477,27 @@
 		   !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 (inter) {
+                origline = interline;
+                origcs = intercs;
+                origll = interll;
+                cs = 0;
+                foredel(ll);
+                spaceinline(origll);
+                strncpy((char *) line, origline, origll);
+                cs = origcs;
+                minfo.len = interlen;
+            } else {
+                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")) {
+            inter = 0;
 	    comprecursive = 1;
 	    reversemenucomplete(zlenoargs);
 	    mselect = (*(minfo.cur))->gnum;
@@ -2341,6 +2505,7 @@
 	    mline = -1;
 	    continue;
 	} else if (cmd == Th(z_undefinedkey)) {
+            inter = 0;
 	    continue;
 	} else {
 	    ungetkeycmd();
diff -ur -r ../oz/Src/Zle/compresult.c ./Src/Zle/compresult.c
--- ../oz/Src/Zle/compresult.c	Tue Jun  4 20:03:16 2002
+++ ./Src/Zle/compresult.c	Tue Jun  4 22:22:27 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@xxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author