-- Some language servers are distributed only as npm packages, and Node on Arch -- ships without npm. Without this guard you get two separate rounds of errors: -- -- 1. mason-lspconfig retries the install on every startup and fails, once per -- server ("failed to install yamlls" ...). -- 2. LazyVim still enables the server, so opening any matching file fails with -- "Spawning language server with cmd: { "yaml-language-server", ... } failed". -- -- So each server below is disabled unless its binary can actually be found. -- Nothing is hardcoded to this host: the check is a PATH lookup plus Mason's own -- bin directory, so the moment the server exists it enables itself again. -- -- To get them: sudo pacman -S npm -- nvim +"MasonInstall yaml-language-server dockerfile-language-server" +qa -- LazyVim server name -> the executable Mason/npm installs for it. local npm_servers = { yamlls = "yaml-language-server", dockerls = "docker-langserver", docker_compose_language_service = "docker-compose-langserver", } local mason_bin = vim.fs.joinpath(vim.fn.stdpath("data"), "mason", "bin") ---@param bin string ---@return boolean local function available(bin) if vim.fn.executable(bin) == 1 then return true end -- Mason prepends its bin dir to PATH only after setup, so look there directly. return vim.uv.fs_stat(vim.fs.joinpath(mason_bin, bin)) ~= nil end local missing = {} for server, bin in pairs(npm_servers) do if not available(bin) then missing[#missing + 1] = server end end if #missing == 0 then return {} end return { { "neovim/nvim-lspconfig", opts = function(_, opts) opts.servers = opts.servers or {} for _, server in ipairs(missing) do opts.servers[server] = vim.tbl_deep_extend("force", opts.servers[server] or {}, { enabled = false, -- do not try to spawn a binary that is not there mason = false, -- and do not retry the impossible install every startup }) end return opts end, }, }