diff options
Diffstat (limited to 'src/nvim/tui')
-rw-r--r-- | src/nvim/tui/input.c | 23 | ||||
-rw-r--r-- | src/nvim/tui/input.h | 5 | ||||
-rw-r--r-- | src/nvim/tui/terminfo.c | 3 | ||||
-rw-r--r-- | src/nvim/tui/tui.c | 57 |
4 files changed, 58 insertions, 30 deletions
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index ed9b410a19..c71378463f 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -26,7 +26,8 @@ void tinput_init(TermInput *input, Loop *loop) { input->loop = loop; input->paste = 0; - input->in_fd = 0; + input->in_fd = STDIN_FILENO; + input->waiting_for_bg_response = 0; input->key_buffer = rbuffer_new(KEY_BUFFER_SIZE); uv_mutex_init(&input->key_buffer_mutex); uv_cond_init(&input->key_buffer_cond); @@ -35,7 +36,7 @@ void tinput_init(TermInput *input, Loop *loop) // echo q | nvim -es // ls *.md | xargs nvim #ifdef WIN32 - if (!os_isatty(0)) { + if (!os_isatty(input->in_fd)) { const HANDLE conin_handle = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, @@ -45,8 +46,8 @@ void tinput_init(TermInput *input, Loop *loop) assert(input->in_fd != -1); } #else - if (!os_isatty(0) && os_isatty(2)) { - input->in_fd = 2; + if (!os_isatty(input->in_fd) && os_isatty(STDERR_FILENO)) { + input->in_fd = STDERR_FILENO; } #endif input_global_fd_init(input->in_fd); @@ -443,6 +444,9 @@ static void set_bg_deferred(void **argv) // [1] https://en.wikipedia.org/wiki/Luma_%28video%29 static bool handle_background_color(TermInput *input) { + if (input->waiting_for_bg_response <= 0) { + return false; + } size_t count = 0; size_t component = 0; size_t header_size = 0; @@ -461,8 +465,13 @@ static bool handle_background_color(TermInput *input) header_size = 10; num_components = 4; } else { + input->waiting_for_bg_response--; + if (input->waiting_for_bg_response == 0) { + DLOG("did not get a response for terminal background query"); + } return false; } + input->waiting_for_bg_response = 0; rbuffer_consumed(input->read_stream.buffer, header_size); RBUFFER_EACH(input->read_stream.buffer, c, i) { count = i + 1; @@ -503,6 +512,12 @@ static bool handle_background_color(TermInput *input) } return true; } +#ifdef UNIT_TESTING +bool ut_handle_background_color(TermInput *input) +{ + return handle_background_color(input); +} +#endif static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_, void *data, bool eof) diff --git a/src/nvim/tui/input.h b/src/nvim/tui/input.h index a4071fab40..77bd6fa132 100644 --- a/src/nvim/tui/input.h +++ b/src/nvim/tui/input.h @@ -12,6 +12,7 @@ typedef struct term_input { // Phases: -1=all 0=disabled 1=first-chunk 2=continue 3=last-chunk int8_t paste; bool waiting; + int8_t waiting_for_bg_response; TermKey *tk; #if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18 TermKey_Terminfo_Getstr_Hook *tk_ti_hook_fn; ///< libtermkey terminfo hook @@ -28,4 +29,8 @@ typedef struct term_input { # include "tui/input.h.generated.h" #endif +#ifdef UNIT_TESTING +bool ut_handle_background_color(TermInput *input); +#endif + #endif // NVIM_TUI_INPUT_H diff --git a/src/nvim/tui/terminfo.c b/src/nvim/tui/terminfo.c index 14023ce2cb..03173afe07 100644 --- a/src/nvim/tui/terminfo.c +++ b/src/nvim/tui/terminfo.c @@ -47,9 +47,8 @@ bool terminfo_is_bsd_console(const char *term) // like cursor-shaping. Assume that TERM=xterm is degraded. #8644 return strequal(term, "xterm") && !!os_getenv("XTERM_VERSION"); # endif -#else - return false; #endif + return false; } /// Loads a built-in terminfo db when we (unibilium) failed to load a terminfo diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 791756e5c5..60e1353000 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -93,7 +93,7 @@ typedef struct { int out_fd; bool scroll_region_is_full_screen; bool can_change_scroll_region; - bool can_set_lr_margin; + bool can_set_lr_margin; // smglr bool can_set_left_right_margin; bool can_scroll; bool can_erase_chars; @@ -220,7 +220,7 @@ static void terminfo_start(UI *ui) data->unibi_ext.reset_cursor_style = -1; data->unibi_ext.get_bg = -1; data->unibi_ext.set_underline_color = -1; - data->out_fd = 1; + data->out_fd = STDOUT_FILENO; data->out_isatty = os_isatty(data->out_fd); const char *term = os_getenv("TERM"); @@ -234,7 +234,9 @@ static void terminfo_start(UI *ui) // Set up unibilium/terminfo. char *termname = NULL; if (term) { + os_env_var_lock(); data->ut = unibi_from_term(term); + os_env_var_unlock(); if (data->ut) { termname = xstrdup(term); } @@ -296,6 +298,7 @@ static void terminfo_start(UI *ui) unibi_out(ui, unibi_keypad_xmit); unibi_out(ui, unibi_clear_screen); // Ask the terminal to send us the background color. + data->input.waiting_for_bg_response = 5; unibi_out_ext(ui, data->unibi_ext.get_bg); // Enable bracketed paste unibi_out_ext(ui, data->unibi_ext.enable_bracketed_paste); @@ -312,6 +315,7 @@ static void terminfo_start(UI *ui) uv_pipe_init(&data->write_loop, &data->output_handle.pipe, 0); uv_pipe_open(&data->output_handle.pipe, data->out_fd); } + flush_buf(ui); } static void terminfo_stop(UI *ui) @@ -363,6 +367,7 @@ static void tui_terminal_after_startup(UI *ui) // Emit this after Nvim startup, not during. This works around a tmux // 2.3 bug(?) which caused slow drawing during startup. #7649 unibi_out_ext(ui, data->unibi_ext.enable_focus_reporting); + flush_buf(ui); } static void tui_terminal_stop(UI *ui) @@ -430,9 +435,6 @@ static void tui_main(UIBridgeData *bridge, UI *ui) } if (!tui_is_stopped(ui)) { tui_terminal_after_startup(ui); - // Tickle `main_loop` with a dummy event, else the initial "focus-gained" - // terminal response may not get processed until user hits a key. - loop_schedule_deferred(&main_loop, event_create(loop_dummy_event, 0)); } // "Passive" (I/O-driven) loop: TUI thread "main loop". while (!tui_is_stopped(ui)) { @@ -513,20 +515,8 @@ static void update_attrs(UI *ui, int attr_id) } data->print_attr_id = attr_id; HlAttrs attrs = kv_A(data->attrs, (size_t)attr_id); - - int fg = ui->rgb ? attrs.rgb_fg_color : (attrs.cterm_fg_color - 1); - if (fg == -1) { - fg = ui->rgb ? data->clear_attrs.rgb_fg_color - : (data->clear_attrs.cterm_fg_color - 1); - } - - int bg = ui->rgb ? attrs.rgb_bg_color : (attrs.cterm_bg_color - 1); - if (bg == -1) { - bg = ui->rgb ? data->clear_attrs.rgb_bg_color - : (data->clear_attrs.cterm_bg_color - 1); - } - int attr = ui->rgb ? attrs.rgb_ae_attr : attrs.cterm_ae_attr; + bool bold = attr & HL_BOLD; bool italic = attr & HL_ITALIC; bool reverse = attr & HL_INVERSE; @@ -594,14 +584,29 @@ static void update_attrs(UI *ui, int attr_id) unibi_out_ext(ui, data->unibi_ext.set_underline_color); } } - if (ui->rgb) { + + int fg, bg; + if (ui->rgb && !(attr & HL_FG_INDEXED)) { + fg = ((attrs.rgb_fg_color != -1) + ? attrs.rgb_fg_color : data->clear_attrs.rgb_fg_color); if (fg != -1) { UNIBI_SET_NUM_VAR(data->params[0], (fg >> 16) & 0xff); // red UNIBI_SET_NUM_VAR(data->params[1], (fg >> 8) & 0xff); // green UNIBI_SET_NUM_VAR(data->params[2], fg & 0xff); // blue unibi_out_ext(ui, data->unibi_ext.set_rgb_foreground); } + } else { + fg = (attrs.cterm_fg_color + ? attrs.cterm_fg_color - 1 : (data->clear_attrs.cterm_fg_color - 1)); + if (fg != -1) { + UNIBI_SET_NUM_VAR(data->params[0], fg); + unibi_out(ui, unibi_set_a_foreground); + } + } + if (ui->rgb && !(attr & HL_BG_INDEXED)) { + bg = ((attrs.rgb_bg_color != -1) + ? attrs.rgb_bg_color : data->clear_attrs.rgb_bg_color); if (bg != -1) { UNIBI_SET_NUM_VAR(data->params[0], (bg >> 16) & 0xff); // red UNIBI_SET_NUM_VAR(data->params[1], (bg >> 8) & 0xff); // green @@ -609,17 +614,15 @@ static void update_attrs(UI *ui, int attr_id) unibi_out_ext(ui, data->unibi_ext.set_rgb_background); } } else { - if (fg != -1) { - UNIBI_SET_NUM_VAR(data->params[0], fg); - unibi_out(ui, unibi_set_a_foreground); - } - + bg = (attrs.cterm_bg_color + ? attrs.cterm_bg_color - 1 : (data->clear_attrs.cterm_bg_color - 1)); if (bg != -1) { UNIBI_SET_NUM_VAR(data->params[0], bg); unibi_out(ui, unibi_set_a_background); } } + data->default_attr = fg == -1 && bg == -1 && !bold && !italic && !underline && !undercurl && !reverse && !standout && !strikethrough; @@ -1598,6 +1601,12 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, unibi_set_if_empty(ut, unibi_set_lr_margin, "\x1b[%i%p1%d;%p2%ds"); unibi_set_if_empty(ut, unibi_set_left_margin_parm, "\x1b[%i%p1%ds"); unibi_set_if_empty(ut, unibi_set_right_margin_parm, "\x1b[%i;%p2%ds"); + } else { + // Fix things advertised via TERM=xterm, for non-xterm. + if (unibi_get_str(ut, unibi_set_lr_margin)) { + ILOG("Disabling smglr with TERM=xterm for non-xterm."); + unibi_set_str(ut, unibi_set_lr_margin, NULL); + } } #ifdef WIN32 |