From d232c0b209ee447ec8b40be4aacb59d339d92277 Mon Sep 17 00:00:00 2001 From: Adam Schwalm Date: Mon, 19 Dec 2022 18:57:11 -0600 Subject: [PATCH 2/2] Allow user-enabled tty underline style/color Users can now explicitly enable underline style or color support, even if their terminal's does not seem to support it. The control squence used when a user enables the underline color/style feature this way is the most widely supported sequence currently. For underline style, CSI 4 : m is used and for underline color, CSI 58 : 2 :: : : m is used (if the terminal supports 'true' color. Otherwise, the color pallete version is used: 58 : 5 : m). --- src/term.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/term.c b/src/term.c index 306c57338b..ffc5ca6fe0 100644 --- a/src/term.c +++ b/src/term.c @@ -115,6 +115,10 @@ #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } whil NC_PROTECT = 1 << 7 }; +static bool term_is_24bit (struct tty_display_info *tty) +{ + return tty->TN_max_colors == 16777216; +} enum tty_underline_type { @@ -2280,6 +2284,56 @@ DEFUN ("controlling-tty-p", Fcontrolling_tty_p, Scontrolling_tty_p, 0, 1, 0, return (t && !strcmp (t->display_info.tty->name, DEV_TTY) ? Qt : Qnil); } +DEFUN ("tty-allow-underline-color", Ftty_allow_underline_color, + Stty_allow_underline_color, 0, 1, 0, + doc: /* Declare that the tty used by TERMINAL supports underline colors. +This is used to override the terminfo data, for certain terminals that +support underline with colors that differ from the foreground or background +colors, but do not specify that support in a standard way. This function has +no effect if used on a non-tty terminal. + +TERMINAL can be a terminal object, a frame or nil (meaning the +selected frame's terminal). This function always returns nil if +TERMINAL does not refer to a text terminal. */) + (Lisp_Object terminal) +{ + struct terminal *t = decode_live_terminal (terminal); + + if (t->type == output_termcap) + { + if (!t->display_info.tty->TS_set_underline_color) + { + if (term_is_24bit (t->display_info.tty)) + t->display_info.tty->TS_set_underline_color = "\033[58:2::%p1%{65536}%/%d:%p1%{256}%/%{255}%&%d:%p1%{255}%&%d%;m"; + else + t->display_info.tty->TS_set_underline_color = "\033[58:5:%dm"; + } + + if (!t->display_info.tty->TS_set_underline_color) + t->display_info.tty->TS_reset_underline_color = "\033[59m"; + } + return Qnil; +} + +DEFUN ("tty-allow-underline-style", Ftty_allow_underline_style, + Stty_allow_underline_style, 0, 1, 0, + doc: /* Declare that the tty used by TERMINAL supports underline styles. +This is used to override the terminfo data, for certain terminals that +support underline styles such as 'waves', but do not specify that support +in a standard way. This function has no effect if used on a non-tty terminal. + +TERMINAL can be a terminal object, a frame or nil (meaning the +selected frame's terminal). This function always returns nil if +TERMINAL does not refer to a text terminal. */) + (Lisp_Object terminal) +{ + struct terminal *t = decode_live_terminal (terminal); + + if (t->type == output_termcap && !t->display_info.tty->TS_set_underline_style) + t->display_info.tty->TS_set_underline_style = "\033[4:%p1%dm"; + return Qnil; +} + DEFUN ("tty-no-underline", Ftty_no_underline, Stty_no_underline, 0, 1, 0, doc: /* Declare that the tty used by TERMINAL does not handle underlining. This is used to override the terminfo data, for certain terminals that @@ -4671,6 +4725,8 @@ syms_of_term (void) defsubr (&Stty_display_color_p); defsubr (&Stty_display_color_cells); + defsubr (&Stty_allow_underline_color); + defsubr (&Stty_allow_underline_style); defsubr (&Stty_no_underline); defsubr (&Stty_type); defsubr (&Scontrolling_tty_p); -- 2.39.0