diff options
author | Gregory Anders <greg@gpanders.com> | 2023-12-05 10:01:32 -0800 |
---|---|---|
committer | Gregory Anders <greg@gpanders.com> | 2023-12-06 07:57:09 -0800 |
commit | 2613ba5000d4c0d9b15e2eec2d2b97615575925e (patch) | |
tree | 7fde88589dbf7e5e30130ae65cdb6a9df2e61ccb /src | |
parent | 5b40a1c09dda83275784053b325ad16626fc55f2 (diff) | |
download | rneovim-2613ba5000d4c0d9b15e2eec2d2b97615575925e.tar.gz rneovim-2613ba5000d4c0d9b15e2eec2d2b97615575925e.tar.bz2 rneovim-2613ba5000d4c0d9b15e2eec2d2b97615575925e.zip |
feat(defaults): enable 'termguicolors' by default when supported by terminal
Enable 'termguicolors' automatically when Nvim can detect that truecolor
is supported by the host terminal.
If $COLORTERM is set to "truecolor" or "24bit", or the terminal's
terminfo entry contains capabilities for Tc, RGB, or setrgbf and
setrgbb, then we assume that the terminal supports truecolor. Otherwise,
the terminal is queried (using both XTGETTCAP and SGR + DECRQSS). If the
terminal's response to these queries (if any) indicates that it supports
truecolor, then 'termguicolors' is enabled.
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/options.lua | 4 | ||||
-rw-r--r-- | src/nvim/tui/tui.c | 47 | ||||
-rw-r--r-- | src/nvim/ui_client.c | 9 |
3 files changed, 54 insertions, 6 deletions
diff --git a/src/nvim/options.lua b/src/nvim/options.lua index daaf73d241..50371b8bf3 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -8764,6 +8764,10 @@ return { Enables 24-bit RGB color in the |TUI|. Uses "gui" |:highlight| attributes instead of "cterm" attributes. |guifg| Requires an ISO-8613-3 compatible terminal. + + Nvim will automatically attempt to determine if the host terminal + supports 24-bit color and will enable this option if it does + (unless explicitly disabled by the user). ]=], full_name = 'termguicolors', redraw = { 'ui_option' }, diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index c71eb633e9..d625c22c76 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -148,7 +148,8 @@ static bool cursor_style_enabled = false; # include "tui/tui.c.generated.h" #endif -void tui_start(TUIData **tui_p, int *width, int *height, char **term) +void tui_start(TUIData **tui_p, int *width, int *height, char **term, bool *rgb) + FUNC_ATTR_NONNULL_ALL { TUIData *tui = xcalloc(1, sizeof(TUIData)); tui->is_starting = true; @@ -177,6 +178,7 @@ void tui_start(TUIData **tui_p, int *width, int *height, char **term) *width = tui->width; *height = tui->height; *term = tui->term; + *rgb = tui->rgb; } void tui_set_key_encoding(TUIData *tui) @@ -334,6 +336,9 @@ static void terminfo_start(TUIData *tui) int konsolev = konsolev_env ? (int)strtol(konsolev_env, NULL, 10) : (konsole ? 1 : 0); + // truecolor support must be checked before patching/augmenting terminfo + tui->rgb = term_has_truecolor(tui, colorterm); + patch_terminfo_bugs(tui, term, colorterm, vtev, konsolev, iterm_env, nsterm); augment_terminfo(tui, term, vtev, konsolev, iterm_env, nsterm); tui->can_change_scroll_region = @@ -1439,7 +1444,7 @@ void tui_suspend(TUIData *tui) tui_mouse_on(tui); } stream_set_blocking(tui->input.in_fd, false); // libuv expects this - ui_client_attach(tui->width, tui->height, tui->term); + ui_client_attach(tui->width, tui->height, tui->term, tui->rgb); #endif } @@ -1752,6 +1757,44 @@ static int unibi_find_ext_bool(unibi_term *ut, const char *name) return -1; } +/// Determine if the terminal supports truecolor or not: +/// +/// 1. If $COLORTERM is "24bit" or "truecolor", return true +/// 2. Else, check terminfo for Tc, RGB, setrgbf, or setrgbb capabilities. If +/// found, return true +/// 3. Else, return false +static bool term_has_truecolor(TUIData *tui, const char *colorterm) +{ + // Check $COLORTERM + if (strequal(colorterm, "truecolor") || strequal(colorterm, "24bit")) { + return true; + } + + // Check for Tc and RGB + for (size_t i = 0; i < unibi_count_ext_bool(tui->ut); i++) { + const char *n = unibi_get_ext_bool_name(tui->ut, i); + if (n && (!strcmp(n, "Tc") || !strcmp(n, "RGB"))) { + return true; + } + } + + // Check for setrgbf and setrgbb + bool setrgbf = false; + bool setrgbb = false; + for (size_t i = 0; i < unibi_count_ext_str(tui->ut) && (!setrgbf || !setrgbb); i++) { + const char *n = unibi_get_ext_str_name(tui->ut, i); + if (n) { + if (!setrgbf && !strcmp(n, "setrgbf")) { + setrgbf = true; + } else if (!setrgbb && !strcmp(n, "setrgbb")) { + setrgbb = true; + } + } + } + + return setrgbf && setrgbb; +} + /// Patches the terminfo records after loading from system or built-in db. /// Several entries in terminfo are known to be deficient or outright wrong; /// and several terminal emulators falsely announce incorrect terminal types. diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c index eb32c16881..d744560a86 100644 --- a/src/nvim/ui_client.c +++ b/src/nvim/ui_client.c @@ -70,14 +70,14 @@ uint64_t ui_client_start_server(int argc, char **argv) return channel->id; } -void ui_client_attach(int width, int height, char *term) +void ui_client_attach(int width, int height, char *term, bool rgb) { MAXSIZE_TEMP_ARRAY(args, 3); ADD_C(args, INTEGER_OBJ(width)); ADD_C(args, INTEGER_OBJ(height)); MAXSIZE_TEMP_DICT(opts, 9); - PUT_C(opts, "rgb", BOOLEAN_OBJ(true)); + PUT_C(opts, "rgb", BOOLEAN_OBJ(rgb)); PUT_C(opts, "ext_linegrid", BOOLEAN_OBJ(true)); PUT_C(opts, "ext_termcolors", BOOLEAN_OBJ(true)); if (term) { @@ -111,9 +111,10 @@ void ui_client_run(bool remote_ui) ui_client_is_remote = remote_ui; int width, height; char *term; - tui_start(&tui, &width, &height, &term); + bool rgb; + tui_start(&tui, &width, &height, &term, &rgb); - ui_client_attach(width, height, term); + ui_client_attach(width, height, term, rgb); // os_exit() will be invoked when the client channel detaches while (true) { |