mirror of
https://github.com/neovim/neovim.git
synced 2026-03-31 04:42:03 +00:00
fix(ui2): wildmenu hidden behind dialog window #37684
Problem: The wildmenu is hidden behind the dialog window with "list" in 'wildmode'.
Global ('laststatus' set to 3) statusline is hidden behind the
pager window.
Solution: Check wildmenumode() to adjust the dialog position when necessary.
Ensure pager is positioned above the global statusline with 'laststus' set to 3.
This commit is contained in:
@@ -8,6 +8,7 @@ local M = {
|
||||
srow = 0, -- Buffer row at which the current cmdline starts; > 0 in block mode.
|
||||
erow = 0, -- Buffer row at which the current cmdline ends; messages appended here in block mode.
|
||||
level = -1, -- Current cmdline level; 0 when inactive, -1 one loop iteration after closing.
|
||||
wmnumode = 0, -- Return value of wildmenumode(), dialog position adjusted when toggled.
|
||||
}
|
||||
|
||||
--- Set the 'cmdheight' and cmdline window height. Reposition message windows.
|
||||
@@ -28,6 +29,9 @@ local function win_config(win, hide, height)
|
||||
vim.o.cmdheight = height
|
||||
end)
|
||||
ext.msg.set_pos()
|
||||
elseif M.wmnumode ~= (M.prompt and fn.wildmenumode() or 0) then
|
||||
M.wmnumode = (M.wmnumode == 1 and 0 or 1)
|
||||
ext.msg.set_pos()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -469,25 +469,20 @@ end
|
||||
---@param type? 'cmd'|'dialog'|'msg'|'pager' Type of to be positioned window (nil for all).
|
||||
function M.set_pos(type)
|
||||
local function win_set_pos(win)
|
||||
local cfg = { hide = false, relative = 'laststatus', col = 10000 }
|
||||
local texth = type and api.nvim_win_text_height(win, {}) or {}
|
||||
local height = type and math.min(texth.all, math.ceil(o.lines * 0.5))
|
||||
local top = { vim.opt.fcs:get().msgsep or ' ', 'MsgSeparator' }
|
||||
local border = win ~= ext.wins.msg and { '', top, '', '', '', '', '', '' } or nil
|
||||
local config = {
|
||||
hide = false,
|
||||
relative = (win == ext.wins.pager or win == ext.wins.dialog) and 'editor' or 'laststatus',
|
||||
border = border,
|
||||
height = height,
|
||||
row = (win == ext.wins.pager or win == ext.wins.dialog) and o.lines - o.cmdheight or 0,
|
||||
col = 10000,
|
||||
focusable = type == 'cmd' or nil, -- Allow entering the cmdline window.
|
||||
}
|
||||
api.nvim_win_set_config(win, config)
|
||||
cfg.height = type and math.min(texth.all, math.ceil(o.lines * 0.5))
|
||||
cfg.border = win ~= ext.wins.msg and { '', top, '', '', '', '', '', '' } or nil
|
||||
cfg.focusable = type == 'cmd' or nil
|
||||
cfg.row = (win == ext.wins.msg and 0 or 1) - ext.cmd.wmnumode
|
||||
cfg.row = cfg.row - ((win == ext.wins.pager and o.laststatus == 3) and 1 or 0)
|
||||
api.nvim_win_set_config(win, cfg)
|
||||
|
||||
if type == 'cmd' and not cmd_on_key then
|
||||
-- Temporarily showing a full message in the cmdline, until next key press.
|
||||
local save_spill = M.virt.msg[M.virt.idx.spill][1]
|
||||
local spill = texth.all > height and (' [+%d]'):format(texth.all - height)
|
||||
local spill = texth.all > cfg.height and (' [+%d]'):format(texth.all - cfg.height)
|
||||
M.virt.msg[M.virt.idx.spill][1] = spill and { 0, spill } or nil
|
||||
set_virttext('msg', 'cmd')
|
||||
M.virt.msg[M.virt.idx.spill][1] = save_spill
|
||||
@@ -554,7 +549,7 @@ function M.set_pos(type)
|
||||
end)
|
||||
elseif type == 'msg' then
|
||||
-- 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 > cfg.height and texth.end_row or 0) + 1
|
||||
api.nvim_win_set_cursor(ext.wins.msg, { row, 0 })
|
||||
elseif type == 'pager' then
|
||||
if fn.getcmdwintype() ~= '' then
|
||||
@@ -571,10 +566,10 @@ function M.set_pos(type)
|
||||
api.nvim_create_autocmd({ 'WinEnter', 'CmdwinEnter', 'CmdwinLeave' }, {
|
||||
callback = function(ev)
|
||||
if api.nvim_win_is_valid(ext.wins.pager) then
|
||||
local cfg = ev.event == 'CmdwinLeave' and config
|
||||
local config = ev.event == 'CmdwinLeave' and cfg
|
||||
or ev.event == 'WinEnter' and { hide = true }
|
||||
or { relative = 'win', win = 0, row = 0, col = 0 }
|
||||
api.nvim_win_set_config(ext.wins.pager, cfg)
|
||||
api.nvim_win_set_config(ext.wins.pager, config)
|
||||
end
|
||||
return ev.event == 'WinEnter'
|
||||
end,
|
||||
|
||||
@@ -33,7 +33,7 @@ local tab = 0
|
||||
---Ensure target buffers and windows are still valid.
|
||||
function M.check_targets()
|
||||
local curtab = api.nvim_get_current_tabpage()
|
||||
for _, type in ipairs({ 'cmd', 'dialog', 'msg', 'pager' }) do
|
||||
for i, type in ipairs({ 'cmd', 'dialog', 'msg', 'pager' }) do
|
||||
local setopt = not api.nvim_buf_is_valid(M.bufs[type])
|
||||
if setopt then
|
||||
M.bufs[type] = api.nvim_create_buf(false, false)
|
||||
@@ -50,8 +50,8 @@ function M.check_targets()
|
||||
anchor = type ~= 'cmd' and 'SE' or nil,
|
||||
hide = type ~= 'cmd' or M.cmdheight == 0 or nil,
|
||||
border = type ~= 'msg' and 'none' or nil,
|
||||
-- kZIndexMessages < zindex < kZIndexCmdlinePopupMenu (grid_defs.h), pager below others.
|
||||
zindex = 200 + (type == 'cmd' and 1 or type == 'pager' and -1 or 0),
|
||||
-- kZIndexMessages < cmd zindex < kZIndexCmdlinePopupMenu (grid_defs.h), pager below others.
|
||||
zindex = 201 - i,
|
||||
_cmdline_offset = type == 'cmd' and 0 or nil,
|
||||
})
|
||||
if tab ~= curtab and api.nvim_win_is_valid(M.wins[type]) then
|
||||
|
||||
@@ -13,6 +13,7 @@ describe('cmdline2', function()
|
||||
screen = Screen.new()
|
||||
screen:add_extra_attr_ids({
|
||||
[100] = { foreground = Screen.colors.Magenta1, bold = true },
|
||||
[101] = { background = Screen.colors.Yellow, foreground = Screen.colors.Grey0 },
|
||||
})
|
||||
exec_lua(function()
|
||||
require('vim._extui').enable({})
|
||||
@@ -180,6 +181,44 @@ describe('cmdline2', function()
|
||||
{16::}{15:s}{16:/f}^ |
|
||||
]])
|
||||
end)
|
||||
|
||||
it('dialog position is adjusted for toggled wildmenu', function()
|
||||
exec([[
|
||||
set wildmode=list:full,full wildoptions-=pum
|
||||
func Foo()
|
||||
endf
|
||||
func Fooo()
|
||||
endf
|
||||
]])
|
||||
feed(':call Fo<C-Z>')
|
||||
screen:expect([[
|
||||
|
|
||||
{1:~ }|*9
|
||||
{3: }|
|
||||
Foo() Fooo() |
|
||||
|
|
||||
{16::}{15:call} Fo^ |
|
||||
]])
|
||||
feed('<C-Z>')
|
||||
screen:expect([[
|
||||
|
|
||||
{1:~ }|*8
|
||||
{3: }|
|
||||
Foo() Fooo() |
|
||||
|
|
||||
{101:Foo()}{3: Fooo() }|
|
||||
{16::}{15:call} {25:Foo}{16:()}^ |
|
||||
]])
|
||||
feed('()')
|
||||
screen:expect([[
|
||||
|
|
||||
{1:~ }|*9
|
||||
{3: }|
|
||||
Foo() Fooo() |
|
||||
|
|
||||
{16::}{15:call} {25:Foo}{16:()()}^ |
|
||||
]])
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('cmdline2', function()
|
||||
|
||||
Reference in New Issue
Block a user