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

Re: PATCH: Add $ZLE_STATE in zle widgets



On Fri, 06 Aug 2010 22:23:49 +0200
Frank Terbeck <ft@xxxxxxxxxxxxxxxxxxx> wrote:
> So, I started to write a number of wrapper widgets that keep track of
> zle's state entirely in shell code. That works surprisingly well. I
> could even call "zle reset-prompt" from a TRAPINT(), which seems to
> work. It just prints the following message to stderr:
> 
>       zle_thingy.c:649: line metafied
> 
> I'm ignoring that for now (2> /dev/null), since the widget does its
> work.

That's a bug that needs looking at.

> I'm pretty happy with my current setup anyway. It would be cool to
> have a way to add a "V" mode to my prompt when `vared' is active.
> That could probably be done with {pre,post}-vared hook widgets. I
> didn't look into that yet, though.  (Actually, since I wrote this
> mail while being on a train, I did look at this by now. This is not
> as trivial as I had hoped, since zle cannot be run recursively. Oh
> well, I'm rarely using `vared' anyway.)

Should be trivial to add this to ZLE_STATE internally.

> So it might be worth committing this patch after all, since if
> $ZLE_STATE contains "overwrite", you can be sure that's the state
> you're in.
>
> To cut a long story short: I'd like someone more competent to comment
> on whether it's okay to commit this or not. :)

It should be basically OK, though I'd be tempted to make it more
future-proof as below, which is rather picky, and make the documentation a
bit more explicit.

Index: Doc/Zsh/zle.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/zle.yo,v
retrieving revision 1.82
diff -p -u -r1.82 zle.yo
--- Doc/Zsh/zle.yo	22 Mar 2010 19:49:02 -0000	1.82
+++ Doc/Zsh/zle.yo	11 Aug 2010 11:58:56 -0000
@@ -854,6 +854,17 @@ executed; the second argument that follo
 defined.  This is the name of a builtin completion widget.  For widgets
 defined with tt(zle -N) this is set to the empty string.  Read-only.
 )
+vindex(ZLE_STATE)
+item(tt(ZLE_STATE) (scalar))(
+Contains a set of space-separated words that describe the current tt(zle)
+state.
+
+Currently, the only state shown is the insert mode as set by the
+tt(overwrite-mode) or tt(vi-replace) widgets.  The string contains
+`tt(insert)' if characters to be inserted on the command line move existing
+characters to the right, `tt(overwrite)' if characters to be inserted
+overwrite existing characters.
+)
 enditem()
 
 subsect(Special Widgets)
Index: Src/Zle/zle_params.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_params.c,v
retrieving revision 1.34
diff -p -u -r1.34 zle_params.c
--- Src/Zle/zle_params.c	22 Mar 2010 16:26:00 -0000	1.34
+++ Src/Zle/zle_params.c	11 Aug 2010 11:58:56 -0000
@@ -76,6 +76,8 @@ static const struct gsu_scalar widgetfun
 { get_widgetfunc, nullstrsetfn, zleunsetfn };
 static const struct gsu_scalar widgetstyle_gsu =
 { get_widgetstyle, nullstrsetfn, zleunsetfn };
+static const struct gsu_scalar zle_state_gsu =
+{ get_zle_state, nullstrsetfn, zleunsetfn };
 
 static const struct gsu_integer bufferlines_gsu =
 { get_bufferlines, NULL, zleunsetfn };
@@ -134,6 +136,7 @@ static struct zleparam {
     { "WIDGET", PM_SCALAR | PM_READONLY, GSU(widget_gsu), NULL },
     { "WIDGETFUNC", PM_SCALAR | PM_READONLY, GSU(widgetfunc_gsu), NULL },
     { "WIDGETSTYLE", PM_SCALAR | PM_READONLY, GSU(widgetstyle_gsu), NULL },
+    { "ZLE_STATE", PM_SCALAR | PM_READONLY, GSU(zle_state_gsu), NULL },
     { NULL, 0, NULL, NULL }
 };
 
@@ -695,3 +698,60 @@ get_context(UNUSED(Param pm))
 	break;
     }
 }
+
+/**/
+static char *
+get_zle_state(UNUSED(Param pm))
+{
+    char *zle_state = NULL, *ptr = NULL;
+    int itp, istate, len = 0;
+
+    /*
+     * When additional substrings are added, they should be kept in
+     * alphabetical order, so the user can easily match against this
+     * parameter: if [[ $ZLE_STATE == *bar*foo*zonk* ]]; then ...; fi
+     */
+    for (itp = 0; itp < 2; itp++) {
+	char *str;
+	/*
+	 * Currently there is only one state: insert or overwrite.
+	 * This loop is to make it easy to add others.
+	 */
+	for (istate = 0; istate < 1; istate++) {
+	    int slen;
+	    switch (istate) {
+	    case 0:
+		if (insmode) {
+		    str = "insert";
+		} else {
+		    str = "overwrite";
+		}
+		break;
+
+	    default:
+		str = "";
+	    }
+	    slen = strlen(str);
+	    if (itp == 0) {
+		/* Accumulating length */
+		if (istate)
+		    len++;	/* for space */
+		len += slen;
+	    } else {
+		/* Accumulating string */
+		if (istate)
+		    *ptr++ = ' ';
+		memcpy(ptr, str, slen);
+		ptr += slen;
+	    }
+	}
+	if (itp == 0) {
+	    len++;		/* terminating NULL */
+	    ptr = zle_state = (char *)zhalloc(len);
+	} else {
+	    *ptr = '\0';
+	}
+    }
+
+    return zle_state;
+}

-- 
Peter Stephenson <pws@xxxxxxx>            Software Engineer
Tel: +44 (0)1223 692070                   Cambridge Silicon Radio Limited
Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, UK


Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom



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