-- LSP Configuration -- Extends LazyVim's built-in LSP support -- Helper function for monorepo root detection -- Finds nearest project marker, with fallback to git root local function make_root_detector(markers) return function(fname) local util = require("lspconfig.util") -- First try language-specific markers (nearest to file) local root = util.root_pattern(unpack(markers))(fname) if root then return root end -- Fallback to git root return util.root_pattern(".git")(fname) end end return { -- Mason: manage LSP servers, linters, formatters { "mason-org/mason.nvim", opts = { ensure_installed = { -- LSP servers "gopls", -- Go "lua-language-server", -- Lua "typescript-language-server", -- TypeScript/JavaScript "js-debug-adapter", -- JS "html-lsp", -- HTML "css-lsp", -- CSS "json-lsp", -- JSON "yaml-language-server", -- YAML "marksman", -- Markdown "sqlls", -- SQL "pyright", --Python "ruff", --Python "docker-language-server", -- Docker "zls", -- Zig -- Linters "golangci-lint", "eslint_d", "markdownlint", "hadolint", -- Formatters "gofumpt", "goimports", "prettier", "stylua", "sql-formatter", -- DAP "delve", -- Go debugger }, }, }, -- LSP configuration { "neovim/nvim-lspconfig", opts = { servers = { -- Go gopls = { -- Root detection: find go.work first, then go.mod, then git root -- root_dir = make_root_detector({ "go.work", "go.mod" }), settings = { gopls = { gofumpt = true, codelenses = { gc_details = false, generate = true, regenerate_cgo = true, run_govulncheck = true, test = true, tidy = true, upgrade_dependency = true, vendor = true, }, hints = { assignVariableTypes = true, compositeLiteralFields = true, compositeLiteralTypes = true, constantValues = true, functionTypeParameters = true, parameterNames = true, rangeVariableTypes = true, }, analyses = { fieldalignment = true, nilness = true, unusedparams = true, unusedwrite = true, useany = true, }, usePlaceholders = true, completeUnimported = true, staticcheck = true, directoryFilters = { "-.git", "-.vscode", "-.idea", "-.vscode-test", "-node_modules" }, semanticTokens = true, -- Monorepo/workspace support expandWorkspaceToModule = true, experimentalPostfixCompletions = true, -- Handle multiple modules ["build.standaloneTags"] = { "ignore" }, }, }, }, -- Lua lua_ls = { root_dir = make_root_detector({ ".luarc.json", ".luarc.jsonc", ".luacheckrc", ".stylua.toml", "stylua.toml", "selene.toml", "selene.yml" }), settings = { Lua = { workspace = { checkThirdParty = false, }, completion = { callSnippet = "Replace", }, diagnostics = { globals = { "vim" }, }, }, }, }, -- TypeScript/JavaScript ts_ls = { -- Root detection: find nearest tsconfig/package.json root_dir = make_root_detector({ "tsconfig.json", "jsconfig.json", "package.json" }), 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, }, }, }, }, -- HTML html = { root_dir = make_root_detector({ "package.json", ".git" }), filetypes = { "html", "templ" }, }, -- CSS cssls = { root_dir = make_root_detector({ "package.json", ".git" }), }, -- JSON jsonls = { root_dir = make_root_detector({ "package.json", ".git" }), }, -- YAML yamlls = { root_dir = make_root_detector({ "package.json", ".git" }), settings = { yaml = { keyOrdering = false, schemas = { ["https://json.schemastore.org/github-workflow.json"] = "/.github/workflows/*", ["https://json.schemastore.org/docker-compose.json"] = "docker-compose*.yml", }, }, }, }, -- Markdown marksman = { root_dir = make_root_detector({ ".marksman.toml", ".git" }), }, -- SQL sqlls = { root_dir = make_root_detector({ ".sqllsrc.json", "sqlls.json", ".git" }), }, -- Docker dockerls = {}, docker_compose_language_server = {}, }, }, }, -- Treesitter for better syntax highlighting { "nvim-treesitter/nvim-treesitter", opts = { ensure_installed = { "go", "gomod", "gowork", "gosum", "lua", "luadoc", "typescript", "javascript", "tsx", "html", "css", "json", "jsonc", "yaml", "markdown", "markdown_inline", "ninja", "sql", "make", "vim", "vimdoc", "bash", "regex", "diff", "gitcommit", "git_rebase", "dockerfile", }, highlight = { enable = true }, indent = { enable = true }, }, }, }