1
0
Fork 0
mirror of https://github.com/nix-community/nixvim.git synced 2025-11-08 19:46:06 +01:00

plugins/conform-nvim: add automatic installation of formatters

Signed-off-by: saygo-png <saygo.mail@proton.me>
This commit is contained in:
saygo-png 2025-09-14 03:30:32 +02:00 committed by Austin Horstman
parent d113982eba
commit fd0c423550
4 changed files with 298 additions and 1 deletions

View file

@ -0,0 +1,78 @@
{
pkgs,
lib,
...
}:
let
inherit (lib) elem throwIfNot;
inherit (builtins)
filter
isString
isAttrs
attrValues
attrNames
concatMap
partition
;
inherit (import ./formatter-packages.nix { inherit pkgs lib; }) sType formatter-packages;
sTypeList = attrValues sType;
isSTypeAttrSet = x: lib.elem (x.mark or null) sTypeList;
in
rec {
cleanMaybePackageList = filter (x: !isSTypeAttrSet x);
getPackageByName =
{ configuredFormatters, overrides }:
name:
let
permittedNames = attrNames configuredFormatters;
isSType = x: elem x sTypeList;
notFoundMsg = ''
A package for the conform-nvim formatter '${name}' could not be found.
It is not a user defined formatter. Is the formatter name correct?
'';
maybePackage =
overrides.${name} or formatter-packages.${name} or pkgs.${name}
or (throwIfNot (elem name permittedNames) notFoundMsg null);
in
if isSType maybePackage then
{
inherit name;
mark = maybePackage;
}
else
maybePackage;
mkWarnsFromMaybePackageList =
opts: list:
let
mkWarn =
{ name, mark }:
lib.nixvim.mkWarnings "conform-nvim" [
{
when = true;
message = ''
You have enabled the '${name}' formatter that relies on a package marked '${mark}'.
Because of that it will not be installed. To disable this warning, explicitly disable installing the package
by setting the '${opts.autoInstall.overrides}.${name}' option to 'null'. You can also disable
all warnings related to packages not installed by 'autoInstall' with '${opts.autoInstall.enableWarnings}'.
'';
}
];
in
concatMap mkWarn (filter isSTypeAttrSet list);
collectFormatters =
formatters:
let
partitioned = lib.pipe formatters [
lib.flatten
(filter (x: isString x || isAttrs x))
(partition isString)
];
in
lib.optionals (formatters != [ ]) (
partitioned.right ++ concatMap (fmts: collectFormatters (attrValues fmts)) partitioned.wrong
);
}

View file

@ -1,9 +1,11 @@
{
lib,
pkgs,
...
}:
let
inherit (lib) types;
inherit (builtins) attrValues;
inherit (lib.nixvim) defaultNullOpts;
in
lib.nixvim.plugins.mkNeovimPlugin {
@ -12,7 +14,10 @@ lib.nixvim.plugins.mkNeovimPlugin {
packPathName = "conform.nvim";
description = "Lightweight yet powerful formatter plugin for Neovim.";
maintainers = [ lib.maintainers.khaneliman ];
maintainers = with lib.maintainers; [
khaneliman
saygo-png
];
# TODO: added 2024-08-23 remove after 24.11
deprecateExtraOptions = true;
@ -43,6 +48,36 @@ lib.nixvim.plugins.mkNeovimPlugin {
"formatOnSave"
];
extraOptions = {
autoInstall = {
enable = lib.mkEnableOption ''
automatic installation of formatters listed in `settings.formatters_by_ft` and `settings.formatters`
'';
enableWarnings = lib.mkOption {
default = true;
example = false;
description = "Whether to enable warnings.";
type = lib.types.bool;
};
overrides = lib.mkOption {
type = with types; attrsOf (nullOr package);
default = { };
example = lib.literalExpression ''
{
"treefmt" = null;
"pyproject-fmt" = pkgs.python312Packages.pyproject-parser;
};
'';
description = ''
Attribute set of formatter names to nix packages.
You can set a formatter to `null` to disable auto-installing its package.
'';
};
};
};
settingsOptions =
let
lsp_format =
@ -234,4 +269,27 @@ lib.nixvim.plugins.mkNeovimPlugin {
}
```
'';
extraConfig =
cfg: opts:
let
inherit (cfg.autoInstall) enable enableWarnings;
inherit (import ./auto-install.nix { inherit pkgs lib; })
getPackageByName
collectFormatters
cleanMaybePackageList
mkWarnsFromMaybePackageList
;
getPackageByNameWith = getPackageByName {
configuredFormatters = cfg.settings.formatters;
inherit (cfg.autoInstall) overrides;
};
names = collectFormatters (attrValues cfg.settings.formatters_by_ft);
packageList = map getPackageByNameWith names;
warns = (mkWarnsFromMaybePackageList opts) packageList;
in
{
warnings = lib.mkIf (enable && warns != [ ] && enableWarnings) warns;
extraPackages = lib.mkIf enable (cleanMaybePackageList packageList);
};
}

View file

@ -0,0 +1,146 @@
{
pkgs,
...
}:
with pkgs;
rec {
sType = {
broken = "broken";
darwinOnly = "Darwin only";
unpackaged = "unpackaged";
};
formatter-packages = {
swift_format = if !stdenv.isDarwin then sType.darwinOnly else swift-format;
swiftlint = if !stdenv.isDarwin then sType.darwinOnly else swiftlint;
# 2025-09-13 build failure
inko = sType.broken;
# 2025-09-13 build failure
commitmsgfmt = sType.broken;
# 2025-09-17 build failure
gci = sType.broken;
format-queries = null; # Uses neovim itself
init = null; # Internal thingamajig
injected = null; # Internal formatter
trim_newlines = null; # Conform native formatter
trim_whitespace = null; # Conform native formatter
auto_optional = sType.unpackaged;
bake = sType.unpackaged;
blue = sType.unpackaged;
bpfmt = sType.unpackaged;
bsfmt = sType.unpackaged;
caramel_fmt = sType.unpackaged;
crlfmt = sType.unpackaged;
darker = sType.unpackaged;
dcm_fix = sType.unpackaged;
dcm_format = sType.unpackaged;
easy-coding-standard = sType.unpackaged;
findent = sType.unpackaged;
ghokin = sType.unpackaged;
gluon_fmt = sType.unpackaged;
grain_format = sType.unpackaged;
hledger-fmt = sType.unpackaged;
imba_fmt = sType.unpackaged;
janet-format = sType.unpackaged;
liquidsoap-prettier = sType.unpackaged;
llf = sType.unpackaged;
markdown-toc = sType.unpackaged;
markdownfmt = sType.unpackaged;
mdslw = sType.unpackaged;
mojo_format = sType.unpackaged;
nomad_fmt = sType.unpackaged;
npm-groovy-lint = sType.unpackaged;
packer_fmt = sType.unpackaged;
pangu = sType.unpackaged;
perlimports = sType.unpackaged;
pint = sType.unpackaged;
purs-tidy = sType.unpackaged;
pycln = sType.unpackaged;
pyink = sType.unpackaged;
pymarkdownlnt = sType.unpackaged;
reformat-gherkin = sType.unpackaged;
rescript-format = sType.unpackaged;
runic = sType.unpackaged;
spotless_gradle = sType.unpackaged;
spotless_maven = sType.unpackaged;
standard-clj = sType.unpackaged;
standardjs = sType.unpackaged;
tlint = sType.unpackaged;
twig-cs-fixer = sType.unpackaged;
vsg = sType.unpackaged;
ziggy = sType.unpackaged;
ziggy_schema = sType.unpackaged;
inherit (python313Packages) autopep8;
awk = gawk;
bean-format = beancount;
biome-check = biome;
biome-organize-imports = biome;
cabal_fmt = haskellPackages.cabal-fmt;
clang_format = clang-tools;
clang-format = clang-tools;
cmake_format = cmake-format;
css_beautify = nodePackages.js-beautify;
cue_fmt = cue;
dart_format = dart;
deno_fmt = deno;
dioxus = dioxus-cli;
inherit (python313Packages) docformatter;
elm_format = elmPackages.elm-format;
erb_format = rubyPackages.erb-formatter;
fish_indent = fishMinimal;
forge_fmt = foundry;
format-dune-file = dune_3;
gdformat = gdtoolkit_4;
gofmt = go;
goimports = gotools;
hcl = hclfmt;
inherit (haskellPackages) hindent;
html_beautify = nodePackages.js-beautify;
inherit (rubyPackages) htmlbeautifier;
hurlfmt = hurl;
js_beautify = nodePackages.js-beautify;
jsonnetfmt = jsonnet;
inherit (texlive.pkgs) latexindent;
lua-format = luaformatter;
mago_format = mago;
mago_lint = mago;
markdownlint = markdownlint-cli;
mix = beamMinimal28Packages.elixir;
nginxfmt = nginx-config-formatter;
nimpretty = nim;
nixpkgs_fmt = nixpkgs-fmt;
inherit (ocamlPackages) ocp-indent;
odinfmt = ols;
opa_fmt = open-policy-agent;
perltidy = perl538Packages.PerlTidy;
pg_format = pgformatter;
php_cs_fixer = php83Packages.php-cs-fixer;
phpcbf = php84Packages.php-codesniffer;
inherit (php84Packages) phpinsights;
prolog = swi-prolog;
pyproject-fmt = python313Packages.pyproject-parser;
inherit (python313Packages) python-ly;
qmlformat = libsForQt5.qt5.qtdeclarative;
inherit (python313Packages) reorder-python-imports;
ruff_fix = ruff;
ruff_format = ruff;
ruff_organize_imports = ruff;
sql_formatter = sql-formatter;
inherit (python313Packages) sqlfmt;
squeeze_blanks = coreutils;
standardrb = rubyPackages.standard;
styler = R;
inherit (rubyPackages) syntax_tree;
terraform_fmt = tenv;
terragrunt_hclfmt = terragrunt;
tofu_fmt = opentofu;
v = vlang;
xmlformatter = xmlformat;
xmllint = libxml2;
zigfmt = zig;
};
}