return { -- Mason (LSP server installer) { "mason-org/mason.nvim", config = function() require("mason").setup() end, }, -- Mason Tool Installer (auto-install formatters and linters) { "WhoIsSethDaniel/mason-tool-installer.nvim", dependencies = { "mason-org/mason.nvim" }, event = "VeryLazy", config = function() require("mason-tool-installer").setup({ ensure_installed = { -- Formatters "prettier", "black", "stylua", "shfmt", -- Linters "eslint_d", "ruff", "selene", "shellcheck", "jsonlint", "yamllint", "markdownlint", }, auto_update = false, run_on_start = true, }) end, }, -- Mason-LSPconfig (bridge Mason and nvim-lspconfig) { "mason-org/mason-lspconfig.nvim", dependencies = { "mason-org/mason.nvim" }, -- Ensure mason loads first to prevent registry errors event = "VeryLazy", config = function() require("mason-lspconfig").setup({ ensure_installed = { "pyright", -- Python "ts_ls", -- TypeScript/JavaScript "vue_ls", -- Vue (Volar) "jsonls", -- JSON "yamlls", -- YAML "html", -- HTML "cssls", -- CSS "bashls", -- Bash "lua_ls", -- Lua "rust_analyzer", -- Rust --"stylua", }, }) end, }, -- nvim-lspconfig { "neovim/nvim-lspconfig", config = function() local function get_venv_python() local cwd = vim.fn.getcwd() local handles = vim.fn.glob(cwd .. "/.venv*", true, true) for _, v in ipairs(handles) do if vim.fn.isdirectory(v) == 1 then return v .. "/bin/python" end end return vim.fn.exepath("python3") or "python3" end -- Lua vim.lsp.config("lua_ls", { settings = { Lua = { runtime = { version = "LuaJIT" }, diagnostics = { globals = { "vim" } }, workspace = { library = vim.api.nvim_get_runtime_file("", true) }, }, }, }) -- Python vim.lsp.config("pyright", { settings = { python = { pythonPath = get_venv_python(), analysis = { typeCheckingMode = "basic", }, }, }, }) -- Type- and JavaScript vim.lsp.config("ts_ls", { filetypes = { "javascript", "javascriptreact", "typescript", "typescriptreact", "vue", }, init_options = { hostInfo = "neovim", plugins = { { name = "@vue/typescript-plugin", location = vim.fn.stdpath("data") .. "/mason/packages/vue-language-server/node_modules/@vue/language-server", languages = { "vue" }, configNamespace = "typescript", }, }, }, 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, }, }, }, }) -- Vue (Volar): bundled config in nvim-lspconfig provides cmd, -- filetypes and tsserver/request forwarding to ts_ls (hybrid mode) vim.lsp.config("vue_ls", {}) -- Rust vim.lsp.config("rust_analyzer", { setting = { ["rust-analyzer"] = { checkOnSave = { command = "clippy" }, }, }, }) -- Other languages vim.lsp.config("jsonls", {}) vim.lsp.config("yamlls", {}) vim.lsp.config("html", {}) vim.lsp.config("cssls", {}) vim.lsp.config("bashls", {}) -- Enable servers vim.lsp.enable("lua_ls") vim.lsp.enable("pyright") vim.lsp.enable("ts_ls") vim.lsp.enable("vue_ls") vim.lsp.enable("jsonls") vim.lsp.enable("yamlls") vim.lsp.enable("html") vim.lsp.enable("cssls") vim.lsp.enable("bashls") vim.lsp.enable("rust_analyzer") end, }, }