From e2c0c634522b7742ef0fb0018bca8b373cf35417 Mon Sep 17 00:00:00 2001 From: Tanishq <139997424+dev-tnsq@users.noreply.github.com> Date: Wed, 5 Aug 2026 23:05:09 +0530 Subject: [PATCH] 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. --- src/nvim/statusline.c | 12 ++++++++++-- test/functional/ui/messages2_spec.lua | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 3a7f0cd0fd..fd089aa9e5 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -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); } diff --git a/test/functional/ui/messages2_spec.lua b/test/functional/ui/messages2_spec.lua index f600cd8ed4..56f20f37cd 100644 --- a/test/functional/ui/messages2_spec.lua +++ b/test/functional/ui/messages2_spec.lua @@ -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)