Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: [PATCH] prompt, etc: trust when termcap says we have no colour
- X-seq: zsh-workers 54977
- From: dana <dana@xxxxxxx>
- To: "Oliver Kiddle" <opk@xxxxxxx>
- Cc: zsh-workers@xxxxxxx
- Subject: Re: [PATCH] prompt, etc: trust when termcap says we have no colour
- Date: Wed, 15 Jul 2026 20:31:51 -0500
- Archived-at: <https://zsh.org/workers/54977>
- Feedback-id: i9be146f9:Fastmail
- In-reply-to: <35831-1776906408.734956@X0gm.2xts.6Xm->
- List-id: <zsh-workers.zsh.org>
- References: <10895965-af97-4800-ba2e-cf65b9b6e25f@app.fastmail.com> <35831-1776906408.734956@X0gm.2xts.6Xm->
On Wed 22 Apr 2026, at 20:06, Oliver Kiddle wrote:
> However, I don't follow the logic behind using this as a heuristic for
> italic and faint.
we discussed this on irc a few times. oliver said it's not uncommon for
him to see italic missing from termcap where it should be supported
at his suggestion i was going to replace my 'heuristic' by a hard-coded
exemption for the linux console. but at the last minute i thought to
check console_codes(4) and it actually says that dim, italic, and
underscore are 'simulated with color on a color display'
so it's meant to look like that after all
here's a revised patch:
- leave polyfills alone, since TERM=dumb ignores them via another path
and i don't have evidence that it causes problems for anything else
- avoid setting colours also if the terminal is unknown
- remove ZLS_COLORS override. comptest uses list colours to add 'tags'
to the match list. we can probably do this in a way that supports that
use case but it needs more thought
dana
diff --git a/Doc/Zsh/prompt.yo b/Doc/Zsh/prompt.yo
index d68f00826..3154901b7 100644
--- a/Doc/Zsh/prompt.yo
+++ b/Doc/Zsh/prompt.yo
@@ -222,6 +222,14 @@ and may work if the system supports them.
enditem()
subsect(Visual Effects)
+These sequences affect the way text is displayed. Where applicable,
+their behaviour depends on the capabilities supported by the terminal
+type currently in use (normally dictated by the tt(TERM) environment
+variable). For example, the terminal type tt(dumb) doesn't support
+underline, so `tt(TERM=dumb print -P %Utest%u)' prints the unformatted
+string `tt(test)'. This can be exploited to conditionally disable
+colours and styling in scripts.
+
startitem()
item(tt(%B) LPAR()tt(%b)RPAR())(
Start (stop) boldface mode.
diff --git a/Src/init.c b/Src/init.c
index f36bc332b..55fbf5cf3 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -790,6 +790,8 @@ init_term(void)
static char termbuf[2048]; /* the termcap buffer */
#endif
+ termflags &= ~TERM_NOCOLOUR;
+
if (!*term) {
termflags |= TERM_UNKNOWN;
return 0;
@@ -838,6 +840,8 @@ init_term(void)
tccolumns = tgetnum("co");
tccolours = tgetnum("Co");
+ termflags |= tccolours <= 0 ? TERM_NOCOLOUR : 0;
+
/* if there's no termcap entry for cursor up, use single line mode: *
* this is flagged by termflags which is examined in zle_refresh.c *
*/
@@ -890,6 +894,8 @@ init_term(void)
/* rprompt_indent = ((hasam && !hasbw) || hasye || !tccan(TCLEFT)); */
/* if there's no termcap entry for italics, use CSI 3 m */
+ /* note that these have no effect on TERM=dumb due to the check for */
+ /* TERM_NOUP in tsetcap() */
if (!tccan(TCITALICSBEG)) {
zsfree(tcstr[TCITALICSBEG]);
tcstr[TCITALICSBEG] = ztrdup("\033[3m");
diff --git a/Src/prompt.c b/Src/prompt.c
index 7db074da8..9546b45cd 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -2444,6 +2444,9 @@ set_colour_attribute(zattr atr, int fg_bg, int flags)
int colour, tc, def, use_truecolor;
int is_default_zle_highlight = 1;
+ if (termflags & (TERM_UNKNOWN | TERM_NOCOLOUR))
+ return;
+
if (fg_bg == COL_SEQ_FG) {
colour = txtchangeget(atr, TXT_ATTR_FG_COL);
tc = TCFGCOLOUR;
diff --git a/Src/zsh.h b/Src/zsh.h
index 1f1ecc3e6..d2c1e026e 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -2633,6 +2633,7 @@ struct ttyinfo {
#define TERM_NOUP 0x04 /* terminal has no up capability */
#define TERM_SHORT 0x08 /* terminal is < 3 lines high */
#define TERM_NARROW 0x10 /* terminal is < 3 columns wide */
+#define TERM_NOCOLOUR 0x20 /* terminal is known but has no colour */
/* interesting termcap strings */
diff --git a/Test/D01prompt.ztst b/Test/D01prompt.ztst
index f42e19714..1719ef02c 100644
--- a/Test/D01prompt.ztst
+++ b/Test/D01prompt.ztst
@@ -283,3 +283,18 @@
-fD:RPS1 and RPROMPT are aliases (regression from 5.0.6) (workers/49600)
>foo foo
>bar bar
+
+ if
+ zmodload -s zsh/terminfo &&
+ ( TERM=xterm-color; (( terminfo[colors] >= 8 )) ) &&
+ ( TERM=dumb; (( terminfo[colors] <= 0 )) )
+ then
+ str='%B %S %U %1F %2K test %k %f %u %s %b'
+ for 1 in xterm-color dumb not-a-real-terminal; do (
+ TERM=$1 print -Pr - $str | grep -q $'\e' && print -r - $1 has colours
+ ) 2> /dev/null; done
+ else
+ ZTST_skip="missing terminfo module or can't trust database"
+ fi
+-:unknown/dumb terminal suppresses text style attributes
+>xterm-color has colours
Messages sorted by:
Reverse Date,
Date,
Thread,
Author