Compare commits

..
11 Commits
Author SHA1 Message Date
DarthMooMancer 132a3d0630 REFACTOR: Updated from older config 2026-10-10 05:54:27 -04:00
zknx 48da2ebd5e feat(mapping): add 9 missing formatter tools to conform_to_package mapping
Note: Only verified these specific tools exist - did not audit existing uncommented entries for deprecation or correctness.
2025-08-08 12:49:28 +02:00
zknx 368ee5d3e6 feat(mapping): add missing formatter tools as commented entries 2025-08-08 12:49:28 +02:00
Andreas Palm f3b96fa221 feat: Support Mason 2.0.0 2025-05-20 21:09:14 +02:00
Patryk Kiepas 1983f353b2 Update conform-to-mason mappings (#12)
* Update the list of available conform formatters

* Update conform-to-mason mappings
2025-03-10 15:29:24 +01:00
Andreas Palm abce2be529 Update README.md 2024-06-16 22:50:56 +02:00
Zoltán Reegn ae0d37dd43 feat: link opa_fmt to opa
See https://mason-registry.dev/registry/list#opa
2024-06-14 12:15:27 +02:00
Andreas Palm 40133b4bf3 fix(mapping): Incorrect name for clang-format 2024-06-13 18:25:51 +02:00
Andreas Palm ddb854253d fix: Remove debug statement 2024-05-19 21:03:27 +02:00
Andreas Palm 882a4449e5 feat: Add config opt 'ignore_install'
This option allows the caller to define a list of conform formatters
that should be ignored during the install process. This might be useful
if the caller already have this tools installed and prefer not to have
them downloaded again by mason.
2024-05-19 13:22:23 +02:00
Andreas Palm 3ba75eeae8 chore(mapping): Remove rustfmt
Mason has marked rustfmt as deprecated, remove the mapping so
we stop downloading it.
2024-04-25 10:44:38 +02:00
9 changed files with 570 additions and 86 deletions
+7
View File
@@ -0,0 +1,7 @@
column_width = 120
line_endings = "Unix"
indent_type = "Spaces"
indent_width = 4
quote_style = "AutoPreferDouble"
call_parentheses = "Always"
collapse_simple_statement = "Never"
+50 -2
View File
@@ -1,9 +1,17 @@
# mason-conform.nvim # mason-conform.nvim
Auto install formatters registered with `conform.nvim` via [Mason](https://github.com/williamboman/mason.nvim). Automatically install formatters registered with [conform.nvim](https://github.com/stevearc/conform.nvim) via [Mason](https://github.com/williamboman/mason.nvim).
# Requirements
- Neovim 0.11+
- [mason.nvim](https://github.com/mason-org/mason.nvim) 2.x
- [conform.nvim](https://github.com/stevearc/conform.nvim) (9.x or newer)
# Install # Install
With [lazy.nvim](https://github.com/folke/lazy.nvim):
```lua ```lua
require("lazy").setup({ require("lazy").setup({
"williamboman/mason.nvim", "williamboman/mason.nvim",
@@ -12,6 +20,16 @@ require("lazy").setup({
}) })
``` ```
With Neovim's built-in package manager (`:h vim.pack`, Neovim 0.12+):
```lua
vim.pack.add({
{ src = "https://github.com/mason-org/mason.nvim" },
{ src = "https://github.com/stevearc/conform.nvim" },
{ src = "https://github.com/zapling/mason-conform.nvim" },
})
```
# Setup # Setup
It's crucial to setup plugins in the following order: It's crucial to setup plugins in the following order:
@@ -26,15 +44,45 @@ access the mason registry.
# Configuration # Configuration
```lua ```lua
require("mason-conform").setup() require("mason-conform").setup({
ignore_install = {'prettier'} -- List of formatters to ignore during install
})
``` ```
All the `formatters_by_ft` shapes supported by conform are understood:
```lua
require("conform").setup({
formatters_by_ft = {
-- Plain list
lua = { "stylua" },
-- List with inline format options (`lsp_format`, `stop_after_first`, ...)
python = { "autopep8", lsp_format = "fallback" },
-- Legacy nested list ("run the first available formatter")
markdown = { { "prettierd", "prettier" }, "cbfmt" },
-- Function returning a list (conform "first available" recipe)
javascript = function(bufnr)
return { require("conform").get_formatter_info("prettier", bufnr).available and "prettier" or "prettierd" }
end,
},
})
```
Functions are evaluated without a buffer so that every candidate formatter can
be discovered and installed. A function that requires a buffer is skipped
instead of raising an error.
# Available formatters # Available formatters
Only formatters that are available in the [mason registry](https://github.com/mason-org/mason-registry) Only formatters that are available in the [mason registry](https://github.com/mason-org/mason-registry)
can be downloaded automatically. If the formatter is available in the registry and it's not being can be downloaded automatically. If the formatter is available in the registry and it's not being
downloaded, this plugin might be missing a `conform` => `mason` mapping in the file [lua/mason-conform/mapping.lua](lua/mason-conform/mapping.lua). downloaded, this plugin might be missing a `conform` => `mason` mapping in the file [lua/mason-conform/mapping.lua](lua/mason-conform/mapping.lua).
# Healthcheck
Run `:checkhealth mason-conform` to verify that Neovim, `mason.nvim` and `conform.nvim` are set up
correctly, and to see which configured formatters cannot be installed automatically.
# License # License
`mason-conform.nvim` is a blatant copy of [mason-nvim-lint](https://github.com/rshkarin/mason-nvim-lint) `mason-conform.nvim` is a blatant copy of [mason-nvim-lint](https://github.com/rshkarin/mason-nvim-lint)
+15 -26
View File
@@ -1,36 +1,25 @@
local registry = require("mason-registry")
local mapping = require("mason-conform.mapping")
local function auto_install() local function auto_install()
local formatters_by_ft = require("conform").formatters_by_ft; local config = require("mason-conform").config
local mapping = require("mason-conform.mapping")
local install = require("mason-conform.install")
local formatters_to_install = {} local ignored = {}
for _, formatters in pairs(formatters_by_ft) do for _, name in ipairs(config.ignore_install) do
for _, formatter in pairs(formatters) do ignored[name] = true
-- 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
end
end
end end
for conformFormatter, _ in pairs(formatters_to_install) do for _, name in ipairs(require("mason-conform.formatters").configured()) do
local package = mapping.conform_to_package[conformFormatter] if not ignored[name] then
local package = mapping.conform_to_package[name]
if package ~= nil then if package ~= nil then
require("mason-conform.install").try_install(package) install.try_install(package)
end
end end
end end
end end
if registry.refresh then ---Refresh the mason registry, then install every configured formatter that is
return function() ---missing. Returns immediately; installation happens on the main loop.
registry.refresh(vim.schedule_wrap(auto_install)) return function()
end require("mason-registry").refresh(vim.schedule_wrap(auto_install))
else
return auto_install
end 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
+15 -2
View File
@@ -1,7 +1,20 @@
local M = {} local M = {}
function M.setup() ---@class MasonConformConfig
require "mason-conform.auto_install" () ---@field ignore_install string[] Formatters that should never be installed automatically.
---@type MasonConformConfig
M.config = {
ignore_install = {},
}
---@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 end
return M return M
+23 -32
View File
@@ -1,31 +1,19 @@
local registry = require "mason-registry"
local M = {} local M = {}
local function resolve_package(mason_package_name) ---@param pkg Package The mason package to install.
local Optional = require "mason-core.optional" ---@param version? string Pin the installation to a specific version.
local ok, pkg = pcall(registry.get_package, mason_package_name)
if ok then
return Optional.of_nilable(pkg)
end
end
local function install_package(pkg, 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)) pkg:install({ version = version }):once(
return pkg:install({ version = version }):once(
"closed", "closed",
vim.schedule_wrap(function() vim.schedule_wrap(function()
if pkg:is_installed() then 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 else
vim.notify( vim.notify(
("[mason-conform] failed to install %s. Installation logs are available in :Mason and :MasonLog") ("[mason-conform] failed to install %s. Installation logs are available in :Mason and :MasonLog"):format(
:format( pkg.name
linter_name
), ),
vim.log.levels.ERROR vim.log.levels.ERROR
) )
@@ -34,27 +22,30 @@ local function install_package(pkg, version)
) )
end 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) 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) local package_name, version = Package.Parse(mason_package_name)
resolve_package(package_name) local ok, pkg = pcall(registry.get_package, package_name)
:if_present( if not ok or pkg == nil then
function(pkg)
if not pkg:is_installed() then
install_package(pkg, version)
end
end
)
:if_not_present(function()
vim.notify( vim.notify(
("[mason-conform] Formatter %q is not a valid entry in ensure_installed. Make sure to only provide valid formatter names.") ("[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(
:format(
package_name package_name
), ),
vim.log.levels.WARN vim.log.levels.WARN
) )
end) return
end
if pkg:is_installed() or pkg:is_installing() then
return
end
install_package(pkg, version)
end end
return M return M
+133 -18
View File
@@ -1,9 +1,12 @@
local M = {} local M = {}
-- conform formatter to mason package mapping ---Conform formatter name -> mason package name.
-- https://mason-registry.dev/registry/list ---https://mason-registry.dev/registry/list
---@type table<string, string>
M.conform_to_package = { M.conform_to_package = {
-- alejandra ["air"] = "air",
["alejandra"] = "alejandra",
["ansible-lint"] = "ansible-lint",
["asmfmt"] = "asmfmt", ["asmfmt"] = "asmfmt",
["ast-grep"] = "ast-grep", ["ast-grep"] = "ast-grep",
-- astyle -- astyle
@@ -11,71 +14,145 @@ M.conform_to_package = {
-- autocorrect -- autocorrect
["autoflake"] = "autoflake", ["autoflake"] = "autoflake",
["autopep8"] = "autopep8", ["autopep8"] = "autopep8",
-- awk
-- bean-format -- bean-format
["beautysh"] = "beautysh", ["beautysh"] = "beautysh",
["bibtex-tidy"] = "bibtex-tidy", ["bibtex-tidy"] = "bibtex-tidy",
-- biome-check -- bicep; it exists on Mason, but as LSP (exec: `bicep-lsp`)
["biome"] = "biome", ["biome"] = "biome",
-- biome-check
-- biome-organize-imports
["black"] = "black", ["black"] = "black",
["blade-formatter"] = "blade-formatter", ["blade-formatter"] = "blade-formatter",
["blue"] = "blue", ["blue"] = "blue",
-- bpfmt
["bsfmt"] = "brighterscript-formatter",
["buf"] = "buf", ["buf"] = "buf",
["buildifier"] = "buildifier", ["buildifier"] = "buildifier",
-- cabal_fmt
-- caramel_fmt
["cbfmt"] = "cbfmt", ["cbfmt"] = "cbfmt",
["clang_format"] = "clang-format", -- cedar
["clang-format"] = "clang-format",
["cljfmt"] = "cljfmt",
-- cljstyle -- cljstyle
["cmake_format"] = "cmakelang", ["cmake_format"] = "cmakelang",
-- codeql; it exists on Mason, but as LSP (exec: `codeql`)
["codespell"] = "codespell", ["codespell"] = "codespell",
-- commitmsgfmt
["crlfmt"] = "crlfmt",
-- crystal
["csharpier"] = "csharpier", ["csharpier"] = "csharpier",
-- css_beautify
-- cue_fmt -- cue_fmt
-- d2
["darker"] = "darker", ["darker"] = "darker",
-- dart_format -- dart_format
["dcm_fix"] = "dcm",
["dcm_format"] = "dcm",
["deno_fmt"] = "deno", ["deno_fmt"] = "deno",
-- dfmt -- dfmt
-- dioxus
["djlint"] = "djlint", ["djlint"] = "djlint",
["docformatter"] = "docformatter",
["dockerfmt"] = "dockerfmt",
-- docstrfmt
["doctoc"] = "doctoc",
["dprint"] = "dprint", ["dprint"] = "dprint",
["easy-coding-standard"] = "easy-coding-standard", ["easy-coding-standard"] = "easy-coding-standard",
-- efmt
["elm_format"] = "elm-format", ["elm_format"] = "elm-format",
-- erb_format ["erb_format"] = "erb-formatter",
-- erlfmt
["eslint_d"] = "eslint_d", ["eslint_d"] = "eslint_d",
["fantomas"] = "fantomas", ["fantomas"] = "fantomas",
["findent"] = "findent",
-- fish_indent -- fish_indent
["fixjson"] = "fixjson", ["fixjson"] = "fixjson",
-- fnlfmt -- fnlfmt
-- forge_fmt
-- format-dune-file
-- format-queries
["fourmolu"] = "fourmolu", ["fourmolu"] = "fourmolu",
["fprettify"] = "fprettify",
-- gawk
["gci"] = "gci", ["gci"] = "gci",
["gdformat"] = "gdtoolkit", ["gdformat"] = "gdtoolkit",
["gdscript-formatter"] = "gdscript-formatter",
["gersemi"] = "gersemi", ["gersemi"] = "gersemi",
-- ghokin
-- gleam
-- gluon_fmt
-- gn -- gn
-- gofmt -- gofmt
["gofumpt"] = "gofumpt", ["gofumpt"] = "gofumpt",
["goimports-reviser"] = "goimports-reviser",
["goimports"] = "goimports", ["goimports"] = "goimports",
["goimports-reviser"] = "goimports-reviser",
-- gojq
["golangci-lint"] = "golangci-lint",
["golines"] = "golines", ["golines"] = "golines",
["google-java-format"] = "google-java-format", ["google-java-format"] = "google-java-format",
-- grain_format
["hcl"] = "hclfmt",
-- hindent
-- hledger-fmt
-- html_beautify
["htmlbeautifier"] = "htmlbeautifier", ["htmlbeautifier"] = "htmlbeautifier",
-- hurlfmt
-- imba_fmt
-- indent -- indent
-- init -- init
-- injected -- injected
-- inko
["isort"] = "isort", ["isort"] = "isort",
-- janet-format
["joker"] = "joker", ["joker"] = "joker",
["jq"] = "jq", ["jq"] = "jq",
-- js_beautify
["jsonnetfmt"] = "jsonnetfmt", ["jsonnetfmt"] = "jsonnetfmt",
-- just -- just
["kcl"] = "kcl",
["kdlfmt"] = "kdlfmt",
-- keep-sorted
["ktfmt"] = "ktfmt",
["ktlint"] = "ktlint", ["ktlint"] = "ktlint",
["kulala-fmt"] = "kulala-fmt",
["latexindent"] = "latexindent", ["latexindent"] = "latexindent",
-- leptosfmt
-- liquidsoap-prettier
-- llf
["lua-format"] = "luaformatter",
["luafmt"] = "luafmt",
-- mago_format
-- mago_lint
["markdown-toc"] = "markdown-toc", ["markdown-toc"] = "markdown-toc",
["markdownlint-cli2"] = "markdownlint-cli2", -- markdownfmt
["markdownlint"] = "markdownlint", ["markdownlint"] = "markdownlint",
["markdownlint-cli2"] = "markdownlint-cli2",
["mdformat"] = "mdformat", ["mdformat"] = "mdformat",
["mdsf"] = "mdsf",
["mdslw"] = "mdslw", ["mdslw"] = "mdslw",
-- mix -- mix
-- nixfmt -- mojo_format
-- nginxfmt
-- nickel; it exists on Mason, but as LSP (exec: `nls`)
-- nimpretty
["nixfmt"] = "nixfmt",
["nixpkgs_fmt"] = "nixpkgs-fmt", ["nixpkgs_fmt"] = "nixpkgs-fmt",
["nomad_fmt"] = "nomad",
-- nph
["npm-groovy-lint"] = "npm-groovy-lint",
-- nufmt
["ocamlformat"] = "ocamlformat", ["ocamlformat"] = "ocamlformat",
-- opa_fmt -- ocp-indent
-- odinfmt
["opa_fmt"] = "opa",
["ormolu"] = "ormolu",
["oxfmt"] = "oxfmt",
["oxlint"] = "oxlint",
-- packer_fmt -- packer_fmt
["palantir-java-format"] = "palantir-java-format",
["panache"] = "panache",
["panache-fix"] = "panache",
-- pangu -- pangu
-- perlimports -- perlimports
-- perltidy -- perltidy
@@ -87,51 +164,89 @@ M.conform_to_package = {
["prettier"] = "prettier", ["prettier"] = "prettier",
["prettierd"] = "prettierd", ["prettierd"] = "prettierd",
["pretty-php"] = "pretty-php", ["pretty-php"] = "pretty-php",
["prettypst"] = "prettypst",
-- puppet-lint -- puppet-lint
["purs-tidy"] = "purescript-tidy",
-- pycln
["pyink"] = "pyink",
["pymarkdownlnt"] = "pymarkdownlnt",
["pyproject-fmt"] = "pyproject-fmt",
-- python-ly
["pyupgrade"] = "pyupgrade",
["reformat-gherkin"] = "reformat-gherkin",
["reorder-python-imports"] = "reorder-python-imports", ["reorder-python-imports"] = "reorder-python-imports",
-- rescript-format -- rescript-format
-- roc
-- rstfmt
["rubocop"] = "rubocop", ["rubocop"] = "rubocop",
["rubyfmt"] = "rubyfmt", ["rubyfmt"] = "rubyfmt",
-- ruff ["ruff"] = "ruff",
["ruff_fix"] = "ruff", ["ruff_fix"] = "ruff",
["ruff_format"] = "ruff", ["ruff_format"] = "ruff",
["ruff_organize_imports"] = "ruff",
["rufo"] = "rufo", ["rufo"] = "rufo",
["rustfmt"] = "rustfmt", ["rumdl"] = "rumdl",
-- runic
-- ["rustfmt"] = "rustfmt", Deprecated by mason
["rustywind"] = "rustywind", ["rustywind"] = "rustywind",
-- scalafmt -- scalafmt
["shellcheck"] = "shellcheck", ["shellcheck"] = "shellcheck",
["shellharden"] = "shellharden", ["shellharden"] = "shellharden",
["shfmt"] = "shfmt", ["shfmt"] = "shfmt",
["sleek"] = "sleek",
-- smlfmt
["snakefmt"] = "snakefmt",
["sql_formatter"] = "sql-formatter", ["sql_formatter"] = "sql-formatter",
["sqlfluff"] = "sqlfluff", ["sqlfluff"] = "sqlfluff",
["sqlfmt"] = "sqlfmt", ["sqlfmt"] = "sqlfmt",
["sqruff"] = "sqruff",
-- squeeze_blanks -- squeeze_blanks
-- standard-clj
["standardjs"] = "standardjs", ["standardjs"] = "standardjs",
["standardrb"] = "standardrb", ["standardrb"] = "standardrb",
["stylelint"] = "stylelint", ["stylelint"] = "stylelint",
-- styler -- styler
-- stylish-haskell
["stylua"] = "stylua", ["stylua"] = "stylua",
["superhtml"] = "superhtml",
-- swift
-- swift_format -- swift_format
-- swiftformat ["swiftformat"] = "swiftformat",
["swiftlint"] = "swiftlint",
-- syntax_tree
["taplo"] = "taplo", ["taplo"] = "taplo",
["templ"] = "templ", ["templ"] = "templ",
-- terraform_fmt ["terraform_fmt"] = "terraform",
-- terragrunt_hclfmt -- terragrunt_hclfmt
["tex-fmt"] = "tex-fmt",
["tlint"] = "tlint", ["tlint"] = "tlint",
-- tofu_fmt
["tombi"] = "tombi",
-- treefmt
-- trim_newlines -- trim_newlines
-- trim_whitespace -- trim_whitespace
-- twig-cs-fixer ["twig-cs-fixer"] = "twig-cs-fixer",
-- typespec
["typos"] = "typos", ["typos"] = "typos",
-- typstfmt ["typstyle"] = "typstyle",
-- ufmt
-- uncrustify -- uncrustify
["usort"] = "usort", ["usort"] = "usort",
["xmlformat"] = "xmlformatter", -- v
["verible"] = "verible",
["vsg"] = "vsg",
["xmlformat"] = "xmlformatter", -- Deprecated in conform.nvim; redirects to xmlformatter
["xmlformatter"] = "xmlformatter",
-- xmllint -- xmllint
-- xmlstarlet
["yamlfix"] = "yamlfix", ["yamlfix"] = "yamlfix",
["yamlfmt"] = "yamlfmt", ["yamlfmt"] = "yamlfmt",
["yapf"] = "yapf", ["yapf"] = "yapf",
-- yew-fmt
["yq"] = "yq", ["yq"] = "yq",
-- zigfmt -- zigfmt
-- ziggy
-- ziggy_schema
["zprint"] = "zprint", ["zprint"] = "zprint",
} }
+182
View File
@@ -0,0 +1,182 @@
-- Smoke test for mason-conform.nvim with stubbed mason/conform.
-- Run from the repository root: nvim -l tests/smoke_test.lua
local script = (arg and arg[0]) or "tests/smoke_test.lua"
local root = script:match("^(.*)/tests/") or "."
package.path = ("%s/lua/?.lua;%s/lua/?/init.lua;"):format(root, root) .. package.path
local failures = {}
local function check(cond, msg)
if not cond then
failures[#failures + 1] = msg
print("FAIL: " .. msg)
else
print("ok: " .. msg)
end
end
-- ---- stubs -------------------------------------------------------------
local notifications = {}
local install_calls = {}
local installed = {}
local installing = {}
package.preload["conform"] = function()
return {
formatters_by_ft = {
lua = { "stylua" },
python = { "autopep8", lsp_format = "fallback", stop_after_first = true },
markdown = { { "prettierd", "prettier" }, "cbfmt" },
javascript = function()
error("needs a buffer")
end,
go = function()
return { "gofumpt" }
end,
},
}
end
package.preload["mason-registry"] = function()
local registry = {}
function registry.refresh(cb)
if cb then
cb(true, {})
end
end
function registry.get_package(name)
if name == "not-in-registry" then
error(('Cannot find package "%q".'):format(name))
end
local pkg = { name = name }
function pkg:is_installed()
return installed[name] or false
end
function pkg:is_installing()
return installing[name] or false
end
function pkg:install(opts)
install_calls[#install_calls + 1] = { name = name, version = opts and opts.version }
local handle = {}
function handle:once(event, cb2)
assert(event == "closed")
installed[name] = true
cb2()
end
return handle
end
return pkg
end
return registry
end
package.preload["mason-core.package"] = function()
local Package = {}
function Package.Parse(identifier)
local name, version = identifier:match("^([^@]+)@?(.*)$")
if version == "" then
version = nil
end
return name, version
end
return Package
end
package.preload["mason.version"] = function()
return { MAJOR_VERSION = 2, MINOR_VERSION = 3 }
end
local original_notify = vim.notify
vim.notify = function(msg, level)
notifications[#notifications + 1] = { msg = msg, level = level or vim.log.levels.INFO }
end
-- ---- tests -------------------------------------------------------------
-- setup() with defaults
local mc = require("mason-conform")
mc.setup()
vim.wait(200)
check(vim.deep_equal(mc.config, { ignore_install = {} }), "setup() without opts keeps defaults")
local function installed_names()
local names = {}
for _, call in ipairs(install_calls) do
names[#names + 1] = call.name
end
table.sort(names)
return names
end
check(
vim.deep_equal(installed_names(), { "autopep8", "cbfmt", "gofumpt", "prettier", "prettierd", "stylua" }),
"installs mapped formatters from every formatters_by_ft shape; skips broken function: "
.. table.concat(installed_names(), ",")
)
-- setup() again with ignore_install
install_calls = {}
notifications = {}
installed = {}
mc.setup({ ignore_install = { "prettierd" } })
vim.wait(200)
check(
vim.deep_equal(installed_names(), { "autopep8", "cbfmt", "gofumpt", "prettier", "stylua" }),
"ignore_install is respected: " .. table.concat(installed_names(), ",")
)
check(vim.deep_equal(mc.config.ignore_install, { "prettierd" }), "ignore_install stored")
-- installed / installing packages are skipped
install_calls = {}
installed = {}
installing = {}
installed["stylua"] = true
installing["autopep8"] = true
mc.setup({ ignore_install = {} })
vim.wait(200)
check(
vim.deep_equal(installed_names(), { "cbfmt", "gofumpt", "prettier", "prettierd" }),
"already installed/installing packages are skipped: " .. table.concat(installed_names(), ",")
)
-- unknown mason package -> warning, no error
local install = require("mason-conform.install")
notifications = {}
local ok = pcall(install.try_install, "not-in-registry")
check(ok, "try_install on unknown package does not raise")
check(#notifications == 1 and notifications[1].level == vim.log.levels.WARN, "unknown package emits a warning")
check(
notifications[1] and notifications[1].msg:find("not%-in%-registry", 1, false) ~= nil,
"warning names the formatter"
)
-- version pinning passes through Package.Parse
installed = {}
install_calls = {}
install.try_install("stylua@1.2.0")
check(install_calls[1] and install_calls[1].version == "1.2.0", "version suffix forwarded to mason")
-- setup() validates its argument
ok = pcall(mc.setup, "not a table")
check(not ok, "setup() rejects non-table opts")
-- health check runs
local health_ok, err = pcall(function()
require("mason-conform.health").check()
end)
check(health_ok, "health check runs without error" .. (health_ok and "" or (": " .. tostring(err))))
-- formatters module
local formatters = require("mason-conform.formatters").configured()
check(
vim.deep_equal(formatters, { "autopep8", "cbfmt", "gofumpt", "prettier", "prettierd", "stylua" }),
"formatters.configured() returns sorted unique names"
)
vim.notify = original_notify
print(("-"):rep(60))
if #failures > 0 then
print(("%d FAILURE(S)"):format(#failures))
os.exit(1)
end
print("all tests passed")