262 lines
7.2 KiB
Lua
262 lines
7.2 KiB
Lua
-- Install LSP servers and 3rd-party tools
|
|
-- source: https://github.com/ruicsh/nvim-config/blob/main/lua/plugins/mason.lua
|
|
-- sauce: https://github.com/ruicsh/nvim-config/blob/main/lua/plugins/mason.lua
|
|
-- https://github.com/williamboman/mason.nvim
|
|
|
|
-- https://mason-registry.dev/registry/list
|
|
local PACKAGES = {
|
|
-- LSP
|
|
"ansible-language-server",
|
|
"css-lsp",
|
|
"cssmodules-language-server",
|
|
"css-variables-language-server",
|
|
"dockerfile-language-server",
|
|
"harper-ls",
|
|
"html-lsp",
|
|
"json-lsp",
|
|
"lua-language-server",
|
|
"pyright",
|
|
"typescript-language-server",
|
|
"yaml-language-server",
|
|
"vue-language-server",
|
|
"ts_ls",
|
|
"typescript-tools",
|
|
-- Format
|
|
"black",
|
|
"flake8",
|
|
"prettierd",
|
|
"stylua",
|
|
-- Lint
|
|
"eslint-lsp",
|
|
"pylint",
|
|
"jq",
|
|
"php-cs-fixer",
|
|
"intelephense",
|
|
"prettier",
|
|
}
|
|
|
|
local function install(pack, version)
|
|
local notifyOpts = { title = "Mason", icon = "", id = "mason.install" }
|
|
|
|
local msg = version and ("[%s] updating to %s…"):format(pack.name, version)
|
|
or ("[%s] installing…"):format(pack.name)
|
|
vim.defer_fn(function()
|
|
vim.notify(msg, nil, notifyOpts)
|
|
end, 0)
|
|
|
|
pack:once("install:success", function()
|
|
local msg2 = ("[%s] %s"):format(pack.name, version and "updated." or "installed.")
|
|
notifyOpts.icon = " "
|
|
vim.defer_fn(function()
|
|
vim.notify(msg2, nil, notifyOpts)
|
|
end, 0)
|
|
end)
|
|
|
|
pack:once("install:failed", function()
|
|
local error = "Failed to install [" .. pack.name .. "]"
|
|
vim.defer_fn(function()
|
|
vim.notify(error, vim.log.levels.ERROR, notifyOpts)
|
|
end, 0)
|
|
end)
|
|
|
|
pack:install({ version = version })
|
|
end
|
|
|
|
local function syncPackages(ensurePacks)
|
|
local masonReg = require("mason-registry")
|
|
|
|
local function refreshCallback()
|
|
-- Auto-install missing packages & auto-update installed ones
|
|
vim.iter(ensurePacks):each(function(packName)
|
|
-- Extract package name and pinned version if specified
|
|
local name, pinnedVersion = packName:match("([^@]+)@?(.*)")
|
|
if not masonReg.has_package(name) then
|
|
return
|
|
end
|
|
local pack = masonReg.get_package(name)
|
|
if pack:is_installed() then
|
|
-- Only check for updates if no version was pinned
|
|
if pinnedVersion == "" then
|
|
local latest_version = pack:get_latest_version()
|
|
-- Check if the latest version is different from the installed one
|
|
if latest_version and latest_version ~= pack:get_installed_version() then
|
|
local msg = ("[%s] updating to %s…"):format(pack.name, latest_version)
|
|
vim.defer_fn(function()
|
|
vim.notify(msg, nil, { title = "Mason", icon = "" })
|
|
end, 0)
|
|
-- Install the latest version
|
|
pack:install({ version = latest_version })
|
|
end
|
|
end
|
|
else
|
|
-- Install with pinned version if specified
|
|
install(pack, pinnedVersion ~= "" and pinnedVersion or nil)
|
|
end
|
|
end)
|
|
|
|
-- Auto-clean unused packages
|
|
-- local installedPackages = masonReg.get_installed_package_names()
|
|
-- vim.iter(installedPackages):each(function(packName)
|
|
-- -- Check if installed package is in our ensure list (without version suffix)
|
|
-- local isEnsured = vim.iter(ensurePacks):any(function(ensurePack)
|
|
-- local name = ensurePack:match("([^@]+)")
|
|
-- return name == packName
|
|
-- end)
|
|
--
|
|
-- if not isEnsured then
|
|
-- masonReg.get_package(packName):uninstall()
|
|
-- local msg = ("[%s] uninstalled."):format(packName)
|
|
-- vim.defer_fn(function()
|
|
-- vim.notify(msg, nil, { title = "Mason", icon = "" })
|
|
-- end, 0)
|
|
-- end
|
|
-- end)
|
|
end
|
|
|
|
masonReg.refresh(refreshCallback)
|
|
end
|
|
|
|
return {
|
|
{
|
|
"williamboman/mason.nvim",
|
|
init = function()
|
|
-- Do not crowd home directory with NPM cache folder
|
|
vim.env.npm_config_cache = vim.env.HOME .. "/.cache/npm"
|
|
end,
|
|
opts = {
|
|
ui = {
|
|
border = "rounded",
|
|
height = 0.85,
|
|
width = 0.8,
|
|
},
|
|
},
|
|
config = function(_, opts)
|
|
require("mason").setup(opts)
|
|
|
|
-- Filter out disabled packages
|
|
local packages = {}
|
|
for _, package in ipairs(PACKAGES) do
|
|
table.insert(packages, package)
|
|
end
|
|
|
|
vim.defer_fn(function()
|
|
syncPackages(packages)
|
|
end, 3000)
|
|
end,
|
|
|
|
event = { "VeryLazy" },
|
|
},
|
|
{
|
|
"williamboman/mason-lspconfig.nvim",
|
|
dependencies = { "williamboman/mason.nvim" },
|
|
config = function()
|
|
local capabilities = require("cmp_nvim_lsp").default_capabilities()
|
|
|
|
local on_attach = function(client, bufnr)
|
|
local opts = { buffer = bufnr, silent = true }
|
|
|
|
vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts)
|
|
vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts)
|
|
vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts)
|
|
vim.keymap.set("n", "go", vim.lsp.buf.type_definition, opts)
|
|
vim.keymap.set("n", "gr", vim.lsp.buf.references, opts)
|
|
vim.keymap.set("n", "gs", vim.lsp.buf.signature_help, opts)
|
|
vim.keymap.set("n", "<F2>", vim.lsp.buf.rename, opts)
|
|
vim.keymap.set({ "n", "x" }, "<F3>", function()
|
|
vim.lsp.buf.format({ async = true })
|
|
end, opts)
|
|
vim.keymap.set("n", "<F4>", vim.lsp.buf.code_action, opts)
|
|
end
|
|
|
|
-- Configure LSP servers using new vim.lsp.config API
|
|
vim.lsp.config("lua_ls", {
|
|
on_attach = on_attach,
|
|
capabilities = capabilities,
|
|
settings = {
|
|
Lua = {
|
|
runtime = { version = "LuaJIT" },
|
|
diagnostics = { globals = { "vim" } },
|
|
workspace = {
|
|
library = vim.api.nvim_get_runtime_file("", true),
|
|
checkThirdParty = false,
|
|
},
|
|
telemetry = { enable = false },
|
|
},
|
|
},
|
|
})
|
|
|
|
vim.lsp.config("ts_ls", {
|
|
on_attach = on_attach,
|
|
capabilities = capabilities,
|
|
root_markers = { "tsconfig.json", "jsconfig.json", "package.json", ".git" },
|
|
init_options = {
|
|
hostInfo = "neovim",
|
|
preferences = {
|
|
importModuleSpecifierPreference = "relative",
|
|
},
|
|
},
|
|
settings = {
|
|
typescript = {
|
|
preferences = {
|
|
importModuleSpecifierPreference = "relative",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
vim.lsp.enable("ts_ls")
|
|
|
|
vim.lsp.config("pyright", { on_attach = on_attach, capabilities = capabilities })
|
|
vim.lsp.config("html", { on_attach = on_attach, capabilities = capabilities })
|
|
vim.lsp.config("cssls", { on_attach = on_attach, capabilities = capabilities })
|
|
vim.lsp.config("jsonls", { on_attach = on_attach, capabilities = capabilities })
|
|
vim.lsp.enable("jsonls")
|
|
vim.lsp.config("yamlls", { on_attach = on_attach, capabilities = capabilities })
|
|
vim.lsp.config("intelephense", {
|
|
on_attach = on_attach,
|
|
capabilities = capabilities,
|
|
settings = {
|
|
intelephense = {
|
|
format = {
|
|
enable = true,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
vim.lsp.config("eslint", {
|
|
on_attach = on_attach,
|
|
capabilities = capabilities,
|
|
root_markers = { "eslint.config.js", ".eslintrc.js", ".eslintrc.json", ".eslintrc", "package.json" },
|
|
settings = {
|
|
workingDirectories = { mode = "auto" },
|
|
},
|
|
})
|
|
vim.lsp.enable("eslint")
|
|
vim.lsp.config("vue_ls", {
|
|
on_attach = on_attach,
|
|
capabilities = capabilities,
|
|
})
|
|
vim.lsp.enable("vue_ls")
|
|
|
|
require("mason-lspconfig").setup({
|
|
ensure_installed = {
|
|
"lua_ls",
|
|
"ts_ls",
|
|
"pyright",
|
|
"html",
|
|
"cssls",
|
|
"jsonls",
|
|
"yamlls",
|
|
"intelephense",
|
|
"eslint",
|
|
"vue_ls",
|
|
},
|
|
automatic_installation = true,
|
|
})
|
|
end,
|
|
},
|
|
{
|
|
"neovim/nvim-lspconfig",
|
|
dependencies = { "williamboman/mason-lspconfig.nvim" },
|
|
},
|
|
}
|