aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-06-01 22:53:29 +0800
committerGitHub <noreply@github.com>2022-06-01 22:53:29 +0800
commit19e80738e03f352602ec573d3634d53cb6cd09f7 (patch)
tree1c73bf9034ee4b5d0726cc95bbc437a9bb0b15db
parent9f1ec825cdcb5e2f4bd8c7b15b50fb763ddd5cca (diff)
downloadrneovim-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.c20
-rw-r--r--test/functional/ui/decorations_spec.lua45
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()