diff options
author | Mathias Fußenegger <mfussenegger@users.noreply.github.com> | 2025-03-14 09:51:52 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-14 09:51:52 +0100 |
commit | 123f8d229eef05869ee4c98dfd4934c22a03b1f6 (patch) | |
tree | 8d61078fb3ffd635e3926d3c17d8eeea94b27b2b /test/functional/lua/snippet_spec.lua | |
parent | 6401b433f7c040663b1ae01204e1b07b567d6a1b (diff) | |
download | rneovim-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.lua | 34 |
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) |