hrsh7th / nvim-cmp

A completion plugin for neovim coded in Lua.
MIT License
7.9k stars 394 forks source link

`nvim-cmp` is disrupted when luasnip's update_events is set to `{ "TextChanged", "TextChangedI" }` within a function/dynamic node #1743

Open schardev opened 11 months ago

schardev commented 11 months ago

FAQ

Announcement

Minimal reproducible full config

if has('vim_starting')
  set encoding=utf-8
endif
scriptencoding utf-8

if &compatible
  set nocompatible
endif

let s:plug_dir = expand('/tmp/plugged/vim-plug')
if !filereadable(s:plug_dir .. '/autoload/plug.vim')
  execute printf('!curl -fLo %s/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim', s:plug_dir)
end

execute 'set runtimepath+=' . s:plug_dir
call plug#begin(s:plug_dir)
Plug 'hrsh7th/nvim-cmp'
Plug 'hrsh7th/cmp-buffer'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'neovim/nvim-lspconfig'
Plug 'L3MON4D3/LuaSnip', {'tag': 'v2.*'}
Plug 'saadparwaiz1/cmp_luasnip'
call plug#end()
PlugInstall | quit

" Setup global configuration. More on configuration below.
lua << EOF
local cmp = require("cmp")
local ls = require("luasnip")
local fmt = require("luasnip.extras.fmt").fmt

ls.setup({
    update_events = { "TextChanged", "TextChangedI" },
})

ls.add_snippets("lua", {
    ls.s(
        { trig = "req", name = "require name" },
        fmt('local {} = require("{}")', {
            ls.d(2, function(args)
                local specifier = args[1][1]
                return ls.sn(nil, { ls.i(1, specifier) })
            end, { 1 }),
            ls.i(1, "specifier"),
        })
    ),
})

cmp.setup({
    snippet = {
        expand = function(args)
            require("luasnip").lsp_expand(args.body)
        end,
    },

    mapping = {
        ["<Tab>"] = cmp.mapping(function(fallback)
            if cmp.visible() then
                cmp.select_next_item()
            elseif ls.expand_or_jumpable() then
                ls.expand_or_jump()
            else
                fallback()
            end
        end, { "i", "s" }),
        ["<S-Tab>"] = cmp.mapping(function(fallback)
            if cmp.visible() then
                cmp.select_prev_item()
            elseif ls.jumpable(-1) then
                ls.jump(-1)
            else
                fallback()
            end
        end, { "i", "s" }),
        ["<CR>"] = cmp.mapping.confirm({ select = true }),
    },

    sources = cmp.config.sources({
        { name = "luasnip" },
        { name = "nvim_lsp" },
        { name = "buffer" },
    }),
})

local capabilities = require("cmp_nvim_lsp").default_capabilities()

require("lspconfig").lua_ls.setup({
    capabilities = capabilities,
})

EOF

Description

nvim-cmp is disrupted when luasnip's update_events is set to { "TextChanged", "TextChangedI" } within a function/dynamic node.

See https://github.com/L3MON4D3/LuaSnip/issues/503

Steps to reproduce

Try to use the require snippet in a lua file (as used in the minimal config above) and when inside the require parenthesis if the completion menu is visible instead of going to the next completion item after <Tab>-ing it directly jumps to the next insert node.

Expected behavior

It should cycle through the completion items list.

Actual behavior

As stated above.

Additional context

No response