diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2025-02-05 23:09:29 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2025-02-05 23:09:29 +0000 |
commit | d5f194ce780c95821a855aca3c19426576d28ae0 (patch) | |
tree | d45f461b19f9118ad2bb1f440a7a08973ad18832 /src/nvim/tui/tui.c | |
parent | c5d770d311841ea5230426cc4c868e8db27300a8 (diff) | |
parent | 44740e561fc93afe3ebecfd3618bda2d2abeafb0 (diff) | |
download | rneovim-rahm.tar.gz rneovim-rahm.tar.bz2 rneovim-rahm.zip |
Diffstat (limited to 'src/nvim/tui/tui.c')
-rw-r--r-- | src/nvim/tui/tui.c | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 2839a665da..31f95a1006 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -1,9 +1,9 @@ // Terminal UI functions. Invoked (by ui_client.c) on the UI process. #include <assert.h> +#include <inttypes.h> #include <signal.h> #include <stdbool.h> -#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -22,8 +22,6 @@ #include "nvim/event/stream.h" #include "nvim/globals.h" #include "nvim/grid.h" -#include "nvim/grid_defs.h" -#include "nvim/highlight.h" #include "nvim/highlight_defs.h" #include "nvim/log.h" #include "nvim/macros_defs.h" @@ -107,7 +105,7 @@ struct TUIData { bool busy, is_invisible, want_invisible; bool cork, overflow; bool set_cursor_color_as_str; - bool cursor_color_changed; + bool cursor_has_color; bool is_starting; bool did_set_grapheme_cluster_mode; FILE *screenshot; @@ -241,16 +239,19 @@ void tui_handle_term_mode(TUIData *tui, TermMode mode, TermModeState state) tui->unibi_ext.sync = (int)unibi_add_ext_str(tui->ut, "Sync", "\x1b[?2026%?%p1%{1}%-%tl%eh%;"); break; - case kTermModeResizeEvents: - signal_watcher_stop(&tui->winch_handle); - tui_set_term_mode(tui, mode, true); - break; case kTermModeGraphemeClusters: if (!is_set) { tui_set_term_mode(tui, mode, true); tui->did_set_grapheme_cluster_mode = true; } break; + case kTermModeThemeUpdates: + tui_set_term_mode(tui, mode, true); + break; + case kTermModeResizeEvents: + signal_watcher_stop(&tui->winch_handle); + tui_set_term_mode(tui, mode, true); + break; } } } @@ -295,7 +296,10 @@ void tui_set_key_encoding(TUIData *tui) { switch (tui->input.key_encoding) { case kKeyEncodingKitty: - out(tui, S_LEN("\x1b[>1u")); + // Progressive enhancement flags: + // 0b01 (1) Disambiguate escape codes + // 0b10 (2) Report event types + out(tui, S_LEN("\x1b[>3u")); break; case kKeyEncodingXterm: out(tui, S_LEN("\x1b[>4;2m")); @@ -310,7 +314,7 @@ static void tui_reset_key_encoding(TUIData *tui) { switch (tui->input.key_encoding) { case kKeyEncodingKitty: - out(tui, S_LEN("\x1b[<1u")); + out(tui, S_LEN("\x1b[<u")); break; case kKeyEncodingXterm: out(tui, S_LEN("\x1b[>4;0m")); @@ -320,6 +324,18 @@ static void tui_reset_key_encoding(TUIData *tui) } } +/// Write the OSC 11 sequence to the terminal emulator to query the current +/// background color. +/// +/// The response will be handled by the TermResponse autocommand created in +/// _defaults.lua. +void tui_query_bg_color(TUIData *tui) + FUNC_ATTR_NONNULL_ALL +{ + out(tui, S_LEN("\x1b]11;?\x07")); + flush_buf(tui); +} + /// Enable the alternate screen and emit other control sequences to start the TUI. /// /// This is also called when the TUI is resumed after being suspended. We reinitialize all state @@ -336,7 +352,7 @@ static void terminfo_start(TUIData *tui) tui->cork = false; tui->overflow = false; tui->set_cursor_color_as_str = false; - tui->cursor_color_changed = false; + tui->cursor_has_color = false; tui->showing_mode = SHAPE_IDX_N; tui->unibi_ext.enable_mouse = -1; tui->unibi_ext.disable_mouse = -1; @@ -438,14 +454,13 @@ static void terminfo_start(TUIData *tui) // Enable bracketed paste unibi_out_ext(tui, tui->unibi_ext.enable_bracketed_paste); - // Query support for mode 2026 (Synchronized Output). Some terminals also - // support an older DCS sequence for synchronized output, but we will only use - // mode 2026. + // Query support for private DEC modes that Nvim can take advantage of. // Some terminals (such as Terminal.app) do not support DECRQM, so skip the query. if (!nsterm) { tui_request_term_mode(tui, kTermModeSynchronizedOutput); - tui_request_term_mode(tui, kTermModeResizeEvents); tui_request_term_mode(tui, kTermModeGraphemeClusters); + tui_request_term_mode(tui, kTermModeThemeUpdates); + tui_request_term_mode(tui, kTermModeResizeEvents); } // Don't use DECRQSS in screen or tmux, as they behave strangely when receiving it. @@ -493,6 +508,10 @@ static void terminfo_start(TUIData *tui) /// Disable the alternate screen and prepare for the TUI to close. static void terminfo_stop(TUIData *tui) { + // Disable theme update notifications. We do this first to avoid getting any + // more notifications after we reset the cursor and any color palette changes. + tui_set_term_mode(tui, kTermModeThemeUpdates, false); + // Destroy output stuff tui_mode_change(tui, NULL_STRING, SHAPE_IDX_N); tui_mouse_off(tui); @@ -509,6 +528,7 @@ static void terminfo_stop(TUIData *tui) if (tui->did_set_grapheme_cluster_mode) { tui_set_term_mode(tui, kTermModeGraphemeClusters, false); } + // May restore old title before exiting alternate screen. tui_set_title(tui, NULL_STRING); if (ui_client_exit_status == 0) { @@ -521,7 +541,7 @@ static void terminfo_stop(TUIData *tui) // Exit alternate screen. unibi_out(tui, unibi_exit_ca_mode); } - if (tui->cursor_color_changed) { + if (tui->cursor_has_color) { unibi_out_ext(tui, tui->unibi_ext.reset_cursor_color); } // Disable bracketed paste @@ -1302,11 +1322,12 @@ static void tui_set_mode(TUIData *tui, ModeShape mode) UNIBI_SET_NUM_VAR(tui->params[0], aep.rgb_bg_color); } unibi_out_ext(tui, tui->unibi_ext.set_cursor_color); - tui->cursor_color_changed = true; + tui->cursor_has_color = true; } - } else if (c.id == 0) { + } else if (c.id == 0 && (tui->want_invisible || tui->cursor_has_color)) { // No cursor color for this mode; reset to default. tui->want_invisible = false; + tui->cursor_has_color = false; unibi_out_ext(tui, tui->unibi_ext.reset_cursor_color); } @@ -1319,7 +1340,7 @@ static void tui_set_mode(TUIData *tui, ModeShape mode) case SHAPE_VER: shape = 5; break; } - UNIBI_SET_NUM_VAR(tui->params[0], shape + (int)(c.blinkon == 0)); + UNIBI_SET_NUM_VAR(tui->params[0], shape + (int)(c.blinkon == 0 || c.blinkoff == 0)); unibi_out_ext(tui, tui->unibi_ext.set_cursor_style); } @@ -2273,6 +2294,7 @@ static void augment_terminfo(TUIData *tui, const char *term, int vte_version, in bool putty = terminfo_is_term_family(term, "putty"); bool screen = terminfo_is_term_family(term, "screen"); bool tmux = terminfo_is_term_family(term, "tmux") || !!os_getenv("TMUX"); + bool st = terminfo_is_term_family(term, "st"); bool iterm = terminfo_is_term_family(term, "iterm") || terminfo_is_term_family(term, "iterm2") || terminfo_is_term_family(term, "iTerm.app") @@ -2357,9 +2379,10 @@ static void augment_terminfo(TUIData *tui, const char *term, int vte_version, in // would use a tmux control sequence and an extra if(screen) test. tui->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(ut, NULL, TMUX_WRAP(tmux, "\033]Pl%p1%06x\033\\")); - } else if ((xterm || hterm || rxvt || tmux || alacritty) + } else if ((xterm || hterm || rxvt || tmux || alacritty || st) && (vte_version == 0 || vte_version >= 3900)) { // Supported in urxvt, newer VTE. + // Supported in st, but currently missing in ncurses definitions. #32217 tui->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(ut, "ext.set_cursor_color", "\033]12;%p1%s\007"); } |