diff options
| author | luukvbaal <luukvbaal@gmail.com> | 2026-03-24 14:53:25 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-24 09:53:25 -0400 |
| commit | b2adfe775d5e22efca2f9943abeb48e0cc4498c5 (patch) | |
| tree | 5efde8499779fa9ffbca7023cdde83ed89ce210f /runtime/lua/vim/_core | |
| parent | 042c66e4f9a6f03ccfcf20cda99876175178e4cd (diff) | |
| download | rneovim-b2adfe775d5e22efca2f9943abeb48e0cc4498c5.tar.gz rneovim-b2adfe775d5e22efca2f9943abeb48e0cc4498c5.tar.bz2 rneovim-b2adfe775d5e22efca2f9943abeb48e0cc4498c5.zip | |
fix(ui2): show messages in dialog window when entering expanded cmdline #38465
Problem: - With expanded messages exceeding cfg.msg.cmd.height, entering
the cmdline scrolls to the bottom and expands to the full "cmd"
buffer text height.
- Cursor in the pager is not always at the last message and at
the bottom of the window when appending to the pager.
- unreliable test: messages2_spec: "closed msg window timer removes
empty lines".
Solution: - Achieve separation of the cmdline and message text by moving
messages to the dialog window when entering the cmdline below
expanded messages.
- Set cursor to start of the first message only when first
entering the pager. Use `norm! zb` to position last message
at the bottom of the window (which shouldn't crash anymore
since 911337eb).
- Increase cfg.msg.msg.timeout used in the test file.
Diffstat (limited to 'runtime/lua/vim/_core')
| -rw-r--r-- | runtime/lua/vim/_core/ui2/cmdline.lua | 7 | ||||
| -rw-r--r-- | runtime/lua/vim/_core/ui2/messages.lua | 31 |
2 files changed, 20 insertions, 18 deletions
diff --git a/runtime/lua/vim/_core/ui2/cmdline.lua b/runtime/lua/vim/_core/ui2/cmdline.lua index 6532074181..0b9638275f 100644 --- a/runtime/lua/vim/_core/ui2/cmdline.lua +++ b/runtime/lua/vim/_core/ui2/cmdline.lua @@ -92,10 +92,11 @@ end ---@param level integer ---@param hl_id integer function M.cmdline_show(content, pos, firstc, prompt, indent, level, hl_id) - -- When entering the cmdline while it is expanded, place cmdline below messages. + -- When entering the cmdline while it is expanded, move messages to dialog window. if M.level == 0 and ui.msg.cmd_on_key then - M.srow = api.nvim_buf_line_count(ui.bufs.cmd) - M.expand, ui.msg.cmd_on_key = 1, nil + M.expand, M.dialog, ui.msg.cmd_on_key = 1, true, nil + api.nvim_win_set_config(ui.wins.cmd, { border = 'none' }) + ui.msg.expand_msg('cmd') elseif ui.msg.cmd.msg_row ~= -1 and M.expand == 0 then ui.msg.msg_clear() end diff --git a/runtime/lua/vim/_core/ui2/messages.lua b/runtime/lua/vim/_core/ui2/messages.lua index 9ddbca5e76..8f1bea929d 100644 --- a/runtime/lua/vim/_core/ui2/messages.lua +++ b/runtime/lua/vim/_core/ui2/messages.lua @@ -191,13 +191,13 @@ local function set_virttext(type, tgt) end local hlopts = { undo_restore = false, invalidate = true, priority = 1 } ---- Move messages to expanded cmdline or pager to show in full. -local function expand_msg(src) +--- Move messages to expanded cmdline, dialog or pager to show in full. +function M.expand_msg(src) -- Copy and clear message from src to enlarged cmdline that is dismissed by any -- key press. Append to pager instead if it isn't hidden or we want to enter it -- after cmdline was entered during expanded cmdline. local hidden = api.nvim_win_get_config(ui.wins.pager).hide - local tgt = (ui.cmd.expand > 0 or not hidden) and 'pager' or 'cmd' + local tgt = (src == 'dialog' or not hidden) and 'pager' or ui.cmd.expand > 0 and 'dialog' or 'cmd' if tgt ~= src then local srow = hidden and 0 or api.nvim_buf_line_count(ui.bufs.pager) local opts = { details = true, type = 'highlight' } @@ -322,17 +322,16 @@ function M.show_msg(tgt, kind, content, replace_last, append, id) api.nvim_win_set_width(ui.wins.msg, width) local texth = api.nvim_win_text_height(ui.wins.msg, { start_row = start_row, end_row = row }) if texth.all > math.ceil(o.lines * 0.5) then - expand_msg(tgt) + M.expand_msg(tgt) else M.msg.width = width M.msg:start_timer(buf, id) end elseif tgt == 'cmd' and dupe == 0 then fn.clearmatches(ui.wins.cmd) -- Clear matchparen highlights. - if ui.cmd.srow > 0 and ui.cmd.expand == 0 then + if ui.cmd.srow > 0 then -- In block mode the cmdheight is already dynamic, so just print the full message - -- regardless of height. Put cmdline below message. Don't do this if the block mode - -- was simulated for a cmdline entered while expanded, will open pager instead. + -- regardless of height. Put cmdline below message. ui.cmd.srow = row + 1 else api.nvim_win_set_cursor(ui.wins.cmd, { 1, 0 }) -- ensure first line is visible @@ -345,7 +344,7 @@ function M.show_msg(tgt, kind, content, replace_last, append, id) -- Expand the cmdline for a non-error message that doesn't fit. local error_kinds = { rpc_error = 1, emsg = 1, echoerr = 1, lua_error = 1 } if texth.all > ui.cmdheight and (ui.cmdheight == 0 or not error_kinds[kind]) then - expand_msg(tgt) + M.expand_msg(tgt) end end end @@ -429,17 +428,18 @@ function M.msg_show(kind, content, replace_last, _, append, id, trigger) -- When message was emitted below an already expanded cmdline, move and route to pager. tgt = ui.cmd.expand > 0 and 'pager' or tgt if ui.cmd.expand == 1 then - expand_msg('cmd') + M.expand_msg('dialog') end ui.cmd.expand = ui.cmd.expand + (ui.cmd.expand > 0 and 1 or 0) local enter_pager = tgt == 'pager' and not in_pager - M.show_msg(tgt, kind, content, replace_last or enter_pager or ui.cmd.expand > 0, append, id) - -- Don't remember search_cmd message as actual message. + M.show_msg(tgt, kind, content, replace_last or enter_pager, append, id) if kind == 'search_cmd' then + -- Don't remember search_cmd message as actual message. M.cmd.ids, M.prev_msg = {}, '' - elseif tgt == 'pager' and in_pager and not enter_pager then - api.nvim_win_set_cursor(ui.wins.pager, { api.nvim_buf_line_count(ui.bufs.pager), 0 }) + elseif tgt == 'pager' then + -- Position cursor at start of first or last message at bottom of window. + fn.win_execute(ui.wins.pager, 'norm! ' .. (enter_pager and 'gg0' or 'G0zb')) end end end @@ -500,6 +500,7 @@ function M.msg_history_show(entries, prev_cmd) for i, entry in ipairs(entries) do M.show_msg('pager', entry[1], entry[2], i == 1, entry[3], 0) end + api.nvim_win_set_cursor(ui.wins.pager, { 1, 0 }) M.set_pos('pager') end @@ -526,6 +527,7 @@ local cmd_on_key = function(_, typed) api.nvim_command('norm! g<') end set_virttext('msg') + return entered and '' end --- Add virtual [+x] text to indicate scrolling is possible. @@ -595,7 +597,6 @@ local function enter_pager() -- Cmdwin is closed one event iteration later so schedule in case it was open. vim.schedule(function() local height, id = api.nvim_win_get_height(ui.wins.pager), 0 - api.nvim_win_set_cursor(ui.wins.pager, { 1, 0 }) api.nvim_set_option_value('eiw', '', { scope = 'local', win = ui.wins.pager }) api.nvim_set_current_win(ui.wins.pager) id = api.nvim_create_autocmd({ 'WinEnter', 'CmdwinEnter', 'WinResized' }, { @@ -646,7 +647,7 @@ function M.set_pos(tgt) cfg.row, cfg.height = win_row_height(t, texth.all) cfg.border = t ~= 'msg' and { '', top, '', '', '', '', '', '' } or nil cfg.mouse = tgt == 'cmd' or nil - cfg.title = tgt == 'dialog' and cfg.height < texth.all and { hint } or nil + cfg.title = tgt == 'dialog' and { cfg.height < texth.all and hint or { '' } } or nil api.nvim_win_set_config(win, cfg) if tgt == 'cmd' and not M.cmd_on_key then |