about summary refs log tree commit diff
path: root/Src/Zle/zle_refresh.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle/zle_refresh.c')
-rw-r--r--Src/Zle/zle_refresh.c316
1 files changed, 81 insertions, 235 deletions
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index 2db5f0642..ae8e5c109 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -208,7 +208,7 @@ int predisplaylen, postdisplaylen;
  * displayed on screen.
  */
 
-static zattr default_atr_on, special_atr_on;
+static zattr default_attr, special_attr;
 
 /*
  * Array of region highlights, no special termination.
@@ -245,12 +245,12 @@ char *tcout_func_name;
 int cost;
 
 # define SELECT_ADD_COST(X)	(cost += X)
-# define zputc(a)		(zwcputc(a, NULL), cost++)
+# define zputc(a)		(zwcputc(a), cost++)
 # define zwrite(a, b)		(zwcwrite((a), (b)), \
 				 cost += ((b) * ZLE_CHAR_SIZE))
 #else
 # define SELECT_ADD_COST(X)
-# define zputc(a)		zwcputc(a, NULL)
+# define zputc(a)		zwcputc(a)
 # define zwrite(a, b)		zwcwrite((a), (b))
 #endif
 
@@ -316,14 +316,14 @@ static void
 zle_set_highlight(void)
 {
     char **atrs = getaparam("zle_highlight");
-    int special_atr_on_set = 0;
-    int region_atr_on_set = 0;
-    int isearch_atr_on_set = 0;
-    int suffix_atr_on_set = 0;
-    int paste_atr_on_set = 0;
+    int special_attr_set = 0;
+    int region_attr_set = 0;
+    int isearch_attr_set = 0;
+    int suffix_attr_set = 0;
+    int paste_attr_set = 0;
     struct region_highlight *rhp;
 
-    special_atr_on = default_atr_on = 0;
+    special_attr = default_attr = 0;
     if (!region_highlights) {
 	region_highlights = (struct region_highlight *)
 	    zshcalloc(N_SPECIAL_HIGHLIGHTS*sizeof(struct region_highlight));
@@ -340,41 +340,41 @@ zle_set_highlight(void)
 	for (; *atrs; atrs++) {
 	    if (!strcmp(*atrs, "none")) {
 		/* reset attributes for consistency... usually unnecessary */
-		special_atr_on = default_atr_on = 0;
-		special_atr_on_set = 1;
-		paste_atr_on_set = region_atr_on_set =
-		    isearch_atr_on_set = suffix_atr_on_set = 1;
+		special_attr = default_attr = 0;
+		special_attr_set = 1;
+		paste_attr_set = region_attr_set =
+		    isearch_attr_set = suffix_attr_set = 1;
 	    } else if (strpfx("default:", *atrs)) {
-		match_highlight(*atrs + 8, &default_atr_on);
+		match_highlight(*atrs + 8, &default_attr);
 	    } else if (strpfx("special:", *atrs)) {
-		match_highlight(*atrs + 8, &special_atr_on);
-		special_atr_on_set = 1;
+		match_highlight(*atrs + 8, &special_attr);
+		special_attr_set = 1;
 	    } else if (strpfx("region:", *atrs)) {
 		match_highlight(*atrs + 7, &region_highlights[0].atr);
-		region_atr_on_set = 1;
+		region_attr_set = 1;
 	    } else if (strpfx("isearch:", *atrs)) {
 		match_highlight(*atrs + 8, &(region_highlights[1].atr));
-		isearch_atr_on_set = 1;
+		isearch_attr_set = 1;
 	    } else if (strpfx("suffix:", *atrs)) {
 		match_highlight(*atrs + 7, &(region_highlights[2].atr));
-		suffix_atr_on_set = 1;
+		suffix_attr_set = 1;
 	    } else if (strpfx("paste:", *atrs)) {
 		match_highlight(*atrs + 6, &(region_highlights[3].atr));
-		paste_atr_on_set = 1;
+		paste_attr_set = 1;
 	    }
 	}
     }
 
     /* Defaults */
-    if (!special_atr_on_set)
-	special_atr_on = TXTSTANDOUT;
-    if (!region_atr_on_set)
+    if (!special_attr_set)
+	special_attr = TXTSTANDOUT;
+    if (!region_attr_set)
 	region_highlights[0].atr = TXTSTANDOUT;
-    if (!isearch_atr_on_set)
+    if (!isearch_attr_set)
 	region_highlights[1].atr = TXTUNDERLINE;
-    if (!suffix_atr_on_set)
+    if (!suffix_attr_set)
 	region_highlights[2].atr = TXTBOLDFACE;
-    if (!paste_atr_on_set)
+    if (!paste_attr_set)
 	region_highlights[3].atr = TXTSTANDOUT;
 
     allocate_colour_buffer();
@@ -571,22 +571,6 @@ unset_region_highlight(Param pm, int exp)
 }
 
 
-/* The last attributes that were on. */
-static zattr lastatr;
-
-/*
- * Clear the last attributes that we set:  used when we're going
- * to be outputting stuff that shouldn't show up as text.
- */
-static void
-clearattributes(void)
-{
-    if (lastatr) {
-	settextattributes(TXT_ATTR_OFF_FROM_ON(lastatr));
-	lastatr = 0;
-    }
-}
-
 /*
  * Output a termcap capability, clearing any text attributes so
  * as not to mess up the display.
@@ -595,7 +579,7 @@ clearattributes(void)
 static void
 tcoutclear(int cap)
 {
-    clearattributes();
+    cleartextattributes(0);
     tcout(cap);
 }
 
@@ -603,47 +587,20 @@ tcoutclear(int cap)
  * Output the character.  This must come from the new video
  * buffer, nbuf, since we access the multiword buffer nmwbuf
  * directly.
- *
- * curatrp may be NULL, otherwise points to an integer specifying
- * what attributes were turned on for a character output immediately
- * before, in order to optimise output of attribute changes.
  */
 
 /**/
 void
-zwcputc(const REFRESH_ELEMENT *c, zattr *curatrp)
+zwcputc(const REFRESH_ELEMENT *c)
 {
-    /*
-     * 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.
-     */
 #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(TXT_ATTR_OFF_FROM_ON(lastatr & ~c->atr));
-	lastatr = 0;
-    }
-
-    /*
-     * Don't output "on" attributes in a string of characters with
-     * the same attributes.  Be careful in case a different colour
-     * needs setting.
-     */
-    if ((c->atr & TXT_ATTR_ON_MASK) &&
-	(!curatrp ||
-	 ((*curatrp & TXT_ATTR_ON_VALUES_MASK) !=
-	  (c->atr & TXT_ATTR_ON_VALUES_MASK)))) {
-	/* Record just the control flags we might need to turn off... */
-	lastatr = c->atr & TXT_ATTR_ON_MASK;
-	/* ...but set including the values for colour attributes */
-	settextattributes(c->atr & TXT_ATTR_ON_VALUES_MASK);
-    }
+    treplaceattrs(c->atr);
+    applytextattributes(0);
 
 #ifdef MULTIBYTE_SUPPORT
     if (c->atr & TXT_MULTIWORD_MASK) {
@@ -664,35 +621,15 @@ zwcputc(const REFRESH_ELEMENT *c, zattr *curatrp)
 #else
     fputc(c->chr, shout);
 #endif
-
-    /*
-     * Always output "off" attributes since we only turn off at
-     * the end of a chunk of highlighted text.
-     */
-    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
-	 * on, less those that are turned off again.  Include
-	 * colour attributes here in case the colour changes to
-	 * another non-default one.
-	 */
-	*curatrp = (c->atr & TXT_ATTR_ON_VALUES_MASK) &
-	    ~((c->atr & TXT_ATTR_OFF_MASK) >> TXT_ATTR_OFF_ON_SHIFT);
-    }
 }
 
 static int
 zwcwrite(const REFRESH_STRING s, size_t i)
 {
     size_t j;
-    zattr curatr = 0;
 
     for (j = 0; j < i; j++)
-	zwcputc(s + j, &curatr);
+	zwcputc(s + j);
     return i; /* TODO something better for error indication */
 }
 
@@ -939,29 +876,6 @@ snextline(Rparams rpms)
     rpms->sen = rpms->s + winw;
 }
 
-
-/**/
-static void
-settextattributes(zattr atr)
-{
-    if (txtchangeisset(atr, TXTNOBOLDFACE))
-	tsetcap(TCALLATTRSOFF, 0);
-    if (txtchangeisset(atr, TXTNOSTANDOUT))
-	tsetcap(TCSTANDOUTEND, 0);
-    if (txtchangeisset(atr, TXTNOUNDERLINE))
-	tsetcap(TCUNDERLINEEND, 0);
-    if (txtchangeisset(atr, TXTBOLDFACE))
-	tsetcap(TCBOLDFACEBEG, 0);
-    if (txtchangeisset(atr, TXTSTANDOUT))
-	tsetcap(TCSTANDOUTBEG, 0);
-    if (txtchangeisset(atr, TXTUNDERLINE))
-	tsetcap(TCUNDERLINEBEG, 0);
-    if (txtchangeisset(atr, TXTFGCOLOUR|TXTNOFGCOLOUR))
-	set_colour_attribute(atr, COL_SEQ_FG, 0);
-    if (txtchangeisset(atr, TXTBGCOLOUR|TXTNOBGCOLOUR))
-	set_colour_attribute(atr, COL_SEQ_BG, 0);
-}
-
 #ifdef MULTIBYTE_SUPPORT
 /*
  * Add a multiword glyph at the screen location base.
@@ -1043,7 +957,6 @@ zrefresh(void)
     int tmppos;			/* t - tmpline				     */
     int tmpalloced;		/* flag to free tmpline when finished	     */
     int remetafy;		/* flag that zle line is metafied	     */
-    zattr txtchange;		/* attributes set after prompts              */
     int rprompt_off = 1;	/* Offset of rprompt from right of screen    */
     struct rparams rpms;
 #ifdef MULTIBYTE_SUPPORT
@@ -1194,7 +1107,7 @@ zrefresh(void)
 	tsetcap(TCALLATTRSOFF, 0);
 	tsetcap(TCSTANDOUTEND, 0);
 	tsetcap(TCUNDERLINEEND, 0);
-	txtattrmask = 0;
+	txtcurrentattrs = txtpendingattrs = txtunknownattrs = 0;
 
 	if (trashedzle && !clearflag)
 	    reexpandprompt(); 
@@ -1219,8 +1132,8 @@ zrefresh(void)
 	    if (lpromptwof == winw)
 		zputs("\n", shout);	/* works with both hasam and !hasam */
 	} else {
-	    txtchange = pmpt_attr;
-	    settextattributes(txtchange);
+	    treplaceattrs(pmpt_attr);
+	    applytextattributes(0);
 	}
 	if (clearflag) {
 	    zputc(&zr_cr);
@@ -1264,8 +1177,8 @@ zrefresh(void)
     rpms.sen = *nbuf + winw;
     for (t = tmpline, tmppos = 0; tmppos < tmpll; t++, tmppos++) {
 	unsigned ireg;
-	zattr base_atr_on = default_atr_on, base_atr_off = 0;
-	zattr all_atr_on, all_atr_off;
+	zattr base_attr = default_attr;
+	zattr all_attr;
 	struct region_highlight *rhp;
 	/*
 	 * Calculate attribute based on region.
@@ -1282,26 +1195,21 @@ zrefresh(void)
 		tmppos < rhp->end + offset) {
 		if (rhp->atr & (TXTFGCOLOUR|TXTBGCOLOUR)) {
 		    /* override colour with later entry */
-		    base_atr_on = (base_atr_on & ~TXT_ATTR_ON_VALUES_MASK) |
-			rhp->atr;
+		    base_attr = rhp->atr;
 		} else {
 		    /* no colour set yet */
-		    base_atr_on |= rhp->atr;
+		    base_attr |= rhp->atr;
 		}
-		if (tmppos == rhp->end + offset - 1 ||
-		    tmppos == tmpll - 1)
-		    base_atr_off |= TXT_ATTR_OFF_FROM_ON(rhp->atr);
 	    }
 	}
-	if (special_atr_on & (TXTFGCOLOUR|TXTBGCOLOUR)) {
+	if (special_attr & (TXTFGCOLOUR|TXTBGCOLOUR)) {
 	    /* keep colours from special attributes */
-	    all_atr_on = special_atr_on |
-		(base_atr_on & ~TXT_ATTR_COLOUR_ON_MASK);
+	    all_attr = special_attr |
+		(base_attr & ~TXT_ATTR_COLOUR_MASK);
 	} else {
 	    /* keep colours from standard attributes */
-	    all_atr_on = special_atr_on | base_atr_on;
+	    all_attr = special_attr | base_attr;
 	}
-	all_atr_off = TXT_ATTR_OFF_FROM_ON(all_atr_on);
 
 	if (t == scs)			/* if cursor is here, remember it */
 	    rpms.nvcs = rpms.s - nbuf[rpms.nvln = rpms.ln];
@@ -1319,10 +1227,9 @@ zrefresh(void)
 	    } else {
 		do {
 		    rpms.s->chr = ZWC(' ');
-		    rpms.s->atr = base_atr_on;
+		    rpms.s->atr = base_attr;
 		    rpms.s++;
 		} while ((++t0) & 7);
-		rpms.s[-1].atr |= base_atr_off;
 	    }
 	}
 #ifdef MULTIBYTE_SUPPORT
@@ -1341,11 +1248,9 @@ zrefresh(void)
 		    rpms.s->chr = ZWC(' ');
 		    if (!started)
 			started = 1;
-		    rpms.s->atr = all_atr_on;
+		    rpms.s->atr = all_attr;
 		    rpms.s++;
 		} while (rpms.s < rpms.sen);
-		if (started)
-		    rpms.s[-1].atr |= all_atr_off;
 		if (nextline(&rpms, 1))
 		    break;
 		if (t == scs) {
@@ -1369,7 +1274,7 @@ zrefresh(void)
 		 * occurrence.
 		 */
 		rpms.s->chr = ZWC('?');
-		rpms.s->atr = all_atr_on | all_atr_off;
+		rpms.s->atr = all_attr;
 		rpms.s++;
 	    } else {
 		/* We can fit it without reaching the end of the line. */
@@ -1377,7 +1282,7 @@ zrefresh(void)
 		 * As we don't actually output the WEOF, we attach
 		 * any off attributes to the character itself.
 		 */
-		rpms.s->atr = base_atr_on | base_atr_off;
+		rpms.s->atr = base_attr;
 		if (ichars > 1) {
 		    /*
 		     * Glyph includes combining characters.
@@ -1393,7 +1298,7 @@ zrefresh(void)
 		while (--width > 0) {
 		    rpms.s->chr = WEOF;
 		    /* Not used, but be consistent... */
-		    rpms.s->atr = base_atr_on | base_atr_off;
+		    rpms.s->atr = base_attr;
 		    rpms.s++;
 		}
 	    }
@@ -1410,17 +1315,16 @@ zrefresh(void)
 #endif
 	    ) {	/* other control character */
 	    rpms.s->chr = ZWC('^');
-	    rpms.s->atr = all_atr_on;
+	    rpms.s->atr = all_attr;
 	    rpms.s++;
 	    if (rpms.s == rpms.sen) {
 		/* text wrapped */
-		rpms.s[-1].atr |= all_atr_off;
 		if (nextline(&rpms, 1))
 		    break;
 	    }
 	    rpms.s->chr = (((unsigned int)*t & ~0x80u) > 31) ?
 		ZWC('?') : (*t | ZWC('@'));
-	    rpms.s->atr = all_atr_on | all_atr_off;
+	    rpms.s->atr = all_attr;
 	    rpms.s++;
 	}
 #ifdef MULTIBYTE_SUPPORT
@@ -1432,7 +1336,6 @@ zrefresh(void)
 	    char dispchars[11];
 	    char *dispptr = dispchars;
 	    wchar_t wc;
-	    int started = 0;
 
 #ifdef __STDC_ISO_10646__
 	    if (ZSH_INVALID_WCHAR_TEST(*t)) {
@@ -1449,31 +1352,23 @@ zrefresh(void)
 		if (mbtowc(&wc, dispptr, 1) == 1 /* paranoia */)
 		{
 		    rpms.s->chr = wc;
-		    if (!started)
-			started = 1;
-		    rpms.s->atr = all_atr_on;
+		    rpms.s->atr = all_attr;
 		    rpms.s++;
 		    if (rpms.s == rpms.sen) {
 			/* text wrapped */
-			if (started) {
-			    rpms.s[-1].atr |= all_atr_off;
-			    started = 0;
-			}
 			if (nextline(&rpms, 1))
 			    break;
 		    }
 		}
 		dispptr++;
 	    }
-	    if (started)
-		rpms.s[-1].atr |= all_atr_off;
 	    if (*dispptr) /* nextline said stop processing */
 		break;
 	}
 #else
 	else {			/* normal character */
 	    rpms.s->chr = *t;
-	    rpms.s->atr = base_atr_on | base_atr_off;
+	    rpms.s->atr = base_attr;
 	    rpms.s++;
 	}
 #endif
@@ -1499,13 +1394,12 @@ zrefresh(void)
 
     if (statusline) {
 	int outll, outsz;
-	zattr all_atr_on, all_atr_off;
+	zattr all_attr;
 	char *statusdup = ztrdup(statusline);
 	ZLE_STRING_T outputline =
 	    stringaszleline(statusdup, 0, &outll, &outsz, NULL); 
 
-	all_atr_on = special_atr_on;
-	all_atr_off = TXT_ATTR_OFF_FROM_ON(all_atr_on);
+	all_attr = special_attr;
 
 	rpms.tosln = rpms.ln + 1;
 	nbuf[rpms.ln][winw + 1] = zr_zr;	/* text not wrapped */
@@ -1525,7 +1419,7 @@ zrefresh(void)
 		}
 		if (width > rpms.sen - rpms.s) {
 		    rpms.s->chr = ZWC('?');
-		    rpms.s->atr = all_atr_on | all_atr_off;
+		    rpms.s->atr = all_attr;
 		    rpms.s++;
 		} else {
 		    rpms.s->chr = *u;
@@ -1542,7 +1436,7 @@ zrefresh(void)
 #endif
 	    if (ZC_icntrl(*u)) { /* simplified processing in the status line */
 		rpms.s->chr = ZWC('^');
-		rpms.s->atr = all_atr_on;
+		rpms.s->atr = all_attr;
 		rpms.s++;
 		if (rpms.s == rpms.sen) {
 		    nbuf[rpms.ln][winw + 1] = zr_nl;/* text wrapped */
@@ -1550,7 +1444,7 @@ zrefresh(void)
 		}
 		rpms.s->chr = (((unsigned int)*u & ~0x80u) > 31)
 		    ? ZWC('?') : (*u | ZWC('@'));
-		rpms.s->atr = all_atr_on | all_atr_off;
+		rpms.s->atr = all_attr;
 		rpms.s++;
 	    } else {
 		rpms.s->chr = *u;
@@ -1725,7 +1619,6 @@ zrefresh(void)
 
     /* output the right-prompt if appropriate */
 	if (put_rpmpt && !iln && !oput_rpmpt) {
-	    zattr attrchange;
 
 	    moveto(0, winw - rprompt_off - rpromptw);
 	    zputs(rpromptbuf, shout);
@@ -1735,39 +1628,9 @@ zrefresh(void)
 		zputc(&zr_cr);
 		vcs = 0;
 	    }
-	/* reset character attributes to that set by the main prompt */
-	    txtchange = pmpt_attr;
-	    /*
-	     * Keep attributes that have actually changed,
-	     * which are ones off in rpmpt_attr and on in
-	     * pmpt_attr, and vice versa.
-	     */
-	    attrchange = txtchange &
-		(TXT_ATTR_OFF_FROM_ON(rpmpt_attr) |
-		 TXT_ATTR_ON_FROM_OFF(rpmpt_attr));
-	    /*
-	     * Careful in case the colour changed.
-	     */
-	    if (txtchangeisset(txtchange, TXTFGCOLOUR) &&
-		(!txtchangeisset(rpmpt_attr, TXTFGCOLOUR) ||
-		 ((txtchange ^ rpmpt_attr) & TXT_ATTR_FG_COL_MASK)))
-	    {
-		attrchange |=
-		    txtchange & (TXTFGCOLOUR | TXT_ATTR_FG_COL_MASK);
-	    }
-	    if (txtchangeisset(txtchange, TXTBGCOLOUR) &&
-		(!txtchangeisset(rpmpt_attr, TXTBGCOLOUR) ||
-		 ((txtchange ^ rpmpt_attr) & TXT_ATTR_BG_COL_MASK)))
-	    {
-		attrchange |=
-		    txtchange & (TXTBGCOLOUR | TXT_ATTR_BG_COL_MASK);
-	    }
-	    /*
-	     * Now feed these changes into the usual function,
-	     * if necessary.
-	     */
-	    if (attrchange)
-		settextattributes(attrchange);
+	    /* reset character attributes to that set by the main prompt */
+	    treplaceattrs(pmpt_attr);
+	    applytextattributes(0);
 	}
     }
 
@@ -1782,8 +1645,8 @@ individually */
 
 /* reset character attributes */
     if (clearf && postedit) {
-	if ((txtchange = pmpt_attr ? pmpt_attr : rpmpt_attr))
-	    settextattributes(txtchange);
+	treplaceattrs(pmpt_attr ? pmpt_attr : rpmpt_attr);
+	applytextattributes(0);
     }
     clearf = 0;
     oput_rpmpt = put_rpmpt;
@@ -1984,8 +1847,6 @@ refreshline(int ln)
 /* 3: main display loop - write out the buffer using whatever tricks we can */
 
     for (;;) {
-	zattr now_off;
-
 #ifdef MULTIBYTE_SUPPORT
 	if ((!nl->chr || nl->chr != WEOF) && (!ol->chr || ol->chr != WEOF)) {
 #endif
@@ -2087,7 +1948,7 @@ refreshline(int ln)
 			     * deletions, so turn off text attributes.
 			     */
 			    if (first) {
-				clearattributes();
+				cleartextattributes(0);
 				first = 0;
 			    }
 			    tc_delchars(i);
@@ -2176,13 +2037,8 @@ refreshline(int ln)
 	    break;
 	do {
 #endif
-	    /*
-	     * If an attribute was on here but isn't any more,
-	     * output the sequence to turn it off.
-	     */
-	    now_off = ol->atr & ~nl->atr & TXT_ATTR_ON_MASK;
-	    if (now_off)
-		settextattributes(TXT_ATTR_OFF_FROM_ON(now_off));
+	    treplaceattrs(nl->atr);
+	    applytextattributes(0);
 
 	    /*
 	     * This is deliberately called if nl->chr is WEOF
@@ -2560,8 +2416,8 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
 
     for (t0 = 0; t0 < tmpll; t0++) {
 	unsigned ireg;
-	zattr base_atr_on = 0, base_atr_off = 0;
-	zattr all_atr_on, all_atr_off;
+	zattr base_attr = 0;
+	zattr all_attr;
 	struct region_highlight *rhp;
 	/*
 	 * Calculate attribute based on region.
@@ -2576,38 +2432,33 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
 		offset = predisplaylen; /* increment over it */
 	    if (rhp->start + offset <= t0 &&
 		t0 < rhp->end + offset) {
-		if (base_atr_on & (TXTFGCOLOUR|TXTBGCOLOUR)) {
+		if (base_attr & (TXTFGCOLOUR|TXTBGCOLOUR)) {
 		    /* keep colour already set */
-		    base_atr_on |= rhp->atr & ~TXT_ATTR_COLOUR_ON_MASK;
+		    base_attr |= rhp->atr & ~TXT_ATTR_COLOUR_MASK;
 		} else {
 		    /* no colour set yet */
-		    base_atr_on |= rhp->atr;
+		    base_attr |= rhp->atr;
 		}
-		if (t0 == rhp->end + offset - 1 ||
-		    t0 == tmpll - 1)
-		    base_atr_off |= TXT_ATTR_OFF_FROM_ON(rhp->atr);
 	    }
 	}
-	if (special_atr_on & (TXTFGCOLOUR|TXTBGCOLOUR)) {
+	if (special_attr & (TXTFGCOLOUR|TXTBGCOLOUR)) {
 	    /* keep colours from special attributes */
-	    all_atr_on = special_atr_on |
-		(base_atr_on & ~TXT_ATTR_COLOUR_ON_MASK);
+	    all_attr = special_attr |
+		(base_attr & ~TXT_ATTR_COLOUR_MASK);
 	} else {
 	    /* keep colours from standard attributes */
-	    all_atr_on = special_atr_on | base_atr_on;
+	    all_attr = special_attr | base_attr;
 	}
-	all_atr_off = TXT_ATTR_OFF_FROM_ON(all_atr_on);
 
 	if (tmpline[t0] == ZWC('\t')) {
 	    for (*vp++ = zr_sp; (vp - vbuf) & 7; )
 		*vp++ = zr_sp;
-	    vp[-1].atr |= base_atr_off;
 	} else if (tmpline[t0] == ZWC('\n')) {
 	    vp->chr = ZWC('\\');
-	    vp->atr = all_atr_on;
+	    vp->atr = all_attr;
 	    vp++;
 	    vp->chr = ZWC('n');
-	    vp->atr = all_atr_on | all_atr_off;
+	    vp->atr = all_attr;
 	    vp++;
 #ifdef MULTIBYTE_SUPPORT
 	} else if (WC_ISPRINT(tmpline[t0]) &&
@@ -2623,7 +2474,7 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
 		}
 	    } else
 		ichars = 1;
-	    vp->atr = base_atr_on | base_atr_off;
+	    vp->atr = base_attr;
 	    if (ichars > 1)
 		addmultiword(vp, tmpline+t0, ichars);
 	    else
@@ -2631,7 +2482,7 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
 	    vp++;
 	    while (--width > 0) {
 		vp->chr = WEOF;
-		vp->atr = base_atr_on | base_atr_off;
+		vp->atr = base_attr;
 		vp++;
 	    }
 	    t0 += ichars - 1;
@@ -2644,11 +2495,11 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
 	    ZLE_INT_T t = tmpline[++t0];
 
 	    vp->chr = ZWC('^');
-	    vp->atr = all_atr_on;
+	    vp->atr = all_attr;
 	    vp++;
 	    vp->chr = (((unsigned int)t & ~0x80u) > 31) ?
 		ZWC('?') : (t | ZWC('@'));
-	    vp->atr = all_atr_on | all_atr_off;
+	    vp->atr = all_attr;
 	    vp++;
 	}
 #ifdef MULTIBYTE_SUPPORT
@@ -2656,7 +2507,6 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
 	    char dispchars[11];
 	    char *dispptr = dispchars;
 	    wchar_t wc;
-	    int started = 0;
 
 	    if ((unsigned)tmpline[t0] > 0xffffU) {
 		sprintf(dispchars, "<%.08x>", (unsigned)tmpline[t0]);
@@ -2666,20 +2516,16 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
 	    while (*dispptr) {
 		if (mbtowc(&wc, dispptr, 1) == 1 /* paranoia */) {
 		    vp->chr = wc;
-		    if (!started)
-			started = 1;
-		    vp->atr = all_atr_on;
+		    vp->atr = all_attr;
 		    vp++;
 		}
 		dispptr++;
 	    }
-	    if (started)
-		vp[-1].atr |= all_atr_off;
 	}
 #else
 	else {
 	    vp->chr = tmpline[t0];
-	    vp->atr = base_atr_on | base_atr_off;
+	    vp->atr = base_attr;
 	    vp++;
 	}
 #endif