zsh-workers
 help / color / mirror / code / Atom feed
From: Oliver Kiddle <opk@zsh.org>
To: Zsh workers <zsh-workers@zsh.org>
Subject: Re: PATCH: support for italic and faint fonts from region_highlight
Date: Fri, 06 Jan 2023 23:03:21 +0100	[thread overview]
Message-ID: <2468-1673042601.684998@j4zI.qkM4.yrwt> (raw)
In-Reply-To: <36223-1672793943.791824@SLuG.9t5a.jH-P>

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


  reply	other threads:[~2023-01-06 22:03 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-04  0:59 Oliver Kiddle
2023-01-06 22:03 ` Oliver Kiddle [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2468-1673042601.684998@j4zI.qkM4.yrwt \
    --to=opk@zsh.org \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).