fix(statusline): don't clobber global statusline during autocmd #41169

Problem:
With `laststatus=3`, a pager float shares the main grid's statusline
row. Setting a diagnostic fires `DiagnosticChanged`, whose handler calls
`nvim__redraw({ statusline = true })`.

Analysis:
Inside the autocmd, `curwin` is temporarily switched to the tiled window
showing that buffer, so `win_redr_status()` paints its statusline over
the pager's `[Pager]` statusline on the shared row. After the autocmd,
`curwin` is restored but the pager statusline is never repainted.

Solution:
Use `ctx_saved_curwin()` decide whether to draw the global statusline,
matching `win_redr_stl_expr()` and `update_screen()`. No behavior change
if no buffer-context switch is active.
This commit is contained in:
Tanishq
2026-08-05 23:05:09 +05:30
committed by GitHub
parent e58f29ca3e
commit e2c0c63452
2 changed files with 32 additions and 2 deletions

View File

@@ -91,14 +91,22 @@ void win_redr_status(win_T *wp)
busy = true;
wp->w_redr_status = false;
if (wp->w_status_height == 0 && !(is_stl_global && wp == curwin)) {
// curwin may be temporarily switched during autocmds (ctx_switch).
win_T *stl_curwin = ctx_saved_curwin();
if (stl_curwin == NULL) {
stl_curwin = curwin;
}
bool is_stl_curwin = wp == stl_curwin;
if (wp->w_status_height == 0 && !(is_stl_global && is_stl_curwin)) {
// no status line, either global statusline is enabled or the window is a last window
redraw_cmdline = true;
} else if (!redrawing()) {
// Don't redraw right now, do it later. Don't update status line when
// popup menu is visible and may be drawn over it
wp->w_redr_status = true;
} else if (*wp->w_p_stl != NUL || !wp->w_floating || (is_stl_global && wp == curwin)) {
} else if (*wp->w_p_stl != NUL || !wp->w_floating || (is_stl_global && is_stl_curwin)) {
win_redr_stl_expr(wp, false, false, false);
}

View File

@@ -1259,4 +1259,26 @@ describe('messages2', function()
----------------------------------------------------0|
]])
end)
it('pager statusline is not clobbered by DiagnosticChanged redraw #41130', function()
exec_lua(function()
vim.o.laststatus = 3
vim.print('message')
vim.cmd.mes()
end)
screen:expect([[
|
{1:~ }|*9
{3: }|
^message |
{3:[Pager] }|
message |
]])
exec_lua(function()
vim.diagnostic.config({ signs = false, virtual_text = false, underline = false })
local ns = vim.api.nvim_create_namespace('repro-41130')
vim.diagnostic.set(ns, 1, { { lnum = 0, message = 'random error' } }, {})
end)
screen:expect_unchanged()
end)
end)