zsh-workers
 help / color / mirror / code / Atom feed
* Re: Patch available for 3.0.6-pre-5
@ 1999-06-21  9:38 Sven Wischnowsky
  1999-06-21  9:55 ` Andrej Borsenkow
  1999-06-21 12:21 ` collist Peter Stephenson
  0 siblings, 2 replies; 4+ messages in thread
From: Sven Wischnowsky @ 1999-06-21  9:38 UTC (permalink / raw)
  To: zsh-workers


I wrote:

> [ ... collist ... ]

This one is even weirder... (if memory serves, Peter once talked about 
this).

It adds:
- the `ma' capability to collist; it is used during menucompletion to
  highlight the match inserted (note that you still have to set
  `ZLS_COLO(|U)RS' to see this -- an empty string will suffice)
- the `menu-select' widget which is a bit like `menu-complete' but
  displays the list and then lets you use cursor-movement keys to
  navigate in the list; to return to line editing, you can use
  `accept-line' or `send-break'; `accept-and-hold' leaves the match
  inserted in place and continues selecting matches from the list
  (i.e. it's like `accept-and-menu-complete')

Dunno if this is interesting to anyone, so I haven't written a manual
for this. (sorry :-}

Bye
 Sven

diff -u -r oos/Zle/collist.c Src/Zle/collist.c
--- oos/Zle/collist.c	Mon Jun 21 11:07:11 1999
+++ Src/Zle/collist.c	Mon Jun 21 11:32:27 1999
@@ -30,6 +30,8 @@
 #include "collist.mdh"
 #include "collist.pro"
 
+static Widget w_menuselect;
+
 /* We use the parameters ZLS_COLORS and ZLS_COLOURS in the same way as
  * the color ls does. It's just that we don't support the `or' file
  * type. */
@@ -50,21 +52,22 @@
 #define COL_LC 10
 #define COL_RC 11
 #define COL_EC 12
+#define COL_MA 13
 
-#define NUM_COLS 13
+#define NUM_COLS 14
 
 /* Names of the terminal strings. */
 
 static char *colnames[] = {
     "no", "fi", "di", "ln", "pi", "so", "bd", "cd", "ex", "mi",
-    "lc", "rc", "ec", NULL
+    "lc", "rc", "ec", "ma", NULL
 };
 
 /* Default values. */
 
 static char *defcols[] = {
     "0", "0", "32", "36", "31", "33", "44;37", "44;37", "35", NULL,
-    "\033[", "m", NULL
+    "\033[", "m", NULL, "7"
 };
 
 /* This describes a terminal string for a filename extension. */
@@ -200,9 +203,13 @@
     int i;
 
     if (!(s = getsparam("ZLS_COLORS")) &&
-	!(s = getsparam("ZLS_COLOURS")))
+	!(s = getsparam("ZLS_COLOURS"))) {
+	for (i = 0; i < NUM_COLS; i++)
+	    c->cols[i] = "";
+	
+	c->exts = NULL;
 	return 1;
-
+    }
     /* We have one of the parameters, use it. */
     memset(c, 0, sizeof(*c));
     s = dupstring(s);
@@ -216,6 +223,7 @@
     /* Default for missing files. */
     if (!c->cols[COL_MI])
 	c->cols[COL_MI] = c->cols[COL_FI];
+
     if (!c->cols[COL_EC]) {
 	char *e = (char *) zhalloc(strlen(c->cols[COL_LC]) +
 				   strlen(c->cols[COL_NO]) +
@@ -260,21 +268,27 @@
     return c->cols[COL_FI];
 }
 
+/* Information about the list shown. */
+
+static int noselect, mselect, mcol, mline, mcols, mlines;
+static Cmatch *mmatch, **mtab;
+static Cmgroup mgroup, *mgtab;
+
 /* List the matches. Most of this is just taken from ilistmatches(),
  * of course. */
 
-static int
-collistmatches(Hookdef dummy, Cmgroup amatches)
+static void
+icollistmatches(Cmgroup amatches, int mark)
 {
     Cmgroup g;
     Cmatch *p, m;
     Cexpl *e;
     int nlines = 0, ncols, nlist = 0, longest = 1, pnl = 0, opl = 0;
     int of = isset(LISTTYPES);
+    int mc, ml = 0, cc;
     struct listcols col;
 
-    if (getcols(&col))
-	return ilistmatches(dummy, amatches);
+    getcols(&col);
 
     /* Set the cursor below the prompt. */
     trashzle();
@@ -298,7 +312,7 @@
 		char *nlptr, *sptr;
 
 		g->flags |= CGF_LINES;
-		
+		noselect = 1;
 		while ((sptr = *pp)) {
 		    while (sptr && *sptr) {
 			nlines += (nlptr = strchr(sptr, '\n'))
@@ -363,6 +377,7 @@
     if ((complistmax && nlist > complistmax) ||
 	(!complistmax && nlines >= lines)) {
 	int qup;
+	noselect = 1;
 	zsetterm();
 	qup = printfmt("zsh: do you wish to see all %n possibilities? ", nlist, 1);
 	fflush(shout);
@@ -375,7 +390,6 @@
 		tcmultout(TCUP, TCMULTUP, nlnct);
 	    } else
 		putc('\n', shout);
-	    return 0;
 	}
 	if (clearflag) {
 	    putc('\r', shout);
@@ -386,7 +400,20 @@
 	    putc('\n', shout);
 	settyinfo(&shttyinfo);
     }
+    if (mselect >= 0) {
+	int i;
 
+	mark = mselect;
+	i = ncols * nlines;
+	free(mtab);
+	mtab = (Cmatch **) zalloc(i * sizeof(Cmatch **));
+	memset(mtab, 0, i * sizeof(Cmatch **));
+	free(mgtab);
+	mgtab = (Cmgroup *) zalloc(i * sizeof(Cmgroup));
+	memset(mgtab, 0, i * sizeof(Cmgroup));
+	mcols = ncols;
+	mlines = nlines;
+    }
     /* Now print the matches. */
     g = amatches;
     while (g) {
@@ -398,8 +425,9 @@
 		    if (pnl) {
 			putc('\n', shout);
 			pnl = 0;
+			ml++;
 		    }
-		    printfmt((*e)->str, (*e)->count, 1);
+		    ml += printfmt((*e)->str, (*e)->count, 1);
 		    pnl = 1;
 		}
 		e++;
@@ -409,6 +437,7 @@
 	    if (pnl) {
 		putc('\n', shout);
 		pnl = 0;
+		ml++;
 	    }
 	    if (g->flags & CGF_LINES) {
 		while (*pp) {
@@ -422,6 +451,7 @@
 
 		while (n && nl--) {
 		    i = ncols;
+		    mc = 0;
 		    pq = pp;
 		    while (n && i--) {
 			if (pq - g->ylist >= g->lcount)
@@ -435,8 +465,10 @@
 			pq += nc;
 			n--;
 		    }
-		    if (n)
+		    if (n) {
 			putc('\n', shout);
+			ml++;
+		    }
 		    pp++;
 		}
 	    }
@@ -448,9 +480,11 @@
 	    if (n && pnl) {
 		putc('\n', shout);
 		pnl = 0;
+		ml++;
 	    }
 	    for (p = skipnolist(g->matches); n && nl--;) {
 		i = ncols;
+		mc = 0;
 		q = p;
 		while (n && i--) {
 		    fputs(col.cols[COL_LC], shout);
@@ -463,6 +497,18 @@
 			fputs(col.cols[COL_EC], shout);
 			break;
 		    }
+		    if (mselect >= 0) {
+			mtab[mc + (ncols * ml)] = q;
+			mgtab[mc + (ncols * ml)] = g;
+		    }
+		    if (m->gnum == mark) {
+			mcol = mc;
+			mline = ml;
+			mmatch = q;
+			mgroup = g;
+			cc = COL_MA;
+		    } else
+			cc = -1;
 		    if (m->flags & CMF_FILE) {
 			struct stat buf;
 			char *pb;
@@ -472,7 +518,10 @@
 			sprintf(pb, "%s%s", (m->prpre ? m->prpre : "./"),
 				m->str);
 
-			if ((zt = ztat(pb, &buf, 1)))
+			zt = ztat(pb, &buf, 1);
+			if (cc >= 0)
+			    fputs(col.cols[cc], shout);
+			else if (zt)
 			    fputs(col.cols[COL_NO], shout);
 			else
 			    fputs(getcolstr(&col, pb, buf.st_mode), shout);
@@ -483,7 +532,7 @@
 			else
 			    putc(file_type(buf.st_mode), shout);
 		    } else {
-			fputs(col.cols[COL_NO], shout);
+			fputs(col.cols[cc >= 0 ? cc : COL_NO], shout);
 			fputs(col.cols[COL_RC], shout);
 			nicezputs(m->str, shout);
 			if (of)
@@ -503,6 +552,7 @@
 		    if (--n)
 			for (j = nc; j && *q; j--)
 			    q = skipnolist(q + 1);
+		    mc++;
 		}
 		if (i > 0) {
 		    fputs(col.cols[COL_LC], shout);
@@ -515,6 +565,7 @@
 		}
 		if (n) {
 		    putc('\n', shout);
+		    ml++;
 		    if (n && nl)
 			p = skipnolist(p + 1);
 		}
@@ -536,6 +587,179 @@
 	    clearflag = 0, putc('\n', shout);
     } else
 	putc('\n', shout);
+}
+
+static int
+collistmatches(Hookdef dummy, Cmgroup amatches)
+{
+    icollistmatches(amatches, (menucur ? (*menucur)->gnum : -1));
+    return 0;
+}
+
+static int
+markcollistmatches(Hookdef dummy, void **m)
+{
+    if (listshown && menucur)
+	icollistmatches(((Cmgroup) m[0]), ((Cmatch) m[1])->gnum);
+    return 0;
+}
+
+static int
+menuselect(char **args)
+{
+    Cmatch **p;
+    Cmgroup *pg;
+    Thingy cmd;
+    int i = 0;
+
+    if (!menucur)
+	menucomplete(args);
+
+    if (!menucur)
+	return 1;
+
+    noselect = 0;
+    mselect = (*menucur)->gnum;
+    for (;;) {
+	showinglist = -2;
+	zrefresh();
+	if (noselect)
+	    break;
+	if (!i) {
+	    i = mcols * mlines;
+	    while (i--)
+		if (mtab[i])
+		    break;
+	    if (!i)
+		break;
+	    i = 1;
+	}
+	p = mtab + mcol + (mline * mcols);
+	pg = mgtab + mcol + (mline * mcols);
+	menucur = *p;
+	menugrp = *pg;
+
+    getk:
+
+	if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak) ||
+	    cmd == Th(z_acceptline))
+	    break;
+	else if (cmd == Th(z_acceptandhold)) {
+	    acceptlast();
+	} else if (cmd == Th(z_redisplay)) {
+	    redisplay(zlenoargs);
+	    continue;
+	} else if (cmd == Th(z_clearscreen)) {
+	    clearscreen(zlenoargs);
+	    continue;
+	} else if (cmd == Th(z_downhistory) ||
+		   cmd == Th(z_downlineorhistory) ||
+		   cmd == Th(z_downlineorsearch) ||
+		   cmd == Th(z_vidownlineorhistory)) {
+	    do {
+		if (mline == mlines - 1) {
+		    p -= mline * mcols;
+		    mline = 0;
+		} else {
+		    mline++;
+		    p += mcols;
+		}
+	    } while (!*p);
+	} else if (cmd == Th(z_uphistory) ||
+		   cmd == Th(z_uplineorhistory) ||
+		   cmd == Th(z_uplineorsearch) ||
+		   cmd == Th(z_viuplineorhistory)) {
+	    do {
+		if (!mline) {
+		    mline = mlines - 1;
+		    p += mline * mcols;
+		} else {
+		    mline--;
+		    p -= mcols;
+		}
+	    } while (!*p);
+	} else if (cmd == Th(z_forwardchar) || cmd == Th(z_viforwardchar)) {
+	    do {
+		if (mcol == mcols - 1) {
+		    p -= mcol;
+		    mcol = 0;
+		} else {
+		    mcol++;
+		    p++;
+		}
+	    } while (!*p);
+	} else if (cmd == Th(z_backwardchar) || cmd == Th(z_vibackwardchar)) {
+	    do {
+		if (!mcol) {
+		    mcol = mcols - 1;
+		    p += mcol;
+		} else {
+		    mcol--;
+		    p--;
+		}
+	    } while (!*p);
+	} else if (cmd == Th(z_beginningofbufferorhistory) ||
+		   cmd == Th(z_beginningofline) ||
+		   cmd == Th(z_beginningoflinehist) ||
+		   cmd == Th(z_vibeginningofline)) {
+	    p -= mcol;
+	    mcol = 0;
+	    while (!*p) {
+		mcol++;
+		p++;
+	    }
+	} else if (cmd == Th(z_endofbufferorhistory) ||
+		   cmd == Th(z_endofline) ||
+		   cmd == Th(z_endoflinehist) ||
+		   cmd == Th(z_viendofline)) {
+	    p += mcols - mcol - 1;
+	    mcol = mcols - 1;
+	    while (!*p) {
+		mcol--;
+		p--;
+	    }
+	} else if (cmd == Th(z_forwardword) ||
+		   cmd == Th(z_emacsforwardword) ||
+		   cmd == Th(z_viforwardword) ||
+		   cmd == Th(z_viforwardwordend)) {
+	    Cmgroup g = *pg;
+	    int ol = mline;
+
+	    do {
+		if (mline == mlines - 1) {
+		    p -= mline * mcols;
+		    pg -= mline * mcols;
+		    mline = 0;
+		} else {
+		    mline++;
+		    p += mcols;
+		    pg += mcols;
+		}
+	    } while (ol != mline && (*pg == g || !*pg));
+	} else if (cmd == Th(z_backwardword) ||
+		   cmd == Th(z_emacsbackwardword) ||
+		   cmd == Th(z_vibackwardword)) {
+	    Cmgroup g = *pg;
+	    int ol = mline;
+
+	    do {
+		if (!mline) {
+		    mline = mlines - 1;
+		    p += mline * mcols;
+		    pg += mline * mcols;
+		} else {
+		    mline--;
+		    p -= mcols;
+		    pg -= mcols;
+		}
+	    } while (ol != mline && (*pg == g || !*pg));
+	} else
+	    goto getk;
+
+	do_single(**p);
+	mselect = (**p)->gnum;
+    }
+    mselect = -1;
     return 0;
 }
 
@@ -543,7 +767,6 @@
 int
 setup_example(Module m)
 {
-    addhookfunc("list_matches", (Hookfn) collistmatches);
     return 0;
 }
 
@@ -551,6 +774,18 @@
 int
 boot_example(Module m)
 {
+    mtab = NULL;
+    mselect = -1;
+
+    w_menuselect = addzlefunction("menu-select", menuselect,
+                                    ZLE_MENUCMP|ZLE_KEEPSUFFIX|ZLE_ISCOMP);
+    if (!w_menuselect) {
+	zwarnnam(m->nam, "name clash when adding ZLE function `menu-select'",
+		 NULL, 0);
+	return -1;
+    }
+    addhookfunc("list_matches", (Hookfn) collistmatches);
+    addhookfunc("insert_match", (Hookfn) markcollistmatches);
     return 0;
 }
 
@@ -560,6 +795,11 @@
 int
 cleanup_example(Module m)
 {
+    free(mtab);
+
+    deletezlefunction(w_menuselect);
+    deletehookfunc("list_matches", (Hookfn) collistmatches);
+    deletehookfunc("insert_match", (Hookfn) markcollistmatches);
     return 0;
 }
 
@@ -567,7 +807,6 @@
 int
 finish_example(Module m)
 {
-    deletehookfunc("list_matches", (Hookfn) collistmatches);
     return 0;
 }
 
diff -u -r oos/Zle/zle_main.c Src/Zle/zle_main.c
--- oos/Zle/zle_main.c	Mon Jun 21 11:07:12 1999
+++ Src/Zle/zle_main.c	Mon Jun 21 11:08:00 1999
@@ -959,6 +959,7 @@
 /**/
 struct hookdef zlehooks[] = {
     HOOKDEF("list_matches", ilistmatches, 0),
+    HOOKDEF("insert_match", NULL, HOOKF_ALL),
 };
 
 /**/
diff -u -r oos/Zle/zle_tricky.c Src/Zle/zle_tricky.c
--- oos/Zle/zle_tricky.c	Mon Jun 21 11:07:12 1999
+++ Src/Zle/zle_tricky.c	Mon Jun 21 11:08:01 1999
@@ -113,8 +113,11 @@
 /* Pointers to the current position in the groups list and in the menu-    *
  * completion array (the one that was put in the command line last).       */
 
-static Cmgroup menugrp;
-static Cmatch *menucur;
+/**/
+Cmgroup menugrp;
+
+/**/
+Cmatch *menucur;
 
 /* menupos is the point (in the command line) where the menu-completion   *
  * strings are inserted.  menulen is the length of the string that was    *
@@ -541,7 +544,8 @@
  * with the next completions. This gives you a way to   *
  * accept several selections from the list of matches.  */
 
-static void
+/**/
+void
 acceptlast(void)
 {
     if (brbeg && *brbeg) {
@@ -7513,7 +7517,7 @@
 /* Insert a single match in the command line. */
 
 /**/
-static void
+void
 do_single(Cmatch m)
 {
     int l, sr = 0, scs;
@@ -7669,6 +7673,17 @@
 
     if ((menucmp && !menuwe) || !movetoend)
 	cs = menuend;
+    {
+	void *data[2];
+	Cmatch *om = menucur;
+
+	if (menucmp)
+	    menucur = &m;
+	data[0] = (void *) amatches;
+	data[1] = (void *) m;
+	runhookdef(zlehooks + 1, (void *) data);
+	menucur = om;
+    }
 }
 
 /* This maps the value in v into the range [0,m-1], decrementing v

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


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

* RE: Patch available for 3.0.6-pre-5
  1999-06-21  9:38 Patch available for 3.0.6-pre-5 Sven Wischnowsky
@ 1999-06-21  9:55 ` Andrej Borsenkow
  1999-06-21 12:21 ` collist Peter Stephenson
  1 sibling, 0 replies; 4+ messages in thread
From: Andrej Borsenkow @ 1999-06-21  9:55 UTC (permalink / raw)
  To: Sven Wischnowsky, zsh-workers

> - the `menu-select' widget which is a bit like `menu-complete' but
>   displays the list and then lets you use cursor-movement keys to
>   navigate in the list; to return to line editing, you can use
>   `accept-line' or `send-break'; `accept-and-hold' leaves the match
>   inserted in place and continues selecting matches from the list
>   (i.e. it's like `accept-and-menu-complete')
>

Wow! I was tempted to ask for it long long time ... but I always had a feeling,
that zsh-workers are more of the old Unix teletype guys :-)

Is it possible to transparently use menu-select instead of menu-complete? I
mean, I currently have TAB bound to complete-word with additional stuff like
menu et al governed by configuration keys. Can I still use menu-select in this
case? Some configuration key to use menu-select instead of menu-complete
transparently ...

/andrej


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

* collist
  1999-06-21  9:38 Patch available for 3.0.6-pre-5 Sven Wischnowsky
  1999-06-21  9:55 ` Andrej Borsenkow
@ 1999-06-21 12:21 ` Peter Stephenson
  1999-06-21 14:32   ` collist Andrej Borsenkow
  1 sibling, 1 reply; 4+ messages in thread
From: Peter Stephenson @ 1999-06-21 12:21 UTC (permalink / raw)
  To: zsh-workers

Sven Wischnowsky wrote:
> - the `ma' capability to collist; it is used during menucompletion to
>   highlight the match inserted (note that you still have to set
>   `ZLS_COLO(|U)RS' to see this -- an empty string will suffice)
> - the `menu-select' widget which is a bit like `menu-complete' but
>   displays the list and then lets you use cursor-movement keys to
>   navigate in the list; to return to line editing, you can use
>   `accept-line' or `send-break'; `accept-and-hold' leaves the match
>   inserted in place and continues selecting matches from the list
>   (i.e. it's like `accept-and-menu-complete')

That's incredible.  It works fine on my black and white xterm with inverse
video (this is a good default), so I don't see why old fashioned vt100
people shouldn't be able to use it too.  And it's only tangentially related
to ordinary menu-completion --- in fact, it's real menucompletion rather
than just cycling through a list.  It should make every command line
interface in the world green with envy, if they're not already.
 
I had to add comp1 explicitly to the dependencies; this was to persuade AIX
to use comp1.export to resolve the links.  The .export files need updating
too, but having been bothering to post all that.

Some comments:
- It's hard to get out of at the moment.  Unrecognized keys should probably
  turn it off, particularly self insert, in much the same way they do with
  ordinary menu completion.  You should also be able to deactivate it
  leaving nothing inserted but without aborting everything.  That ought
  to satisfy many of the ordinary-menu-completion-phobes.
- When it does get deactivated, the chosen item should be unhighlighted
  immediately as a piece of visual feedback.
- (This is pretty much the same thing):  I actually find it annoying that
  the current menucompletion item is highlighted even when menu-select
  is not active.  I think at least there should be a separate code for
  the two (and I'd suggest the default for the ordinary menu completion one
  wasn't so highly visible).
- It would be quite nice to have some way of getting into it automatically,
  I suppose either by compconfig or by a completer.  To get this to work
  naturally, it's particularly important to have the visual feedback for
  menu-select on/off, as a signal that the cursor keys and a few others are
  special.  Then any other key could deactivate it and have its usual effect.
- Something a bit grotesque is happening when the completions don't all fit
  on the screen.  Maybe it shouldn't even work in that case (certainly not
  automatically).  It certainly shouldn't override `do you wish to see all
  2811 possibilities' as it does at present.
- I suppose a long term aim would be to have special keymaps for the
  minibuffer and this, too.  But there's no hurry for that.
- Probably not only this needs documenting, but the codes for ZLS_COLOURS in
  more detail; I don't think we can rely on using GNU ls manual.  But then
  we'll have to write it from scratch.

By the way, the translation of `colorize' is also `colour'.  Do children in
the US have colorizing books?

-- 
Peter Stephenson <pws@ibmth.df.unipi.it>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy


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

* RE: collist
  1999-06-21 12:21 ` collist Peter Stephenson
@ 1999-06-21 14:32   ` Andrej Borsenkow
  0 siblings, 0 replies; 4+ messages in thread
From: Andrej Borsenkow @ 1999-06-21 14:32 UTC (permalink / raw)
  To: Peter Stephenson, zsh-workers

> - When it does get deactivated, the chosen item should be unhighlighted
>   immediately as a piece of visual feedback.
> - (This is pretty much the same thing):  I actually find it annoying that
>   the current menucompletion item is highlighted even when menu-select
>   is not active.  I think at least there should be a separate code for
>   the two (and I'd suggest the default for the ordinary menu completion one
>   wasn't so highly visible).

After all patches I started zsh and found this ma capability working :-) A small
comment - I think, it is better to highlight just the current item. Currently,
the highlighted area corresponds to the longest item possible. Example:

bor@itsrm2:/tools/var%> l /var/adm/log/messages
memory_messages   messages
                  ^^^^^^^^^^^^^^^
                  Highlighted area

Looks a bit confusing.

And I agree, either this should be off by default, or some (easy) way to turn it
off is needed (easy, I mean - I can set ma to back/foreground colors, but this
is ugly). I have empty ZLS_COLORS.

But, folks, this *is* great!

/andrej


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

end of thread, other threads:[~1999-06-21 14:33 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-06-21  9:38 Patch available for 3.0.6-pre-5 Sven Wischnowsky
1999-06-21  9:55 ` Andrej Borsenkow
1999-06-21 12:21 ` collist Peter Stephenson
1999-06-21 14:32   ` collist Andrej Borsenkow

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).