nvim: Drop nvim-lspconfig

Use the new vim.lsp.start API and LspAttach/Detach auto commands.
Drop nvim-lspconfig in the process.

LSP server specific configuration has been taken from nvim-lspconfig.
This commit is contained in:
Sanchayan Maity 2022-08-30 20:54:43 +05:30
parent a18a0415b7
commit 9a26ef9c10
8 changed files with 222 additions and 99 deletions

View File

@ -0,0 +1,22 @@
local default_capabilities = {
textDocument = {
completion = {
editsNearCursor = true,
},
},
offsetEncoding = { 'utf-8', 'utf-16' },
}
local root_files = { '.clangd', '.clang-tidy', '.clang-format', 'compile_commands.json', 'compile_flags.txt' }
local clangd_cmd = { "clangd", "--background-index", "--pch-storage=memory", "--clang-tidy", "--header-insertion=never" }
local path = vim.fs.find(root_files, { type = "file" })
local root = vim.fs.dirname(path[1])
vim.lsp.start({
name = "clangd",
cmd = clangd_cmd,
root_dir = root,
filetypes = { 'c', 'cpp' },
single_file_support = true,
capabilities = default_capabilities,
})

View File

@ -0,0 +1,12 @@
local root_files = { 'hie.yaml', 'stack.yaml', 'cabal.project', '*.cabal', 'package.yaml' }
local path = vim.fs.find(root_files, { type = "file" })
local root = vim.fs.dirname(path[1])
vim.lsp.start({
name = "hls",
cmd = { 'haskell-language-server-wrapper', '--lsp' },
root_dir = root,
filetypes = { 'haskell' },
single_file_support = true,
settings = { haskell = { formattingProvider = 'ormolu' } },
})

View File

@ -0,0 +1,34 @@
local root_files = { 'jsconfig.json', 'tsconfig.json', 'package.json' }
local file_types = { 'javascript', 'javascriptreact', 'javascript.jsx', 'typescript', 'typescriptreact', 'typescript.tsx' }
local path = vim.fs.find(root_files, { type = "file" })
vim.lsp.start({
name = "tsserver",
cmd = { "typescript-language-server", "--stdio" },
root_dir = vim.fs.dirname(path[1]),
filetypes = file_types,
settings = {
typescript = {
inlayHints = {
includeInlayParameterNameHints = 'all',
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
}
},
javascript = {
inlayHints = {
includeInlayParameterNameHints = 'all',
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
}
}
}
})

View File

@ -0,0 +1,23 @@
local root_files = { 'pyproject.toml', 'setup.py', 'setup.cfg', 'requirements.txt', 'Pipfile' }
local path = vim.fs.find(root_files, { type = "file" })
local root = vim.fs.dirname(path[1])
vim.lsp.start({
name = "jedi-language-server",
cmd = { "jedi-language-server" },
filetypes = { 'python' },
root_dir = root,
init_options = {
completion = {
resolveEagerly = true,
},
jediSettings = {
caseInsensitiveCompletion = false,
},
workspace = {
symbols = {
maxSymbols = 50
},
},
},
})

View File

@ -0,0 +1,18 @@
local path = vim.fs.find({ "Cargo.toml" }, { type = "file" })
local root = vim.fs.dirname(path[1])
vim.lsp.start({
name = "rust-analyzer",
cmd = { "rust-analyzer" },
root_dir = root,
settings = {
["rust-analyzer"] = {
procMacro = {
enable = true
},
checkOnSave = {
command = "clippy"
},
},
},
})

View File

@ -0,0 +1,34 @@
local root_files = { 'jsconfig.json', 'tsconfig.json', 'package.json' }
local file_types = { 'javascript', 'javascriptreact', 'javascript.jsx', 'typescript', 'typescriptreact', 'typescript.tsx' }
local path = vim.fs.find(root_files, { type = "file" })
vim.lsp.start({
name = "tsserver",
cmd = { "typescript-language-server", "--stdio" },
root_dir = vim.fs.dirname(path[1]),
filetypes = file_types,
settings = {
typescript = {
inlayHints = {
includeInlayParameterNameHints = 'all',
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
}
},
javascript = {
inlayHints = {
includeInlayParameterNameHints = 'all',
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
}
}
}
})

View File

@ -1,6 +1,4 @@
local nvim_lsp = require 'lspconfig'
local protocol = require 'vim.lsp.protocol'
local util = require 'lspconfig/util'
local lightbulb = require 'nvim-lightbulb'
local inlay_hint = require 'lsp-inlayhints'
@ -65,6 +63,8 @@ protocol.CompletionItemKind = {
' TypeParameter';
}
local lsp_augroup_id = vim.api.nvim_create_augroup("LSP", { clear = true })
local lsp_key_mappings = {
{ "definitionProvider" , 'n', 'pd' , '<cmd>lua PeekDefinition()<CR>' },
{ "definitionProvider" , 'n', 'gd' , '<cmd>lua vim.lsp.buf.definition()<CR>' },
@ -95,6 +95,49 @@ local tsserver_setup = function(client)
end
end
local get_active_client_by_name = function(bufnr, servername)
for _, client in pairs(vim.lsp.buf_get_clients(bufnr)) do
if client.name == servername then
return client
end
end
end
local switch_source_header = function()
local clangd_client = get_active_client_by_name(0, 'clangd')
local params = { uri = vim.uri_from_bufnr(0) }
if clangd_client then
clangd_client.request('textDocument/switchSourceHeader', params, function(err, result)
if err then
print 'Error dane'
error(tostring(err))
end
if not result then
print 'Corresponding file cannot be determined'
return
end
vim.api.nvim_command('edit ' .. vim.uri_to_fname(result))
end, 0)
else
print 'Method switchSourceHeader is not supported by server active on the current buffer'
end
end
local clangd_setup = function(client)
if client.name == 'clangd' then
vim.api.nvim_create_user_command("ClangdSwitchSourceHeader", switch_source_header, {desc = 'Switch between source/header'})
end
end
local clangd_cleanup = function(client)
if client.name == 'clangd' then
vim.api.nvim_del_user_command("ClangdSwitchSourceHeader")
end
end
local on_attach = function(client, bufnr)
vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc')
vim.lsp.set_log_level('warn')
@ -110,6 +153,8 @@ local on_attach = function(client, bufnr)
-- actually checking it below.
tsserver_setup(client)
clangd_setup(client)
for _, mappings in pairs(lsp_key_mappings) do
local capability, mode, lhs, rhs = unpack(mappings)
if client.server_capabilities[capability] then
@ -118,8 +163,6 @@ local on_attach = function(client, bufnr)
end
if client.server_capabilities.codeLensProvider or client.server_capabilities.documentHighlightProvider then
local lsp_augroup_id = vim.api.nvim_create_augroup("LSP", {clear = true})
if client.server_capabilities.codeLensProvider then
vim.api.nvim_buf_set_keymap(bufnr, "n", "<Leader>l", "<cmd>lua vim.lsp.codelens.run()<CR>", opts)
vim.api.nvim_create_autocmd({"CursorHold", "CursorHoldI", "InsertLeave"}, {
@ -159,97 +202,37 @@ local on_attach = function(client, bufnr)
inlay_hint.on_attach(client, bufnr)
end
local on_init = function(client)
if client.config.settings then
client.notify('workspace/didChangeConfiguration', { settings = client.config.settings })
end
end
vim.api.nvim_create_autocmd("LspAttach", {
group = lsp_augroup_id,
callback = function(args)
local bufnr = args.buf
local client = vim.lsp.get_client_by_id(args.data.client_id)
local opts = { noremap=true, silent=true }
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities.workspace.configuration = true
capabilities.textDocument.completion.completionItem.snippetSupport = true
capabilities.textDocument.completion.completionItem.resolveSupport = {
properties = { 'documentation', 'detail', 'additionalTextEdits', }
}
for _, mappings in pairs(lsp_key_mappings) do
local capability, mode, lhs, rhs = unpack(mappings)
if client.server_capabilities[capability] then
vim.api.nvim_buf_set_keymap(bufnr, mode, lhs, rhs, opts)
end
end
local servers = {
clangd = {
default_config = {
cmd = { "clangd", "--background-index", "--pch-storage=memory", "--clang-tidy", "--header-insertion=never" },
filetypes = { 'c', 'cpp' },
root_dir = function(fname)
-- We specify build/compile_commands.json as that is where the compile_commands.json
-- gets generated automatically for meson projects.
local root_pattern = util.root_pattern('build/compile_commands.json', 'compile_commands.json', 'compile_flags.txt', '.git')
local filename = util.path.is_absolute(fname) and fname or util.path.join(vim.loop.cwd(), fname)
return root_pattern(filename) or util.path.dirname(filename)
end,
}
},
eslint = {},
hls = {},
jedi_language_server = {
init_options = {
completion = {
resolveEagerly = true,
},
jediSettings = {
caseInsensitiveCompletion = false,
},
workspace = {
symbols = {
maxSymbols = 50
},
},
},
},
rust_analyzer = {
settings = {
["rust-analyzer"] = {
procMacro = {
enable = true
},
checkOnSave = {
command = "clippy"
},
}
}
},
tsserver = {
settings = {
typescript = {
inlayHints = {
includeInlayParameterNameHints = 'all',
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
}
},
javascript = {
inlayHints = {
includeInlayParameterNameHints = 'all',
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
}
}
}
},
}
on_attach(client, bufnr)
end,
})
for client, config in pairs(servers) do
config.on_init = on_init
config.on_attach = on_attach
config.capabilities = vim.tbl_deep_extend(
'keep',
config.capabilities or {},
capabilities
)
nvim_lsp[client].setup(config)
end
vim.api.nvim_create_autocmd("LspDetach", {
group = lsp_augroup_id,
callback = function(args)
local bufnr = args.buf
local client = vim.lsp.get_client_by_id(args.data.client_id)
for _, mappings in pairs(lsp_key_mappings) do
local capability, mode, lhs, _ = unpack(mappings)
if client.server_capabilities[capability] then
vim.api.nvim_buf_del_keymap(bufnr, mode, lhs)
end
end
clangd_cleanup(client)
end,
})

View File

@ -63,10 +63,7 @@ local init = function ()
use 'junegunn/vim-easy-align'
use 'nvim-lua/plenary.nvim'
-- LSP
use {
'neovim/nvim-lspconfig',
'kosayoda/nvim-lightbulb',
}
use 'kosayoda/nvim-lightbulb'
-- Language support & syntax highlighting
use 'mfussenegger/nvim-lint'
use 'lvimuser/lsp-inlayhints.nvim'