diff options
-rw-r--r-- | runtime/doc/lua.txt | 15 | ||||
-rw-r--r-- | runtime/lua/vim/_defaults.lua | 21 | ||||
-rw-r--r-- | runtime/lua/vim/snippet.lua | 75 | ||||
-rw-r--r-- | test/functional/lua/snippet_spec.lua | 34 | ||||
-rw-r--r-- | test/functional/plugin/lsp/completion_spec.lua | 4 |
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() |