mirror of
https://github.com/neovim/neovim.git
synced 2026-09-13 01:21:06 +00:00
fix(ui2): dialog messages offset by the pager line count #41839
Problem: expand_msg() derives its start row from the pager buffer even when the target is the cmd or dialog buffer, so the copied lines are appended instead of replacing, and the copied extmarks are placed at pager rows in a smaller buffer: "Invalid 'end_col': out of range", thrown inside a UI event handler. Solution: Offset only when appending to a visible pager, and read the line count after msg_clear(), whose autocmds may write to the pager. Copy marks with `strict = false`, since the rows and columns are recomputed for a different buffer and should clamp rather than raise. AI-assisted
This commit is contained in:
@@ -228,7 +228,7 @@ local function pager_shown()
|
||||
return api.nvim_win_is_valid(ui.wins.pager) and not api.nvim_win_get_config(ui.wins.pager).hide
|
||||
end
|
||||
|
||||
local hlopts = { undo_restore = false, invalidate = true, priority = 1 }
|
||||
local hlopts = { undo_restore = false, invalidate = true, priority = 1, strict = false }
|
||||
--- Move messages to expanded cmdline, dialog or pager to show in full.
|
||||
--- Return updated target+buffer in case it differs from 'src'.
|
||||
---
|
||||
@@ -240,7 +240,6 @@ function M.expand_msg(src, tgt, focus)
|
||||
local hidden = not pager_shown()
|
||||
tgt = tgt or not hidden and 'pager' or 'cmd' ---@type 'cmd'|'dialog'|'msg'|'pager'
|
||||
if tgt ~= src then
|
||||
local srow = hidden and 0 or api.nvim_buf_line_count(ui.bufs.pager)
|
||||
local opts = { details = true, type = 'highlight' }
|
||||
local marks = api.nvim_buf_get_extmarks(ui.bufs[src], -1, 0, -1, opts)
|
||||
local lines = api.nvim_buf_get_lines(ui.bufs[src], 0, -1, false)
|
||||
@@ -252,6 +251,8 @@ function M.expand_msg(src, tgt, focus)
|
||||
M.virt[src] = { {}, {} }
|
||||
end
|
||||
|
||||
-- Append to visible pager, replace any other target. msg_clear() events may have edited pager.
|
||||
local srow = (not hidden and tgt == 'pager') and api.nvim_buf_line_count(ui.bufs.pager) or 0
|
||||
api.nvim_buf_set_lines(ui.bufs[tgt], srow, -1, false, lines)
|
||||
for _, m in ipairs(marks) do
|
||||
hlopts.hl_group, hlopts.end_col, hlopts.end_row =
|
||||
|
||||
@@ -1450,5 +1450,23 @@ describe('messages2', function()
|
||||
{9:de} |
|
||||
|
|
||||
]])
|
||||
|
||||
-- A prompt with pending cmd messages moves them to the dialog (cmdline.lua). The pager is
|
||||
-- still shown, but its line count must not offset the marks copied into the dialog.
|
||||
exec_lua(function()
|
||||
local ui = require('vim._core.ui2')
|
||||
vim.api.nvim_buf_set_lines(ui.bufs.cmd, 0, -1, false, { 'err' })
|
||||
local o = { end_row = 0, end_col = 3, hl_group = 'ErrorMsg' }
|
||||
vim.api.nvim_buf_set_extmark(ui.bufs.cmd, ui.ns, 0, 0, o)
|
||||
ui.msg.expand_msg('cmd', 'dialog')
|
||||
end)
|
||||
screen:expect([[
|
||||
|
|
||||
{1:~ }|*9
|
||||
{3: }|
|
||||
{3:^ }|
|
||||
{9:err} |
|
||||
|
|
||||
]])
|
||||
end)
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user