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

Re: zle reset-prompt



On Sat, 31 Jul 2010 20:34:56 +0200
Frank Terbeck <ft@xxxxxxxxxxxxxxxxxxx> wrote:
> I thought `reset-prompt' alone was enough, but it's not. Also, this only
> happens, when `clear-screen' and `reset-prompt are used in a single
> widget. If called separately, this doesn't happen either.

Aha, thanks, that's exactly what I need to know to pin down at least one
problem...  It's actually fairly obvious from your description.  We
maintain a global status which we save and restore within functions such
as zle widgets that aren't part of the main execution path, but we don't
explicitly restore that global status when redrawing the prompt, so if
we're already in a zle function and the local status has been changed we
use that.  So we need to maintain the global status specially for use in
this case.  However, we should still maintain the local status within the
function since it needs to obey normal syntax rules, so we have to save
and restore around the prompt redisplay, too.

This should fix that problem, anyway.  There's a pretty good chance this
is Simon's, too.

(See those things with slashes and stars?  Those are called
"comments"...  Yes, I'm still feeling a bit of completion code shell
shock.)

Index: Src/Zle/zle_main.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_main.c,v
retrieving revision 1.123
diff -p -u -r1.123 zle_main.c
--- Src/Zle/zle_main.c	16 Dec 2009 18:39:06 -0000	1.123
+++ Src/Zle/zle_main.c	31 Jul 2010 19:22:03 -0000
@@ -84,6 +84,14 @@ int done;
 int mark;
 
 /*
+ * Status ($?) saved before function entry.  This is the
+ * status we need to use in prompts.
+ */
+
+/**/
+static int pre_zle_status;
+
+/*
  * Last character pressed.
  *
  * Depending how far we are with processing, the lastcharacter may
@@ -1129,6 +1137,12 @@ zleread(char **lp, char **rp, int flags,
 	free(pptbuf);
 	return shingetline();
     }
+    /*
+     * The current status is what we need if we are going
+     * to display a prompt.  We'll remember it here for
+     * use further in.
+     */
+    pre_zle_status = lastval;
 
     keytimeout = (time_t)getiparam("KEYTIMEOUT");
     if (!shout) {
@@ -1756,6 +1770,14 @@ reexpandprompt(void)
     static int reexpanding;
 
     if (!reexpanding++) {
+	/*
+	 * If we're displaying a status in the prompt, it
+	 * needs to be the toplevel one, not the one from
+	 * any status set within the local zle function.
+	 */
+	int local_lastval = lastval;
+	lastval = pre_zle_status;
+
 	free(lpromptbuf);
 	lpromptbuf = promptexpand(raw_lp ? *raw_lp : NULL, 1, NULL, NULL,
 				  &pmpt_attr);
@@ -1763,6 +1785,7 @@ reexpandprompt(void)
 	free(rpromptbuf);
 	rpromptbuf = promptexpand(raw_rp ? *raw_rp : NULL, 1, NULL, NULL,
 				  &rpmpt_attr);
+	lastval = local_lastval;
     }
     reexpanding--;
 }

-- 
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/



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