diff options
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) { |