mirror of
https://github.com/neovim/neovim.git
synced 2026-06-16 00:31:16 +00:00
fix(ui2): dialog paging is inconsistent #39128
Problem: - Paging keys in the dialog window consume input when the user
may not expect it. The dismissable title hint intended to
mitigate that results in having to press Escape twice to
abandon the prompt.
- Mimicked "msgsep" float border is taking up unnecessary
space when window takes up the entire screen.
Solution: - Use (conventional, albeit less convenient) keys intended
for scrolling to page the dialog window:
<(Mousewheel/Page)Up/Down>, <Home/End>.
- Only set the float top border when separation is actually
necessary, i.e. window does not reach the first row.
(cherry picked from commit f0a8e6f337)
This commit is contained in:
committed by
github-actions[bot]
parent
9d66c7828e
commit
b08c289a45
@@ -527,6 +527,7 @@ local cmd_on_key = function(key, typed)
|
||||
or (typed:find('LeftMouse') and fn.getmousepos().winid == ui.wins.cmd)
|
||||
if entered then
|
||||
M.expand_msg('cmd', 'pager')
|
||||
api.nvim_win_set_cursor(ui.wins.pager, { 1, 0 })
|
||||
end
|
||||
pcall(api.nvim_win_close, ui.wins.cmd, true)
|
||||
ui.check_targets()
|
||||
@@ -554,28 +555,19 @@ local dialog_on_key = function(_, typed)
|
||||
typed = typed and fn.keytrans(typed)
|
||||
if not typed then
|
||||
return
|
||||
elseif typed == '<Esc>' then
|
||||
-- Stop paging, redraw empty title to reflect paging is no longer active.
|
||||
api.nvim_win_set_config(ui.wins.dialog, { title = '' })
|
||||
api.nvim__redraw({ flush = true })
|
||||
vim.on_key(nil, M.dialog_on_key)
|
||||
M.dialog_on_key = nil
|
||||
return ''
|
||||
end
|
||||
|
||||
local page_keys = {
|
||||
g = 'gg',
|
||||
G = 'G',
|
||||
j = 'Lj',
|
||||
k = 'Hk',
|
||||
d = [[\<C-D>]],
|
||||
u = [[\<C-U>]],
|
||||
f = [[\<C-F>]],
|
||||
b = [[\<C-B>]],
|
||||
}
|
||||
local info = page_keys[typed] and fn.getwininfo(ui.wins.dialog)[1]
|
||||
if info and (typed ~= 'f' or info.botline < api.nvim_buf_line_count(ui.bufs.dialog)) then
|
||||
fn.win_execute(ui.wins.dialog, ('exe "norm! %s"'):format(page_keys[typed]))
|
||||
-- TODO: no hint anymore, so should at least be documented at some point.
|
||||
local map, eob = {}, typed:match('PageDown')
|
||||
map['<Home>'], map['<End>'] = 'gg', 'G'
|
||||
map['<Up>'], map['<C-Y>'] = 'Hk', 'Hk'
|
||||
map['<Down>'], map['<C-E>'] = 'Lj', 'Lj'
|
||||
map['<PageUp>'], map['<S-PageUp>'] = [[\<C-B>]], [[\<C-B>]]
|
||||
map['<PageDown>'], map['<S-PageDown>'] = [[\<C-F>]], [[\<C-F>]]
|
||||
|
||||
local info = map[typed] and fn.getwininfo(ui.wins.dialog)[1]
|
||||
if info and (not eob or info.botline < api.nvim_buf_line_count(ui.bufs.dialog)) then
|
||||
fn.win_execute(ui.wins.dialog, ('exe "norm! %s"'):format(map[typed]))
|
||||
set_top_bot_spill()
|
||||
return fn.getwininfo(ui.wins.dialog)[1].topline ~= info.topline and '' or nil
|
||||
end
|
||||
@@ -583,16 +575,17 @@ end
|
||||
|
||||
local was_cmdwin = ''
|
||||
---@param min integer Minimum window height.
|
||||
local function win_row_height(tgt, min)
|
||||
local function win_row_height_border(tgt, min)
|
||||
local cfgmin = ui.cfg.msg[tgt].height --[[@as number]]
|
||||
cfgmin = cfgmin > 1 and cfgmin or math.ceil(o.lines * cfgmin)
|
||||
min = math.min(min, cfgmin > 1 and cfgmin or math.ceil(o.lines * cfgmin))
|
||||
if tgt ~= 'pager' then
|
||||
return (tgt == 'msg' and 0 or 1) - ui.cmd.wmnumode, math.min(min, cfgmin)
|
||||
return (tgt == 'msg' and 0 or 1) - ui.cmd.wmnumode, min, min < o.lines - ui.cmdheight
|
||||
end
|
||||
local cmdwin = fn.getcmdwintype() ~= was_cmdwin and api.nvim_win_get_height(0) or 0
|
||||
local global_stl = (cmdwin > 0 or o.laststatus == 3) and 1 or 0
|
||||
local row = 1 - cmdwin - global_stl
|
||||
return row, math.min(math.min(cfgmin, min), o.lines - 1 - ui.cmdheight - global_stl - cmdwin)
|
||||
local top = min < o.lines - ui.cmdheight - global_stl - cmdwin
|
||||
return row, math.min(min, o.lines - (top and 1 or 0) - ui.cmdheight - global_stl - cmdwin), top
|
||||
end
|
||||
|
||||
local function enter_pager()
|
||||
@@ -624,7 +617,7 @@ local function enter_pager()
|
||||
in_pager = in_pager and api.nvim_win_is_valid(ui.wins.pager)
|
||||
local cfg = in_pager and { relative = 'laststatus', col = 0 } or { hide = true }
|
||||
if in_pager then
|
||||
cfg.row, cfg.height = win_row_height('pager', height)
|
||||
cfg.row, cfg.height, cfg.border = win_row_height_border('pager', height)
|
||||
else
|
||||
pcall(api.nvim_set_option_value, 'eiw', 'all', { scope = 'local', win = ui.wins.pager })
|
||||
api.nvim_del_autocmd(id)
|
||||
@@ -651,14 +644,10 @@ function M.set_pos(tgt)
|
||||
if cfg and (tgt or not cfg.hide) then
|
||||
local texth = api.nvim_win_text_height(win, {})
|
||||
local top = { vim.opt.fcs:get().msgsep or ' ', 'MsgSeparator' }
|
||||
local hint = 'f/d/j: screen/page/line down, b/u/k: up, <Esc>: stop paging'
|
||||
cfg = { hide = false, relative = 'laststatus', col = 10000 } ---@type table
|
||||
cfg.row, cfg.height = win_row_height(t, texth.all)
|
||||
cfg.border = t ~= 'msg' and { '', top, '', '', '', '', '', '' } or nil
|
||||
cfg.row, cfg.height, cfg.border = win_row_height_border(t, texth.all)
|
||||
cfg.border = cfg.border and t ~= 'msg' and { '', top, '', '', '', '', '', '' } or nil
|
||||
cfg.mouse = tgt == 'cmd' or nil
|
||||
cfg.title = tgt == 'dialog'
|
||||
and { { ui.cmd.expand == 0 and cfg.height < texth.all and hint or '', 'MsgMore' } }
|
||||
or nil
|
||||
api.nvim_win_set_config(win, cfg)
|
||||
|
||||
if tgt == 'cmd' then
|
||||
@@ -668,7 +657,7 @@ function M.set_pos(tgt)
|
||||
set_virttext('msg', 'cmd')
|
||||
M.virt.msg[M.virt.idx.spill][1] = { 0, (' [+%d]'):format(texth.all - ui.cmdheight) }
|
||||
M.cmd_on_key = vim.on_key(cmd_on_key, ui.ns)
|
||||
elseif tgt == 'dialog' and set_top_bot_spill() and #cfg.title[1][1] > 0 then
|
||||
elseif tgt == 'dialog' and set_top_bot_spill() then
|
||||
M.dialog_on_key = vim.on_key(dialog_on_key, M.dialog_on_key)
|
||||
elseif tgt == 'msg' then
|
||||
-- Ensure last line is visible and first line is at top of window.
|
||||
|
||||
@@ -182,25 +182,22 @@ describe('messages2', function()
|
||||
-- Do enter the pager in normal mode.
|
||||
feed('<CR>')
|
||||
screen:expect([[
|
||||
{3: }|
|
||||
^foo |
|
||||
foo |*11
|
||||
foo |*12
|
||||
1,1 Top|
|
||||
]])
|
||||
-- Changing 'laststatus' reveals the global statusline with a pager height
|
||||
-- exceeding the available lines: #38008.
|
||||
command('set laststatus=3')
|
||||
screen:expect([[
|
||||
{3: }|
|
||||
^foo |
|
||||
foo |*10
|
||||
foo |*11
|
||||
{3:[Pager] 1,1 Top}|
|
||||
|
|
||||
]])
|
||||
feed(':<C-F>')
|
||||
screen:expect([[
|
||||
{3: }|
|
||||
foo |*4
|
||||
foo |*5
|
||||
{1::}echo "foo" | echo "bar\nbaz\n"->repeat(&lines) |
|
||||
{1::}^ |
|
||||
{1:~ }|*5
|
||||
@@ -209,8 +206,7 @@ describe('messages2', function()
|
||||
]])
|
||||
command('wincmd +')
|
||||
screen:expect([[
|
||||
{3: }|
|
||||
foo |*3
|
||||
foo |*4
|
||||
{1::}echo "foo" | echo "bar\nbaz\n"->repeat(&lines) |
|
||||
{1::}^ |
|
||||
{1:~ }|*6
|
||||
@@ -219,8 +215,7 @@ describe('messages2', function()
|
||||
]])
|
||||
command('echo "foo"')
|
||||
screen:expect([[
|
||||
{3: }|
|
||||
foo |*3
|
||||
foo |*4
|
||||
{1::}echo "foo" | echo "bar\nbaz\n"->repeat(&lines) |
|
||||
{1::}^ |
|
||||
{1:~ }|*6
|
||||
@@ -229,8 +224,7 @@ describe('messages2', function()
|
||||
]])
|
||||
feed('<C-C>')
|
||||
screen:expect([[
|
||||
{3: }|
|
||||
foo |*11
|
||||
foo |*12
|
||||
{3:[Pager] 1,1 Top}|
|
||||
{16::}^ |
|
||||
]])
|
||||
@@ -248,9 +242,8 @@ describe('messages2', function()
|
||||
]])
|
||||
feed(':messages<CR>')
|
||||
screen:expect([[
|
||||
{3: }|
|
||||
^foo |
|
||||
foo |*10
|
||||
foo |*11
|
||||
{3:[Pager] 1,1 Top}|
|
||||
|
|
||||
]])
|
||||
@@ -527,7 +520,7 @@ describe('messages2', function()
|
||||
local top = [[
|
||||
|
|
||||
{1:~ }|*4
|
||||
{3: }f/d/j: screen/page/line down, b/u/k: up, <Esc>: stop paging{3: }|
|
||||
{3: }|
|
||||
0 |
|
||||
1 |
|
||||
2 |
|
||||
@@ -539,11 +532,11 @@ describe('messages2', function()
|
||||
]]
|
||||
feed(':call inputlist(range(100))<CR>')
|
||||
screen:expect(top)
|
||||
feed('j')
|
||||
feed('<Down>')
|
||||
screen:expect([[
|
||||
|
|
||||
{1:~ }|*4
|
||||
{3: }f/d/j: screen/page/line down, b/u/k: up, <Esc>: stop paging{3: }|
|
||||
{3: }|
|
||||
1 [+1] |
|
||||
2 |
|
||||
3 |
|
||||
@@ -553,29 +546,13 @@ describe('messages2', function()
|
||||
7 [+92] |
|
||||
Type number and <Enter> or click with the mouse (q or empty cancels): ^ |
|
||||
]])
|
||||
feed('k')
|
||||
feed('<Up>')
|
||||
screen:expect(top)
|
||||
feed('d')
|
||||
feed('<PageDown>')
|
||||
screen:expect([[
|
||||
|
|
||||
{1:~ }|*4
|
||||
{3: }f/d/j: screen/page/line down, b/u/k: up, <Esc>: stop paging{3: }|
|
||||
3 [+3] |
|
||||
4 |
|
||||
5 |
|
||||
6 |
|
||||
7 |
|
||||
8 |
|
||||
9 [+90] |
|
||||
Type number and <Enter> or click with the mouse (q or empty cancels): ^ |
|
||||
]])
|
||||
feed('u')
|
||||
screen:expect(top)
|
||||
feed('f')
|
||||
screen:expect([[
|
||||
|
|
||||
{1:~ }|*4
|
||||
{3: }f/d/j: screen/page/line down, b/u/k: up, <Esc>: stop paging{3: }|
|
||||
{3: }|
|
||||
5 [+5] |
|
||||
6 |
|
||||
7 |
|
||||
@@ -585,13 +562,13 @@ describe('messages2', function()
|
||||
11 [+88] |
|
||||
Type number and <Enter> or click with the mouse (q or empty cancels): ^ |
|
||||
]])
|
||||
feed('b')
|
||||
feed('<PageUp>')
|
||||
screen:expect(top)
|
||||
feed('G')
|
||||
feed('<End>')
|
||||
screen:expect([[
|
||||
|
|
||||
{1:~ }|*4
|
||||
{3: }f/d/j: screen/page/line down, b/u/k: up, <Esc>: stop paging{3: }|
|
||||
{3: }|
|
||||
93 [+93] |
|
||||
94 |
|
||||
95 |
|
||||
@@ -602,38 +579,10 @@ describe('messages2', function()
|
||||
Type number and <Enter> or click with the mouse (q or empty cancels): ^ |
|
||||
]])
|
||||
-- No scrolling beyond end of buffer #36114
|
||||
feed('f')
|
||||
screen:expect([[
|
||||
|
|
||||
{1:~ }|*3
|
||||
{3: }f/d/j: screen/page/line down, b/u/k: up, <Esc>: stop paging{3: }|
|
||||
93 [+93] |
|
||||
94 |
|
||||
95 |
|
||||
96 |
|
||||
97 |
|
||||
98 |
|
||||
99 |
|
||||
Type number and <Enter> or click with the mouse (q or empty cancels): f|
|
||||
^ |
|
||||
]])
|
||||
feed('<Backspace>g')
|
||||
feed('<PageDown>')
|
||||
screen:expect_unchanged()
|
||||
feed('<Home>')
|
||||
screen:expect(top)
|
||||
feed('<Esc>f')
|
||||
screen:expect([[
|
||||
|
|
||||
{1:~ }|*3
|
||||
{3: }|
|
||||
0 |
|
||||
1 |
|
||||
2 |
|
||||
3 |
|
||||
4 |
|
||||
5 |
|
||||
6 [+93] |
|
||||
Type number and <Enter> or click with the mouse (q or empty cancels): f|
|
||||
^ |
|
||||
]])
|
||||
end)
|
||||
|
||||
it('FileType is fired after default options are set', function()
|
||||
|
||||
Reference in New Issue
Block a user