mirror of
https://github.com/neovim/neovim.git
synced 2025-09-05 19:08:15 +00:00
feat(extui): don't enter pager for routed message #34679
Problem: Messages routed to the pager to be shown in full, enter the pager automatically, yielding another "press-q-prompt". Solution: Only enter the pager when requested explicitly. Otherwise, close the pager on the next typed mapping, unless that mapping entered the pager.
This commit is contained in:
@@ -114,7 +114,7 @@ end
|
|||||||
---@param level integer
|
---@param level integer
|
||||||
---@param abort boolean
|
---@param abort boolean
|
||||||
function M.cmdline_hide(level, abort)
|
function M.cmdline_hide(level, abort)
|
||||||
if M.row > 0 or level > 1 then
|
if M.row > 0 or level > (fn.getcmdwintype() == '' and 1 or 2) then
|
||||||
return -- No need to hide when still in nested cmdline or cmdline_block.
|
return -- No need to hide when still in nested cmdline or cmdline_block.
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@@ -227,7 +227,7 @@ function M.show_msg(tar, content, replace_last, append, pager)
|
|||||||
count = M[tar].count + ((restart or msg == '\n') and 0 or 1)
|
count = M[tar].count + ((restart or msg == '\n') and 0 or 1)
|
||||||
|
|
||||||
-- Ensure cmdline is clear when writing the first message.
|
-- Ensure cmdline is clear when writing the first message.
|
||||||
if tar == 'cmd' and not will_pager and dupe == 0 and M.cmd.count == 0 then
|
if tar == 'cmd' and not will_pager and dupe == 0 and M.cmd.count == 0 and ext.cmd.row == 0 then
|
||||||
api.nvim_buf_set_lines(ext.bufs.cmd, 0, -1, false, {})
|
api.nvim_buf_set_lines(ext.bufs.cmd, 0, -1, false, {})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -450,6 +450,7 @@ function M.msg_history_show(entries)
|
|||||||
M.set_pos('pager')
|
M.set_pos('pager')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local routed = false
|
||||||
--- Adjust dimensions of the message windows after certain events.
|
--- Adjust dimensions of the message windows after certain events.
|
||||||
---
|
---
|
||||||
---@param type? 'cmd'|'dialog'|'msg'|'pager' Type of to be positioned window (nil for all).
|
---@param type? 'cmd'|'dialog'|'msg'|'pager' Type of to be positioned window (nil for all).
|
||||||
@@ -472,16 +473,37 @@ function M.set_pos(type)
|
|||||||
-- Ensure last line is visible and first line is at top of window.
|
-- Ensure last line is visible and first line is at top of window.
|
||||||
local row = (texth.all > height and texth.end_row or 0) + 1
|
local row = (texth.all > height and texth.end_row or 0) + 1
|
||||||
api.nvim_win_set_cursor(ext.wins.msg, { row, 0 })
|
api.nvim_win_set_cursor(ext.wins.msg, { row, 0 })
|
||||||
elseif type == 'pager' and api.nvim_win_get_config(win).hide then
|
elseif type == 'pager' then
|
||||||
-- Cannot leave the cmdwin to enter the pager, so close it.
|
|
||||||
-- NOTE: regression w.r.t. the message grid, which allowed this. Resolving
|
|
||||||
-- that would require somehow bypassing textlock for the pager.
|
|
||||||
if fn.getcmdwintype() ~= '' then
|
if fn.getcmdwintype() ~= '' then
|
||||||
api.nvim_command('quit')
|
if will_pager then
|
||||||
|
config.relative, config.win, config.row, config.col = 'win', 0, 0, 0
|
||||||
|
else
|
||||||
|
-- Cannot leave the cmdwin to enter the pager, so close it.
|
||||||
|
-- NOTE: regression w.r.t. the message grid, which allowed this.
|
||||||
|
-- Resolving that would require somehow bypassing textlock for the pager.
|
||||||
|
api.nvim_command('quit')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
routed = will_pager
|
||||||
-- It's actually closed one event iteration later so schedule in case it was open.
|
-- It's actually closed one event iteration later so schedule in case it was open.
|
||||||
vim.schedule(function()
|
vim.schedule(function()
|
||||||
|
-- For a routed message, hide pager on user input (unless that input focused the pager).
|
||||||
|
if routed then
|
||||||
|
vim.on_key(function(_, typed)
|
||||||
|
if typed then
|
||||||
|
vim.schedule(function()
|
||||||
|
if routed and api.nvim_win_is_valid(win) and api.nvim_get_current_win() ~= win then
|
||||||
|
api.nvim_win_set_config(win, { hide = true })
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
vim.on_key(nil, ext.ns)
|
||||||
|
end, ext.ns)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- When explicitly opened, enter and hide when window other than the cmdwin is entered.
|
||||||
api.nvim_set_current_win(win)
|
api.nvim_set_current_win(win)
|
||||||
api.nvim_create_autocmd({ 'WinEnter', 'CmdwinEnter', 'CmdwinLeave' }, {
|
api.nvim_create_autocmd({ 'WinEnter', 'CmdwinEnter', 'CmdwinLeave' }, {
|
||||||
callback = function(ev)
|
callback = function(ev)
|
||||||
@@ -492,7 +514,6 @@ function M.set_pos(type)
|
|||||||
if api.nvim_win_is_valid(win) then
|
if api.nvim_win_is_valid(win) then
|
||||||
api.nvim_win_set_config(win, config)
|
api.nvim_win_set_config(win, config)
|
||||||
end
|
end
|
||||||
-- Delete autocmd when a window other than the cmdwin is entered.
|
|
||||||
return ev.event == 'WinEnter'
|
return ev.event == 'WinEnter'
|
||||||
end,
|
end,
|
||||||
desc = 'Hide inactive pager window.',
|
desc = 'Hide inactive pager window.',
|
||||||
|
@@ -54,4 +54,38 @@ describe('cmdline2', function()
|
|||||||
/foo^ |
|
/foo^ |
|
||||||
]])
|
]])
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('block mode', function()
|
||||||
|
feed(':if 1<CR>')
|
||||||
|
screen:expect([[
|
||||||
|
|
|
||||||
|
{1:~ }|*11
|
||||||
|
{16::}{15:if} {26:1} |
|
||||||
|
{16::} ^ |
|
||||||
|
]])
|
||||||
|
feed('echo "foo"<CR>')
|
||||||
|
screen:expect([[
|
||||||
|
|
|
||||||
|
{1:~ }|*9
|
||||||
|
{16::}{15:if} {26:1} |
|
||||||
|
{16::} {15:echo} {26:"foo"} |
|
||||||
|
{15:foo} |
|
||||||
|
{16::} ^ |
|
||||||
|
]])
|
||||||
|
feed('endif')
|
||||||
|
screen:expect([[
|
||||||
|
|
|
||||||
|
{1:~ }|*9
|
||||||
|
{16::}{15:if} {26:1} |
|
||||||
|
{16::} {15:echo} {26:"foo"} |
|
||||||
|
{15:foo} |
|
||||||
|
{16::} {15:endif}^ |
|
||||||
|
]])
|
||||||
|
feed('<CR>')
|
||||||
|
screen:expect([[
|
||||||
|
^ |
|
||||||
|
{1:~ }|*12
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
@@ -48,29 +48,42 @@ describe('messages2', function()
|
|||||||
-- Multiple messages in same event loop iteration are appended.
|
-- Multiple messages in same event loop iteration are appended.
|
||||||
feed([[q:echo "foo\nbar" | echo "baz"<CR>]])
|
feed([[q:echo "foo\nbar" | echo "baz"<CR>]])
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
|
|
^ |
|
||||||
{1:~ }|*8
|
{1:~ }|*8
|
||||||
─────────────────────────────────────────────────────|
|
─────────────────────────────────────────────────────|
|
||||||
{4:^foo }|
|
{4:foo }|
|
||||||
{4:bar }|
|
{4:bar }|
|
||||||
{4:baz }|
|
{4:baz }|
|
||||||
1,1 All|
|
0,0-1 All|
|
||||||
|
]])
|
||||||
|
-- Any key press closes the routed pager.
|
||||||
|
feed('j')
|
||||||
|
screen:expect([[
|
||||||
|
^ |
|
||||||
|
{1:~ }|*12
|
||||||
|
0,0-1 All|
|
||||||
]])
|
]])
|
||||||
-- No error for ruler virt_text msg_row exceeding buffer length.
|
-- No error for ruler virt_text msg_row exceeding buffer length.
|
||||||
command([[map Q <cmd>echo "foo\nbar" <bar> ls<CR>]])
|
command([[map Q <cmd>echo "foo\nbar" <bar> ls<CR>]])
|
||||||
feed('qQ')
|
feed('Q')
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
|
|
^ |
|
||||||
{1:~ }|*7
|
{1:~ }|*7
|
||||||
─────────────────────────────────────────────────────|
|
─────────────────────────────────────────────────────|
|
||||||
{4:^foo }|
|
{4:foo }|
|
||||||
{4:bar }|
|
{4:bar }|
|
||||||
{4: }|
|
{4: }|
|
||||||
{4: 1 %a "[No Name]" line 1 }|
|
{4: 1 %a "[No Name]" line 1 }|
|
||||||
1,1 All|
|
0,0-1 All|
|
||||||
|
]])
|
||||||
|
feed('<Esc>')
|
||||||
|
screen:expect([[
|
||||||
|
^ |
|
||||||
|
{1:~ }|*12
|
||||||
|
0,0-1 All|
|
||||||
]])
|
]])
|
||||||
-- edit_unputchar() does not clear already updated screen #34515.
|
-- edit_unputchar() does not clear already updated screen #34515.
|
||||||
feed('qix<Esc>dwi<C-r>')
|
feed('ix<Esc>dwi<C-r>')
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
{18:^"} |
|
{18:^"} |
|
||||||
{1:~ }|*12
|
{1:~ }|*12
|
||||||
|
Reference in New Issue
Block a user