From be862a83d607a1dc7489ba2429891d29ce7d9e3e Mon Sep 17 00:00:00 2001 From: jdhao Date: Sat, 26 Apr 2025 17:19:46 +0200 Subject: [PATCH] Use new lsp configuration structure (#403) In this new structure, the main configuration for a LSP server is provided by the plugin nvim-lspconfig. Some of the config may be overridden by the configuration under directory `after/lsp/xxx.lua`, where `xxx` is the lsp server name used by nvim-lspconfig. Note that it is necessary to put the custom lsp server configuration under `after/` directory, in order to correctly override the config provided by nvim-lspconfig. --- after/lsp/bashls.lua | 5 ++ after/lsp/clangd.lua | 9 +++ after/lsp/ltex.lua | 12 +++ after/lsp/lua_ls.lua | 17 +++++ after/lsp/pyright.lua | 56 ++++++++++++++ after/lsp/ruff.lua | 11 +++ after/lsp/vimls.lua | 8 ++ lua/config/lsp.lua | 167 ++++++------------------------------------ lua/lsp_utils.lua | 15 ++++ 9 files changed, 155 insertions(+), 145 deletions(-) create mode 100644 after/lsp/bashls.lua create mode 100644 after/lsp/clangd.lua create mode 100644 after/lsp/ltex.lua create mode 100644 after/lsp/lua_ls.lua create mode 100644 after/lsp/pyright.lua create mode 100644 after/lsp/ruff.lua create mode 100644 after/lsp/vimls.lua create mode 100644 lua/lsp_utils.lua diff --git a/after/lsp/bashls.lua b/after/lsp/bashls.lua new file mode 100644 index 0000000..8aa4921 --- /dev/null +++ b/after/lsp/bashls.lua @@ -0,0 +1,5 @@ +local lsp_utils = require("lsp_utils") + +return { + capabilities = lsp_utils.get_default_capabilities(), +} diff --git a/after/lsp/clangd.lua b/after/lsp/clangd.lua new file mode 100644 index 0000000..189fd95 --- /dev/null +++ b/after/lsp/clangd.lua @@ -0,0 +1,9 @@ +local lsp_utils = require("lsp_utils") + +return { + filetypes = { "c", "cpp", "cc" }, + flags = { + debounce_text_changes = 500, + }, + capabilities = lsp_utils.get_default_capabilities(), +} diff --git a/after/lsp/ltex.lua b/after/lsp/ltex.lua new file mode 100644 index 0000000..e488bc1 --- /dev/null +++ b/after/lsp/ltex.lua @@ -0,0 +1,12 @@ +local lsp_utils = require("lsp_utils") + +return { + filetypes = { "text", "plaintex", "tex", "markdown" }, + settings = { + ltex = { + language = "en", + }, + }, + flags = { debounce_text_changes = 300 }, + capabilities = lsp_utils.get_default_capabilities(), +} diff --git a/after/lsp/lua_ls.lua b/after/lsp/lua_ls.lua new file mode 100644 index 0000000..eae9a94 --- /dev/null +++ b/after/lsp/lua_ls.lua @@ -0,0 +1,17 @@ +local lsp_utils = require("lsp_utils") + +-- settings for lua-language-server can be found on https://luals.github.io/wiki/settings/ +return { + settings = { + Lua = { + runtime = { + -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim) + version = "LuaJIT", + }, + hint = { + enable = true, + }, + }, + }, + capabilities = lsp_utils.get_default_capabilities(), +} diff --git a/after/lsp/pyright.lua b/after/lsp/pyright.lua new file mode 100644 index 0000000..8c5aa32 --- /dev/null +++ b/after/lsp/pyright.lua @@ -0,0 +1,56 @@ +local lsp_utils = require("lsp_utils") + +-- For what diagnostic is enabled in which type checking mode, check doc: +-- https://github.com/microsoft/pyright/blob/main/docs/configuration.md#diagnostic-settings-defaults +-- Currently, the pyright also has some issues displaying hover documentation: +-- https://www.reddit.com/r/neovim/comments/1gdv1rc/what_is_causeing_the_lsp_hover_docs_to_looks_like/ + +local new_capability = { + -- this will remove some of the diagnostics that duplicates those from ruff, idea taken and adapted from + -- here: https://github.com/astral-sh/ruff-lsp/issues/384#issuecomment-1989619482 + textDocument = { + publishDiagnostics = { + tagSupport = { + valueSet = { 2 }, + }, + }, + hover = { + contentFormat = { "plaintext" }, + dynamicRegistration = true, + }, + }, +} + +local capabilities = lsp_utils.get_default_capabilities() +local merged_capability = vim.tbl_deep_extend("force", capabilities, new_capability) + +return { + cmd = { "delance-langserver", "--stdio" }, + settings = { + pyright = { + -- disable import sorting and use Ruff for this + disableOrganizeImports = true, + disableTaggedHints = false, + }, + python = { + analysis = { + autoSearchPaths = true, + diagnosticMode = "workspace", + typeCheckingMode = "standard", + useLibraryCodeForTypes = true, + -- we can this setting below to redefine some diagnostics + diagnosticSeverityOverrides = { + deprecateTypingAliases = false, + }, + -- inlay hint settings are provided by pylance? + inlayHints = { + callArgumentNames = "partial", + functionReturnTypes = true, + pytestParameters = true, + variableTypes = true, + }, + }, + }, + }, + capabilities = merged_capability, +} diff --git a/after/lsp/ruff.lua b/after/lsp/ruff.lua new file mode 100644 index 0000000..adf4e98 --- /dev/null +++ b/after/lsp/ruff.lua @@ -0,0 +1,11 @@ +local lsp_utils = require("lsp_utils") + +return { + init_options = { + -- the settings can be found here: https://docs.astral.sh/ruff/editors/settings/ + settings = { + organizeImports = true, + }, + }, + capabilities = lsp_utils.get_default_capabilities(), +} diff --git a/after/lsp/vimls.lua b/after/lsp/vimls.lua new file mode 100644 index 0000000..950e44c --- /dev/null +++ b/after/lsp/vimls.lua @@ -0,0 +1,8 @@ +local lsp_utils = require("lsp_utils") + +return { + flags = { + debounce_text_changes = 500, + }, + capabilities = lsp_utils.get_default_capabilities(), +} diff --git a/lua/config/lsp.lua b/lua/config/lsp.lua index 1af07cc..fcad0a8 100644 --- a/lua/config/lsp.lua +++ b/lua/config/lsp.lua @@ -1,7 +1,7 @@ local utils = require("utils") vim.api.nvim_create_autocmd("LspAttach", { - group = vim.api.nvim_create_augroup("buf_behavior_conf", { clear = true }), + group = vim.api.nvim_create_augroup("lsp_buf_conf", { clear = true }), callback = function(event_context) local client = vim.lsp.get_client_by_id(event_context.data.client_id) -- vim.print(client.name, client.server_capabilities) @@ -72,151 +72,28 @@ vim.api.nvim_create_autocmd("LspAttach", { desc = "Configure buffer keymap and behavior based on LSP", }) -local capabilities = vim.lsp.protocol.make_client_capabilities() +-- Enable lsp servers when they are available --- required by nvim-ufo -capabilities.textDocument.foldingRange = { - dynamicRegistration = false, - lineFoldingOnly = true, +-- A mapping from lsp server name to the executable name +local enabled_lsp_servers = { + pyright = "delance-langserver", + ruff = "ruff", + ltex = "ltex-ls", + clangd = "clangd", + vimls = "vim-language-server", + bashls = "bash-language-server", + lua_ls = "lua-language-server", } --- For what diagnostic is enabled in which type checking mode, check doc: --- https://github.com/microsoft/pyright/blob/main/docs/configuration.md#diagnostic-settings-defaults --- Currently, the pyright also has some issues displaying hover documentation: --- https://www.reddit.com/r/neovim/comments/1gdv1rc/what_is_causeing_the_lsp_hover_docs_to_looks_like/ - -if utils.executable("pyright") then - local new_capability = { - -- this will remove some of the diagnostics that duplicates those from ruff, idea taken and adapted from - -- here: https://github.com/astral-sh/ruff-lsp/issues/384#issuecomment-1989619482 - textDocument = { - publishDiagnostics = { - tagSupport = { - valueSet = { 2 }, - }, - }, - hover = { - contentFormat = { "plaintext" }, - dynamicRegistration = true, - }, - }, - } - local merged_capability = vim.tbl_deep_extend("force", capabilities, new_capability) - - vim.lsp.config("pyright", { - cmd = { "delance-langserver", "--stdio" }, - capabilities = merged_capability, - settings = { - pyright = { - -- disable import sorting and use Ruff for this - disableOrganizeImports = true, - disableTaggedHints = false, - }, - python = { - analysis = { - autoSearchPaths = true, - diagnosticMode = "workspace", - typeCheckingMode = "standard", - useLibraryCodeForTypes = true, - -- we can this setting below to redefine some diagnostics - diagnosticSeverityOverrides = { - deprecateTypingAliases = false, - }, - -- inlay hint settings are provided by pylance? - inlayHints = { - callArgumentNames = "partial", - functionReturnTypes = true, - pytestParameters = true, - variableTypes = true, - }, - }, - }, - }, - }) - - vim.lsp.enable("pyright") -else - vim.notify("pyright not found!", vim.log.levels.WARN, { title = "Nvim-config" }) -end - -if utils.executable("ruff") then - vim.lsp.config("ruff", { - capabilities = capabilities, - init_options = { - -- the settings can be found here: https://docs.astral.sh/ruff/editors/settings/ - settings = { - organizeImports = true, - }, - }, - }) - vim.lsp.enable("ruff") -end - -if utils.executable("ltex-ls") then - vim.lsp.config("ltex", { - filetypes = { "text", "plaintex", "tex", "markdown" }, - settings = { - ltex = { - language = "en", - }, - }, - flags = { debounce_text_changes = 300 }, - }) - - vim.lsp.enable("ltex") -end - -if utils.executable("clangd") then - vim.lsp.config("clangd", { - capabilities = capabilities, - filetypes = { "c", "cpp", "cc" }, - flags = { - debounce_text_changes = 500, - }, - }) - - vim.lsp.enable("clangd") -end - --- set up vim-language-server -if utils.executable("vim-language-server") then - vim.lsp.config("vimls", { - flags = { - debounce_text_changes = 500, - }, - capabilities = capabilities, - }) - - vim.lsp.enable("vimls") -else - vim.notify("vim-language-server not found!", vim.log.levels.WARN, { title = "Nvim-config" }) -end - --- set up bash-language-server -if utils.executable("bash-language-server") then - vim.lsp.config("bashls", { - capabilities = capabilities, - }) - - vim.lsp.enable("bashls") -end - --- settings for lua-language-server can be found on https://luals.github.io/wiki/settings/ -if utils.executable("lua-language-server") then - vim.lsp.config("lua_ls", { - settings = { - Lua = { - runtime = { - -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim) - version = "LuaJIT", - }, - hint = { - enable = true, - }, - }, - }, - capabilities = capabilities, - }) - - vim.lsp.enable("lua_ls") +for server_name, lsp_executable in pairs(enabled_lsp_servers) do + if utils.executable(lsp_executable) then + vim.lsp.enable(server_name) + else + local msg = string.format( + "Executable '%s' for server '%s' not found! Server will not be enabled", + lsp_executable, + server_name + ) + vim.notify(msg, vim.log.levels.WARN, { title = "Nvim-config" }) + end end diff --git a/lua/lsp_utils.lua b/lua/lsp_utils.lua new file mode 100644 index 0000000..4345c3c --- /dev/null +++ b/lua/lsp_utils.lua @@ -0,0 +1,15 @@ +local M = {} + +M.get_default_capabilities = function() + local capabilities = vim.lsp.protocol.make_client_capabilities() + + -- required by nvim-ufo + capabilities.textDocument.foldingRange = { + dynamicRegistration = false, + lineFoldingOnly = true, + } + + return capabilities +end + +return M