fix(cmdwin): handle control characters properly #40488

- Replace newlines in the current cmdline with NULs when opening cmdwin,
  and do the reverse when putting a cmdwin line back into the cmdline.
- Escape control characters with Ctrl-V when feeding cmdline.
This commit is contained in:
zeertzjq
2026-06-30 20:00:31 +08:00
committed by GitHub
parent f89972e13a
commit 6c5f0cf29f
2 changed files with 31 additions and 8 deletions

View File

@@ -81,9 +81,10 @@ function M.open(type, init_line, init_col)
vim.wo[win][0].statuscolumn = '%#NonText#' .. type
local filled = fill_history(buf, type)
init_line = init_line and init_line:gsub('\n', '\0') or ''
-- Append the in-flight cmdline as the last line (or only line if history is empty).
vim.api.nvim_buf_set_lines(buf, filled and -1 or 0, -1, false, { init_line or '' })
vim.api.nvim_buf_set_lines(buf, filled and -1 or 0, -1, false, { init_line })
local last = vim.api.nvim_buf_line_count(buf)
vim.api.nvim_win_set_cursor(win, { last, math.max(0, (init_col or 1) - 1) })
@@ -92,6 +93,11 @@ function M.open(type, init_line, init_col)
vim.bo[buf].filetype = 'vim'
end
if vim.o.wildchar == ('\t'):byte() then
vim.keymap.set('i', '<Tab>', '<C-X><C-V>', { buf = buf })
vim.keymap.set('n', '<Tab>', 'a<C-X><C-V>', { buf = buf })
end
vim.api.nvim__cmdwin_set(type, buf) -- Update the C-side globals.
state = {
@@ -155,6 +161,7 @@ function M.confirm()
return
end
local line, type = _close()
line = line:gsub('%z', '\n'):gsub('(%c)', '\022%1') -- Escape control characters.
vim.api.nvim_feedkeys(type .. line .. vim.keycode('<CR>'), 'nt', false)
end
@@ -164,6 +171,7 @@ function M.cancel()
return
end
local line, type = _close()
line = line:gsub('%z', '\n'):gsub('(%c)', '\022%1') -- Escape control characters.
vim.api.nvim_feedkeys(type .. line, 'nt', false)
end