nvim: lsp: Use vim.lsp.config and vim.lsp.enable

Use the newly introduced config and enable APIs.
https://github.com/neovim/neovim/pull/31031

We drop the settings for deno and typescript here. We added
javascript and typescript support as it was required for our
last client a while back. Drop them for now, we will add it
back if we need to. ts_ls is absolute garbage and hopefully
we won't have to work with the fuck all nonsense that is the
javascript ecosystem in the foreseeable future.
This commit is contained in:
Sanchayan Maity 2024-12-10 23:39:41 +05:30
parent 7c865bf17e
commit 72b1a2f0ea
Signed by: sanchayanmaity
GPG key ID: 6F6A0609C12038F3
16 changed files with 82 additions and 416 deletions

View file

@ -1,8 +1,3 @@
local lsp_utils = require('lsp-utils')
local clangd_config = lsp_utils.clangd_config()
vim.lsp.start(clangd_config)
vim.bo.makeprg = 'meson compile -C build'
vim.keymap.set('n', 'gh', ":ClangdSwitchSourceHeader<CR>", { noremap=true, buffer=0 })

View file

@ -1,4 +0,0 @@
local lsp_utils = require('lsp-utils')
local elixir_config = lsp_utils.elixir_config()
vim.lsp.start(elixir_config)

View file

@ -1,4 +0,0 @@
local lsp_utils = require('lsp-utils')
local gleam_config = lsp_utils.gleam_config()
vim.lsp.start(gleam_config)

View file

@ -1,4 +0,0 @@
local lsp_utils = require('lsp-utils')
local gopls_config = lsp_utils.gopls_config()
vim.lsp.start(gopls_config)

View file

@ -1,8 +1,3 @@
local lsp_utils = require('lsp-utils')
local hls_config = lsp_utils.hls_config()
vim.lsp.start(hls_config)
vim.bo.makeprg = 'cabal build --write-ghc-environment-files=always all'
vim.api.nvim_create_autocmd({ "BufWritePost" }, {

View file

@ -1,13 +0,0 @@
local lsp_utils = require('lsp-utils')
local tsserver_config = lsp_utils.tsserver_config()
vim.lsp.start(tsserver_config)
vim.keymap.set('n', 'gq', "<cmd>!npx prettier --write %:p<CR>:e<CR>", { noremap=true, silent=true, buffer=0 })
vim.api.nvim_create_autocmd({ "BufReadPre", "BufWinEnter" }, {
pattern = { "*/node_modules/*" },
callback = function()
vim.bo.buflisted = false
end,
})

View file

@ -1,4 +0,0 @@
local lsp_utils = require('lsp-utils')
local leanls_config = lsp_utils.leanls_config()
vim.lsp.start(leanls_config)

View file

@ -1,11 +1,6 @@
vim.bo.textwidth = 0
vim.bo.wrapmargin = 0
local lsp_utils = require('lsp-utils')
local puresls_config = lsp_utils.pursls_config()
vim.lsp.start(puresls_config)
vim.api.nvim_create_autocmd({ "BufReadPre", "BufWinEnter" }, {
pattern = { "*.spago/*" },
callback = function()

View file

@ -1,8 +1,3 @@
local lsp_utils = require('lsp-utils')
local ruff_config = lsp_utils.ruff_config()
vim.lsp.start(ruff_config)
vim.bo.textwidth = 0
vim.api.nvim_create_autocmd({ "BufWritePost" }, {

View file

@ -1,4 +0,0 @@
local lsp_utils = require('lsp-utils')
local scheme_config = lsp_utils.scheme_config()
vim.lsp.start(scheme_config)

View file

@ -1,8 +1,3 @@
local lsp_utils = require('lsp-utils')
local ra_config = lsp_utils.ra_config()
vim.lsp.start(ra_config)
vim.cmd.compiler('cargo')
vim.bo.makeprg = 'cargo build --workspace'

View file

@ -1,13 +0,0 @@
local lsp_utils = require('lsp-utils')
local typescript_config = lsp_utils.typescript_config()
vim.lsp.start(typescript_config)
vim.keymap.set('n', 'gq', "<cmd>!npx prettier --write %:p<CR>:e<CR>", { noremap=true, silent=true, buffer=0 })
vim.api.nvim_create_autocmd({ "BufReadPre", "BufWinEnter" }, {
pattern = { "*/node_modules/*" },
callback = function()
vim.bo.buflisted = false
end,
})

View file

@ -1,8 +1,3 @@
local lsp_utils = require('lsp-utils')
local zls_config = lsp_utils.zls_config()
vim.lsp.start(zls_config)
vim.cmd.compiler('zig_build')
vim.api.nvim_create_autocmd({ "BufReadPre", "BufWinEnter" }, {

View file

@ -0,0 +1,74 @@
return {
["clangd"] = {
cmd = { 'clangd', '--background-index', '--pch-storage=memory', '--clang-tidy', '--header-insertion=never' },
filetypes = { 'c', 'cpp' },
root_markers = { '.clangd', '.clang-tidy', '.clang-format', 'compile_commands.json', 'compile_flags.txt' },
},
["elixirls"] = {
cmd = { 'elixir-ls' },
filetypes = { 'elixir', 'eelixir', 'heex', 'surface' },
root_markers = { 'mix.exs' },
},
["gleam"] = {
cmd = { 'gleam', 'lsp' },
filetypes = { 'gleam' },
root_markers = { 'gleam.toml' },
},
["gopls"] = {
cmd = { 'gopls' },
filetypes = { 'go', 'gomod', 'gowork', 'gotmpl' },
root_markers = { 'go.mod', 'go.work' },
},
["leanls"] = {
cmd = { 'lake', 'serve', '--' },
filetypes = { 'lean' },
root_markers = { 'lakefile.lean', 'lean-toolchain', 'leanpkg.toml' },
},
["purescriptls"] = {
cmd = { 'purescript-language-server', '--stdio' },
filetypes = { 'purescript' },
root_markers = { 'bower.json', 'psc-package.json', 'spago.dhall' },
settings = {
purescript = {
formatter = 'purs-tidy',
}
},
},
["rust_analyzer"] = {
cmd = { 'rust-analyzer' },
filetypes = { 'rust' },
root_markers = { "Cargo.toml" },
settings = {
["rust-analyzer"] = {
checkOnSave = {
command = 'clippy'
},
diagnostics = {
-- https://rust-analyzer.github.io/manual.html#diagnostics
disabled = {
'macro-def-error',
'macro-error'
},
},
procMacro = {
enable = false
},
},
},
},
["ruff"] = {
cmd = { 'ruff', 'server' },
filetypes = { 'python' },
root_markers = { 'pyproject.toml', 'ruff.toml', '.ruff.toml' },
},
["staticls"] = {
cmd = { 'static-ls' },
filetypes = { 'haskell' },
root_markers = { '.hiedb', '.hiefiles' },
},
["zls"] = {
cmd = { 'zls' },
filetypes = { 'zig', 'zir' },
root_markers = { 'zls.json', 'build.zig' },
}
}

View file

@ -1,332 +0,0 @@
local M = {}
-- All configuration is taken from nvim-lspconfig except for may be minor changes
--
-- Deno specific functions
local buf_cache = function(bufnr, client)
local params = {
command = 'deno.cache',
arguments = { {}, vim.uri_from_bufnr(bufnr) },
}
client.request('workspace/executeCommand', params, function(err, _result, ctx)
if err then
local uri = ctx.params.arguments[2]
vim.api.nvim_err_writeln('Cache command failed for ' .. vim.uri_to_fname(uri))
end
end, bufnr)
end
local virtual_text_document_handler = function(uri, res, client)
if not res then
return nil
end
local lines = vim.split(res.result, '\n')
local bufnr = vim.uri_to_bufnr(uri)
local current_buf = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
if #current_buf ~= 0 then
return nil
end
vim.api.nvim_buf_set_lines(bufnr, 0, -1, nil, lines)
vim.api.nvim_set_option_value('readonly' , true, { buf = bufnr })
vim.api.nvim_set_option_value('modified' , false, { buf = bufnr })
vim.api.nvim_set_option_value('modifiable', false, { buf = bufnr })
vim.lsp.buf_attach_client(bufnr, client.id)
end
local virtual_text_document = function(uri, client)
local params = {
textDocument = {
uri = uri,
},
}
local result = client.request_sync('deno/virtualTextDocument', params)
virtual_text_document_handler(uri, result, client)
end
local denols_handler = function(err, result, ctx)
if not result or vim.tbl_isempty(result) then
return nil
end
local client = vim.lsp.get_client_by_id(ctx.client_id)
for _, res in pairs(result) do
local uri = res.uri or res.targetUri
if uri:match '^deno:' then
virtual_text_document(uri, client)
res['uri'] = uri
res['targetUri'] = uri
end
end
vim.lsp.handlers[ctx.method](err, result, ctx)
end
-- End of deno specific functions
local get_root_directory = function(root_files)
return vim.fs.root(0, root_files)
end
local default_capabilities = vim.lsp.protocol.make_client_capabilities()
function M.clangd_config()
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 root_directory = get_root_directory(root_files)
local clangd_caps = {
textDocument = { completion = { editsNearCursor = true } },
offsetEncoding = { 'utf-8', 'utf-16' },
}
return {
name = "clangd",
cmd = clangd_cmd,
capabilities = clangd_caps,
root_dir = root_directory,
filetypes = { 'c', 'cpp' },
single_file_support = false,
}
end
function M.deno_config()
local root_files = { 'deno.json', 'deno.jsonc' }
local file_types = { 'javascript', 'javascriptreact', 'javascript.jsx', 'typescript', 'typescriptreact', 'typescript.tsx' }
local root_directory = get_root_directory(root_files)
return {
cmd = { 'deno', 'lsp' },
capabilities = default_capabilities,
filetypes = file_types,
root_dir = root_directory,
settings = {
deno = {
enable = true,
suggest = {
imports = {
hosts = {
['https://deno.land'] = true,
},
},
},
},
},
handlers = {
['textDocument/definition'] = denols_handler,
['textDocument/typeDefinition'] = denols_handler,
['textDocument/references'] = denols_handler,
},
commands = {
DenolsCache = {
function()
local clients = vim.lsp.get_clients({ bufnr = 0, name = 'denols' })
if #clients > 0 then
buf_cache(0, clients[#clients])
end
end,
description = 'Cache a module and all of its dependencies.',
},
}
}
end
function M.elixir_config()
local root_files = { 'mix.exs' }
local root_directory = get_root_directory(root_files)
return {
name = "elixirls",
cmd = { "elixir-ls" },
capabilities = default_capabilities,
root_dir = root_directory,
filetypes = { 'elixir', 'eelixir', 'heex', 'surface' },
single_file_support = true,
}
end
function M.gleam_config()
local root_files = { 'gleam.toml' }
local root_directory = get_root_directory(root_files)
return {
name = "gleam",
cmd = { 'gleam', 'lsp' },
capabilities = default_capabilities,
root_dir = root_directory,
filetypes = { 'gleam' },
}
end
function M.gopls_config()
local root_files = { 'go.mod', 'go.work', '.git' }
local root_directory = get_root_directory(root_files)
return {
name = "gopls",
cmd = { "gopls" },
capabilities = default_capabilities,
root_dir = root_directory,
filetypes = { 'go', 'gomod', 'gowork', 'gotmpl' },
}
end
function M.hls_config()
local root_files = { '*.cabal', 'cabal.project', 'hie.yaml', 'package.yaml', 'stack.yaml' }
local root_directory = get_root_directory(root_files)
return {
name = "static-ls",
cmd = { 'static-ls' },
capabilities = default_capabilities,
root_dir = root_directory,
filetypes = { 'haskell' },
}
end
function M.leanls_config()
local root_files = { 'lakefile.lean', 'lean-toolchain', 'leanpkg.toml' }
local root_directory = get_root_directory(root_files)
return {
name = "leanls",
cmd = { 'lake', 'serve', '--' },
capabilities = default_capabilities,
root_dir = root_directory,
filetypes = { 'lean' },
single_file_support = true,
}
end
function M.pursls_config()
local root_files = { 'bower.json', 'psc-package.json', 'spago.dhall' }
local root_directory = get_root_directory(root_files)
return {
name = "purescriptls",
cmd = { 'purescript-language-server', '--stdio' },
capabilities = default_capabilities,
root_dir = root_directory,
filetypes = { 'purescript' },
single_file_support = false,
settings = {
purescript = {
formatter = 'purs-tidy',
}
},
}
end
function M.ra_config()
local root_files = { "Cargo.toml" }
local root_directory = get_root_directory(root_files)
local ra_caps = vim.lsp.protocol.make_client_capabilities()
ra_caps.experimental = {
serverStatusNotification = true,
}
return {
name = "rust-analyzer",
cmd = { "rust-analyzer" },
capabilities = ra_caps,
root_dir = root_directory,
settings = {
["rust-analyzer"] = {
checkOnSave = {
command = "clippy"
},
diagnostics = {
-- https://rust-analyzer.github.io/manual.html#diagnostics
disabled = {
"macro-def-error",
"macro-error"
},
},
procMacro = {
enable = false
},
},
},
}
end
function M.ruff_config()
local root_files = { 'pyproject.toml', 'ruff.toml', '.ruff.toml' }
local root_directory = get_root_directory(root_files)
return {
name = "ruff",
cmd = { 'ruff', 'server' },
filetypes = { 'python' },
capabilities = default_capabilities,
root_dir = root_directory,
single_file_support = true,
}
end
function M.scheme_config()
local root_files = { '.git' }
local root_directory = get_root_directory(root_files)
return {
name = "racket-langserver",
cmd = { 'racket', '--lib', 'racket-langserver' },
capabilities = default_capabilities,
filetypes = { 'scheme', 'racket' },
root_dir = root_directory,
single_file_support = true,
}
end
function M.tsserver_config()
local root_files = { 'jsconfig.json', 'tsconfig.json', 'package.json' }
local file_types = { 'javascript', 'javascriptreact', 'javascript.jsx', 'typescript', 'typescriptreact', 'typescript.tsx' }
local root_directory = get_root_directory(root_files)
return {
name = "ts_ls",
cmd = { "typescript-language-server", "--stdio" },
init_options = { hostInfo = 'neovim' },
capabilities = default_capabilities,
root_dir = root_directory,
filetypes = file_types
}
end
function M.typescript_config()
local root_files = { 'jsconfig.json', 'tsconfig.json', 'package.json' }
local root_dir = get_root_directory(root_files)
-- Look for npm based typescript files first and if found return tsserver
-- configuration, else return deno configuration. This allows us to work
-- with both npm and deno based typescript projects.
if root_dir then
return M.tsserver_config()
else
return M.deno_config()
end
end
function M.zls_config()
local root_files = { 'zls.json', 'build.zig' }
local root_directory = get_root_directory(root_files)
return {
name = "zls",
cmd = { "zls" },
capabilities = default_capabilities,
root_dir = root_directory,
filetypes = { 'zig', 'zir' },
single_file_support = true,
}
end
return M

View file

@ -1,5 +1,6 @@
local protocol = require 'vim.lsp.protocol'
local lsp_configs = require 'lsp-configs'
local lsp_util = vim.lsp.util
local protocol = require 'vim.lsp.protocol'
vim.lsp.set_log_level("OFF")
@ -161,12 +162,6 @@ local client_custom_setup = function(client, bufnr)
if client.name == 'rust-analyzer' then
vim.api.nvim_buf_create_user_command(bufnr, "CargoReload", cargo_reload_workspace, {desc = 'Reload current cargo workspace'})
end
if client.name == 'tsserver' then
-- Disable tsserver formatting, we want formatting via prettier
client.server_capabilities.documentFormattingProvider = false
client.server_capabilities.documentRangeFormattingProvider = false
end
end
local client_custom_cleanup = function(client, bufnr)
@ -309,3 +304,8 @@ vim.api.nvim_create_autocmd("LspProgress", {
group = lsp_augroup_id,
command = "redrawstatus"
})
for lsp, config in pairs(lsp_configs) do
vim.lsp.config[lsp] = config
vim.lsp.enable(lsp)
end