From 18e62c1bdbbb6b93bfb74d974bc511fc4c03748e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 5 Feb 2024 11:08:52 +0800 Subject: [PATCH] perf(redraw): only redraw Visual area when cursor has moved (#27340) --- src/nvim/move.c | 3 +++ src/nvim/normal.c | 5 +---- src/nvim/optionstr.c | 14 +++++++++++++- test/functional/ui/decorations_spec.lua | 20 ++++++++++++++++++++ 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/nvim/move.c b/src/nvim/move.c index dd64a7ff2b..ea35813d21 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -147,6 +147,9 @@ static void redraw_for_cursorcolumn(win_T *wp) // When 'cursorcolumn' is set or "CurSearch" is in use // need to redraw with UPD_SOME_VALID. redraw_later(wp, UPD_SOME_VALID); + } else if (VIsual_active) { + // In Visual mode need to redraw with UPD_INVERTED. + redraw_later(wp, UPD_INVERTED); } else if (wp->w_p_cul && (wp->w_p_culopt_flags & CULOPT_SCRLINE)) { // When 'cursorlineopt' contains "screenline" need to redraw with UPD_VALID. redraw_later(wp, UPD_VALID); diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 8c388b4318..9966e6129c 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -1347,10 +1347,6 @@ static void normal_redraw(NormalState *s) show_cursor_info_later(false); - if (VIsual_active) { - redraw_curbuf_later(UPD_INVERTED); // update inverted part - } - if (must_redraw) { update_screen(); } else { @@ -5129,6 +5125,7 @@ static void n_start_visual_mode(int c) curwin->w_old_cursor_lnum = curwin->w_cursor.lnum; curwin->w_old_visual_lnum = curwin->w_cursor.lnum; } + redraw_curbuf_later(UPD_VALID); } /// CTRL-W: Window commands diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index a4e69dd6b6..00e024e735 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -1541,7 +1541,15 @@ int expand_set_formatoptions(optexpand_T *args, int *numMatches, char ***matches /// The 'guicursor' option is changed. const char *did_set_guicursor(optset_T *args FUNC_ATTR_UNUSED) { - return parse_shape_opt(SHAPE_CURSOR); + const char *errmsg = parse_shape_opt(SHAPE_CURSOR); + if (errmsg != NULL) { + return errmsg; + } + if (VIsual_active) { + // In Visual mode cursor may be drawn differently. + redrawWinline(curwin, curwin->w_cursor.lnum); + } + return NULL; } /// The 'helpfile' option is changed. @@ -1958,6 +1966,10 @@ const char *did_set_selection(optset_T *args FUNC_ATTR_UNUSED) if (*p_sel == NUL || check_opt_strings(p_sel, p_sel_values, false) != OK) { return e_invarg; } + if (VIsual_active) { + // In Visual mode cursor may be drawn differently. + redrawWinline(curwin, curwin->w_cursor.lnum); + } return NULL; } diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index a4c024b526..fd8a06d898 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -39,6 +39,7 @@ describe('decorations providers', function() [16] = {special = Screen.colors.Red, undercurl = true}, [17] = {foreground = Screen.colors.Red}, [18] = {bold = true, foreground = Screen.colors.SeaGreen}; + [19] = {bold = true}; } end) @@ -738,6 +739,25 @@ describe('decorations providers', function() | ]]} end) + + it('is not invoked repeatedly in Visual mode with vim.schedule() #20235', function() + exec_lua([[_G.cnt = 0]]) + setup_provider([[ + function on_do(event, ...) + if event == 'win' then + vim.schedule(function() end) + _G.cnt = _G.cnt + 1 + end + end + ]]) + feed('v') + screen:expect([[ + ^ | + {1:~ }|*6 + {19:-- VISUAL --} | + ]]) + eq(2, exec_lua([[return _G.cnt]])) + end) end) local example_text = [[