about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--Src/Zle/zle_refresh.c22
2 files changed, 22 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index c21163446..6e0483f51 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2008-04-04  Peter Stephenson  <pws@csr.com>
 
+	* 24792: Src/Zle/zle_refresh.c: try to be safer about turning
+	off attributes when outputting at a new position.
+
 	* c.f Mikael, 24790: Doc/Zsh/zle.yo: item()s need closing
 	parentheses on next line.
 
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index cabefe7e7..b1a5bc83d 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -506,20 +506,34 @@ unset_region_highlight(Param pm, int exp)
 void
 zwcputc(const REFRESH_ELEMENT *c, REFRESH_CHAR *curatrp)
 {
+    /*
+     * Safety: turn attributes off if last heard of turned on.
+     * This differs from *curatrp, which is an optimisation for
+     * writing lots of stuff at once.
+     */
+    static int lastatr;
 #ifdef MULTIBYTE_SUPPORT
     mbstate_t mbstate;
     int i;
     VARARR(char, mbtmp, MB_CUR_MAX + 1);
 #endif
 
+    if (lastatr & ~c->atr) {
+	/* Stuff on we don't want, turn it off */
+	settextattributes((lastatr & ~c->atr) << TXT_ATTR_OFF_ON_SHIFT);
+	lastatr = 0;
+    }
+
     /*
      * Don't output "on" attributes in a string of characters with
      * the same attributes.
      */
     if ((c->atr & TXT_ATTR_ON_MASK) &&
 	(!curatrp ||
-	 ((*curatrp & TXT_ATTR_ON_MASK) != (c->atr & TXT_ATTR_ON_MASK))))
-	settextattributes(c->atr & TXT_ATTR_ON_MASK);
+	 ((*curatrp & TXT_ATTR_ON_MASK) != (c->atr & TXT_ATTR_ON_MASK)))) {
+	lastatr = c->atr & TXT_ATTR_ON_MASK;
+	settextattributes(lastatr);
+    }
 
 #ifdef MULTIBYTE_SUPPORT
     if (c->chr != WEOF) {
@@ -531,8 +545,10 @@ zwcputc(const REFRESH_ELEMENT *c, REFRESH_CHAR *curatrp)
     fputc(c->chr, shout);
 #endif
 
-    if (c->atr & TXT_ATTR_OFF_MASK)
+    if (c->atr & TXT_ATTR_OFF_MASK) {
 	settextattributes(c->atr & TXT_ATTR_OFF_MASK);
+	lastatr &= ~((c->atr & TXT_ATTR_OFF_MASK) >> TXT_ATTR_OFF_ON_SHIFT);
+    }
     if (curatrp) {
 	/*
 	 * Remember the current attributes:  those that are turned