Snippet Expansion not working with tsserver
Hey all,
The snippet ecosystem is tightly coupled, so please let me know if you believe I should open this issue elsewhere. Below I provide my two relevant files. I will say that using the kickstarter.nvim and providing tsserver = { capabilities = capabilities } to set enable the completion protocol does not result in any changes from my config. Nor does it result in changes if I using the lspconfig.tsserver.setup syntax. I also followed another individuals configuration to see if it would help me, and although they show snippet expansion for TS, I still do not receive it.
The issue is that while I receive, say, a function name I defined in typescript in my autocomplete, selecting that function does not expand the snippet, it only completes the word.
In lua, defined functions are able to expand into snippets properly.
I would appreciate any guidance. I've been attempting to debug for hours now, and there seems to be little out there in terms of other people experiencing this issue.
lsp config:
{
'neovim/nvim-lspconfig',
lazy = false,
dependencies = {
{ 'williamboman/mason.nvim', config = true },
'williamboman/mason-lspconfig.nvim',
'WhoIsSethDaniel/mason-tool-installer.nvim',
{ 'j-hui/fidget.nvim', opts = {} },
{ 'folke/neodev.nvim', opts = {} },
},
config = function()
vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }),
callback = function(event)
local map = function(keys, func, desc)
vim.keymap.set('n', keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc })
end
map('gd', require('telescope.builtin').lsp_definitions, '[G]oto [D]efinition')
map('gr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences')
map('gI', require('telescope.builtin').lsp_implementations, '[G]oto [I]mplementation')
map('<leader>D', require('telescope.builtin').lsp_type_definitions, 'Type [D]efinition')
map('<leader>ds', require('telescope.builtin').lsp_document_symbols, '[D]ocument [S]ymbols')
map('<leader>ws', require('telescope.builtin').lsp_dynamic_workspace_symbols, '[W]orkspace [S]ymbols')
map('<leader>rn', vim.lsp.buf.rename, '[R]e[n]ame')
map('<leader>ca', vim.lsp.buf.code_action, '[C]ode [A]ction')
map('K', vim.lsp.buf.hover, 'Hover Documentation')
map('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration')
local client = vim.lsp.get_client_by_id(event.data.client_id)
if client and client.server_capabilities.documentHighlightProvider then
local highlight_augroup = vim.api.nvim_create_augroup('kickstart-lsp-highlight', { clear = false })
vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, {
buffer = event.buf,
group = highlight_augroup,
callback = vim.lsp.buf.document_highlight,
})
vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, {
buffer = event.buf,
group = highlight_augroup,
callback = vim.lsp.buf.clear_references,
})
vim.api.nvim_create_autocmd('LspDetach', {
group = vim.api.nvim_create_augroup('kickstart-lsp-detach', { clear = true }),
callback = function(event2)
vim.lsp.buf.clear_references()
vim.api.nvim_clear_autocmds { group = 'kickstart-lsp-highlight', buffer = event2.buf }
end,
})
end
if client and client.server_capabilities.inlayHintProvider and vim.lsp.inlay_hint then
map('<leader>th', function()
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled())
end, '[T]oggle Inlay [H]ints')
end
end,
})
local capabilities = require("cmp_nvim_lsp").default_capabilities()
local lspconfig = require("lspconfig")
lspconfig.tsserver.setup({
capabilities = capabilities
})
local servers = {
lua_ls = {
settings = {
Lua = {
completion = {
callSnippet = 'Replace',
},
},
},
},
}
require('mason').setup()
local ensure_installed = vim.tbl_keys(servers or {})
vim.list_extend(ensure_installed, {
'stylua',
})
require('mason-tool-installer').setup { ensure_installed = ensure_installed }
require('mason-lspconfig').setup {
handlers = {
function(server_name)
local server = servers[server_name] or {}
server.capabilities = vim.tbl_deep_extend('force', {}, capabilities, server.capabilities or {})
require('lspconfig')[server_name].setup(server)
end,
},
}
end,
},
}
-- vim: ts=2 sts=2 sw=2 et
autocomplete config:
{
"hrsh7th/cmp-nvim-lsp",
},
{
'hrsh7th/nvim-cmp',
priority = 100,
dependencies = {
{ 'L3MON4D3/LuaSnip', build = "make install_jsregexp", },
'saadparwaiz1/cmp_luasnip',
"rafamadriz/friendly-snippets",
'hrsh7th/cmp-nvim-lsp',
'hrsh7th/cmp-path',
'hrsh7th/cmp-buffer',
'onsails/lspkind.nvim',
},
config = function()
local cmp = require 'cmp'
require("luasnip.loaders.from_vscode").lazy_load()
local luasnip = require 'luasnip'
local lspkind = require("lspkind")
cmp.setup {
formatting = {
format = lspkind.cmp_format({
mode = "symbol_text",
preset = "codicons",
maxwidth = 50,
ellipsis_char = "...",
show_labelDetails = true,
})
},
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
completion = { completeopt = 'menu,menuone,noinsert' },
mapping = cmp.mapping.preset.insert {
['<C-n>'] = cmp.mapping.select_next_item(),
['<C-p>'] = cmp.mapping.select_prev_item(),
['<C-b>'] = cmp.mapping.scroll_docs(-4),
['<C-f>'] = cmp.mapping.scroll_docs(4),
['<C-y>'] = cmp.mapping.confirm { select = true },
['<C-l>'] = cmp.mapping(function()
if luasnip.expand_or_locally_jumpable() then
luasnip.expand_or_jump()
end
end, { 'i', 's' }),
['<C-h>'] = cmp.mapping(function()
if luasnip.locally_jumpable(-1) then
luasnip.jump(-1)
end
end, { 'i', 's' }),
},
sources = {
{ name = 'luasnip' },
{ name = 'nvim_lsp' },
{ name = 'buffer' },
{ name = 'path' },
},
}
local capabilities = require("cmp_nvim_lsp").default_capabilities()
require("lspconfig").tsserver.setup {
capabilities = capabilities
}
end,
},
}
-- vim: ts=2 sts=2 sw=2 et
I figured out how to pull up debug logs and interestingly it seems I'm getting the communication for textDocument/completion from my LSP, but perhaps the completion is not resulting in anything for some reason:
[DEBUG][2024-05-23 10:06:45] .../vim/lsp/rpc.lua:286 "rpc.send" { id = 2, jsonrpc = "2.0", method = "textDocument/completion", params = { context = { triggerKind = 1 }, position = { character = 3, line = 38 }, textDocument = { uri = "my-path" } }}
[DEBUG][2024-05-23 10:06:45] .../vim/lsp/rpc.lua:408 "rpc.receive" { id = 9, jsonrpc = "2.0", result = { data = {} }}
Perhaps that means this is an LSP issue and not a LuaSnip issue?