commit 628d569a594c762952b769776b9c79221fdb23d0
parent dff78f580dfae583023b20aa58e46e616607bdb6
Author: TheBlob42 <hessenmobbel@web.de>
Date: Sun, 27 Jul 2025 22:10:00 +0200
fix(snippet): jumping backwards to choice node (#35062)
Avoid duplicate text when jumping back to a choice node. Set cursor to
end of tabstop range and prioritize current choice in completion items.
Diffstat:
2 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/runtime/lua/vim/snippet.lua b/runtime/lua/vim/snippet.lua
@@ -257,10 +257,21 @@ local M = { session = nil }
local function display_choices(tabstop)
assert(tabstop.choices, 'Tabstop has no choices')
+ local text = tabstop:get_text()
+ local found_text = false
+
local start_col = tabstop:get_range()[2] + 1
local matches = {} --- @type table[]
for _, choice in ipairs(tabstop.choices) do
- matches[#matches + 1] = { word = choice }
+ if choice ~= text then
+ matches[#matches + 1] = { word = choice }
+ else
+ found_text = true
+ end
+ end
+
+ if found_text then
+ table.insert(matches, 1, text)
end
vim.defer_fn(function()
@@ -298,6 +309,7 @@ local function select_tabstop(tabstop)
vim.cmd.startinsert({ bang = range[4] >= #vim.api.nvim_get_current_line() })
end
if tabstop.choices then
+ vim.fn.cursor(range[3] + 1, range[4] + 1)
display_choices(tabstop)
end
else
diff --git a/test/functional/lua/snippet_spec.lua b/test/functional/lua/snippet_spec.lua
@@ -240,6 +240,23 @@ describe('vim.snippet', function()
eq({ 'public function foo() {', '\t', '}' }, buf_lines(0))
end)
+ it('does not change the chosen text when jumping back to a choice tabstop', function()
+ test_expand_success(
+ { '${1|public,protected,private|} function ${2:name}() {', '\t$0', '}' },
+ { ' function name() {', '\t', '}' }
+ )
+ wait_for_pum()
+ feed('<C-n><C-y><Tab>')
+ poke_eventloop()
+ feed('<S-Tab>')
+ poke_eventloop()
+ wait_for_pum()
+ feed('<Tab>')
+ poke_eventloop()
+ feed('foo')
+ eq({ 'protected function foo() {', '\t', '}' }, buf_lines(0))
+ end)
+
it('jumps through adjacent tabstops', function()
test_expand_success(
{ 'for i=1,${1:to}${2:,step} do\n\t$3\nend' },