Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH] Support true colours via termcap interface

Dear all,

ncurses recently added support for 24 bit colour terminals. It kind of
works out of the box with zsh, except for the hardcoded 256 colour
limit in match_colour. I think previously you could get away with
using colours 0-7 when tccolours is less than 8, which now would emit
the default text escape sequence. I don't think this change should
cause any trouble, but if the old behaviour needs to be preserved, it
can be done by changing the corresponding line below to
if (colour < 0 || (colour > 7 && colour >= tccolours))

I also let the termcap interface handle the recently implemented true
colours, which required only a minimal change as ncurses' terminfo
entries use the same encoding as Oliver's implementation. For colours
0-7, however, one has to bypass the termcap interface as the terminfo
entries specify for that range the standard ansi colours.

I didn't touch the hardcoded escape sequence for true colours because,
although there is some dispute on how the escape sequence should look
like, it seems that this sequence is recognized by all terminals with
true colours support. Please note that the disagreement revolves
around whether semicolons or colons should be used as separators, so
if the situation changes, the current approach of being able to
customize only the start and the end of the escape sequence would need
to be extended to let users specify the separator.

In summary, the patch enables the following:

$ TERM=xterm-direct print -P %F{'#ffcc33'} | cat -v

$ TERM=xterm-direct print -P %F{16763955} | cat -v

which is what tput delivers:

$ TERM=xterm-direct tput setaf 16763955 | cat -v

Best regards,

diff --git a/Src/prompt.c b/Src/prompt.c
index f2b3f161e..589ee7664 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -1652,8 +1652,10 @@ match_colour(const char **teststrp, int is_fg, int colour)
 	    colour = runhookdef(GETCOLORATTR, &color) - 1;
 	    if (colour == -1) { /* no hook function added, try true color (24-bit) */
 		colour = (((color.red << 8) + color.green) << 8) + color.blue;
-		return on | (is_fg ? TXT_ATTR_FG_24BIT : TXT_ATTR_BG_24BIT) |
-			(zattr)colour << shft;
+                if (tccolours != 0x1000000 || colour < 8) {
+                        return on | (is_fg ? TXT_ATTR_FG_24BIT :
+                                     TXT_ATTR_BG_24BIT) | (zattr)colour << shft;
+                }
 	    } else if (colour <= -2) {
 		return TXT_ERROR;
@@ -1668,7 +1670,7 @@ match_colour(const char **teststrp, int is_fg, int colour)
 	else {
 	    colour = (int)zstrtol(*teststrp, (char **)teststrp, 10);
-	    if (colour < 0 || colour >= 256)
+	    if (colour < 0 || colour >= tccolours)
 		return TXT_ERROR;

Messages sorted by: Reverse Date, Date, Thread, Author