aboutsummaryrefslogtreecommitdiff
path: root/test/functional/lua/snippet_spec.lua
diff options
context:
space:
mode:
authorMathias Fußenegger <mfussenegger@users.noreply.github.com>2025-03-14 09:51:52 +0100
committerGitHub <noreply@github.com>2025-03-14 09:51:52 +0100
commit123f8d229eef05869ee4c98dfd4934c22a03b1f6 (patch)
tree8d61078fb3ffd635e3926d3c17d8eeea94b27b2b /test/functional/lua/snippet_spec.lua
parent6401b433f7c040663b1ae01204e1b07b567d6a1b (diff)
downloadrneovim-123f8d229eef05869ee4c98dfd4934c22a03b1f6.tar.gz
rneovim-123f8d229eef05869ee4c98dfd4934c22a03b1f6.tar.bz2
rneovim-123f8d229eef05869ee4c98dfd4934c22a03b1f6.zip
feat(snippet): set snippet keymaps permanent instead of dynamic (#31887)
Problem: Given that `vim.snippet.expand()` sets temporary `<tab>`/`<s-tab>` keymaps there is no way to build "smart-tab" functionality where `<tab>` chooses the next completion candidate if the popup menu is visible. Solution: Set the keymap permanent in `_defaults`. The downside of this approach is that users of multiple snippet engine's need to adapt their keymaps to handle all their engines that are in use. For example: vim.keymap.set({ 'i', 's' }, "<Tab>", function() if foreign_snippet.active() then return "<Cmd>lua require('foreign_snippet').jump()<CR>" elseif vim.snippet.active({ direction = 1 }) then return "<Cmd>lua vim.snippet.jump(1)<CR>" else return key end end, { expr = true }) Upside is that using `vim.keymap.set` to override keymaps is a well established pattern and `vim.snippet.expand` calls made by nvim itself or plugins have working keymaps out of the box. Co-authored-by: Maria José Solano <majosolano99@gmail.com>
Diffstat (limited to 'test/functional/lua/snippet_spec.lua')
-rw-r--r--test/functional/lua/snippet_spec.lua34
1 files changed, 14 insertions, 20 deletions
diff --git a/test/functional/lua/snippet_spec.lua b/test/functional/lua/snippet_spec.lua
index eb2f17216c..be18fe7898 100644
--- a/test/functional/lua/snippet_spec.lua
+++ b/test/functional/lua/snippet_spec.lua
@@ -18,6 +18,20 @@ local retry = t.retry
describe('vim.snippet', function()
before_each(function()
clear()
+ exec_lua(function()
+ local function set_snippet_jump(direction, key)
+ vim.keymap.set({ 'i', 's' }, key, function()
+ if vim.snippet.active({ direction = direction }) then
+ return string.format('<Cmd>lua vim.snippet.jump(%d)<CR>', direction)
+ else
+ return key
+ end
+ end, { silent = true, expr = true })
+ end
+
+ set_snippet_jump(1, '<Tab>')
+ set_snippet_jump(-1, '<S-Tab>')
+ end)
end)
after_each(clear)
@@ -289,24 +303,4 @@ describe('vim.snippet', function()
]]
)
end)
-
- it('restores snippet navigation keymaps', function()
- -- Create a buffer keymap in insert mode that deletes all lines.
- local curbuf = api.nvim_get_current_buf()
- exec_lua('vim.api.nvim_buf_set_keymap(..., "i", "<Tab>", "<cmd>normal ggdG<cr>", {})', curbuf)
-
- test_expand_success({ 'var $1 = $2' }, { 'var = ' })
-
- -- While the snippet is active, <Tab> should navigate between tabstops.
- feed('x')
- poke_eventloop()
- feed('<Tab>0')
- eq({ 'var x = 0' }, buf_lines(0))
-
- exec_lua('vim.snippet.stop()')
-
- -- After exiting the snippet, the buffer keymap should be restored.
- feed('<Esc>O<cr><Tab>')
- eq({ '' }, buf_lines(0))
- end)
end)