zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: support for highlighting ellipses in zle
@ 2023-01-09 23:18 Oliver Kiddle
  0 siblings, 0 replies; only message in thread
From: Oliver Kiddle @ 2023-01-09 23:18 UTC (permalink / raw)
  To: Zsh workers

If the line is too big for the terminal window, zle prints markers such as
">...." at the beginning or "<...." at the end. There's also other
variations. This patch adds support for colour highlighting of these
markers with the key "ellipsis" in zle_highlight. Other names could be
used, "marker" perhaps?

By default, I've gone with blue on a yellow background. We've generally
been very conservative in our choices of default attributes but these
markers are only rarely seen and probably should stand out more. I'm not
inclined to argue hard for any particular choice, however.

It might also be nice to be able to configure the exact characters used
and substitute in some suitable Unicode characters. I won't be doing
that so if someone is looking for ideas, feel free to go ahead. The lack
of symmetry in the existing characters seems a little odd to me, why not
"....>" as the start?

Applying TXT_ERROR as the attributes to zr_sp and zr_zr (' ' and '\0',
respectively) in my earlier patch did actually break things somewhat
which this patch fixes.

Oliver

diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 60254e828..c622483d7 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -2691,6 +2691,9 @@ for different completions.
 item(tt(paste))(
 Following a command to paste text, the characters that were inserted.
 )
+item(tt(ellipsis))(
+Markers used to indicate where the text doesn't fit within the terminal.
+)
 enditem()
 
 When tt(region_highlight) is set, the contexts that describe a region DASH()-
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index b196370dc..a587f696a 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -203,12 +203,12 @@ int predisplaylen, postdisplaylen;
 
 
 /*
- * Attributes used by default on the command line, and
- * attributes for highlighting special (unprintable) characters
- * displayed on screen.
+ * Attributes used by default on the command line,
+ * for highlighting special (unprintable) characters displayed on screen,
+ * and for ellipsis continuation markers.
  */
 
-static zattr default_attr, special_attr;
+static zattr default_attr, special_attr, ellipsis_attr;
 
 /*
  * Array of region highlights, no special termination.
@@ -259,8 +259,8 @@ static const REFRESH_ELEMENT zr_cr = { ZWC('\r'), TXT_ERROR };
 static const REFRESH_ELEMENT zr_dt = { ZWC('.'), TXT_ERROR };
 #endif
 static const REFRESH_ELEMENT zr_nl = { ZWC('\n'), TXT_ERROR };
-static const REFRESH_ELEMENT zr_sp = { ZWC(' '), TXT_ERROR };
-static const REFRESH_ELEMENT zr_zr = { ZWC('\0'), TXT_ERROR };
+static const REFRESH_ELEMENT zr_sp = { ZWC(' '), 0 };
+static const REFRESH_ELEMENT zr_zr = { ZWC('\0'), 0 };
 
 /*
  * Constant arrays to be copied into place: these are memcpy'd,
@@ -269,10 +269,10 @@ static const REFRESH_ELEMENT zr_zr = { ZWC('\0'), TXT_ERROR };
 static const REFRESH_ELEMENT zr_end_ellipsis[] = {
     { ZWC(' '), 0 },
     { ZWC('<'), 0 },
-    { ZWC('.'), 0 },
-    { ZWC('.'), 0 },
-    { ZWC('.'), 0 },
-    { ZWC('.'), 0 },
+    { ZWC('.'), TXT_ERROR },
+    { ZWC('.'), TXT_ERROR },
+    { ZWC('.'), TXT_ERROR },
+    { ZWC('.'), TXT_ERROR },
     { ZWC(' '), 0 },
 };
 #define ZR_END_ELLIPSIS_SIZE	\
@@ -281,16 +281,16 @@ static const REFRESH_ELEMENT zr_end_ellipsis[] = {
 static const REFRESH_ELEMENT zr_mid_ellipsis1[] = {
     { ZWC(' '), 0 },
     { ZWC('<'), 0 },
-    { ZWC('.'), 0 },
-    { ZWC('.'), 0 },
-    { ZWC('.'), 0 },
-    { ZWC('.'), 0 },
+    { ZWC('.'), TXT_ERROR },
+    { ZWC('.'), TXT_ERROR },
+    { ZWC('.'), TXT_ERROR },
+    { ZWC('.'), TXT_ERROR },
 };
 #define ZR_MID_ELLIPSIS1_SIZE	\
     ((int)(sizeof(zr_mid_ellipsis1)/sizeof(zr_mid_ellipsis1[0])))
 
 static const REFRESH_ELEMENT zr_mid_ellipsis2[] = {
-    { ZWC('>'), 0 },
+    { ZWC('>'), TXT_ERROR },
     { ZWC(' '), 0 },
 };
 #define ZR_MID_ELLIPSIS2_SIZE	\
@@ -298,10 +298,10 @@ static const REFRESH_ELEMENT zr_mid_ellipsis2[] = {
 
 static const REFRESH_ELEMENT zr_start_ellipsis[] = {
     { ZWC('>'), 0 },
-    { ZWC('.'), 0 },
-    { ZWC('.'), 0 },
-    { ZWC('.'), 0 },
-    { ZWC('.'), 0 },
+    { ZWC('.'), TXT_ERROR },
+    { ZWC('.'), TXT_ERROR },
+    { ZWC('.'), TXT_ERROR },
+    { ZWC('.'), TXT_ERROR },
 };
 #define ZR_START_ELLIPSIS_SIZE	\
     ((int)(sizeof(zr_start_ellipsis)/sizeof(zr_start_ellipsis[0])))
@@ -321,6 +321,7 @@ zle_set_highlight(void)
     int isearch_attr_set = 0;
     int suffix_attr_set = 0;
     int paste_attr_set = 0;
+    int ellipsis_attr_set = 0;
     struct region_highlight *rhp;
 
     special_attr = default_attr = 0;
@@ -361,6 +362,9 @@ zle_set_highlight(void)
 	    } else if (strpfx("paste:", *atrs)) {
 		match_highlight(*atrs + 6, &(region_highlights[3].atr));
 		paste_attr_set = 1;
+	    } else if (strpfx("ellipsis:", *atrs)) {
+		match_highlight(*atrs + 9, &ellipsis_attr);
+		ellipsis_attr_set = 1;
 	    }
 	}
     }
@@ -376,6 +380,9 @@ zle_set_highlight(void)
 	region_highlights[2].atr = TXTBOLDFACE;
     if (!paste_attr_set)
 	region_highlights[3].atr = TXTSTANDOUT;
+    if (!ellipsis_attr_set)
+	ellipsis_attr = TXTBGCOLOUR | ((zattr) 3 << TXT_ATTR_BG_COL_SHIFT) |
+		TXTFGCOLOUR | ((zattr) 4 << TXT_ATTR_FG_COL_SHIFT);
 
     allocate_colour_buffer();
 }
@@ -599,10 +606,8 @@ zwcputc(const REFRESH_ELEMENT *c)
     VARARR(char, mbtmp, MB_CUR_MAX + 1);
 #endif
 
-    if (c->atr != TXT_ERROR) {
-	treplaceattrs(c->atr);
-	applytextattributes(0);
-    }
+    treplaceattrs(c->atr);
+    applytextattributes(0);
 
 #ifdef MULTIBYTE_SUPPORT
     if (c->atr & TXT_MULTIWORD_MASK) {
@@ -1479,6 +1484,7 @@ zrefresh(void)
 	}
 #endif
 	ZR_memcpy(rpms.sen, zr_end_ellipsis, ZR_END_ELLIPSIS_SIZE);
+	rpms.sen[1].atr = ellipsis_attr;
 #ifdef MULTIBYTE_SUPPORT
 	/* Extend to the end if we backed off for a wide character */
 	if (extra_ellipsis) {
@@ -1514,6 +1520,7 @@ zrefresh(void)
 	}
 #endif
 	ZR_memcpy(rpms.sen, zr_mid_ellipsis1, ZR_MID_ELLIPSIS1_SIZE);
+	rpms.sen[1].atr = ellipsis_attr;
 	rpms.sen += ZR_MID_ELLIPSIS1_SIZE;
 #ifdef MULTIBYTE_SUPPORT
 	/* Extend if we backed off for a wide character */
@@ -1523,6 +1530,7 @@ zrefresh(void)
 	}
 #endif
 	ZR_memcpy(rpms.sen, zr_mid_ellipsis2, ZR_MID_ELLIPSIS2_SIZE);
+	rpms.sen[1].atr = prompt_attr;
 	nbuf[rpms.tosln][winw] = nbuf[rpms.tosln][winw + 1] = zr_zr;
     }
 
@@ -1555,7 +1563,9 @@ zrefresh(void)
 	t0 = winw - lpromptw;
 	t0 = t0 > ZR_START_ELLIPSIS_SIZE ? ZR_START_ELLIPSIS_SIZE : t0;
 	ZR_memcpy(nbuf[0] + lpromptw, zr_start_ellipsis, t0);
+	(*nbuf + lpromptw)->atr = ellipsis_attr;
 	ZR_memset(nbuf[0] + lpromptw + t0, zr_sp, winw - t0 - lpromptw);
+	(*nbuf + lpromptw + t0)->atr = prompt_attr;
 	nbuf[0][winw] = nbuf[0][winw + 1] = zr_zr;
     }
 
@@ -2514,11 +2524,11 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
     }
     if (winpos) {
 	vbuf[winpos].chr = ZWC('<');	/* line continues to the left */
-	vbuf[winpos].atr = 0;
+	vbuf[winpos].atr = ellipsis_attr;
     }
     if ((int)ZR_strlen(vbuf + winpos) > (winw - hasam)) {
 	vbuf[winpos + winw - hasam - 1].chr = ZWC('>');	/* line continues to right */
-	vbuf[winpos + winw - hasam - 1].atr = 0;
+	vbuf[winpos + winw - hasam - 1].atr = ellipsis_attr;
 	vbuf[winpos + winw - hasam] = zr_zr;
     }
     ZR_strcpy(nbuf[0], vbuf + winpos);
diff --git a/Src/prompt.c b/Src/prompt.c
index 4f29a6728..39fcf5eb7 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -1648,6 +1648,9 @@ cleartextattributes(int flags)
 mod_export void
 treplaceattrs(zattr newattrs)
 {
+    if (newattrs == TXT_ERROR)
+	return;
+
     if (txtunknownattrs) {
 	/* Set current attributes to the opposite of the new ones
 	 * for any that are unknown so that applytextattributes()


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-01-09 23:19 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-09 23:18 PATCH: support for highlighting ellipses in zle Oliver Kiddle

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