Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: PATCH: colour mixing with layers
On 13 Nov, I wrote:
> The following adds an opaque= key for use in zle_highlight/region_highlight
> which will use a blend of the new and inherited colours.
The following additional patch allows this to work together with the
nearcolor module or with colours specified from the 256 colour palette.
There's also some test cases, some of which cover layers or other newer
features.
By the way, where you want text to stand out less, using fg=${.term.bg}
with opacity works quite well.
Oliver
diff --git a/Src/Modules/nearcolor.c b/Src/Modules/nearcolor.c
index d50a6bb44..83d7118b0 100644
--- a/Src/Modules/nearcolor.c
+++ b/Src/Modules/nearcolor.c
@@ -146,7 +146,7 @@ mapRGBto256(int red, int green, int blue)
static int
getnearestcolor(UNUSED(Hookdef dummy), Color_rgb col)
{
- /* we add 1 to the colours so that colour 0 (black) is
+ /* we add 1 to the colours so that colour 0 (default) is
* distinguished from runhookdef() indicating that no
* hook function is registered */
if (tccolours == 256)
diff --git a/Src/prompt.c b/Src/prompt.c
index b1bb87e40..c3c34abf2 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -1764,6 +1764,32 @@ tunsetattrs(zattr newattrs)
txtpendingattrs &= ~TXT_ATTR_BG_MASK;
}
+void
+map256toRGB(zattr *atr, int shift, zattr set24)
+{
+ unsigned colour, red, green, blue;
+
+ if (*atr & set24)
+ return;
+
+ if ((colour = ((*atr >> shift) & 0xff)) < 16)
+ return;
+
+ if (colour >= 16 && colour < 232) {
+ colour -= 16;
+ blue = !!colour * 0x37 + 40 * (colour % 6);
+ colour /= 6;
+ green = !!colour * 0x37 + 40 * (colour % 6);
+ colour /= 6;
+ red = !!colour * 0x37 + 40 * colour;
+ } else {
+ red = green = blue = 8 + 10 * (colour - 232);
+ }
+
+ *atr &= ~((zattr) 0xffffff << shift);
+ *atr |= set24 | (zattr) ((((red << 8) + green) << 8) + blue) << shift;
+}
+
/* Merge two attribute sets.
* secondary is the background base attributes
* primary is attributes to be overlaid, taking precedence.
@@ -1793,7 +1819,7 @@ mixattrs(zattr primary, zattr mask, zattr secondary)
keep = ~replace;
do {
- if ((opacity = (mask >> shift) & 127)) {
+ if (mask & isset && (opacity = (mask >> shift) & 127)) {
zattr argb, brgb;
/* we may know the default colours from the startup query */
zattr aatt = (primary & isset) ? primary : memo_term_color;
@@ -1801,14 +1827,33 @@ mixattrs(zattr primary, zattr mask, zattr secondary)
keep &= ~toset;
replace &= ~toset;
- /* can only mix truecolor */
+
+ if (tccolours == 256) {
+ map256toRGB(&aatt, shift, istrue);
+ map256toRGB(&batt, shift, istrue);
+ }
+
+ /* can only mix if we now have truecolor */
if (aatt & batt & istrue) {
mix |= istrue | isset;
- for (i = 0; i < 3; i++, shift += 8) {
- argb = (aatt >> shift) & 0xff;
- brgb = (batt >> shift) & 0xff;
+ for (i = 0; i < 24; i += 8) {
+ argb = (aatt >> (shift + i)) & 0xff;
+ brgb = (batt >> (shift + i)) & 0xff;
mix |= ((argb * (100 - opacity) + brgb * opacity) / 100)
- << shift;
+ << (shift + i);
+ }
+ if (!truecolor_terminal() && (!empty(GETCOLORATTR->funcs) ||
+ !load_module("zsh/nearcolor", NULL, 1))) {
+ struct color_rgb color = {
+ (mix >> (shift + 16)) & 0xff,
+ (mix >> (shift + 8)) & 0xff,
+ (mix >> shift) & 0xff
+ };
+ int color_idx = runhookdef(GETCOLORATTR, &color) - 1;
+ if (color_idx >= 0) {
+ mix &= ~toset;
+ mix |= isset | ((zattr) color_idx << shift);
+ }
}
} else if (opacity <= 50)
replace |= toset;
@@ -1885,6 +1930,7 @@ match_named_colour(const char **teststrp)
return -1;
}
+/**/
static int
truecolor_terminal()
{
@@ -2011,7 +2057,7 @@ match_highlight(const char *teststr, zattr *on_var, zattr *setmask, int *layer)
found = 1;
/* skip out of range colours but keep scanning attributes */
if (atr != TXT_ERROR) {
- *on_var &= is_fg ? ~TXT_ATTR_FG_MASK : ~TXT_ATTR_BG_MASK;
+ *on_var &= is_fg ? (zattr) ~TXT_ATTR_FG_MASK : (zattr) ~TXT_ATTR_BG_MASK;
*on_var |= atr;
mask |= is_fg ? TXTFGCOLOUR : TXTBGCOLOUR;
}
diff --git a/Test/X04zlehighlight.ztst b/Test/X04zlehighlight.ztst
index ecb309605..bfb3dd135 100644
--- a/Test/X04zlehighlight.ztst
+++ b/Test/X04zlehighlight.ztst
@@ -93,6 +93,46 @@
0:basic region_highlight with 8 colors
>0mCDE|32|true
+ zpty_start
+ zpty_input 'zle-line-pre-redraw() { BUFFER=": abcde" region_highlight=( "2 5 faint,bold" ) }'
+ zpty_input 'zle -N zle-line-pre-redraw'
+ zpty_enable_zle
+ zpty_input $'\C-a'
+ zpty_line 1 p
+ zpty_stop
+0:later highlight attribute takes precedence over earlier one that contradicts
+>0m: 1mabc0mde
+
+ zpty_start
+ zpty_input 'zle-line-pre-redraw() { BUFFER=": abcde" region_highlight=( "2 5 faint,unrecognised,bold" ) }'
+ zpty_input 'zle -N zle-line-pre-redraw'
+ zpty_enable_zle
+ zpty_input $'\C-a'
+ zpty_line 1 p
+ zpty_stop
+0:unrecognised highlight attribute and any subsequent ones ignored
+>0m: 2mabc0mde
+
+ zpty_start
+ zpty_input 'zle-line-pre-redraw() { BUFFER=": abcd" region_highlight=( "2 5 bold" "3 4 nobold" ) }'
+ zpty_input 'zle -N zle-line-pre-redraw'
+ zpty_enable_zle
+ zpty_input $'\C-a'
+ zpty_line 1 p
+ zpty_stop
+0:disable highlight attribute with "no" prefix
+>0m: 1ma0mb1mc0md
+
+ zpty_start
+ zpty_input 'zle-line-pre-redraw() { BUFFER=": abcdefg" region_highlight=( "2 5 faint,layer=14" "3 4 bold,layer=12" ) }'
+ zpty_input 'zle -N zle-line-pre-redraw'
+ zpty_enable_zle
+ zpty_input $'\C-a'
+ zpty_line 1 p
+ zpty_stop
+0:use layers to override precedence of ordering
+>0m: 2mabc0mdefg
+
zpty_start
zpty_input 'rh_widget() { region_highlight+=( "0 4 fg=green memo=someplugin" ); typeset -p region_highlight }'
zpty_input 'zle -N rh_widget'
@@ -160,6 +200,18 @@
0:basic region_highlight with near-color (hex-triplets at input)
>0mCDE|3232|true
+ zpty_start
+ zpty_input 'zmodload zsh/nearcolor'
+ zpty_input 'rh_widget() { BUFFER="true"; region_highlight+=( "0 4 fg=#000000,bg=#ffffff" ); }'
+ zpty_input 'zle -N rh_widget'
+ zpty_input 'bindkey "\C-a" rh_widget'
+ zpty_enable_zle
+ zpty_input $'\C-a' # emits newline, which executes BUFFER="true" command
+ zpty_line 1 p # the line of interest, preserving escapes ("p")
+ zpty_stop
+0:basic region_highlight with near-color using extremes - all black and all white
+>0mCDE|316|BCDE|4231|true
+
zpty_start
zpty_input 'rh_widget() { BUFFER="true"; region_highlight+=( "0 4 fg=green" ); rh2; }'
zpty_input 'rh2() { region_highlight+=( "1 2 fg=red" ); }' # `r' in red; the above line would be too long
@@ -208,6 +260,38 @@
0:zle $widgetname -f nolast
>0m0m: clear-screen
+ zpty_start
+ zpty_input '.term.extensions[(r)truecolor]=-truecolor'
+ zpty_input 'zle-line-pre-redraw() { BUFFER=": abc" region_highlight=( "2 4 fg=230" "3 5 fg=132,opacity=50%" ) }'
+ zpty_input 'zle -N zle-line-pre-redraw'
+ zpty_enable_zle
+ zpty_input $'\C-a'
+ zpty_line 1 p
+ zpty_stop
+0:overlapping backgrounds with opacity and nearcolor
+>0m: CDE|3230|aCDE|3181|bCDE|3132|c
+
+ zpty_start
+ zpty_input '.term.extensions[(r)truecolor]=-truecolor'
+ zpty_input 'zle-line-pre-redraw() { BUFFER=": abcde" region_highlight=( "3 4 fg=149,opacity=80" "5 6 fg=182,opacity=49" ) }'
+ zpty_input 'zle -N zle-line-pre-redraw'
+ zpty_enable_zle
+ zpty_input $'\C-a'
+ zpty_line 1 p
+ zpty_stop
+0:opacity with an unknown base colour
+>0m: aCDE|3149|b0mcde
+
+ zpty_start
+ zpty_input 'zle-line-pre-redraw() { BUFFER=": abcde" region_highlight=( "2 7 bg=#d5e7c2,fg=#00005f,bold" "4 6 bg=#e0ff50,fg=#e00020,opacity=60/40" ) }'
+ zpty_input 'zle -N zle-line-pre-redraw'
+ zpty_enable_zle
+ zpty_input $'\C-a'
+ zpty_line 1 p
+ zpty_stop
+0:foreground and background opacity
+>0m: 1m38;2;0;0;95m48;2;213;231;194mab38;2;134;0;57m48;2;217;240;148mcd38;2;0;0;95m48;2;213;231;194me
+
%clean
zmodload -ui zsh/zpty
Messages sorted by:
Reverse Date,
Date,
Thread,
Author