From c01479a2ede78b9b53057322e4b9f5bd0a103a00 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 10 Jan 2023 20:57:03 +0100 Subject: 51280: add support for italic and faint fonts in the line editor --- ChangeLog | 4 ++++ Doc/Zsh/zle.yo | 10 +++++++++- Src/Zle/zle_refresh.c | 26 +++----------------------- Src/init.c | 19 ++++++++++++++++++- Src/prompt.c | 39 ++++++++++++++++++++++++++++++++++++-- Src/zsh.h | 52 +++++++++++++++++++++++++++++---------------------- 6 files changed, 101 insertions(+), 49 deletions(-) diff --git a/ChangeLog b/ChangeLog index b3518f1bf..9e2938bf8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-01-10 Oliver Kiddle + * 51280: Doc/Zsh/zle.yo, Src/Zle/zle_refresh.c, Src/init.c, + Src/prompt.c, Src/zsh.h: add support for italic and faint + fonts in the line editor + * 51258, 51272: Src/Modules/watch.c, Src/Zle/complist.c, Src/Zle/zle.h, Src/Zle/zle_main.c, Src/Zle/zle_refresh.c, Src/Zle/zle_tricky.c, Src/Zle/zle_utils.c, Src/builtin.c, 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 ae8e5c109..d40400886 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 -- cgit 1.4.1