aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/lua.txt15
-rw-r--r--runtime/lua/vim/_defaults.lua21
-rw-r--r--runtime/lua/vim/snippet.lua75
-rw-r--r--test/functional/lua/snippet_spec.lua34
-rw-r--r--test/functional/plugin/lsp/completion_spec.lua4
5 files changed, 43 insertions, 106 deletions
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index 6705768aeb..a99b050195 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -4551,16 +4551,6 @@ vim.snippet.active({filter}) *vim.snippet.active()*
Returns `true` if there's an active snippet in the current buffer,
applying the given filter if provided.
- You can use this function to navigate a snippet as follows: >lua
- vim.keymap.set({ 'i', 's' }, '<Tab>', function()
- if vim.snippet.active({ direction = 1 }) then
- return '<Cmd>lua vim.snippet.jump(1)<CR>'
- else
- return '<Tab>'
- end
- end, { expr = true })
-<
-
Parameters: ~
• {filter} (`vim.snippet.ActiveFilter?`) Filter to constrain the search
with:
@@ -4585,14 +4575,15 @@ vim.snippet.jump({direction}) *vim.snippet.jump()*
Jumps to the next (or previous) placeholder in the current snippet, if
possible.
- For example, map `<Tab>` to jump while a snippet is active: >lua
+ By default `<Tab>` is setup to jump if a snippet is active. The default
+ mapping looks like: >lua
vim.keymap.set({ 'i', 's' }, '<Tab>', function()
if vim.snippet.active({ direction = 1 }) then
return '<Cmd>lua vim.snippet.jump(1)<CR>'
else
return '<Tab>'
end
- end, { expr = true })
+ end, { descr = '...', expr = true, silent = true })
<
Parameters: ~
diff --git a/runtime/lua/vim/_defaults.lua b/runtime/lua/vim/_defaults.lua
index dcf9b6ba70..7440af1a96 100644
--- a/runtime/lua/vim/_defaults.lua
+++ b/runtime/lua/vim/_defaults.lua
@@ -218,6 +218,27 @@ do
end, { desc = 'vim.lsp.buf.signature_help()' })
end
+ do
+ ---@param direction vim.snippet.Direction
+ ---@param key string
+ 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, {
+ desc = 'vim.snippet.jump if active, otherwise ' .. key,
+ expr = true,
+ silent = true,
+ })
+ end
+
+ set_snippet_jump(1, '<Tab>')
+ set_snippet_jump(-1, '<S-Tab>')
+ end
+
--- Map [d and ]d to move to the previous/next diagnostic. Map <C-W>d to open a floating window
--- for the diagnostic under the cursor.
---
diff --git a/runtime/lua/vim/snippet.lua b/runtime/lua/vim/snippet.lua
index bfd439181e..2edea6d5ad 100644
--- a/runtime/lua/vim/snippet.lua
+++ b/runtime/lua/vim/snippet.lua
@@ -2,8 +2,6 @@ local G = vim.lsp._snippet_grammar
local snippet_group = vim.api.nvim_create_augroup('nvim.snippet', {})
local snippet_ns = vim.api.nvim_create_namespace('nvim.snippet')
local hl_group = 'SnippetTabstop'
-local jump_forward_key = '<tab>'
-local jump_backward_key = '<s-tab>'
--- Returns the 0-based cursor position.
---
@@ -213,64 +211,9 @@ function Session.new(bufnr, snippet_extmark, tabstop_data)
end
end
- self:set_keymaps()
-
return self
end
---- Sets the snippet navigation keymaps.
----
---- @package
-function Session:set_keymaps()
- local function maparg(key, mode)
- local map = vim.fn.maparg(key, mode, false, true) --[[ @as table ]]
- if not vim.tbl_isempty(map) and map.buffer == 1 then
- return map
- else
- return nil
- end
- end
-
- local function set(jump_key, direction)
- vim.keymap.set({ 'i', 's' }, jump_key, function()
- return vim.snippet.active({ direction = direction })
- and '<cmd>lua vim.snippet.jump(' .. direction .. ')<cr>'
- or jump_key
- end, { expr = true, silent = true, buffer = self.bufnr })
- end
-
- self.tab_keymaps = {
- i = maparg(jump_forward_key, 'i'),
- s = maparg(jump_forward_key, 's'),
- }
- self.shift_tab_keymaps = {
- i = maparg(jump_backward_key, 'i'),
- s = maparg(jump_backward_key, 's'),
- }
- set(jump_forward_key, 1)
- set(jump_backward_key, -1)
-end
-
---- Restores/deletes the keymaps used for snippet navigation.
----
---- @package
-function Session:restore_keymaps()
- local function restore(keymap, lhs, mode)
- if keymap then
- vim._with({ buf = self.bufnr }, function()
- vim.fn.mapset(keymap)
- end)
- else
- vim.api.nvim_buf_del_keymap(self.bufnr, mode, lhs)
- end
- end
-
- restore(self.tab_keymaps.i, jump_forward_key, 'i')
- restore(self.tab_keymaps.s, jump_forward_key, 's')
- restore(self.shift_tab_keymaps.i, jump_backward_key, 'i')
- restore(self.shift_tab_keymaps.s, jump_backward_key, 's')
-end
-
--- Returns the destination tabstop index when jumping in the given direction.
---
--- @package
@@ -604,7 +547,7 @@ end
--- Jumps to the next (or previous) placeholder in the current snippet, if possible.
---
---- For example, map `<Tab>` to jump while a snippet is active:
+--- By default `<Tab>` is setup to jump if a snippet is active. The default mapping looks like:
---
--- ```lua
--- vim.keymap.set({ 'i', 's' }, '<Tab>', function()
@@ -613,7 +556,7 @@ end
--- else
--- return '<Tab>'
--- end
---- end, { expr = true })
+--- end, { descr = '...', expr = true, silent = true })
--- ```
---
--- @param direction (vim.snippet.Direction) Navigation direction. -1 for previous, 1 for next.
@@ -656,18 +599,6 @@ end
--- Returns `true` if there's an active snippet in the current buffer,
--- applying the given filter if provided.
---
---- You can use this function to navigate a snippet as follows:
----
---- ```lua
---- vim.keymap.set({ 'i', 's' }, '<Tab>', function()
---- if vim.snippet.active({ direction = 1 }) then
---- return '<Cmd>lua vim.snippet.jump(1)<CR>'
---- else
---- return '<Tab>'
---- end
---- end, { expr = true })
---- ```
----
--- @param filter? vim.snippet.ActiveFilter Filter to constrain the search with:
--- - `direction` (vim.snippet.Direction): Navigation direction. Will return `true` if the snippet
--- can be jumped in the given direction.
@@ -689,8 +620,6 @@ function M.stop()
return
end
- M._session:restore_keymaps()
-
vim.api.nvim_clear_autocmds({ group = snippet_group, buffer = M._session.bufnr })
vim.api.nvim_buf_clear_namespace(M._session.bufnr, snippet_ns, 0, -1)
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)
diff --git a/test/functional/plugin/lsp/completion_spec.lua b/test/functional/plugin/lsp/completion_spec.lua
index 8d362642de..94578aa6da 100644
--- a/test/functional/plugin/lsp/completion_spec.lua
+++ b/test/functional/plugin/lsp/completion_spec.lua
@@ -1241,7 +1241,9 @@ describe('vim.lsp.completion: integration', function()
}
end)
)
- feed('<tab>')
+ exec_lua(function()
+ vim.snippet.jump(1)
+ end)
eq(
#'hello friends',
exec_lua(function()