Steps to reproduce
Open an alacritty terminal.
Run this shell command:
vim -Nu NONE -S <(tee <<'EOF'
vim9script
&termguicolors = true
&t_8u = "\<Esc>[58;2;%lu;%lu;%lum"
&spell = true
highlight SpellBad ctermbg=NONE cterm=underline
'Couleur'->setline(1)
EOF
)
Couleur is not underlined.
Expected behavior
Couleur is underlined in red.
Version of Vim
8.2 Included patches: 1-4796
Environment
Operating system: Ubuntu 20.04.4 LTS
Terminal: alacritty
Value of $TERM: alacritty
Shell: GNU bash, version 5.0.17
Additional context
Regression introduced in patch 8.2.4777.
Before the patch, Vim sent this sequence to the terminal:
^[[4m^[[58;2;255;0;0mCouleur^[[24m
Now, it sends this instead:
^[[4mCouleur^[[24m
Notice that t_8u is now missing.
IOW, Vim ignores the 't_8u' setting in our vimrc, which seems wrong.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Couleur is not underlined.
My bad. It is underlined. But not in red.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I'm on 8.2.4800, and the underline is still not colored in alacritty. In the latter, the value of TERM is alacritty. And the issue disappears if we start Vim with TERM=xterm-256color.
v:termresponse is empty, and the ouput of terminalprops() is:
{'mouse': 'u', 'cursor_style': 'y', 'underline_rgb': 'u', 'cursor_blink_mode': 'y'}
When TERM is xterm-256color, v:termresponse is:
^[[>0;1700;1c
And terminalprops() is:
{'mouse': 's', 'cursor_style': 'y', 'underline_rgb': 'u', 'cursor_blink_mode': 'y'}
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
This fixes the issue:
&t_RB = "\<Esc>]11;?\<C-G>"
&t_RV = "\<Esc>[>c"
Why do we need to set 't_RB' and 't_RV'?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Actually, only 't_RV' needs to be set. But on startup, we need to wait for a redraw, before the underline is colored; that can be fixed by setting 't_RB'.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Well, without t_RV Vim gets no clue about what kind of terminal it's
using. That should be set in the termcap/termlib entry, right?
I would expect Vim to use 't_u8' if it was manually set by the user, regardless of whether Vim knows the identity of the terminal. If it causes issues, the user can clear the option. And it seems that's what happened before the patch 8.2.4777.
I have no idea how alacritty relates to that. Perhaps someone who
actually uses alacritty can make a PR to optimize this.
I hate to include terminal-specific code inside Vim, but it appears it's
currently the only way to deal with this.
I don't think that would fix the issue anyway. The issue is not specific to alacritty. It can also be reproduced in xfce4-terminal when the latter runs tmux. And again, we can "fix" the issue by setting TERM to xterm-256color. In which case, here is the value of v:termresponse:
^[[>84;0;0c
I think the issue is more general. As soon as TERM has a value which Vim does not consider as xterm compatible, it completely ignores how the user set 't_u8' in their vimrc. This seems wrong.
We do not recognize this version yet. If we do, I wonder what we should
do with it? You can see in src/term.c in function
handle_version_response() what different recognized terminals can do.
I will try to have a look at the code, and see if I can gather more information.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
We do not recognize this version yet. If we do, I wonder what we should
do with it?
I guess terminalprops() can tell us which features alacritty support:
{'mouse': 's', 'cursor_style': 'y', 'underline_rgb': 'u', 'cursor_blink_mode': 'y'}
I think this means it supports:
set ttymouse=sgrt_RS (which requests the current cursor style)t_RC (which requests the cursor blink status)Also, the 'underline_rgb': 'u' key-value confirms that Vim doesn't know whether the terminal supports colored underlines. As a result, according to the help, 't_8u' should be made empty:
When "underline_rgb" is not 'y', then |t_8u| will be made empty.
This avoids sending it to xterm, which would clear the colors.
But that's not the case. If we manually set the option, it's not made empty:
# start alacritty
$ vim -Nu NONE --cmd 'let &t_8u = "\<Esc>[58;2;%lu;%lu;%lum"'
:vim9cmd echo &t_8u == ''
false
I guess this means that Vim knows that the option was manually set by the user, and does not want to interfere, which is good. Unfortunately, it still doesn't respect the value. It just ignores it.
Unrelated but there are 2 typos in handle_version_response():
diff --git a/src/term.c b/src/term.c index 0f80e9c40..0603e7b0c 100644 --- a/src/term.c +++ b/src/term.c @@ -4691,7 +4691,7 @@ handle_version_response(int first, int *arg, int argc, char_u *tp) if (version > 20000) version = 0; - // Figure out more if the reeponse is CSI > 99 ; 99 ; 99 c + // Figure out more if the response is CSI > 99 ; 99 ; 99 c if (first == '>' && argc == 3) { int need_flush = FALSE; @@ -4836,7 +4836,7 @@ handle_version_response(int first, int *arg, int argc, char_u *tp) if (*T_8U != NUL && write_t_8u_state == MAYBE) // Did skip writing t_8u, a complete redraw is needed. redraw_later_clear(); - write_t_8u_state = OK; // can otuput t_8u now + write_t_8u_state = OK; // can output t_8u now // Only set 'ttymouse' automatically if it was not set // by the user already.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
That is not true. If the terminal is recognized and known to support
t_u8 then then it can be set.
I don't remember another terminal option for which this extra requirement exists. For example, 't_fd' and 't_fe' enable the focus event tracking feature. And in alacritty, all we need to do is set these options:
let &t_fe = "\<Esc>[?1004h"
let &t_fd = "\<Esc>[?1004l"
execute "set <FocusGained>=\<Esc>[I"
execute "set <FocusLost>=\<Esc>[O"
There is no need to set t_RV. And I haven't found any source code which is specific to alacritty.
It should actually come from termlib/terminfo, but that systems is very much lacking.
Indeed, I had a look at man terminfo and man tmux, and I don't think there is any terminal capability which declares whether a terminal supports colored underlines. Which is why tmux had to introduce the unofficial extension Setulc/ol. I think this feature is just too recent for terminfo.
I can see 3 possibilities:
With regards to 2., I'm not sure whether it will be possible to handle a terminal running screen or tmux, because those report a TERM which obfuscates their true identity (e.g. In an xfce4-terminal running tmux, TERM might be tmux-256color; not xfce).
With regards to 3., here is an attempt at a patch:
diff --git a/runtime/doc/term.txt b/runtime/doc/term.txt index e059d1858..591142d99 100644 --- a/runtime/doc/term.txt +++ b/runtime/doc/term.txt @@ -401,6 +401,9 @@ Added by Vim (there are no standard codes for these): t_8b set background color (R, G, B) *t_8b* *'t_8b'* |xterm-true-color| t_8u set underline color (R, G, B) *t_8u* *'t_8u'* + NOTE: This option is only considered if the terminal is + detected as supporting the feature. If the detection fails, + you might need to set |t_RV|: `execute "set t_RV=\<Esc>[>c"` t_BE enable bracketed paste mode *t_BE* *'t_BE'* |xterm-bracketed-paste| t_BD disable bracketed paste mode *t_BD* *'t_BD'*
However, it seems wrong to set 't_RV' just for colored underlines, because this option might have broader implications.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Setting &t_RV = "\<Esc>[>c" in my vimrc works for me.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
And what was $TERM set to?
According to their comment here, they've found this issue in the xfce4-terminal, when the latter is running tmux. Also in alacritty (regardless of whether tmux is running).
According to their other comment here, their TERM is tmux-256color when running tmux, because of this tmux setting:
set-option -s default-terminal 'tmux-256color'
In alacritty, TERM is alacritty by default.
Now, when TERM is tmux-256color or alacritty, t_RV is not set.
You might want to find out why it isn't set by default.
Here is what :help 't_RV' says:
t_RV request terminal version string (for xterm) t_RV 't_RV'
The response is stored in |v:termresponse|
|xterm-8bit| |'ttymouse'| |xterm-codes|
The "for xterm" part seems to imply that it's only set automatically for xterm, and possibly other terminals which are considered as compatible with xterm.
Take the xfce4-terminal as an example:
# start an xfce4-terminal
$ echo $TERM
xterm-256color
$ vim --clean
:put =execute('filter /RV/ set! termcap') | /Terminal keys/,$ delete
--- Terminal codes ---
t_RV=^[[>c
First, notice that the xfce4-terminal lies by default, and pretends that it's xterm.
Second, notice that t_RV was set automatically.
Now, remember that if we run tmux, TERM is reset to tmux-256color. So, let's make the same experiment, with TERM=tmux-256color:
# start an xfce4-terminal
$ TERM=tmux-256color vim --clean
:put =execute('filter /RV/ set! termcap') | /Terminal keys/,$ delete
--- Terminal codes ---
t_RV=
Notice that this time, t_RV is no longer set automatically; instead, it's empty.
Same thing with alacritty. But this time, it's worse. Because by default, alacritty doesn't pretend to be xterm. TERM says the truth:
# start alacritty
$ echo $TERM
alacritty
$ vim --clean
:put =execute('filter /RV/ set! termcap') | /Terminal keys/,$ delete
--- Terminal codes ---
t_RV=
This means that – for alacritty – the issue doesn't even need tmux to be reproduced.
IOW, the issue seems to be only triggered in terminals which Vim doesn't detect as xterm or xterm-compatible.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
And what was $TERM set to?
| terminal | TERM (no tmux) |
TERM (in tmux) |
|---|---|---|
| alacritty | alacritty |
tmux-256color |
| xfce4-terminal | xterm-256color¹ |
tmux-256color |
¹t_RV was set by default, colored underlines worked out of the box.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Yeah, when $TERM indicates an xterm, the builtin xterm entries are used, which were added because there were so many systems with an incomplete termcap setup. It looks like for other terminals this is also true. Well, I'm not going to add all of them inside Vim, it's like ignoring the actual problem and solving it by hacking a solution into Vim while it should actually be solved elsewhere.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
it should actually be solved elsewhere.
True, terminfo should tell us whether the terminal supports the feature.
FWIW, the kitty terminal seems to avoid all these kinds of issues by setting TERM to xterm-kitty (and by providing its own terminfo description which can be found with $ toe -as | grep xterm-kitty or locate xterm-kitty). It seems that the mere presence of xterm in the value of TERM is enough for Vim to correctly set various terminal options.
I don't see any issue with having to set 't_8u'. I'm just surprised that we also have to set 't_RV', because:
't_RV' is related to xterm; but the latter does not support colored underlines (tested on the latest version, XTerm patch 372)'t_RV' before 8.2.4777't_RV' when 'termguicolors' is reset; only when it's set, which seems inconsistent't_RV' for other features (like bracketed paste, focus events, strikethrough, ...)'t_RV' might come with its own issues (e.g. #4836)It seems that 8.2.4777 waits for a termresponse before outputting 't_8u'. I would have thought that this condition could be removed when 't_u8' is set. Because if it set, then it means that the user expects the feature to work; from their point of view, they've configured the only relevant option to make it work. Why should they configure 't_RV' too? And why only if 'termguicolors' is reset, and only if the terminal was not detected as compatible with xterm?
Anyway, even if we keep 't_RV' as a new requirement, the feature is not documented enough. If a user wants to have colored underlines:
There is already :help termcap-cursor-color. How about we also add :help termcap-underline-color?
diff --git a/runtime/doc/term.txt b/runtime/doc/term.txt index e059d1858..55fb3f65f 100644 --- a/runtime/doc/term.txt +++ b/runtime/doc/term.txt @@ -643,6 +643,39 @@ NOTE: When Vim exits the shape for Normal mode will remain. The shape from before Vim started will not be restored. {not available when compiled without the |+cursorshape| feature} + *termcap-underline-color* +Some terminals support a separate color for underlines. You can find out if +your terminal is among them with these shell commands: > + printf '\e[4m\e[58;5;196mColored Underline\e[m\n' + printf '\e[4m\e[58;2;255;0;0mColored Underline\e[m\n' +The printed text should be underlined in red. The first command uses a color +from the terminal 256-color palette. The second one uses a 24-bit truecolor. +You can find the specification for this feature here: +https://sw.kovidgoyal.net/kitty/underlines/ + +For this feature to work in Vim, you need to set 't_8u' or 't_AU', depending on +whether 'termguicolors' is set or reset. Here is an example when +'termguicolors' is set: > + highlight ColoredUnderline cterm=underline guisp=Red guifg=Green + let &termguicolors = v:true + let &t_8u = "\<Esc>[58;2;%lu;%lu;%lum" + " only necessary to set the `guifg` foreground attribute + let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum" + " only necessary for terminals which are not detected as xterm compatible + let &t_RV = "\<Esc>[>c" + + call setline(1, 'Colored Underline') + match ColoredUnderline /Colored Underline/ + +And here is another example when 'termguicolors' is reset: > + highlight ColoredUnderline cterm=underline ctermul=Red ctermfg=Green + let &t_AU = "\<Esc>[58;5;%dm" + call setline(1, 'Colored Underline') + match ColoredUnderline /Colored Underline/ + +NOTE: Inside tmux, you might also need this setting: > + set-option -as terminal-features '*:usstyle' +< *termcap-title* The 't_ts' and 't_fs' options are used to set the window title if the terminal allows title setting via sending strings. They are sent before and after the
This would make the feature easier to discover, configure, and thus prevent future issues from being opened.
I included a link to the kitty documentation, because:
58): it's the reference 41If the patch is not good enough, I can try to improve it. Although, I'm sick right now; so, I can't work much. Maybe later.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()