fix(snippet): use <cmd>call cursor() for visual range

Problem:  Change applied in d3e495ce uses a byte-offset where a virtual
          column is expected.
Solution: Set the cursor directly through a <Cmd> mapping, while making
          sure the commands are ordered correctly by adding them to the
          type-ahead buffer.
(cherry picked from commit 019b2050e1)
This commit is contained in:
Luuk van Baal
2025-04-22 21:35:10 +02:00
committed by github-actions[bot]
parent 155529b91a
commit c1d3777db2
2 changed files with 16 additions and 16 deletions

View File

@ -278,15 +278,6 @@ local function select_tabstop(tabstop)
vim.api.nvim_feedkeys(keys, 'n', true)
end
--- NOTE: We don't use `vim.api.nvim_win_set_cursor` here because it causes the cursor to end
--- at the end of the selection instead of the start.
---
--- @param row integer
--- @param col integer
local function move_cursor_to(row, col)
feedkeys(string.format('%sG%s|', row, col))
end
local range = tabstop:get_range()
local mode = vim.fn.mode()
@ -311,13 +302,16 @@ local function select_tabstop(tabstop)
end
else
-- Else, select the tabstop's text.
if mode ~= 'n' then
feedkeys('<Esc>')
end
move_cursor_to(range[1] + 1, range[2] + 1)
feedkeys('v')
move_cursor_to(range[3] + 1, range[4])
feedkeys('o<c-g><c-r>_')
-- Need this exact order so cannot mix regular API calls with feedkeys, which
-- are not executed immediately. Use <Cmd> to set the cursor position.
local keys = {
mode ~= 'n' and '<Esc>' or '',
('<Cmd>call cursor(%s,%s)<CR>'):format(range[1] + 1, range[2] + 1),
'v',
('<Cmd>call cursor(%s,%s)<CR>'):format(range[3] + 1, range[4]),
'o<c-g><c-r>_',
}
feedkeys(table.concat(keys))
end
end

View File

@ -307,4 +307,10 @@ describe('vim.snippet', function()
]]
)
end)
it('correct visual selection with multi-byte text', function()
test_expand_success({ 'function(${1:var})' }, { '口口function(var)' }, nil, '口口')
feed('foo')
eq({ '口口function(foo)' }, buf_lines(0))
end)
end)