mirror of
https://github.com/neovim/neovim
synced 2025-07-16 09:11:51 +00:00
fix(extui): translate <Tab> in cmdline text (#34055)
Problem: <Tab> is not translated on the cmdline, and exposes a wrong assumption in search messages that may contain multiple chunks. Solution: Translate unprintable characters in the cmdline content. Extract the 'search_count' from the last chunk and route 'search_cmd' to cmdline to handle multiple chunks.
This commit is contained in:
@ -30,6 +30,7 @@ local function win_config(win, hide, height)
|
||||
end
|
||||
end
|
||||
|
||||
local cmdbuff ---@type string Stored cmdline used to calculate translation offset.
|
||||
local promptlen = 0 -- Current length of the prompt, stored for use in "cmdline_pos"
|
||||
--- Concatenate content chunks and set the text for the current row in the cmdline buffer.
|
||||
---
|
||||
@ -42,7 +43,8 @@ local function set_text(content, prompt)
|
||||
for _, chunk in ipairs(content) do
|
||||
prompt = prompt .. chunk[2]
|
||||
end
|
||||
api.nvim_buf_set_lines(ext.bufs.cmd, M.row, -1, false, { prompt .. ' ' })
|
||||
cmdbuff = prompt
|
||||
api.nvim_buf_set_lines(ext.bufs.cmd, M.row, -1, false, { fn.strtrans(cmdbuff) .. ' ' })
|
||||
end
|
||||
|
||||
--- Set the cmdline buffer text and cursor position.
|
||||
@ -93,6 +95,7 @@ local curpos = { 0, 0 } -- Last drawn cursor position.
|
||||
---@param pos integer
|
||||
--@param level integer
|
||||
function M.cmdline_pos(pos)
|
||||
pos = #fn.strtrans(cmdbuff:sub(1, pos + 1)) - 1
|
||||
if curpos[1] ~= M.row + 1 or curpos[2] ~= promptlen + pos then
|
||||
curpos[1], curpos[2] = M.row + 1, promptlen + pos
|
||||
-- Add matchparen highlighting to non-prompt part of cmdline.
|
||||
|
@ -311,14 +311,10 @@ local replace_bufwrite = false
|
||||
---@alias MsgContent MsgChunk[]
|
||||
---@param content MsgContent
|
||||
function M.msg_show(kind, content)
|
||||
if kind == 'search_cmd' then
|
||||
-- Set the entered search command in the cmdline.
|
||||
api.nvim_buf_set_lines(ext.bufs.cmd, 0, -1, false, { content[1][2] })
|
||||
M.virt.msg = ext.cfg.msg.pos == 'cmd' and { {}, {} } or M.virt.msg
|
||||
M.prev_msg = ext.cfg.msg.pos == 'cmd' and '' or M.prev_msg
|
||||
elseif kind == 'search_count' then
|
||||
if kind == 'search_count' then
|
||||
-- Extract only the search_count, not the entered search command.
|
||||
-- Match any of search.c:cmdline_search_stat():' [(x | >x | ?)/(y | >y | ??)]'
|
||||
content = { content[#content] }
|
||||
content[1][2] = content[1][2]:match('W? %[>?%d*%??/>?%d*%?*%]') .. ' '
|
||||
M.virt.last[M.virt.idx.search] = content
|
||||
M.virt.last[M.virt.idx.cmd] = { { 0, (' '):rep(11) } }
|
||||
@ -336,7 +332,8 @@ function M.msg_show(kind, content)
|
||||
M.show_msg('prompt', content, true)
|
||||
M.set_pos('prompt')
|
||||
else
|
||||
local tar = ext.cfg.msg.pos
|
||||
-- Set the entered search command in the cmdline.
|
||||
local tar = kind == 'search_cmd' and 'cmd' or ext.cfg.msg.pos
|
||||
if tar == 'cmd' then
|
||||
if ext.cmd.level > 0 then
|
||||
return -- Do not overwrite an active cmdline.
|
||||
@ -352,6 +349,8 @@ function M.msg_show(kind, content)
|
||||
M.show_msg(tar, content, replace_bufwrite, more)
|
||||
-- Replace message for every second bufwrite message.
|
||||
replace_bufwrite = not replace_bufwrite and kind == 'bufwrite'
|
||||
-- Don't remember search_cmd message as actual mesage.
|
||||
M.prev_msg = kind == 'search_cmd' and '' or M.prev_msg
|
||||
end
|
||||
end
|
||||
|
||||
|
Reference in New Issue
Block a user