Skip to content

Conversation

saygo-png
Copy link
Contributor

@saygo-png saygo-png commented Sep 13, 2025

Closes #1141

This PR tries to automatically install the needed packages for Conform formatters.
It extracts formatters names from the settings.formatters_by_ft option. Then for each name
it searches for a corresponding package in 4 attribute sets, in order of priority

  1. User overrides
  2. Manually written special cases
  3. Auto generated defaults
  4. Custom formatters (all set to null)

A user can choose what package a formatter should install, especially useful for versioned formatters like for python 3.12 or 3.13. Since this value can be null, they can also make a formatter not install anything.

The automatic package attrset right now is created with pkgs.${conform-name}. More advanced logic could be added, such as replacing all _ with - and checking if that exists in nixpkgs. But i choose against this since it would only cut down the manual list by a few entries but would add a lot of hard to predict behavior. The current simple defaulting mechanism cuts the manual list in about half.

The test right now is very simple. Upstream has each formatter in its own file with a name identical to the Conform name. So I just list that directory of the nix derivation for the plugin, remove .nix and generate a Nix list of strings.
To prevent IFD this is generated with CI. Then I just create a Nixvim config with every supported formatter in Conform.

Limitations of this approach:

  1. There could be a Conform formatter "foo" that matches nixpkgs pkgs.foo. But the formatter expects executable foofmt meanwhile the nixpkg does not contain it. This will not be caught as an error in the test.
  2. It could also be the case that Conform formatter "foo" matches pkgs.foo AND contains an executable with the same name, but it actually is a totally different executable and package, just with incidentally matching names.

I think one could write a more extensive test that covers 1 using Lua but i'm not good enough with Lua to do that.

There is no test for the override functionality or one that checks if custom formatters' packages are getting set to null
This is because I have no clue how to write that. I'd have to eval those options first, read them, and assert that some predicates hold. For example for the nulling i'd imagine I would read the customFormatters attrset, get the values with lib.attrValues and assert that everything is null. If someone could point me to how to achieve that I could write those tests.

@saygo-png saygo-png force-pushed the conform-autoinstall branch 3 times, most recently from 55345a3 to ab90457 Compare September 14, 2025 01:30
@saygo-png saygo-png marked this pull request as ready for review September 14, 2025 01:32
@nixvim-ci nixvim-ci bot requested a review from khaneliman September 14, 2025 01:33
@saygo-png
Copy link
Contributor Author

Almost forgot about this:
The example for the overrides option does not render properly in the docs. The issue is with the python package. How do I add that properly? I know i can brute force it with just a plain string but is there no way to make this package render nicely without turning the entire example into a string?

@saygo-png
Copy link
Contributor Author

saygo-png commented Sep 14, 2025

Just found issue #2412
This pr is not as ready as I thought. I'm gonna change the behavior for unpackaged formatters. I'll send a warning if a user declares a formatter that isn't packaged.

@saygo-png saygo-png marked this pull request as draft September 17, 2025 02:55
@saygo-png saygo-png force-pushed the conform-autoinstall branch 4 times, most recently from cf48224 to 22d3f92 Compare September 17, 2025 14:51
@saygo-png
Copy link
Contributor Author

saygo-png commented Sep 17, 2025

I've added warnings for packages that do not get installed, they look like this:

evaluation warning: Nixvim (conform-nvim): You have enabled the 'blue' formatter that relies on a package marked 'unpackaged'.
                    Because of that it will not be installed. To disable this warning, explicitly disable installing the package
                    by setting the 'conform-nvim.autoInstall.overrides.blue' option to 'null'. You can also disable
                    all warnings related to packages not installed by autoInstall with 'conform-nvim.autoInstall.enableWarnings'.

I did a small refactor of the generate.nix script to make it easier to add more JSON generated files.

I think the code for this looks like a bit of a disaster but it does work and I couldn't come up with a cleaner implementation. It would look better in Haskell with algebraic data types and pattern matching :).

@saygo-png saygo-png marked this pull request as ready for review September 17, 2025 15:03
@MattSturgeon
Copy link
Member

It would look better in Haskell with algebraic data types and pattern matching :).

Just for the record, the generate scripts can technically be in any language. We commonly use bash either at buildtime (runCommand) or at runtime (writeShellApplication, writeShellScriptBin), sometimes we also use python scripts. However, the language chosen should be one that @nix-community/nixvim-committers are comfortable with; we're probably not ready for haskell just yet, but I'd personally love to learn at some point™ 😁

Copy link
Member

@MattSturgeon MattSturgeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nits, tips, suggestions. Feel free to discuss, dismiss, implement as you see fit.

The overall diff SGTM. Thanks for another great contribution!

@saygo-png
Copy link
Contributor Author

Just for the record, the generate scripts can technically be in any language.

Sorry I was unclear; I meant the Nix code for the plugin which obviously is staying Nix.

@saygo-png saygo-png force-pushed the conform-autoinstall branch 6 times, most recently from 7606baa to e6e0068 Compare September 18, 2025 07:17
@saygo-png saygo-png force-pushed the conform-autoinstall branch 2 times, most recently from 7cd6e1e to 09f87f3 Compare September 18, 2025 15:57
Copy link
Member

@MattSturgeon MattSturgeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for another great contribution!

Copy link
Contributor

@khaneliman khaneliman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this, I meant to do it a long time ago!

Seems to work fine for most formatters. For some reason, I get a lua error trying to use ConformInfo when letting csharpier get auto installed. But, if I leave my manual configuration of the pkg mapping in formatters.*.command it is fine.

@MattSturgeon
Copy link
Member

But, if I leave my manual configuration of the pkg mapping in formatters.*.command it is fine.

Would that make for a suitable example (in a followup PR)?

@khaneliman khaneliman added this pull request to the merge queue Sep 20, 2025
Merged via the queue into nix-community:main with commit fd0c423 Sep 20, 2025
4 checks passed
khaneliman added a commit to khaneliman/khanelivim that referenced this pull request Sep 20, 2025
Auto installation of packages with
nix-community/nixvim#3682 so I don't need to
maintain EVERY mapping.
@GaetanLepage
Copy link
Member

Well done @saygo-png!

@saygo-png
Copy link
Contributor Author

@khaneliman The csharpier issue is an upstream issue with conform-nvim stevearc/conform.nvim#699 not this PR

@khaneliman
Copy link
Contributor

@khaneliman The csharpier issue is an upstream issue with conform-nvim stevearc/conform.nvim#699 not this PR

Looks like someone created a PR for it, too. Thanks for identifying it. stevearc/conform.nvim#772

@saygo-png saygo-png deleted the conform-autoinstall branch September 26, 2025 20:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Conform plugin does not install enabled formatters

4 participants