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

[PATCH] prompt, etc: trust when termcap says we have no colour



we ignore or override what termcap says about certain text-style
capabilities in a few places. i assume (?) this is because all modern
terminals support these capabilities and we want it to Just Work even if
TERM is incorrect or termcap is broken. but there are cases where you
really *don't* want them. for example you might like to use TERM=dumb to
disable prompt formatting. currently this works for some styles but not
others

my proposal: if we have a good termcap entry, trust when it says there
are no colours. also use this as a heuristic to decide whether it's ok
to polyfill some capabilities like italics

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/Zle/complist.c b/Src/Zle/complist.c
index 9c26b6f99..ddf7e1a70 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -510,8 +510,9 @@ getcols(void)
     max_caplen = lr_caplen = 0;
     mcolors.flags = 0;
     queue_signals();
-    if (!(s = getsparam_u("ZLS_COLORS")) &&
-	!(s = getsparam_u("ZLS_COLOURS"))) {
+    if ((termflags & TERM_NOCOLOUR) ||
+	(!(s = getsparam_u("ZLS_COLORS")) &&
+	!(s = getsparam_u("ZLS_COLOURS")))) {
 	for (i = 0; i < NUM_COLS; i++)
 	    mcolors.files[i] = filecol("");
 	mcolors.pats = NULL;
diff --git a/Src/init.c b/Src/init.c
index 7c3b82461..8f7c27b47 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -774,6 +774,8 @@ init_term(void)
     static char termbuf[2048];	/* the termcap buffer */
 #endif
 
+    termflags &= ~TERM_NOCOLOUR;
+
     if (!*term) {
 	termflags |= TERM_UNKNOWN;
 	return 0;
@@ -822,6 +824,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  *
 	 */
@@ -874,17 +878,18 @@ init_term(void)
 	/* rprompt_indent = ((hasam && !hasbw) || hasye || !tccan(TCLEFT)); */
 
 	/* if there's no termcap entry for italics, use CSI 3 m */
-	if (!tccan(TCITALICSBEG)) {
+	/* as a heuristic, only do this if we have colours */
+	if (!tccan(TCITALICSBEG) && !(termflags & TERM_NOCOLOUR)) {
 	    zsfree(tcstr[TCITALICSBEG]);
 	    tcstr[TCITALICSBEG] = ztrdup("\033[3m");
 	    tclen[TCITALICSBEG] = 4;
 	}
-	if (!tccan(TCITALICSEND)) {
+	if (!tccan(TCITALICSEND) && !(termflags & TERM_NOCOLOUR)) {
 	    zsfree(tcstr[TCITALICSEND]);
 	    tcstr[TCITALICSEND] = ztrdup("\033[23m");
 	    tclen[TCITALICSEND] = 5;
 	}
-	if (!tccan(TCFAINTBEG)) {
+	if (!tccan(TCFAINTBEG) && !(termflags & TERM_NOCOLOUR)) {
 	    zsfree(tcstr[TCFAINTBEG]);
 	    tcstr[TCFAINTBEG] = ztrdup("\033[2m");
 	    tclen[TCFAINTBEG] = 4;
diff --git a/Src/prompt.c b/Src/prompt.c
index 8325bfe2c..1d0ec42ef 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_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 dd58c0816..779535804 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -2635,6 +2635,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..63c253876 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; do
+      TERM=$1 print -Pr - $str | grep -q $'\e' && print -r - $1 has colours
+    done
+  else
+    ZTST_skip="missing terminfo module or can't trust database"
+  fi
+-:dumb terminal suppresses text style attributes
+>xterm-color has colours




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