REFACTOR: Updated from older config

This commit is contained in:
2026-10-10 05:54:27 -04:00
parent 48da2ebd5e
commit 132a3d0630
9 changed files with 444 additions and 84 deletions
+16 -33
View File
@@ -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
+63
View File
@@ -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
+76
View File
@@ -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
+10 -5
View File
@@ -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
+27 -41
View File
@@ -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
+17 -5
View File
@@ -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",