hrsh7th / nvim-cmp

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

Crash plugin while navigate in menu snippets LuaSnip (nvim-cmp/lua/cmp/utils/str.lua:81: bad argument #1 to byte (string expected, got table) #1832

Open Forsigg opened 4 months ago

Forsigg commented 4 months ago

FAQ

Announcement

Minimal reproducible full config

local cmp = require 'cmp'
local luasnip = require 'luasnip'

local has_words_before = function()
  unpack = unpack or table.unpack
  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_kinds = {
  Text = '  ',
  Method = '  ',
  Function = '  ',
  Constructor = '  ',
  Field = '  ',
  Variable = '  ',
  Class = '  ',
  Interface = '  ',
  Module = '  ',
  Property = '  ',
  Unit = '  ',
  Value = '  ',
  Enum = '  ',
  Keyword = '  ',
  Snippet = '  ',
  Color = '  ',
  File = '  ',
  Reference = '  ',
  Folder = '  ',
  EnumMember = '  ',
  Constant = '  ',
  Struct = '  ',
  Event = '  ',
  Operator = '  ',
  TypeParameter = '  ',
}

cmp.setup({
    snippet = {
        -- REQUIRED - you must specify a snippet engine
        expand = function(args)
            -- vim.fn["vsnip#anonymous"](args.body) -- For `vsnip` users.
            luasnip.lsp_expand(args.body) -- For `luasnip` users.
            -- require('snippy').expand_snippet(args.body) -- For `snippy` users.
            -- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users.
        end
    }, 
    formatting = {
        format = function(_, vim_item)
            vim_item.kind = (cmp_kinds[vim_item.kind] or '') .. vim_item.kind
            return vim_item
        end,
    },
    window = {
        completion = cmp.config.window.bordered(),
        documentation = cmp.config.window.bordered()
    },
    mapping = {

        ["<Tab>"] = cmp.mapping(function(fallback)
            if cmp.visible() then
                cmp.select_next_item()
                -- You could replace the expand_or_jumpable() calls with expand_or_locally_jumpable()
                -- that way you will only jump inside the snippet region
            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" }),
    },
    sources = {
        { name = 'nvim_lsp' },
        { name = 'luasnip ', option = { use_show_condition = false, show_autosnippets = true } },
        { name = 'buffer' },
        { name = 'nvim_lsp_signature_help' }
    }
    -- sources = cmp.config.sources({
    --     { name = 'luasnip' },
    --     {name = 'nvim_lsp'}, {name = 'vsnip'} -- For vsnip users.
    -- }, {{name = 'buffer'}, {name = 'nvim_lsp_signature_help'}})
})

-- Set configuration for specific filetype.
cmp.setup.filetype('gitcommit', {
    sources = cmp.config.sources({
        {name = 'cmp_git'} -- You can specify the `cmp_git` source if you were installed it.
    }, {{name = 'buffer'}})
})

-- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore).
cmp.setup.cmdline({'/', '?'}, {
    mapping = cmp.mapping.preset.cmdline(),
    sources = {{name = 'buffer'}}
})

-- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore).
cmp.setup.cmdline(':', {
    mapping = cmp.mapping.preset.cmdline(),
    sources = cmp.config.sources({{name = 'path'}}, {{name = 'cmdline'}})
})

-- Set up lspconfig.
local capabilities = require('cmp_nvim_lsp').default_capabilities()
require('lspconfig')['tsserver'].setup {capabilities = capabilities}

Description

Hello! I apologize in advance for my English. I've installed the Luasnip plugin, write my own snippets for python. Then, I started work in neovim, try to use my snippets, but while I navigating through menu for select snippet neovim crash with that error: изображение

I've try to find solution, but is none. This is my snippet:

{
    "PythonScriptEntrypoint": {
        "prefix": ["ifname", "if __name__"],
        "body": [
            "if __name__ == '__main__':",
            "    main()"
        ],
        "description": "Insert entrypoint for Python script",
        "scope": "python"
    }
}

After debugging nvim-cmp plugin I found that description from my plugin in lua code not string as expected. Its a table (array) with one element - string with description.

Steps to reproduce

  1. Add luasnip plugin
  2. In cmp config select snippet section with luasnip.lsp_expand
  3. Load VSCode-like snippet (require('luasnip.loaders.from_vscode').load({paths = "~/path/to/snippets"})
  4. Check snippets are avialable (:LuaSnipListAvailable)
  5. Try to select snippet in cmp menu

Expected behavior

Description as string. In JSON its string

Actual behavior

Description - table (array) with one element - string

Additional context

I fixed that in my local machine. Next step after that Issue I create PR with fix

rogedelgado commented 4 months ago

Hey, I have the same behavior but with LSP completions. I try with the marksman LPS server and I got:

image

Forsigg commented 4 months ago

@rogedelgado Hey! I've pushing PR that fixed this bug - #1833 You can fix local before its merged

rogedelgado commented 4 months ago

@rogedelgado Hey! I've pushing PR that fixed this bug - #1833 You can fix local before its merged

Thanks @Forsigg, I will try this ASAP