diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-06-01 22:53:29 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-01 22:53:29 +0800 |
commit | 19e80738e03f352602ec573d3634d53cb6cd09f7 (patch) | |
tree | 1c73bf9034ee4b5d0726cc95bbc437a9bb0b15db | |
parent | 9f1ec825cdcb5e2f4bd8c7b15b50fb763ddd5cca (diff) | |
download | rneovim-19e80738e03f352602ec573d3634d53cb6cd09f7.tar.gz rneovim-19e80738e03f352602ec573d3634d53cb6cd09f7.tar.bz2 rneovim-19e80738e03f352602ec573d3634d53cb6cd09f7.zip |
fix(screen): restart win_update() if a decor provider changes signcols (#18768)
-rw-r--r-- | src/nvim/screen.c | 20 | ||||
-rw-r--r-- | test/functional/ui/decorations_spec.lua | 45 |
2 files changed, 61 insertions, 4 deletions
diff --git a/src/nvim/screen.c b/src/nvim/screen.c index b0edad7740..fe306f8c6b 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -326,10 +326,11 @@ int update_screen(int type) type = must_redraw; } - /* must_redraw is reset here, so that when we run into some weird - * reason to redraw while busy redrawing (e.g., asynchronous - * scrolling), or update_topline() in win_update() will cause a - * scroll, the screen will be redrawn later or in win_update(). */ + // must_redraw is reset here, so that when we run into some weird + // reason to redraw while busy redrawing (e.g., asynchronous + // scrolling), or update_topline() in win_update() will cause a + // scroll, or a decoration provider requires a redraw, the screen + // will be redrawn later or in win_update(). must_redraw = 0; } @@ -689,6 +690,9 @@ bool win_cursorline_standout(const win_T *wp) */ static void win_update(win_T *wp, DecorProviders *providers) { + bool called_decor_providers = false; +win_update_start: + ; buf_T *buf = wp->w_buffer; int type; int top_end = 0; /* Below last row of the top area that needs @@ -1306,6 +1310,14 @@ static void win_update(win_T *wp, DecorProviders *providers) DecorProviders line_providers; decor_providers_invoke_win(wp, providers, &line_providers, &provider_err); + (void)win_signcol_count(wp); // check if provider changed signcol width + if (must_redraw != 0) { + must_redraw = 0; + if (!called_decor_providers) { + called_decor_providers = true; + goto win_update_start; + } + } bool cursorline_standout = win_cursorline_standout(wp); diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index 4982506631..cf4845474f 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -30,6 +30,7 @@ describe('decorations providers', function() [11] = {foreground = Screen.colors.Red, background = tonumber('0x005028')}; [12] = {foreground = tonumber('0x990000')}; [13] = {background = Screen.colors.LightBlue}; + [14] = {background = Screen.colors.WebGray, foreground = Screen.colors.DarkBlue}; } end) @@ -404,6 +405,50 @@ describe('decorations providers', function() | ]]} end) + + it('can create and remove signs when CursorMoved autocommand validates botline #18661', function() + exec_lua([[ + local lines = {} + for i = 1, 200 do + lines[i] = 'hello' .. tostring(i) + end + vim.api.nvim_buf_set_lines(0, 0, -1, false, lines) + ]]) + setup_provider([[ + local function on_do(kind, winid, bufnr, topline, botline_guess) + if kind == 'win' then + if topline < 100 and botline_guess > 100 then + vim.api.nvim_buf_set_extmark(bufnr, ns1, 99, -1, { sign_text = 'X' }) + else + vim.api.nvim_buf_clear_namespace(bufnr, ns1, 0, -1) + end + end + end + ]]) + command([[autocmd CursorMoved * call line('w$')]]) + meths.win_set_cursor(0, {100, 0}) + screen:expect([[ + {14: }hello97 | + {14: }hello98 | + {14: }hello99 | + X ^hello100 | + {14: }hello101 | + {14: }hello102 | + {14: }hello103 | + | + ]]) + meths.win_set_cursor(0, {1, 0}) + screen:expect([[ + ^hello1 | + hello2 | + hello3 | + hello4 | + hello5 | + hello6 | + hello7 | + | + ]]) + end) end) describe('extmark decorations', function() |