REFACTOR: Updated from older config
This commit is contained in:
@@ -1,42 +1,25 @@
|
||||
local registry = require("mason-registry")
|
||||
local mapping = require("mason-conform.mapping")
|
||||
|
||||
local function auto_install()
|
||||
local config = require("mason-conform").config
|
||||
local formatters_by_ft = require("conform").formatters_by_ft;
|
||||
local mapping = require("mason-conform.mapping")
|
||||
local install = require("mason-conform.install")
|
||||
|
||||
local formatters_to_install = {}
|
||||
for _, formatters in pairs(formatters_by_ft) do
|
||||
for _, formatter in pairs(formatters) do
|
||||
-- Support case where the user has defined multiple formatters
|
||||
-- for said filetype. E.g javascript = { { "prettierd", "prettier" } }
|
||||
if type(formatter) == "table" then
|
||||
for _, f in pairs(formatter) do
|
||||
formatters_to_install[f] = 1
|
||||
end
|
||||
else
|
||||
formatters_to_install[formatter] = 1
|
||||
local ignored = {}
|
||||
for _, name in ipairs(config.ignore_install) do
|
||||
ignored[name] = true
|
||||
end
|
||||
|
||||
for _, name in ipairs(require("mason-conform.formatters").configured()) do
|
||||
if not ignored[name] then
|
||||
local package = mapping.conform_to_package[name]
|
||||
if package ~= nil then
|
||||
install.try_install(package)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Filter out formatters that the user wants to ignore
|
||||
for _, formatter_to_ignore in pairs(config.ignore_install) do
|
||||
formatters_to_install[formatter_to_ignore] = nil
|
||||
end
|
||||
|
||||
for conformFormatter, _ in pairs(formatters_to_install) do
|
||||
local package = mapping.conform_to_package[conformFormatter]
|
||||
if package ~= nil then
|
||||
require("mason-conform.install").try_install(package)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if registry.refresh then
|
||||
return function()
|
||||
registry.refresh(vim.schedule_wrap(auto_install))
|
||||
end
|
||||
else
|
||||
return auto_install
|
||||
---Refresh the mason registry, then install every configured formatter that is
|
||||
---missing. Returns immediately; installation happens on the main loop.
|
||||
return function()
|
||||
require("mason-registry").refresh(vim.schedule_wrap(auto_install))
|
||||
end
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
local M = {}
|
||||
|
||||
---Collect formatter names from a single `formatters_by_ft` entry.
|
||||
---
|
||||
---A conform filetype formatter can be any of:
|
||||
--- * a list of formatter names, optionally followed by string-keyed format
|
||||
--- options (e.g. `{ "stylua", lsp_format = "fallback" }`)
|
||||
--- * a function `fun(bufnr): string[]`, used by the "run the first available
|
||||
--- formatter" recipe
|
||||
--- * the legacy nested list `{ { "prettierd", "prettier" } }`
|
||||
---
|
||||
---Only the array part of the table is traversed, so format options such as
|
||||
---`lsp_format` and `stop_after_first` are ignored.
|
||||
---@param value any
|
||||
---@param out table<string, boolean>
|
||||
local function collect_entry(value, out)
|
||||
local list = value
|
||||
if type(list) == "function" then
|
||||
-- A function may depend on a buffer and/or on run-time availability.
|
||||
-- We don't have a buffer to pass here, so evaluate it best-effort and
|
||||
-- silently skip it when it cannot be called without one.
|
||||
local ok, result = pcall(list)
|
||||
if not ok or type(result) ~= "table" then
|
||||
return
|
||||
end
|
||||
list = result
|
||||
end
|
||||
|
||||
if type(list) ~= "table" then
|
||||
return
|
||||
end
|
||||
|
||||
for _, formatter in ipairs(list) do
|
||||
if type(formatter) == "table" then
|
||||
-- Legacy "run the first available formatter" syntax.
|
||||
collect_entry(formatter, out)
|
||||
elseif type(formatter) == "string" then
|
||||
out[formatter] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---List every formatter configured in conform's `formatters_by_ft`.
|
||||
---
|
||||
---Understands all `formatters_by_ft` shapes supported by conform, including
|
||||
---functions returning a list and the legacy nested "run the first available"
|
||||
---syntax.
|
||||
---@return string[] names Sorted, de-duplicated formatter names.
|
||||
function M.configured()
|
||||
local out = {}
|
||||
for _, entry in pairs(require("conform").formatters_by_ft or {}) do
|
||||
collect_entry(entry, out)
|
||||
end
|
||||
|
||||
local names = {}
|
||||
for name in pairs(out) do
|
||||
names[#names + 1] = name
|
||||
end
|
||||
table.sort(names)
|
||||
return names
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -0,0 +1,76 @@
|
||||
local M = {}
|
||||
|
||||
---@return boolean
|
||||
local function check_mason()
|
||||
local ok, mason_version = pcall(require, "mason.version")
|
||||
if not ok then
|
||||
vim.health.error("mason.nvim was not found. Is it installed and loaded?")
|
||||
return false
|
||||
end
|
||||
if mason_version.MAJOR_VERSION ~= 2 then
|
||||
vim.health.error(("mason.nvim v2 is required (found v%d)."):format(mason_version.MAJOR_VERSION))
|
||||
return false
|
||||
end
|
||||
vim.health.ok("mason.nvim v2")
|
||||
return true
|
||||
end
|
||||
|
||||
function M.check()
|
||||
vim.health.start("mason-conform.nvim")
|
||||
|
||||
if vim.fn.has("nvim-0.11") == 1 then
|
||||
vim.health.ok("Neovim v0.11+")
|
||||
else
|
||||
vim.health.error("Neovim v0.11 or higher is required.")
|
||||
end
|
||||
|
||||
local mason_installed = check_mason()
|
||||
|
||||
if mason_installed then
|
||||
local registry_ok = pcall(require, "mason-registry")
|
||||
if registry_ok then
|
||||
vim.health.ok("mason registry is accessible")
|
||||
else
|
||||
vim.health.error("mason-registry could not be loaded.")
|
||||
end
|
||||
end
|
||||
|
||||
local conform_ok = pcall(require, "conform")
|
||||
if not conform_ok then
|
||||
vim.health.error("conform.nvim was not found. Is it installed and loaded?")
|
||||
return
|
||||
end
|
||||
vim.health.ok("conform.nvim")
|
||||
|
||||
local formatters = require("mason-conform.formatters").configured()
|
||||
if #formatters == 0 then
|
||||
vim.health.warn("No formatters are configured in conform's formatters_by_ft, so there is nothing to install.")
|
||||
return
|
||||
end
|
||||
vim.health.ok(("%d formatter(s) configured in formatters_by_ft"):format(#formatters))
|
||||
|
||||
local mapping = require("mason-conform.mapping")
|
||||
local unmapped = {}
|
||||
for _, name in ipairs(formatters) do
|
||||
if mapping.conform_to_package[name] == nil then
|
||||
unmapped[#unmapped + 1] = name
|
||||
end
|
||||
end
|
||||
if #unmapped > 0 then
|
||||
vim.health.info(
|
||||
("No mason package mapping for: %s. These will not be installed automatically."):format(
|
||||
table.concat(unmapped, ", ")
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
local ignored = {}
|
||||
for _, name in ipairs(require("mason-conform").config.ignore_install) do
|
||||
ignored[#ignored + 1] = name
|
||||
end
|
||||
if #ignored > 0 then
|
||||
vim.health.info(("Ignored by 'ignore_install': %s"):format(table.concat(ignored, ", ")))
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,13 +1,18 @@
|
||||
local M = {}
|
||||
|
||||
---@class MasonConformConfig
|
||||
---@field ignore_install string[] Formatters that should never be installed automatically.
|
||||
|
||||
---@type MasonConformConfig
|
||||
M.config = {
|
||||
ignore_install = {}
|
||||
ignore_install = {},
|
||||
}
|
||||
|
||||
function M.setup(cfg)
|
||||
if cfg and cfg.ignore_install then
|
||||
M.config.ignore_install = cfg.ignore_install
|
||||
end
|
||||
---@param opts? MasonConformConfig Options overriding the defaults.
|
||||
function M.setup(opts)
|
||||
vim.validate("opts", opts, "table", true)
|
||||
|
||||
M.config = vim.tbl_deep_extend("force", { ignore_install = {} }, opts or {})
|
||||
|
||||
require("mason-conform.auto_install")()
|
||||
end
|
||||
|
||||
@@ -1,31 +1,19 @@
|
||||
local registry = require "mason-registry"
|
||||
|
||||
local M = {}
|
||||
|
||||
local function resolve_package(mason_package_name)
|
||||
local Optional = require "mason-core.optional"
|
||||
|
||||
local ok, pkg = pcall(registry.get_package, mason_package_name)
|
||||
if ok then
|
||||
return Optional.of_nilable(pkg)
|
||||
end
|
||||
end
|
||||
|
||||
---@param pkg Package The mason package to install.
|
||||
---@param version? string Pin the installation to a specific version.
|
||||
local function install_package(pkg, version)
|
||||
local linter_name = pkg.name
|
||||
vim.notify(("[mason-conform] installing %s"):format(pkg.name))
|
||||
|
||||
vim.notify(("[mason-conform] installing %s"):format(linter_name))
|
||||
|
||||
return pkg:install({ version = version }):once(
|
||||
pkg:install({ version = version }):once(
|
||||
"closed",
|
||||
vim.schedule_wrap(function()
|
||||
if pkg:is_installed() then
|
||||
vim.notify(("[mason-conform] %s was successfully installed"):format(linter_name))
|
||||
vim.notify(("[mason-conform] %s was successfully installed"):format(pkg.name))
|
||||
else
|
||||
vim.notify(
|
||||
("[mason-conform] failed to install %s. Installation logs are available in :Mason and :MasonLog")
|
||||
:format(
|
||||
linter_name
|
||||
("[mason-conform] failed to install %s. Installation logs are available in :Mason and :MasonLog"):format(
|
||||
pkg.name
|
||||
),
|
||||
vim.log.levels.ERROR
|
||||
)
|
||||
@@ -34,32 +22,30 @@ local function install_package(pkg, version)
|
||||
)
|
||||
end
|
||||
|
||||
---Install the mason package if it exists in the registry and is not already
|
||||
---installed or installing.
|
||||
---@param mason_package_name string Mason package identifier, optionally `name@version`.
|
||||
function M.try_install(mason_package_name)
|
||||
local Package = require "mason-core.package"
|
||||
local Package = require("mason-core.package")
|
||||
local registry = require("mason-registry")
|
||||
local package_name, version = Package.Parse(mason_package_name)
|
||||
|
||||
resolve_package(package_name)
|
||||
:if_present(
|
||||
function(pkg)
|
||||
if not pkg:is_installed() then
|
||||
if require("mason.version").MAJOR_VERSION == 2 then
|
||||
if pkg:is_installing() then
|
||||
return
|
||||
end
|
||||
end
|
||||
install_package(pkg, version)
|
||||
end
|
||||
end
|
||||
local ok, pkg = pcall(registry.get_package, package_name)
|
||||
if not ok or pkg == nil then
|
||||
vim.notify(
|
||||
("[mason-conform] Formatter %q is not available in the mason registry. Make sure it is a valid formatter name, or add it to 'ignore_install' to silence this warning."):format(
|
||||
package_name
|
||||
),
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
:if_not_present(function()
|
||||
vim.notify(
|
||||
("[mason-conform] Formatter %q is not a valid entry in ensure_installed. Make sure to only provide valid formatter names.")
|
||||
:format(
|
||||
package_name
|
||||
),
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
end)
|
||||
return
|
||||
end
|
||||
|
||||
if pkg:is_installed() or pkg:is_installing() then
|
||||
return
|
||||
end
|
||||
|
||||
install_package(pkg, version)
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
local M = {}
|
||||
|
||||
-- conform formatter to mason package mapping
|
||||
-- https://mason-registry.dev/registry/list
|
||||
---Conform formatter name -> mason package name.
|
||||
---https://mason-registry.dev/registry/list
|
||||
---@type table<string, string>
|
||||
M.conform_to_package = {
|
||||
["air"] = "air",
|
||||
["alejandra"] = "alejandra",
|
||||
@@ -53,6 +54,7 @@ M.conform_to_package = {
|
||||
-- dioxus
|
||||
["djlint"] = "djlint",
|
||||
["docformatter"] = "docformatter",
|
||||
["dockerfmt"] = "dockerfmt",
|
||||
-- docstrfmt
|
||||
["doctoc"] = "doctoc",
|
||||
["dprint"] = "dprint",
|
||||
@@ -75,6 +77,7 @@ M.conform_to_package = {
|
||||
-- gawk
|
||||
["gci"] = "gci",
|
||||
["gdformat"] = "gdtoolkit",
|
||||
["gdscript-formatter"] = "gdscript-formatter",
|
||||
["gersemi"] = "gersemi",
|
||||
-- ghokin
|
||||
-- gleam
|
||||
@@ -118,6 +121,7 @@ M.conform_to_package = {
|
||||
-- liquidsoap-prettier
|
||||
-- llf
|
||||
["lua-format"] = "luaformatter",
|
||||
["luafmt"] = "luafmt",
|
||||
-- mago_format
|
||||
-- mago_lint
|
||||
["markdown-toc"] = "markdown-toc",
|
||||
@@ -143,7 +147,12 @@ M.conform_to_package = {
|
||||
-- odinfmt
|
||||
["opa_fmt"] = "opa",
|
||||
["ormolu"] = "ormolu",
|
||||
["oxfmt"] = "oxfmt",
|
||||
["oxlint"] = "oxlint",
|
||||
-- packer_fmt
|
||||
["palantir-java-format"] = "palantir-java-format",
|
||||
["panache"] = "panache",
|
||||
["panache-fix"] = "panache",
|
||||
-- pangu
|
||||
-- perlimports
|
||||
-- perltidy
|
||||
@@ -160,9 +169,10 @@ M.conform_to_package = {
|
||||
["purs-tidy"] = "purescript-tidy",
|
||||
-- pycln
|
||||
["pyink"] = "pyink",
|
||||
["pymarkdownlnt"] = "pymarkdownlnt",
|
||||
["pyproject-fmt"] = "pyproject-fmt",
|
||||
-- python-ly
|
||||
-- pyupgrade
|
||||
["pyupgrade"] = "pyupgrade",
|
||||
["reformat-gherkin"] = "reformat-gherkin",
|
||||
["reorder-python-imports"] = "reorder-python-imports",
|
||||
-- rescript-format
|
||||
@@ -170,10 +180,12 @@ M.conform_to_package = {
|
||||
-- rstfmt
|
||||
["rubocop"] = "rubocop",
|
||||
["rubyfmt"] = "rubyfmt",
|
||||
["ruff"] = "ruff",
|
||||
["ruff_fix"] = "ruff",
|
||||
["ruff_format"] = "ruff",
|
||||
["ruff_organize_imports"] = "ruff",
|
||||
["rufo"] = "rufo",
|
||||
["rumdl"] = "rumdl",
|
||||
-- runic
|
||||
-- ["rustfmt"] = "rustfmt", Deprecated by mason
|
||||
["rustywind"] = "rustywind",
|
||||
@@ -199,7 +211,7 @@ M.conform_to_package = {
|
||||
["superhtml"] = "superhtml",
|
||||
-- swift
|
||||
-- swift_format
|
||||
-- swiftformat
|
||||
["swiftformat"] = "swiftformat",
|
||||
["swiftlint"] = "swiftlint",
|
||||
-- syntax_tree
|
||||
["taplo"] = "taplo",
|
||||
@@ -216,7 +228,7 @@ M.conform_to_package = {
|
||||
["twig-cs-fixer"] = "twig-cs-fixer",
|
||||
-- typespec
|
||||
["typos"] = "typos",
|
||||
-- typstyle
|
||||
["typstyle"] = "typstyle",
|
||||
-- ufmt
|
||||
-- uncrustify
|
||||
["usort"] = "usort",
|
||||
|
||||
Reference in New Issue
Block a user