neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit 39a5b7f239fb74eae06adbe3995d6bd2c4e230e2
parent c916bdf3298608d26ec6f68dd7eb0f830e7b7909
Author: luukvbaal <luukvbaal@gmail.com>
Date:   Fri,  2 May 2025 19:46:30 +0200

fix(extui): cmdline visibility, cmdheight cursor position (#33774)

Problem:  The cmdline popupmenu is hidden behind extui windows.
          'showmode' message is drawn over the cmdline.
          Changing the 'cmdheight' to accommodate space for the text in
          the cmdline may change the current cursor position.
Solution: Ensure kZIndexMessages < zindex < kZIndexCmdlinePopupMenu.
          Clear the 'showmode' message when the cmdline level is negative.
          Temporarily set 'splitkeep' = "screen" when changing the 'cmdheight'.
Diffstat:
Mruntime/lua/vim/_extui/cmdline.lua | 15++++++++++-----
Mruntime/lua/vim/_extui/messages.lua | 3+--
Mruntime/lua/vim/_extui/shared.lua | 3++-
3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/runtime/lua/vim/_extui/cmdline.lua b/runtime/lua/vim/_extui/cmdline.lua @@ -6,6 +6,7 @@ local M = { indent = 0, -- Current indent for block event. prompt = false, -- Whether a prompt is active; messages are placed in the 'prompt' window. row = 0, -- Current row in the cmdline buffer, > 0 for block events. + level = -1, -- Current cmdline level, < 0 when inactive (otherwise unused). } --- Set the 'cmdheight' and cmdline window height. Reposition message windows. @@ -20,7 +21,11 @@ local function win_config(win, hide, height) api.nvim_win_set_height(win, height) end if vim.o.cmdheight ~= height then - vim.cmd('noautocmd set cmdheight=' .. height) + -- Avoid moving the cursor with 'splitkeep' = "screen", and altering the user + -- configured value with noautocmd. + vim._with({ noautocmd = true, o = { splitkeep = 'screen' } }, function() + vim.o.cmdheight = height + end) ext.msg.set_pos() end end @@ -47,10 +52,10 @@ end ---@param firstc string ---@param prompt string ---@param indent integer ---@param level integer +---@param level integer ---@param hl_id integer -function M.cmdline_show(content, pos, firstc, prompt, indent, _, hl_id) - M.indent, M.prompt = indent, #prompt > 0 +function M.cmdline_show(content, pos, firstc, prompt, indent, level, hl_id) + M.level, M.indent, M.prompt = level, indent, #prompt > 0 -- Only enable TS highlighter for Ex commands (not search or filter commands). M.highlighter.active[ext.bufs.cmd] = firstc == ':' and M.highlighter or nil set_text(content, ('%s%s%s'):format(firstc, prompt, (' '):rep(indent))) @@ -127,7 +132,7 @@ function M.cmdline_hide(_, abort) end) end - M.prompt, curpos[1], curpos[2] = false, 0, 0 + M.prompt, M.level, curpos[1], curpos[2] = false, -1, 0, 0 win_config(ext.wins[ext.tab].cmd, true, ext.cmdheight) end diff --git a/runtime/lua/vim/_extui/messages.lua b/runtime/lua/vim/_extui/messages.lua @@ -331,7 +331,7 @@ function M.msg_clear() end --- ---@param content MsgContent function M.msg_showmode(content) - M.virt.last[M.virt.idx.mode] = content + M.virt.last[M.virt.idx.mode] = ext.cmd.level < 0 and content or {} M.virt.last[M.virt.idx.search] = {} set_virttext('last') end @@ -386,7 +386,6 @@ function M.set_pos(type) height = height, row = win == ext.wins[ext.tab].box and 0 or 1, col = 10000, - zindex = type == 'more' and 299 or nil, }) if type == 'box' then -- Ensure last line is visible and first line is at top of window. diff --git a/runtime/lua/vim/_extui/shared.lua b/runtime/lua/vim/_extui/shared.lua @@ -29,7 +29,6 @@ local wincfg = { -- Default cfg for nvim_open_win(). width = 10000, height = 1, noautocmd = true, - zindex = 300, } --- Ensure the various buffers and windows have not been deleted. @@ -63,6 +62,8 @@ function M.tab_check_wins() hide = type ~= 'cmd' or M.cmdheight == 0 or nil, title = type == 'more' and 'Messages' or nil, border = type == 'box' and not o.termguicolors and 'single' or border or 'none', + -- kZIndexMessages < zindex < kZIndexCmdlinePopupMenu (grid_defs.h), 'more' below others. + zindex = 200 - (type == 'more' and 1 or 0), _cmdline_offset = type == 'cmd' and 0 or nil, }) M.wins[M.tab][type] = api.nvim_open_win(M.bufs[type], false, cfg)