neovim

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

commit 8e8f4523c687cac4e966cb78856f73706dcec37d
parent f40e14008331fb6c5d83f09f7d245a9ec1d1abbd
Author: luukvbaal <luukvbaal@gmail.com>
Date:   Sat, 17 May 2025 11:24:05 +0200

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.
Diffstat:
Mruntime/lua/vim/_extui/cmdline.lua | 5++++-
Mruntime/lua/vim/_extui/messages.lua | 13++++++-------
2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/runtime/lua/vim/_extui/cmdline.lua b/runtime/lua/vim/_extui/cmdline.lua @@ -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. diff --git a/runtime/lua/vim/_extui/messages.lua b/runtime/lua/vim/_extui/messages.lua @@ -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