return { { "neovim/nvim-lspconfig", event = { "BufReadPost", "BufNewFile", "BufWritePre" }, dependencies = { "mason.nvim", { "williamboman/mason-lspconfig.nvim", config = function() end }, -- don't configure yet }, ---@class PluginLspOpts opts = { ---@type vim.diagnostic.Opts diagnostics = { underline = true, update_in_insert = false, virtual_text = { spacing = 4, source = "if_many", prefix = "●", }, severity_sort = true, signs = { text = { [vim.diagnostic.severity.ERROR] = " ", [vim.diagnostic.severity.WARN] = " ", [vim.diagnostic.severity.HINT] = " ", [vim.diagnostic.severity.INFO] = " ", }, }, }, inlay_hints = { enabled = false, }, codelens = { enabled = false, }, document_highlight = { enabled = true, }, capabilities = { workspace = { fileOperations = { didRename = true, willRename = true, }, }, }, format = { formatting_options = nil, timeout_ms = nil, }, -- LSP Server Settings ---@type lspconfig.options servers = { lua_ls = { settings = { Lua = { workspace = { checkThirdParty = false, }, codeLens = { enable = true, }, completion = { callSnippet = "Replace", }, doc = { privateName = { "^_" }, }, hint = { enable = true, setType = false, paramType = true, paramName = "Disable", semicolon = "Disable", arrayIndex = "Disable", }, diagnostics = { disable = { "missing-fields", }, }, }, }, }, -- TODO: Add clangd extensions -- https://github.com/p00f/clangd_extensions.nvim }, -- you can do any additional lsp server setup here -- return true if you don't want this server to be setup with lspconfig ---@type table setup = { -- example to setup with typescript.nvim -- tsserver = function(_, opts) -- require("typescript").setup({ server = opts }) -- return true -- end, -- Specify * to use this function as a fallback for any server -- ["*"] = function(server, opts) end, }, }, ---@param opts PluginLspOpts config = function(_, opts) local lspconfig = require('lspconfig') for server, config in pairs(opts.servers) do local capabilities = vim.tbl_deep_extend("force", vim.lsp.protocol.make_client_capabilities() or {}, require('blink.cmp').get_lsp_capabilities() or {}, config.capabilities or {} ) config.capabilities = capabilities lspconfig[server].setup(config) end -- setup keymaps rmz.lsp.on_attach(function(client, buffer) require("plugins.lsp.keymaps").on_attach(client, buffer) end) rmz.lsp.setup() rmz.lsp.on_dynamic_capability(require("plugins.lsp.keymaps").on_attach) -- TODO: should vim.diagnostics be condigured directly? vim.diagnostic.config(vim.deepcopy(opts.diagnostics)) -- get all the servers that are available through mason-lspconfig local mlsp = require("mason-lspconfig") -- TODO: use mason-lspconfig.get_available_servers()? local all_mslp_servers = vim.tbl_keys(require("mason-lspconfig.mappings.server").lspconfig_to_package) local ensure_installed = {} ---@type string[] for server, server_opts in pairs(opts.servers) do if server_opts then server_opts = server_opts == true and {} or server_opts if server_opts.enabled ~= false then -- run manual setup if mason=false or if this is a server that cannot be installed with mason-lspconfig if server_opts.mason == false or not vim.tbl_contains(all_mslp_servers, server) then require("lspconfig")[server].setup(server_opts) else ensure_installed[#ensure_installed + 1] = server end end end end mlsp.setup({ ensure_installed = vim.tbl_deep_extend( "force", ensure_installed, rmz.lazy.opts("mason-lspconfig.nvim").ensure_installed or {} ), handlers = { setup }, }) end }, { "williamboman/mason.nvim", cmd = "Mason", keys = { { "cm", "Mason", desc = "Mason" } }, build = ":MasonUpdate", opts_extend = { "ensure_installed" }, opts = { ensure_installed = { "stylua", "shfmt", }, }, ---@param opts MasonSettings | {ensure_installed: string[]} config = function(_, opts) require("mason").setup(opts) local mr = require("mason-registry") mr:on("package:install:success", function() vim.defer_fn(function() -- trigger FileType event to possibly load this newly installed LSP server require("lazy.core.handler.event").trigger({ event = "FileType", buf = vim.api.nvim_get_current_buf(), }) end, 100) end) mr.refresh(function() for _, tool in ipairs(opts.ensure_installed) do local p = mr.get_package(tool) if not p:is_installed() then p:install() end end end) end, }, }