fix(screen): restart win_update() if a decor provider changes signcols (#18768)

This commit is contained in:
zeertzjq 2022-06-01 22:53:29 +08:00 committed by GitHub
parent 9f1ec825cd
commit 19e80738e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 4 deletions

View File

@ -326,10 +326,11 @@ int update_screen(int type)
type = must_redraw; type = must_redraw;
} }
/* must_redraw is reset here, so that when we run into some weird // must_redraw is reset here, so that when we run into some weird
* reason to redraw while busy redrawing (e.g., asynchronous // reason to redraw while busy redrawing (e.g., asynchronous
* scrolling), or update_topline() in win_update() will cause a // scrolling), or update_topline() in win_update() will cause a
* scroll, the screen will be redrawn later or in win_update(). */ // scroll, or a decoration provider requires a redraw, the screen
// will be redrawn later or in win_update().
must_redraw = 0; must_redraw = 0;
} }
@ -689,6 +690,9 @@ bool win_cursorline_standout(const win_T *wp)
*/ */
static void win_update(win_T *wp, DecorProviders *providers) static void win_update(win_T *wp, DecorProviders *providers)
{ {
bool called_decor_providers = false;
win_update_start:
;
buf_T *buf = wp->w_buffer; buf_T *buf = wp->w_buffer;
int type; int type;
int top_end = 0; /* Below last row of the top area that needs 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; DecorProviders line_providers;
decor_providers_invoke_win(wp, providers, &line_providers, &provider_err); 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); bool cursorline_standout = win_cursorline_standout(wp);

View File

@ -30,6 +30,7 @@ describe('decorations providers', function()
[11] = {foreground = Screen.colors.Red, background = tonumber('0x005028')}; [11] = {foreground = Screen.colors.Red, background = tonumber('0x005028')};
[12] = {foreground = tonumber('0x990000')}; [12] = {foreground = tonumber('0x990000')};
[13] = {background = Screen.colors.LightBlue}; [13] = {background = Screen.colors.LightBlue};
[14] = {background = Screen.colors.WebGray, foreground = Screen.colors.DarkBlue};
} }
end) end)
@ -404,6 +405,50 @@ describe('decorations providers', function()
| |
]]} ]]}
end) 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) end)
describe('extmark decorations', function() describe('extmark decorations', function()