LuaSnip
LuaSnip copied to clipboard
luasnip doesn't remove autocomplete placeholder marks after exiting insert mode
Basic description is that after accepting an autocompletion luasnip, somehow pressing again tab in insert mode results in the caret jumping back to the autocompletion that was accepted.
I'm using luasnip with basic nvim-cmp integration.
-- Setup Completion
-- See https://github.com/hrsh7th/nvim-cmp#basic-configuration
-- https://github.com/hrsh7th/nvim-cmp/wiki/Example-mappings#luasnip
local has_words_before = function()
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
end
local cmp = require'cmp'
local luasnip = require("luasnip")
cmp.setup({
-- Enable LSP snippets
snippet = {
expand = function(args)
require'luasnip'.lsp_expand(args.body)
end
},
mapping = {
['<C-p>'] = cmp.mapping.select_prev_item(),
['<C-n>'] = cmp.mapping.select_next_item(),
-- Add tab support
['<C-d>'] = cmp.mapping.scroll_docs(-4),
['<C-f>'] = cmp.mapping.scroll_docs(4),
['<C-Space>'] = cmp.mapping.complete(),
['<C-e>'] = cmp.mapping.close(),
['<CR>'] = cmp.mapping.confirm({
behavior = cmp.ConfirmBehavior.Insert,
select = true,
}),
["<Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif luasnip.expand_or_jumpable() then
luasnip.expand_or_jump()
elseif has_words_before() then
cmp.complete()
else
fallback()
end
end, { "i", "s" }),
["<S-Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item()
elseif luasnip.jumpable(-1) then
luasnip.jump(-1)
else
fallback()
end
end, { "i", "s" }),
},
-- Installed sources
sources = {
{ name = 'luasnip' },
{ name = 'nvim_lsp' },
{ name = 'buffer' },
{ name = 'path' },
},
})
Ah, this is just the default-behaviour of luasnip, placeholders are always visited in order (including the $0, which is the one you're jumping back into) (and that does not depend on cursor-movement), so if a snippet is not jumped "through", you'll end up back in it, regardless how the cursor moved.
This can be adjusted by passing a few options to luasnip.setup: region_check_events are the auto-events, on which a check if the cursor is still inside the active snippet is performed. If it is not, the snippet will be jumped "through"/completed/left, so you won't jump back into it.
I'd recommend
luasnip.setup({
region_check_events = "CursorHold,InsertLeave",
-- those are for removing deleted snippets, also a common problem
delete_check_events = "TextChanged,InsertEnter",
})
but you might want to adjust those to fire more regularly.
local luasnip = require("luasnip")
luasnip.config.setup({
region_check_events = "CursorHold,InsertLeave",
delete_check_events = "TextChanged,InsertEnter",
})
cmp.setup({
enabled = function()
-- disable completion in comments
...
});
this doesn't appear to change anything. Even though the author of nvim-cmp sent me back here, the gif doesn't actually trigger a luasnip automcomplete, I think the deal is just in how the <tab> integrates luasnip and nvim-cmp, but the autocomplete that causes this behavior is an nvim-cmp autocomplete.
Appending an ,InsertEnter to region_check_events should do it, if you exactly re-do the gif. I'll check later if that's also the case for me.
Its not an issue with cmp, the problem is that luasnip will always jump through all placeholders/tabstops of a snippet. It does not matter whether the Cursor is moved around, the internal state of which tabstops will be jumped to next is preserved.
Not sure what you mean with Luasnip autocomplete though, the important part is that a snippet is expanded, and luasnip takes care of that.
That seems to have done it.
Is this method still working ?
I have

but it gives the same error, If I move out of the snippets manually and work on something else then the tab brings me back to end of the snippet
edit:
Tab Function of cmp if required

Maybe append append TextChangedI to region_check_events? Or CursorMovedI, but that might be too aggressive.. (ie runs that function too often, maybe affecting performance)
For this snippet if I (instead of pressing tab inside the $$ )manually leave it and then press tab anywhere else then I always come back to the end of the snippet