diff --git a/runtime/doc/tui.txt b/runtime/doc/tui.txt index 96ac54abc5..42d1ad91c3 100644 --- a/runtime/doc/tui.txt +++ b/runtime/doc/tui.txt @@ -61,11 +61,13 @@ unlike most other environment variables. > For this terminal Set $TERM to |builtin-terms| ------------------------------------------------------------------------- - anything libvte-based vte, vte-256color Y - (e.g. GNOME Terminal) (aliases: gnome, gnome-256color) + ansi (unknown) Y + Ghostty ghostty, xterm-ghostty Y iTerm (original) iterm, iTerm.app N iTerm2 (new capabilities) iterm2, iTerm2.app Y Konsole konsole-256color N + libvte-based vte, vte-256color Y + (e.g. GNOME Terminal) (aliases: gnome, gnome-256color) Linux virtual terminal linux, linux-256color Y PuTTY putty, putty-256color Y rxvt rxvt, rxvt-256color Y @@ -76,22 +78,26 @@ unlike most other environment variables. Windows/ConEmu conemu Y Windows/Cygwin-built Nvim cygwin Y Windows/Interix interix Y - Windows/VTP console vtpcon Y Windows/legacy console win32con Y + Windows/VTP console vtpcon Y xterm or compatible xterm, xterm-256color Y < *builtin-terms* *builtin_terms* -If a |terminfo| database is not available or there is no entry for the current -terminal, Nvim will map |$TERM| to a builtin entry according to the above -table, or "ansi" if there is no match. For example "TERM=putty-256color" will -be mapped to the builtin "putty" entry. See also |tui-colors|. +Nvim will map |$TERM| to a builtin entry according to the above table if: + +- a |terminfo| database is not available on the system +- no terminfo entry found for the current detected terminal +- Nvim was built without terminfo support (`has('terminfo')==0`) The builtin terminfo is not combined with any external terminfo database, nor can it be used in preference to one. You can thus entirely override any omissions or out-of-date information in the builtin terminfo database by supplying an external one with entries for the terminal type. +For example "TERM=putty-256color" will be mapped to the builtin "putty" entry. +See also |tui-colors|. + Settings depending on terminal *term-dependent-settings* If you want to set terminal-dependent options or mappings, you can do this in diff --git a/src/gen/gen_terminfo.lua b/src/gen/gen_terminfo.lua index dad69a5828..655c357839 100644 --- a/src/gen/gen_terminfo.lua +++ b/src/gen/gen_terminfo.lua @@ -20,6 +20,7 @@ local target_enum = 'src/nvim/tui/terminfo_enum_defs.h' local entries = { { 'ansi', 'ansi_terminfo' }, + { 'ghostty', 'ghostty_terminfo' }, -- Note: ncurses defs do not exactly match what ghostty ships. { 'interix', 'interix_8colour_terminfo' }, { 'iterm2', 'iterm_256colour_terminfo' }, { 'linux', 'linux_16colour_terminfo' }, diff --git a/src/nvim/tui/terminfo.c b/src/nvim/tui/terminfo.c index a1d5712962..6c870d471d 100644 --- a/src/nvim/tui/terminfo.c +++ b/src/nvim/tui/terminfo.c @@ -70,7 +70,10 @@ bool terminfo_is_bsd_console(const char *term) /// @return [allocated] terminfo structure const TerminfoEntry *terminfo_from_builtin(const char *term, char **termname) { - if (terminfo_is_term_family(term, "xterm")) { + if (strequal(term, "ghostty") || strequal(term, "xterm-ghostty")) { + *termname = "ghostty"; + return &ghostty_terminfo; + } else if (terminfo_is_term_family(term, "xterm")) { *termname = "xterm"; return &xterm_256colour_terminfo; } else if (terminfo_is_term_family(term, "screen")) { diff --git a/src/nvim/tui/terminfo_builtin.h b/src/nvim/tui/terminfo_builtin.h index 34f7caab8a..26318e0ee6 100644 --- a/src/nvim/tui/terminfo_builtin.h +++ b/src/nvim/tui/terminfo_builtin.h @@ -82,6 +82,145 @@ static const TerminfoEntry ansi_terminfo = { }, }; +static const TerminfoEntry ghostty_terminfo = { + .bce = true, + .has_Tc_or_RGB = false, + .Su = false, + .max_colors = 0x100, + .lines = 24, + .columns = 80, + .defs = { + [kTerm_carriage_return] = "\r", + [kTerm_change_scroll_region] = "\033[%i%p1%d;%p2%dr", + [kTerm_clear_screen] = "\033[H\033[2J", + [kTerm_clr_eol] = "\033[K", + [kTerm_clr_eos] = "\033[J", + [kTerm_cursor_address] = "\033[%i%p1%d;%p2%dH", + [kTerm_cursor_down] = "\n", + [kTerm_cursor_invisible] = "\033[?25l", + [kTerm_cursor_left] = "\b", + [kTerm_cursor_home] = "\033[H", + [kTerm_cursor_normal] = "\033[?12l\033[?25h", + [kTerm_cursor_up] = "\033[A", + [kTerm_cursor_right] = "\033[C", + [kTerm_delete_line] = "\033[M", + [kTerm_enter_bold_mode] = "\033[1m", + [kTerm_enter_ca_mode] = "\033[?1049h", + [kTerm_enter_italics_mode] = "\033[3m", + [kTerm_enter_reverse_mode] = "\033[7m", + [kTerm_enter_standout_mode] = "\033[7m", + [kTerm_enter_underline_mode] = "\033[4m", + [kTerm_erase_chars] = "\033[%p1%dX", + [kTerm_exit_attribute_mode] = "\033(B\033[m", + [kTerm_exit_ca_mode] = "\033[?1049l", + [kTerm_from_status_line] = "\a", + [kTerm_insert_line] = "\033[L", + [kTerm_keypad_local] = "\033[?1l\033>", + [kTerm_keypad_xmit] = "\033[?1h\033=", + [kTerm_parm_delete_line] = "\033[%p1%dM", + [kTerm_parm_down_cursor] = "\033[%p1%dB", + [kTerm_parm_insert_line] = "\033[%p1%dL", + [kTerm_parm_left_cursor] = "\033[%p1%dD", + [kTerm_parm_right_cursor] = "\033[%p1%dC", + [kTerm_parm_up_cursor] = "\033[%p1%dA", + [kTerm_set_a_background] = "\033[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m", + [kTerm_set_a_foreground] = "\033[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m", + [kTerm_set_attributes] = "%?%p9%t\033(0%e\033(B%;\033[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p5%t;2%;%?%p7%t;8%;m", + [kTerm_set_lr_margin] = "\033[?69h\033[%i%p1%d;%p2%ds", + [kTerm_to_status_line] = "\033]2;", + [kTerm_reset_cursor_style] = "\033[2 q", + [kTerm_set_cursor_style] = "\033[%p1%d q", + [kTerm_enter_strikethrough_mode] = "\033[9m", + [kTerm_set_rgb_foreground] = NULL, + [kTerm_set_rgb_background] = NULL, + [kTerm_set_cursor_color] = NULL, + [kTerm_reset_cursor_color] = NULL, + [kTerm_set_underline_style] = "\033[4\072%p1%dm", + }, + .keys = { + [kTermKey_backspace] = {"\177", NULL}, + [kTermKey_beg] = {NULL, NULL}, + [kTermKey_btab] = {"\033[Z", NULL}, + [kTermKey_clear] = {NULL, NULL}, + [kTermKey_dc] = {"\033[3~", "\033[3;2~"}, + [kTermKey_end] = {"\033OF", "\033[1;2F"}, + [kTermKey_find] = {NULL, NULL}, + [kTermKey_home] = {"\033OH", "\033[1;2H"}, + [kTermKey_ic] = {"\033[2~", "\033[2;2~"}, + [kTermKey_npage] = {"\033[6~", NULL}, + [kTermKey_ppage] = {"\033[5~", NULL}, + [kTermKey_select] = {NULL, NULL}, + [kTermKey_suspend] = {NULL, NULL}, + [kTermKey_undo] = {NULL, NULL}, + }, + .f_keys = { + // note: offset by one, f_keys[0] is F1 and so on + [0] = "\033OP", + [1] = "\033OQ", + [2] = "\033OR", + [3] = "\033OS", + [4] = "\033[15~", + [5] = "\033[17~", + [6] = "\033[18~", + [7] = "\033[19~", + [8] = "\033[20~", + [9] = "\033[21~", + [10] = "\033[23~", + [11] = "\033[24~", + [12] = "\033[1;2P", + [13] = "\033[1;2Q", + [14] = "\033[1;2R", + [15] = "\033[1;2S", + [16] = "\033[15;2~", + [17] = "\033[17;2~", + [18] = "\033[18;2~", + [19] = "\033[19;2~", + [20] = "\033[20;2~", + [21] = "\033[21;2~", + [22] = "\033[23;2~", + [23] = "\033[24;2~", + [24] = "\033[1;5P", + [25] = "\033[1;5Q", + [26] = "\033[1;5R", + [27] = "\033[1;5S", + [28] = "\033[15;5~", + [29] = "\033[17;5~", + [30] = "\033[18;5~", + [31] = "\033[19;5~", + [32] = "\033[20;5~", + [33] = "\033[21;5~", + [34] = "\033[23;5~", + [35] = "\033[24;5~", + [36] = "\033[1;6P", + [37] = "\033[1;6Q", + [38] = "\033[1;6R", + [39] = "\033[1;6S", + [40] = "\033[15;6~", + [41] = "\033[17;6~", + [42] = "\033[18;6~", + [43] = "\033[19;6~", + [44] = "\033[20;6~", + [45] = "\033[21;6~", + [46] = "\033[23;6~", + [47] = "\033[24;6~", + [48] = "\033[1;3P", + [49] = "\033[1;3Q", + [50] = "\033[1;3R", + [51] = "\033[1;3S", + [52] = "\033[15;3~", + [53] = "\033[17;3~", + [54] = "\033[18;3~", + [55] = "\033[19;3~", + [56] = "\033[20;3~", + [57] = "\033[21;3~", + [58] = "\033[23;3~", + [59] = "\033[24;3~", + [60] = "\033[1;4P", + [61] = "\033[1;4Q", + [62] = "\033[1;4R", + }, +}; + static const TerminfoEntry interix_8colour_terminfo = { .bce = true, .has_Tc_or_RGB = false,