return { { "neovim/nvim-lspconfig", dependencies = { "williamboman/mason.nvim", "williamboman/mason-lspconfig.nvim", }, config = function() require("mason").setup() require("mason-lspconfig").setup({ ensure_installed = { "lua_ls", -- Lua "pyright", -- Python "ts_ls", -- TypeScript/JavaScript (tsserver renamed) "rust_analyzer", -- Rust "gopls", -- Go "clangd", -- C/C++ "bashls", -- Bash "jsonls", -- JSON "yamlls", -- YAML "html", -- HTML "cssls", -- CSS }, automatic_installation = true, }) local lspconfig = require("lspconfig") local capabilities = vim.lsp.protocol.make_client_capabilities() -- Basic LSP keymaps vim.api.nvim_create_autocmd("LspAttach", { group = vim.api.nvim_create_augroup("UserLspConfig", {}), callback = function(ev) local opts = { buffer = ev.buf } vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts) vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts) vim.keymap.set("n", "", vim.lsp.buf.definition, opts) -- Ctrl+] for go to definition vim.keymap.set("n", "K", vim.lsp.buf.hover, opts) vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts) vim.keymap.set("n", "rn", vim.lsp.buf.rename, opts) vim.keymap.set({ "n", "v" }, "ca", vim.lsp.buf.code_action, opts) vim.keymap.set("n", "gr", vim.lsp.buf.references, opts) vim.keymap.set("n", "f", function() vim.lsp.buf.format({ async = true }) end, opts) end, }) -- Auto-setup all installed servers require("mason-lspconfig").setup_handlers({ -- Default handler for all servers function(server_name) lspconfig[server_name].setup({ capabilities = capabilities, }) end, -- Custom configuration for specific servers ["lua_ls"] = function() lspconfig.lua_ls.setup({ capabilities = capabilities, settings = { Lua = { diagnostics = { globals = { "vim" }, }, }, }, }) end, ["pyright"] = function() lspconfig.pyright.setup({ capabilities = capabilities, settings = { python = { analysis = { typeCheckingMode = "basic", autoSearchPaths = true, useLibraryCodeForTypes = true, }, }, }, }) end, }) end, }, }