mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 18:55:14 -07:00
feat(tui): query extended underline support using DECRQSS (#28052)
This commit is contained in:
parent
7168000b53
commit
4ee9e58056
@ -384,13 +384,13 @@ if tty then
|
|||||||
-- attributes, so there should be no attributes in the list.
|
-- attributes, so there should be no attributes in the list.
|
||||||
local attrs = vim.split(decrqss, ';')
|
local attrs = vim.split(decrqss, ';')
|
||||||
if #attrs ~= 1 and (#attrs ~= 2 or attrs[1] ~= '0') then
|
if #attrs ~= 1 and (#attrs ~= 2 or attrs[1] ~= '0') then
|
||||||
return true
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- The returned SGR sequence should begin with 48:2
|
-- The returned SGR sequence should begin with 48:2
|
||||||
local sgr = attrs[#attrs]:match('^48:2:([%d:]+)$')
|
local sgr = attrs[#attrs]:match('^48:2:([%d:]+)$')
|
||||||
if not sgr then
|
if not sgr then
|
||||||
return true
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- The remaining elements of the SGR sequence should be the 3 colors
|
-- The remaining elements of the SGR sequence should be the 3 colors
|
||||||
@ -422,7 +422,8 @@ if tty then
|
|||||||
if os.getenv('TMUX') then
|
if os.getenv('TMUX') then
|
||||||
decrqss = string.format('\027Ptmux;%s\027\\', decrqss:gsub('\027', '\027\027'))
|
decrqss = string.format('\027Ptmux;%s\027\\', decrqss:gsub('\027', '\027\027'))
|
||||||
end
|
end
|
||||||
io.stdout:write(string.format('\027[48;2;%d;%d;%dm%s', r, g, b, decrqss))
|
-- Reset attributes first, as other code may have set attributes.
|
||||||
|
io.stdout:write(string.format('\027[0m\027[48;2;%d;%d;%dm%s', r, g, b, decrqss))
|
||||||
|
|
||||||
timer:start(1000, 0, function()
|
timer:start(1000, 0, function()
|
||||||
-- Delete the autocommand if no response was received
|
-- Delete the autocommand if no response was received
|
||||||
|
@ -553,6 +553,13 @@ static void handle_term_response(TermInput *input, const TermKeyKey *key)
|
|||||||
if (termkey_interpret_string(input->tk, key, &str) == TERMKEY_RES_KEY) {
|
if (termkey_interpret_string(input->tk, key, &str) == TERMKEY_RES_KEY) {
|
||||||
assert(str != NULL);
|
assert(str != NULL);
|
||||||
|
|
||||||
|
// Handle DECRQSS SGR response for the query from tui_query_extended_underline().
|
||||||
|
// Some terminals include "0" in the attribute list unconditionally; others don't.
|
||||||
|
if (key->type == TERMKEY_TYPE_DCS
|
||||||
|
&& (strnequal(str, S_LEN("1$r4:3m")) || strnequal(str, S_LEN("1$r0;4:3m")))) {
|
||||||
|
tui_enable_extended_underline(input->tui_data);
|
||||||
|
}
|
||||||
|
|
||||||
// Send an event to nvim core. This will update the v:termresponse variable
|
// Send an event to nvim core. This will update the v:termresponse variable
|
||||||
// and fire the TermResponse event
|
// and fire the TermResponse event
|
||||||
MAXSIZE_TEMP_ARRAY(args, 2);
|
MAXSIZE_TEMP_ARRAY(args, 2);
|
||||||
|
@ -225,6 +225,26 @@ void tui_handle_term_mode(TUIData *tui, TermMode mode, TermModeState state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Query the terminal emulator to see if it supports extended underline.
|
||||||
|
static void tui_query_extended_underline(TUIData *tui)
|
||||||
|
{
|
||||||
|
// Try to set an undercurl using an SGR sequence, followed by a DECRQSS SGR query.
|
||||||
|
// Reset attributes first, as other code may have set attributes.
|
||||||
|
out(tui, S_LEN("\x1b[0m\x1b[4:3m\x1bP$qm\x1b\\"));
|
||||||
|
tui->print_attr_id = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tui_enable_extended_underline(TUIData *tui)
|
||||||
|
{
|
||||||
|
if (tui->unibi_ext.set_underline_style == -1) {
|
||||||
|
tui->unibi_ext.set_underline_style = (int)unibi_add_ext_str(tui->ut, "ext.set_underline_style",
|
||||||
|
"\x1b[4:%p1%dm");
|
||||||
|
}
|
||||||
|
// Only support colon syntax. #9270
|
||||||
|
tui->unibi_ext.set_underline_color = (int)unibi_add_ext_str(tui->ut, "ext.set_underline_color",
|
||||||
|
"\x1b[58:2::%p1%d:%p2%d:%p3%dm");
|
||||||
|
}
|
||||||
|
|
||||||
/// Query the terminal emulator to see if it supports Kitty's keyboard protocol.
|
/// Query the terminal emulator to see if it supports Kitty's keyboard protocol.
|
||||||
///
|
///
|
||||||
/// Write CSI ? u followed by a primary device attributes request (CSI c). If
|
/// Write CSI ? u followed by a primary device attributes request (CSI c). If
|
||||||
@ -306,6 +326,7 @@ static void terminfo_start(TUIData *tui)
|
|||||||
tui->unibi_ext.reset_scroll_region = -1;
|
tui->unibi_ext.reset_scroll_region = -1;
|
||||||
tui->unibi_ext.set_cursor_style = -1;
|
tui->unibi_ext.set_cursor_style = -1;
|
||||||
tui->unibi_ext.reset_cursor_style = -1;
|
tui->unibi_ext.reset_cursor_style = -1;
|
||||||
|
tui->unibi_ext.set_underline_style = -1;
|
||||||
tui->unibi_ext.set_underline_color = -1;
|
tui->unibi_ext.set_underline_color = -1;
|
||||||
tui->unibi_ext.sync = -1;
|
tui->unibi_ext.sync = -1;
|
||||||
tui->out_fd = STDOUT_FILENO;
|
tui->out_fd = STDOUT_FILENO;
|
||||||
@ -390,6 +411,11 @@ static void terminfo_start(TUIData *tui)
|
|||||||
// mode 2026
|
// mode 2026
|
||||||
tui_request_term_mode(tui, kTermModeSynchronizedOutput);
|
tui_request_term_mode(tui, kTermModeSynchronizedOutput);
|
||||||
|
|
||||||
|
if (tui->unibi_ext.set_underline_style == -1) {
|
||||||
|
// Query the terminal to see if it supports extended underline.
|
||||||
|
tui_query_extended_underline(tui);
|
||||||
|
}
|
||||||
|
|
||||||
// Query the terminal to see if it supports Kitty's keyboard protocol
|
// Query the terminal to see if it supports Kitty's keyboard protocol
|
||||||
tui_query_kitty_keyboard(tui);
|
tui_query_kitty_keyboard(tui);
|
||||||
|
|
||||||
@ -2331,14 +2357,10 @@ static void augment_terminfo(TUIData *tui, const char *term, int vte_version, in
|
|||||||
if (vte_version >= 5102 || konsolev >= 221170
|
if (vte_version >= 5102 || konsolev >= 221170
|
||||||
|| (ext_bool_Su != -1 && unibi_get_ext_bool(ut, (size_t)ext_bool_Su))
|
|| (ext_bool_Su != -1 && unibi_get_ext_bool(ut, (size_t)ext_bool_Su))
|
||||||
|| (weztermv != NULL && strcmp(weztermv, "20210203-095643") > 0)) {
|
|| (weztermv != NULL && strcmp(weztermv, "20210203-095643") > 0)) {
|
||||||
tui->unibi_ext.set_underline_style = (int)unibi_add_ext_str(ut, "ext.set_underline_style",
|
tui_enable_extended_underline(tui);
|
||||||
"\x1b[4:%p1%dm");
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
if (tui->unibi_ext.set_underline_style != -1) {
|
tui_enable_extended_underline(tui);
|
||||||
// Only support colon syntax. #9270
|
|
||||||
tui->unibi_ext.set_underline_color = (int)unibi_add_ext_str(ut, "ext.set_underline_color",
|
|
||||||
"\x1b[58:2::%p1%d:%p2%d:%p3%dm");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!kitty && (vte_version == 0 || vte_version >= 5400)) {
|
if (!kitty && (vte_version == 0 || vte_version >= 5400)) {
|
||||||
|
@ -1588,6 +1588,35 @@ describe('TUI', function()
|
|||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- Note: libvterm doesn't support colored underline or undercurl.
|
||||||
|
it('supports undercurl and underdouble when run in :terminal', function()
|
||||||
|
screen:set_default_attr_ids({
|
||||||
|
[1] = { reverse = true },
|
||||||
|
[2] = { bold = true, reverse = true },
|
||||||
|
[3] = { bold = true },
|
||||||
|
[4] = { foreground = 12 },
|
||||||
|
[5] = { undercurl = true },
|
||||||
|
[6] = { underdouble = true },
|
||||||
|
})
|
||||||
|
child_session:request('nvim_set_hl', 0, 'Visual', { undercurl = true })
|
||||||
|
feed_data('ifoobar\027V')
|
||||||
|
screen:expect([[
|
||||||
|
{5:fooba}{1:r} |
|
||||||
|
{4:~ }|*3
|
||||||
|
{2:[No Name] [+] }|
|
||||||
|
{3:-- VISUAL LINE --} |
|
||||||
|
{3:-- TERMINAL --} |
|
||||||
|
]])
|
||||||
|
child_session:request('nvim_set_hl', 0, 'Visual', { underdouble = true })
|
||||||
|
screen:expect([[
|
||||||
|
{6:fooba}{1:r} |
|
||||||
|
{4:~ }|*3
|
||||||
|
{2:[No Name] [+] }|
|
||||||
|
{3:-- VISUAL LINE --} |
|
||||||
|
{3:-- TERMINAL --} |
|
||||||
|
]])
|
||||||
|
end)
|
||||||
|
|
||||||
it('in nvim_list_uis()', function()
|
it('in nvim_list_uis()', function()
|
||||||
-- $TERM in :terminal.
|
-- $TERM in :terminal.
|
||||||
local exp_term = is_os('bsd') and 'builtin_xterm' or 'xterm-256color'
|
local exp_term = is_os('bsd') and 'builtin_xterm' or 'xterm-256color'
|
||||||
|
Loading…
Reference in New Issue
Block a user