zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: support for italic and faint fonts from region_highlight
@ 2023-01-04  0:59 Oliver Kiddle
  2023-01-06 22:03 ` Oliver Kiddle
  0 siblings, 1 reply; 6+ messages in thread
From: Oliver Kiddle @ 2023-01-04  0:59 UTC (permalink / raw)
  To: Zsh workers

Having got rid of the OFF flags in zattr, there are bits available for
additional attributes. This patch adds support for italic and faint in
$region_highlight using two of the available 8 bits.

Other attributes with widely documented sequences include blink,
strikeout, double underline, invisible. None of these strike me as
especially useful and adding them might limit future expansion. I've
also come across fast blinking, overline, borders, rounded borders,
curly, dotted, dashed and coloured underline.

One approach could be to find a way to support user-defined attributes
e.g:

  zle_highlight+=(
    'user1_begin_code:\e[9m' 'user1_end_code:\e[29m'
    'user2_begin_code:\e[58;5;88m\e[4;3m' 'user2_end_code:\e[4;0m'
    'user2_excl:underline'
    special:user1 paste:user2
  )

This patch doesn't address prompts at all. We've discussed ideas before
such as %O...%o. or %A{italic}. The %A form would need to support
ways to unset attributes too so "noitalic" and perhaps "normal" for font
weight that is neither bold nor faint. But would it be better to instead
use an associative array and lookup attributes via that, e.g:

  zle_theme=( [warning]='fg=yellow' )
  print -P '%A{warning}Yellow text%a'

I currently need to convert colours to a variety of forms in my .zshrc
to suit a variety of commands and this could be made easier.

A final matter where ideas and opinions would be useful is the
precedence of values in region_highlight. In my own setup I've
experienced frustrations with array order not being a convenient way
to manage this and looking at external plugins, everyone just appends
values so I doubt it works especially well when mixing plugins.

Most attributes are merged so if one value requires bold and
another underline, you get both. But for colours, entries later in
region_highlight take precedence. I've followed that pattern for font
weight. A special-case appears to have been made for special character
highlighting. In one instance, I suspect a bug in the old code. A
solution that comes to mind would be to allow a layer= entry in the
attribute list. We could assign default layers to region, paste, special
etc. This also might not need users to wait for plugin authors to update
their plugin where plugins allow attributes to be customised. What would
be a good naming/numbering scheme for layers, are there established
existing conventions on that, e.g. in the graphics field? Would we also
need another parameter to mask what is passed through from lower layers?

Finally, some notes on the patch: italic does have a termcap entry but
it is sometimes missing where it would be supported so this falls back
on defaults. Does anyone have a view on whether we should use "italics"
instead of "italic" as the naming? There is no termcap entry for faint
so that is hard-coded. To avoid duplicating all of tsetcap() I've
extended it to handle fake termcap entries for higher-numbered values of
the cap parameter and an added X in the macro name, e.g. TCXFAINTBEG.

Oliver

diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 58700072a..60254e828 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -2780,9 +2780,13 @@ This works similarly to the foreground colour, except the background is
 not usually affected by the bold attribute.
 )
 item(tt(bold))(
-The characters in the given context are shown in a bold font.
+The characters in the given context are shown with a bold font weight.
 Not all terminals distinguish bold fonts.
 )
+item(tt(faint))(
+The characters in the given context are shown with a faint font weight.
+Not all terminals distinguish faint fonts.
+)
 item(tt(standout))(
 The characters in the given context are shown in the terminal's standout
 mode.  The actual effect is specific to the terminal; on many terminals it
@@ -2796,6 +2800,10 @@ The characters in the given context are shown underlined.  Some
 terminals show the foreground in a different colour instead; in this
 case whitespace will not be highlighted.
 )
+item(tt(italic))(
+The characters in the given context are shown in a italic font.
+Not all terminals support italic fonts.
+)
 enditem()
 
 The characters described above as `special' are as follows.  The
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index d56478147..e2131fb05 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -1193,23 +1193,23 @@ zrefresh(void)
 		offset = predisplaylen; /* increment over it */
 	    if (rhp->start + offset <= tmppos &&
 		tmppos < rhp->end + offset) {
-		if (rhp->atr & (TXTFGCOLOUR|TXTBGCOLOUR)) {
-		    /* override colour with later entry */
-		    base_attr = rhp->atr;
-		} else {
-		    /* no colour set yet */
-		    base_attr |= rhp->atr;
-		}
+		/* override colour with later entry */
+		if (rhp->atr & (TXTFGCOLOUR|TXTBGCOLOUR))
+		    base_attr &= ~TXT_ATTR_COLOUR_MASK;
+		/* override font weight with later entry */
+		if (rhp->atr & TXT_ATTR_FONT_WEIGHT)
+		    base_attr &= ~TXT_ATTR_FONT_WEIGHT;
+		base_attr |= rhp->atr;
 	    }
 	}
-	if (special_attr & (TXTFGCOLOUR|TXTBGCOLOUR)) {
-	    /* keep colours from special attributes */
-	    all_attr = special_attr |
-		(base_attr & ~TXT_ATTR_COLOUR_MASK);
-	} else {
-	    /* keep colours from standard attributes */
-	    all_attr = special_attr | base_attr;
-	}
+	all_attr = base_attr;
+	/* keep colours from special attributes */
+	if (special_attr & (TXTFGCOLOUR|TXTBGCOLOUR))
+	    all_attr &= ~TXT_ATTR_COLOUR_MASK;
+	/* keep font weight from special attributes */
+	if (special_attr & TXT_ATTR_FONT_WEIGHT)
+	    all_attr &= ~TXT_ATTR_FONT_WEIGHT;
+	all_attr |= special_attr;
 
 	if (t == scs)			/* if cursor is here, remember it */
 	    rpms.nvcs = rpms.s - nbuf[rpms.nvln = rpms.ln];
@@ -2441,14 +2441,14 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
 		}
 	    }
 	}
-	if (special_attr & (TXTFGCOLOUR|TXTBGCOLOUR)) {
-	    /* keep colours from special attributes */
-	    all_attr = special_attr |
-		(base_attr & ~TXT_ATTR_COLOUR_MASK);
-	} else {
-	    /* keep colours from standard attributes */
-	    all_attr = special_attr | base_attr;
-	}
+	all_attr = base_attr;
+	/* keep colours from special attributes */
+	if (special_attr & (TXTFGCOLOUR|TXTBGCOLOUR))
+	    all_attr &= ~TXT_ATTR_COLOUR_MASK;
+	/* keep font weight from special attributes */
+	if (special_attr & TXT_ATTR_FONT_WEIGHT)
+	    all_attr &= ~TXT_ATTR_FONT_WEIGHT;
+	all_attr |= special_attr;
 
 	if (tmpline[t0] == ZWC('\t')) {
 	    for (*vp++ = zr_sp; (vp - vbuf) & 7; )
diff --git a/Src/init.c b/Src/init.c
index 75ef2e094..9eef3f16d 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -747,7 +747,7 @@ init_shout(void)
 static char *tccapnams[TC_COUNT] = {
     "cl", "le", "LE", "nd", "RI", "up", "UP", "do",
     "DO", "dc", "DC", "ic", "IC", "cd", "ce", "al", "dl", "ta",
-    "md", "so", "us", "me", "se", "ue", "ch",
+    "md", "so", "us", "ZH", "me", "se", "ue", "ZR", "ch",
     "ku", "kd", "kl", "kr", "sc", "rc", "bc", "AF", "AB"
 };
 
@@ -872,6 +872,19 @@ init_term(void)
 	/* The following is an attempt at a heuristic,
 	 * but it fails in some cases */
 	/* rprompt_indent = ((hasam && !hasbw) || hasye || !tccan(TCLEFT)); */
+
+	/* if there's no termcap entry for italics, use CSI 3 m */
+	if (!tccan(TCITALICSBEG)) {
+	    zsfree(tcstr[TCITALICSBEG]);
+	    tcstr[TCITALICSBEG] = ztrdup("\033[3m");
+	    tclen[TCITALICSBEG] = 4;
+	}
+	if (!tccan(TCITALICSEND)) {
+	    zsfree(tcstr[TCITALICSEND]);
+	    tcstr[TCITALICSEND] = ztrdup("\033[23m");
+	    tclen[TCITALICSEND] = 5;
+	}
+
     }
     return 1;
 }
diff --git a/Src/prompt.c b/Src/prompt.c
index 880194f87..dc575085f 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -45,6 +45,12 @@ mod_export zattr txtpendingattrs;
 /**/
 mod_export zattr txtunknownattrs;
 
+/* common escape sequences not found in termcap */
+
+static char *tcxstr[TCX_COUNT - TC_COUNT] = {
+    "\e[2m", /* faint */
+};
+
 /* the command stack for use with %_ in prompts */
 
 /**/
@@ -1004,22 +1010,23 @@ stradd(char *d)
 mod_export void
 tsetcap(int cap, int flags)
 {
-    if (tccan(cap) && !isset(SINGLELINEZLE) &&
+    if ((cap >= TC_COUNT || tccan(cap)) && !isset(SINGLELINEZLE) &&
         !(termflags & (TERM_NOUP|TERM_BAD|TERM_UNKNOWN))) {
+	const char *tcseq = (cap >= TC_COUNT) ? tcxstr[cap - TC_COUNT] : tcstr[cap];
 	switch (flags) {
 	case TSC_RAW:
-	    tputs(tcstr[cap], 1, putraw);
+	    tputs(tcseq, 1, putraw);
 	    break;
 	case 0:
 	default:
-	    tputs(tcstr[cap], 1, putshout);
+	    tputs(tcseq, 1, putshout);
 	    break;
 	case TSC_PROMPT:
 	    if (!bv->dontcount) {
 		addbufspc(1);
 		*bv->bp++ = Inpar;
 	    }
-	    tputs(tcstr[cap], 1, putstr);
+	    tputs(tcseq, 1, putstr);
 	    if (!bv->dontcount) {
 		int glitch = 0;
 
@@ -1590,7 +1597,14 @@ applytextattributes(int flags)
 	    turnoff &= turnoff - 1;
     }
 
-    if (keepcount < turncount || (change & ~txtpendingattrs & TXTBOLDFACE)) {
+    /* enabling bold can be relied upon to disable faint */
+    if (txtcurrentattrs & TXTFAINT && txtpendingattrs & TXTBOLDFACE) {
+	--turncount;
+	change &= ~TXTFAINT;
+    }
+
+    if (keepcount < turncount ||
+	    (change & ~txtpendingattrs & TXT_ATTR_FONT_WEIGHT)) {
 	tsetcap(TCALLATTRSOFF, flags);
 	/* this cleared all attributes, may need to restore some */
 	change = txtpendingattrs & TXT_ATTR_ALL & ~txtunknownattrs;
@@ -1607,13 +1621,19 @@ applytextattributes(int flags)
 	    /* in some cases, that clears all attributes */
 	    change = txtpendingattrs & TXT_ATTR_ALL & ~txtunknownattrs;
 	}
+	if (change & ~txtpendingattrs & TXTITALIC)
+	    tsetcap(TCITALICSEND, flags);
     }
     if (change & txtpendingattrs & TXTBOLDFACE)
 	tsetcap(TCBOLDFACEBEG, flags);
+    if (change & txtpendingattrs & TXTFAINT)
+	tsetcap(TCXFAINTBEG, flags);
     if (change & txtpendingattrs & TXTSTANDOUT)
 	tsetcap(TCSTANDOUTBEG, flags);
     if (change & txtpendingattrs & TXTUNDERLINE)
 	tsetcap(TCUNDERLINEBEG, flags);
+    if (change & txtpendingattrs & TXTITALIC)
+	tsetcap(TCITALICSBEG, flags);
 
     if (change & TXT_ATTR_FG_MASK)
 	set_colour_attribute(txtpendingattrs, COL_SEQ_FG, flags);
@@ -1700,9 +1720,11 @@ struct highlight {
 
 static const struct highlight highlights[] = {
     { "none", 0, TXT_ATTR_ALL },
-    { "bold", TXTBOLDFACE, 0 },
+    { "bold", TXTBOLDFACE, TXTFAINT },
+    { "faint", TXTFAINT, TXTBOLDFACE },
     { "standout", TXTSTANDOUT, 0 },
     { "underline", TXTUNDERLINE, 0 },
+    { "italic", TXTITALIC, 0 },
     { NULL, 0, 0 }
 };
 
diff --git a/Src/zsh.h b/Src/zsh.h
index 35ae033e3..e8b9fd84b 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -2648,20 +2648,26 @@ struct ttyinfo {
 #define TCBOLDFACEBEG  18
 #define TCSTANDOUTBEG  19
 #define TCUNDERLINEBEG 20
-#define TCALLATTRSOFF  21
-#define TCSTANDOUTEND  22
-#define TCUNDERLINEEND 23
-#define TCHORIZPOS     24
-#define TCUPCURSOR     25
-#define TCDOWNCURSOR   26
-#define TCLEFTCURSOR   27
-#define TCRIGHTCURSOR  28
-#define TCSAVECURSOR   29
-#define TCRESTRCURSOR  30
-#define TCBACKSPACE    31
-#define TCFGCOLOUR     32
-#define TCBGCOLOUR     33
-#define TC_COUNT       34
+#define TCITALICSBEG   21
+#define TCALLATTRSOFF  22
+#define TCSTANDOUTEND  23
+#define TCUNDERLINEEND 24
+#define TCITALICSEND   26
+#define TCHORIZPOS     26
+#define TCUPCURSOR     27
+#define TCDOWNCURSOR   28
+#define TCLEFTCURSOR   29
+#define TCRIGHTCURSOR  30
+#define TCSAVECURSOR   31
+#define TCRESTRCURSOR  32
+#define TCBACKSPACE    33
+#define TCFGCOLOUR     34
+#define TCBGCOLOUR     35
+#define TC_COUNT       36
+
+/* escape sequences for which there is no termcap sequence */
+#define TCXFAINTBEG    36
+#define TCX_COUNT      37
 
 #define tccan(X) (tclen[X])
 
@@ -2676,12 +2682,14 @@ struct ttyinfo {
 #endif
 
 #define TXTBOLDFACE   0x0001
-#define TXTSTANDOUT   0x0002
-#define TXTUNDERLINE  0x0004
-#define TXTFGCOLOUR   0x0008
-#define TXTBGCOLOUR   0x0010
+#define TXTFAINT      0x0002
+#define TXTSTANDOUT   0x0004
+#define TXTUNDERLINE  0x0008
+#define TXTITALIC     0x0010
+#define TXTFGCOLOUR   0x0020
+#define TXTBGCOLOUR   0x0040
 
-#define TXT_ATTR_ALL  0x001F
+#define TXT_ATTR_ALL  0x007F
 
 /*
  * Indicates to zle_refresh.c that the character entry is an
@@ -2690,7 +2698,10 @@ struct ttyinfo {
 #define TXT_MULTIWORD_MASK  0x0400
 
 /* used when, e.g an invalid colour is specified */
-#define TXT_ERROR 0xF00000F000000800
+#define TXT_ERROR 0xF00000F000000003
+
+/* Mask for font weight */
+#define TXT_ATTR_FONT_WEIGHT     (TXTBOLDFACE|TXTFAINT)
 
 /* Mask for colour to use in foreground */
 #define TXT_ATTR_FG_COL_MASK     0x000000FFFFFF0000


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: support for italic and faint fonts from region_highlight
  2023-01-04  0:59 PATCH: support for italic and faint fonts from region_highlight Oliver Kiddle
@ 2023-01-06 22:03 ` Oliver Kiddle
  2023-01-19 16:22   ` Mikael Magnusson
  0 siblings, 1 reply; 6+ messages in thread
From: Oliver Kiddle @ 2023-01-06 22:03 UTC (permalink / raw)
  To: Zsh workers

It was brought to my attention that turning faint on does have a termcap
entry - mh or terminfo dim.

I've attached a replacement for this patch to use this which also adds
a function for combining two attribute sets allowing for priority over
colour and font weight to go to one of the sets. This will get even more
use in the next update for handling leftover attributes from the prompt.

Oliver

diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 58700072a..60254e828 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -2780,9 +2780,13 @@ This works similarly to the foreground colour, except the background is
 not usually affected by the bold attribute.
 )
 item(tt(bold))(
-The characters in the given context are shown in a bold font.
+The characters in the given context are shown with a bold font weight.
 Not all terminals distinguish bold fonts.
 )
+item(tt(faint))(
+The characters in the given context are shown with a faint font weight.
+Not all terminals distinguish faint fonts.
+)
 item(tt(standout))(
 The characters in the given context are shown in the terminal's standout
 mode.  The actual effect is specific to the terminal; on many terminals it
@@ -2796,6 +2800,10 @@ The characters in the given context are shown underlined.  Some
 terminals show the foreground in a different colour instead; in this
 case whitespace will not be highlighted.
 )
+item(tt(italic))(
+The characters in the given context are shown in a italic font.
+Not all terminals support italic fonts.
+)
 enditem()
 
 The characters described above as `special' are as follows.  The
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index d56478147..6cbfe9072 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -1193,23 +1193,10 @@ zrefresh(void)
 		offset = predisplaylen; /* increment over it */
 	    if (rhp->start + offset <= tmppos &&
 		tmppos < rhp->end + offset) {
-		if (rhp->atr & (TXTFGCOLOUR|TXTBGCOLOUR)) {
-		    /* override colour with later entry */
-		    base_attr = rhp->atr;
-		} else {
-		    /* no colour set yet */
-		    base_attr |= rhp->atr;
-		}
+		base_attr = mixattrs(rhp->atr, base_attr);
 	    }
 	}
-	if (special_attr & (TXTFGCOLOUR|TXTBGCOLOUR)) {
-	    /* keep colours from special attributes */
-	    all_attr = special_attr |
-		(base_attr & ~TXT_ATTR_COLOUR_MASK);
-	} else {
-	    /* keep colours from standard attributes */
-	    all_attr = special_attr | base_attr;
-	}
+	all_attr = mixattrs(special_attr, base_attr);
 
 	if (t == scs)			/* if cursor is here, remember it */
 	    rpms.nvcs = rpms.s - nbuf[rpms.nvln = rpms.ln];
@@ -2441,14 +2428,7 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
 		}
 	    }
 	}
-	if (special_attr & (TXTFGCOLOUR|TXTBGCOLOUR)) {
-	    /* keep colours from special attributes */
-	    all_attr = special_attr |
-		(base_attr & ~TXT_ATTR_COLOUR_MASK);
-	} else {
-	    /* keep colours from standard attributes */
-	    all_attr = special_attr | base_attr;
-	}
+	all_attr = mixattrs(special_attr, base_attr);
 
 	if (tmpline[t0] == ZWC('\t')) {
 	    for (*vp++ = zr_sp; (vp - vbuf) & 7; )
diff --git a/Src/init.c b/Src/init.c
index 75ef2e094..68621a0ad 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -747,7 +747,7 @@ init_shout(void)
 static char *tccapnams[TC_COUNT] = {
     "cl", "le", "LE", "nd", "RI", "up", "UP", "do",
     "DO", "dc", "DC", "ic", "IC", "cd", "ce", "al", "dl", "ta",
-    "md", "so", "us", "me", "se", "ue", "ch",
+    "md", "mh", "so", "us", "ZH", "me", "se", "ue", "ZR", "ch",
     "ku", "kd", "kl", "kr", "sc", "rc", "bc", "AF", "AB"
 };
 
@@ -872,6 +872,23 @@ init_term(void)
 	/* The following is an attempt at a heuristic,
 	 * but it fails in some cases */
 	/* rprompt_indent = ((hasam && !hasbw) || hasye || !tccan(TCLEFT)); */
+
+	/* if there's no termcap entry for italics, use CSI 3 m */
+	if (!tccan(TCITALICSBEG)) {
+	    zsfree(tcstr[TCITALICSBEG]);
+	    tcstr[TCITALICSBEG] = ztrdup("\033[3m");
+	    tclen[TCITALICSBEG] = 4;
+	}
+	if (!tccan(TCITALICSEND)) {
+	    zsfree(tcstr[TCITALICSEND]);
+	    tcstr[TCITALICSEND] = ztrdup("\033[23m");
+	    tclen[TCITALICSEND] = 5;
+	}
+	if (!tccan(TCFAINTBEG)) {
+	    zsfree(tcstr[TCFAINTBEG]);
+	    tcstr[TCFAINTBEG] = ztrdup("\033[2m");
+	    tclen[TCFAINTBEG] = 4;
+	}
     }
     return 1;
 }
diff --git a/Src/prompt.c b/Src/prompt.c
index 880194f87..488a90d09 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -1590,7 +1590,15 @@ applytextattributes(int flags)
 	    turnoff &= turnoff - 1;
     }
 
-    if (keepcount < turncount || (change & ~txtpendingattrs & TXTBOLDFACE)) {
+    /* enabling bold can be relied upon to disable faint
+     * (the converse not so as that commonly does nothing at all) */
+    if (txtcurrentattrs & TXTFAINT && txtpendingattrs & TXTBOLDFACE) {
+	--turncount;
+	change &= ~TXTFAINT;
+    }
+
+    if (keepcount < turncount ||
+	    (change & ~txtpendingattrs & TXT_ATTR_FONT_WEIGHT)) {
 	tsetcap(TCALLATTRSOFF, flags);
 	/* this cleared all attributes, may need to restore some */
 	change = txtpendingattrs & TXT_ATTR_ALL & ~txtunknownattrs;
@@ -1607,13 +1615,19 @@ applytextattributes(int flags)
 	    /* in some cases, that clears all attributes */
 	    change = txtpendingattrs & TXT_ATTR_ALL & ~txtunknownattrs;
 	}
+	if (change & ~txtpendingattrs & TXTITALIC)
+	    tsetcap(TCITALICSEND, flags);
     }
     if (change & txtpendingattrs & TXTBOLDFACE)
 	tsetcap(TCBOLDFACEBEG, flags);
+    if (change & txtpendingattrs & TXTFAINT)
+	tsetcap(TCFAINTBEG, flags);
     if (change & txtpendingattrs & TXTSTANDOUT)
 	tsetcap(TCSTANDOUTBEG, flags);
     if (change & txtpendingattrs & TXTUNDERLINE)
 	tsetcap(TCUNDERLINEBEG, flags);
+    if (change & txtpendingattrs & TXTITALIC)
+	tsetcap(TCITALICSBEG, flags);
 
     if (change & TXT_ATTR_FG_MASK)
 	set_colour_attribute(txtpendingattrs, COL_SEQ_FG, flags);
@@ -1678,6 +1692,25 @@ tunsetattrs(zattr newattrs)
 	txtpendingattrs &= ~TXT_ATTR_BG_MASK;
 }
 
+/* Merge two attribute sets. In an case where attributes might conflict
+ * choose those from the first parameter.  Foreground and background
+ * colours are taken together - less likely to end up with unreadable
+ * combinations. */
+
+/**/
+mod_export zattr
+mixattrs(zattr primary, zattr secondary)
+{
+    zattr result = secondary;
+    /* take colours from primary */
+    if (primary & (TXTFGCOLOUR|TXTBGCOLOUR))
+        result &= ~TXT_ATTR_COLOUR_MASK;
+    /* take font weight from primary */
+    if (primary & TXT_ATTR_FONT_WEIGHT)
+        result &= ~TXT_ATTR_FONT_WEIGHT;
+    return result | primary;
+}
+
 /*****************************************************************************
  * Utilities dealing with colour and other forms of highlighting.
  *
@@ -1700,9 +1733,11 @@ struct highlight {
 
 static const struct highlight highlights[] = {
     { "none", 0, TXT_ATTR_ALL },
-    { "bold", TXTBOLDFACE, 0 },
+    { "bold", TXTBOLDFACE, TXTFAINT },
+    { "faint", TXTFAINT, TXTBOLDFACE },
     { "standout", TXTSTANDOUT, 0 },
     { "underline", TXTUNDERLINE, 0 },
+    { "italic", TXTITALIC, 0 },
     { NULL, 0, 0 }
 };
 
diff --git a/Src/zsh.h b/Src/zsh.h
index 35ae033e3..e834c7e06 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -2646,22 +2646,25 @@ struct ttyinfo {
 #define TCDELLINE      16
 #define TCNEXTTAB      17
 #define TCBOLDFACEBEG  18
-#define TCSTANDOUTBEG  19
-#define TCUNDERLINEBEG 20
-#define TCALLATTRSOFF  21
-#define TCSTANDOUTEND  22
-#define TCUNDERLINEEND 23
-#define TCHORIZPOS     24
-#define TCUPCURSOR     25
-#define TCDOWNCURSOR   26
-#define TCLEFTCURSOR   27
-#define TCRIGHTCURSOR  28
-#define TCSAVECURSOR   29
-#define TCRESTRCURSOR  30
-#define TCBACKSPACE    31
-#define TCFGCOLOUR     32
-#define TCBGCOLOUR     33
-#define TC_COUNT       34
+#define TCFAINTBEG     19
+#define TCSTANDOUTBEG  20
+#define TCUNDERLINEBEG 21
+#define TCITALICSBEG   22
+#define TCALLATTRSOFF  23
+#define TCSTANDOUTEND  24
+#define TCUNDERLINEEND 25
+#define TCITALICSEND   27
+#define TCHORIZPOS     27
+#define TCUPCURSOR     28
+#define TCDOWNCURSOR   29
+#define TCLEFTCURSOR   30
+#define TCRIGHTCURSOR  31
+#define TCSAVECURSOR   32
+#define TCRESTRCURSOR  33
+#define TCBACKSPACE    34
+#define TCFGCOLOUR     35
+#define TCBGCOLOUR     36
+#define TC_COUNT       37
 
 #define tccan(X) (tclen[X])
 
@@ -2676,12 +2679,14 @@ struct ttyinfo {
 #endif
 
 #define TXTBOLDFACE   0x0001
-#define TXTSTANDOUT   0x0002
-#define TXTUNDERLINE  0x0004
-#define TXTFGCOLOUR   0x0008
-#define TXTBGCOLOUR   0x0010
+#define TXTFAINT      0x0002
+#define TXTSTANDOUT   0x0004
+#define TXTUNDERLINE  0x0008
+#define TXTITALIC     0x0010
+#define TXTFGCOLOUR   0x0020
+#define TXTBGCOLOUR   0x0040
 
-#define TXT_ATTR_ALL  0x001F
+#define TXT_ATTR_ALL  0x007F
 
 /*
  * Indicates to zle_refresh.c that the character entry is an
@@ -2690,7 +2695,10 @@ struct ttyinfo {
 #define TXT_MULTIWORD_MASK  0x0400
 
 /* used when, e.g an invalid colour is specified */
-#define TXT_ERROR 0xF00000F000000800
+#define TXT_ERROR 0xF00000F000000003
+
+/* Mask for font weight */
+#define TXT_ATTR_FONT_WEIGHT     (TXTBOLDFACE|TXTFAINT)
 
 /* Mask for colour to use in foreground */
 #define TXT_ATTR_FG_COL_MASK     0x000000FFFFFF0000


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: support for italic and faint fonts from region_highlight
  2023-01-06 22:03 ` Oliver Kiddle
@ 2023-01-19 16:22   ` Mikael Magnusson
  2023-01-19 21:18     ` Oliver Kiddle
  0 siblings, 1 reply; 6+ messages in thread
From: Mikael Magnusson @ 2023-01-19 16:22 UTC (permalink / raw)
  To: Oliver Kiddle; +Cc: Zsh workers

On 1/6/23, Oliver Kiddle <opk@zsh.org> wrote:
> It was brought to my attention that turning faint on does have a termcap
> entry - mh or terminfo dim.
>
> I've attached a replacement for this patch to use this which also adds
> a function for combining two attribute sets allowing for priority over
> colour and font weight to go to one of the sets. This will get even more
> use in the next update for handling leftover attributes from the prompt.

I didn't check exactly which of your patches caused this problem, but
i'll reply here.

% zsh -f
% zle_highlight=( default:bg=blue )
[hit enter until you're at the bottom of the terminal]
% cat

Now the whole bottom line is just filled with blue, which it should
not be. Similar artifacts sometimes happen when the completion
continuation prompt is shown ("At Top: Hit space for more..."), and I
also noticed in some circumstances when I hit alt-m to start menu
selection, the selected entry is not showed highlighted until I move
it once or hit ^L, but I don't have a minimal reproducer for those
things.

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: support for italic and faint fonts from region_highlight
  2023-01-19 16:22   ` Mikael Magnusson
@ 2023-01-19 21:18     ` Oliver Kiddle
  2023-01-20  0:22       ` Mikael Magnusson
  0 siblings, 1 reply; 6+ messages in thread
From: Oliver Kiddle @ 2023-01-19 21:18 UTC (permalink / raw)
  To: Mikael Magnusson; +Cc: Zsh workers

Mikael Magnusson wrote:
> I didn't check exactly which of your patches caused this problem, but
> i'll reply here.

Did you check without my patches because I can reproduce the problem
even with 5.8. There is, nevertheless, a patch for it below.
You'll still get the full highlighted line if you leave attributes on at
the end of the prompt but I regard all behaviour associated with doing
that as there for backward compatibility only. I was thinking we should
maybe add zle_highlight tokens for the editarea, messages and statusline
so that there are better alternatives to doing that.

It is something of a curiosity that the following will give you a
highlighted line when it needs to scroll but not when run elsewhere in
the terminal window:

  printf '\e[48;5;189m\ncat\e[49m\n'

Some more obscure terminals don't do this, not sure if that's a bug in
them.

> not be. Similar artifacts sometimes happen when the completion
> continuation prompt is shown ("At Top: Hit space for more..."), and I
> also noticed in some circumstances when I hit alt-m to start menu
> selection, the selected entry is not showed highlighted until I move
> it once or hit ^L, but I don't have a minimal reproducer for those
> things.

All the attribute handling in complist is very much completely separate
code that I haven't touched. The group descriptions do use prompt
sequences but it is otherwise mostly based on the LS_COLOURS compatible
format instead of using the zattr type. It is still certainly possible
I've introduced something there and, either way, a minimal reproducer
would definitely help. Also mention the value of $TERM, the terminal and
what OS/termcap implementation you have. My setup doesn't ever involve
the completion continuation prompt you describe, at least not at the
top. I've seen glitches in the completion display in the past so there
may be old lingering bugs.

Oliver

diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 686c6f5b4..571800a18 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -2069,9 +2069,9 @@ trashzle(void)
 	trashedzle = 1;
 	zrefresh();
 	showinglist = sl;
-	moveto(nlnct, 0);
 	treplaceattrs(prompt_attr);
 	applytextattributes(0);
+	moveto(nlnct, 0);
 	if (clearflag && tccan(TCCLEAREOD)) {
 	    tcout(TCCLEAREOD);
 	    clearflag = listshown = 0;


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: support for italic and faint fonts from region_highlight
  2023-01-19 21:18     ` Oliver Kiddle
@ 2023-01-20  0:22       ` Mikael Magnusson
  2023-02-08 22:52         ` Oliver Kiddle
  0 siblings, 1 reply; 6+ messages in thread
From: Mikael Magnusson @ 2023-01-20  0:22 UTC (permalink / raw)
  To: Oliver Kiddle; +Cc: Zsh workers

On 1/19/23, Oliver Kiddle <opk@zsh.org> wrote:
> Mikael Magnusson wrote:
>> I didn't check exactly which of your patches caused this problem, but
>> i'll reply here.
>
> Did you check without my patches because I can reproduce the problem
> even with 5.8.

I only checked in another terminal window I had open since some time
ago and couldn't reproduce it there, I've also only started noticing
very recently and quite often so it seems weird to me that it would
have been present before...

> There is, nevertheless, a patch for it below.
> You'll still get the full highlighted line if you leave attributes on at
> the end of the prompt but I regard all behaviour associated with doing
> that as there for backward compatibility only. I was thinking we should
> maybe add zle_highlight tokens for the editarea, messages and statusline
> so that there are better alternatives to doing that.
>
> It is something of a curiosity that the following will give you a
> highlighted line when it needs to scroll but not when run elsewhere in
> the terminal window:
>
>   printf '\e[48;5;189m\ncat\e[49m\n'

This is probably because when a new line scrolls in, it is initially
filled with the current background color.

> Some more obscure terminals don't do this, not sure if that's a bug in
> them.
>
>> not be. Similar artifacts sometimes happen when the completion
>> continuation prompt is shown ("At Top: Hit space for more..."), and I
>> also noticed in some circumstances when I hit alt-m to start menu
>> selection, the selected entry is not showed highlighted until I move
>> it once or hit ^L, but I don't have a minimal reproducer for those
>> things.
>
> All the attribute handling in complist is very much completely separate
> code that I haven't touched. The group descriptions do use prompt
> sequences but it is otherwise mostly based on the LS_COLOURS compatible
> format instead of using the zattr type. It is still certainly possible
> I've introduced something there and, either way, a minimal reproducer
> would definitely help. Also mention the value of $TERM, the terminal and
> what OS/termcap implementation you have. My setup doesn't ever involve
> the completion continuation prompt you describe, at least not at the
> top. I've seen glitches in the completion display in the past so there
> may be old lingering bugs.

I'll keep an eye out if I can figure out some pattern to the other
oddities, and try to come up with something minimal. I didn't mention
my terminal for the first problem because it happened in every
terminal I tried (urxvt, and xterm :). I'll make sure to mention these
details next time though.

Tha patch seems to fix my blue problems (but X04 is unhappy). Thanks!

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: support for italic and faint fonts from region_highlight
  2023-01-20  0:22       ` Mikael Magnusson
@ 2023-02-08 22:52         ` Oliver Kiddle
  0 siblings, 0 replies; 6+ messages in thread
From: Oliver Kiddle @ 2023-02-08 22:52 UTC (permalink / raw)
  To: Mikael Magnusson; +Cc: Zsh workers

On 20 Jan, Mikael Magnusson wrote:
> Tha patch seems to fix my blue problems (but X04 is unhappy). Thanks!

This requires a change to the zpty_line() function which is one of the
functions handling the tests. With the earlier patch, it now clears the
attributes after the first \r. So stripping [[:space:]]## from the end
of REPLY was leaving the \r\e[0m in $REPLY.

Bart wrote:
> In a shell running in an emacs buffer, I get ...

Given that for TERM=dumb it is quite valid for %s and %u to be empty,
the test can't rely on that so I've removed the two -n conditions in the
test. This does slightly limit the scope of what is being tested: I took
care that ${(%):-%s} does give you the disable standout sequence despite
not having turned it on before.

The patch also does some handling for leaving attributes on at the end
of zstyle ':completion:*:descriptions' format
That was possible before but with behaviour that can only be described
as a mess. Turning them off explicitly solves problems.

Sorry for having been slow to address these things.

Oliver

diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index 8bdf1bb29..9cb89a60d 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -1305,6 +1305,8 @@ compprintfmt(char *fmt, int n, int dopr, int doesc, int ml, int *stop)
 	}
     }
     if (dopr) {
+	treplaceattrs(0);
+	applytextattributes(0);
         if (!(cc % zterm_columns))
             fputs(" \010", shout);
         cleareol();
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index f94bfce3c..07fac7144 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -2560,6 +2560,8 @@ printfmt(char *fmt, int n, int dopr, int doesc)
 	}
     }
     if (dopr) {
+	treplaceattrs(0);
+	applytextattributes(0);
         if (!(cc % zterm_columns))
             fputs(" \010", shout);
 	if (tccan(TCCLEAREOL))
diff --git a/Test/D01prompt.ztst b/Test/D01prompt.ztst
index a0abb7e1d..55861cca1 100644
--- a/Test/D01prompt.ztst
+++ b/Test/D01prompt.ztst
@@ -261,7 +261,7 @@
   A1=${(%):-%s}
   A2=${(%):-%u}
   A3=${(%):-%s%u%s}
-  [[ $A3 = $A1$A2 && -n $A1 && -n $A2 ]]
+  [[ $A3 = $A1$A2 ]]
 0:Attribute optimisation - preserve initial disabling of attribute but drop useless later one
 
   : ${(%):-%K{blue}}
diff --git a/Test/X04zlehighlight.ztst b/Test/X04zlehighlight.ztst
index 296635bf5..87a59fde5 100644
--- a/Test/X04zlehighlight.ztst
+++ b/Test/X04zlehighlight.ztst
@@ -40,7 +40,7 @@
         # Fix e^Mexit - match ((?)\r(?)), if \2 == \3, then replace with \2
         # otherwise replace with \1 stripped out of leading/trailing [[:space:]]
         REPLY=${REPLY//(#b)((?(#c0,1))$cm(?(#c0,1)))/${${${(M)match[2]:#${match[3]}}:+${match[2]}}:-${${match[1]##[[:space:]]##}%%[[:space:]]##}}}
-        [[ -n "$REPLY" ]] && print -r -- ${${REPLY%%[[:space:]]##}##[[:space:]]##}
+        [[ -n "$REPLY" ]] && print -r -- ${${REPLY%%${~cm}*}##[[:space:]]##}
       done
     }
     zpty_stop() {


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-02-08 22:52 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-04  0:59 PATCH: support for italic and faint fonts from region_highlight Oliver Kiddle
2023-01-06 22:03 ` Oliver Kiddle
2023-01-19 16:22   ` Mikael Magnusson
2023-01-19 21:18     ` Oliver Kiddle
2023-01-20  0:22       ` Mikael Magnusson
2023-02-08 22:52         ` 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).