commit ecded994c17344d0428bffe2a1774522164eb06f
parent 7ed8cbd095805b9e6079def91b13ec24ecec5348
Author: TheBlob42 <hessenmobbel@web.de>
Date: Sun, 3 Aug 2025 21:52:09 +0200
fix(snippet): early return for final tabstop #35115
The cursor movement autocommand can not detect when the final tabstop $0
is directly adjacent to another tabstop, which prevents ending the
snippet session. The fix is an early return when jumping.
Diffstat:
3 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/runtime/lua/vim/snippet.lua b/runtime/lua/vim/snippet.lua
@@ -585,6 +585,12 @@ function M.jump(direction)
M._session.current_tabstop = dest
select_tabstop(dest)
+ -- The cursor is not on a tabstop so exit the session.
+ if dest.index == 0 then
+ M.stop()
+ return
+ end
+
-- Activate expansion of the destination tabstop.
M._session:set_group_gravity(dest.index, false)
diff --git a/test/functional/lua/snippet_spec.lua b/test/functional/lua/snippet_spec.lua
@@ -214,6 +214,20 @@ describe('vim.snippet', function()
eq(false, exec_lua('return vim.snippet.active()'))
end)
+ it('stop session when jumping to $0', function()
+ test_expand_success({ 'local ${1:name} = ${2:value}$0' }, { 'local name = value' })
+ -- Jump to $2
+ feed('<Tab>')
+ poke_eventloop()
+ -- Jump to $0 (stop snippet)
+ feed('<Tab>')
+ poke_eventloop()
+ -- Insert literal \t
+ feed('<Tab>')
+ poke_eventloop()
+ eq({ 'local name = value\t' }, buf_lines(0))
+ end)
+
it('inserts choice', function()
test_expand_success({ 'console.${1|assert,log,error|}()' }, { 'console.()' })
wait_for_pum()
diff --git a/test/functional/plugin/lsp/completion_spec.lua b/test/functional/plugin/lsp/completion_spec.lua
@@ -1309,7 +1309,7 @@ describe('vim.lsp.completion: integration', function()
end)
feed('<C-n><C-y>')
eq(
- { true, { 'if true then', '\t', 'end' } },
+ { false, { 'if true then', '\t', 'end' } },
exec_lua(function()
return {
vim.snippet.active({ direction = 1 }),