-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Add nix formatter build
and nix formatter run
commands
#13063
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
One problem with this PR is that it doesn't provide any mechanism for users to protect against garbage collection between running
I'm happy to implement something like this, but would appreciate some direction from a maintainer before I go to the effort! |
Are you not missing program args here for a correct implementation? I think this might make quoting a bit awkward. So I am wondering if we should have a JSON output option instead |
For the out link flags, look at
The behavior and the format should be separate.
|
It would probably be better to fix the root issue here. Maybe evaluation caching is broken for |
I don't think the evaluation cache can help here, because it would get invalidated on every file change. For context |
@Mic92 already made the point more succinctly, but I went to the effort to capture some numbers, so here they are if it's helpful: Some concrete timingFirst time: cache miss (that's OK, nothing we can do about this): $ time nix fmt flake.nix
2025/04/23 08:58:46 INFO using config file: /nix/store/hhzsjb1ydnrrkc178naf5nqgdw06n05f-treefmt.toml
traversed 1 files
emitted 1 files for processing
formatted 0 files (0 changed) in 24ms
________________________________________________________
Executed in 12.43 secs fish external
usr time 10.28 secs 0.00 millis 10.28 secs
sys time 0.98 secs 1.71 millis 0.97 secs Second time: cache hit. Much better, but still causes one core CPU to spike for $ time nix fmt flake.nix
2025/04/23 08:58:57 INFO using config file: /nix/store/hhzsjb1ydnrrkc178naf5nqgdw06n05f-treefmt.toml
traversed 1 files
emitted 1 files for processing
formatted 0 files (0 changed) in 6ms
________________________________________________________
Executed in 705.00 millis fish external
usr time 348.87 millis 0.32 millis 348.54 millis
sys time 286.94 millis 1.14 millis 285.81 millis Now, if I make a change to $ echo >> flake.nix
$ time nix fmt flake.nix
warning: Git tree '/home/jeremy/src/github.com/NixOS/nixpkgs' is dirty
2025/04/23 09:04:07 INFO using config file: /nix/store/hhzsjb1ydnrrkc178naf5nqgdw06n05f-treefmt.toml
INFO formatter | nixfmt: 1 file(s) processed in 12.494733ms
traversed 1 files
emitted 1 files for processing
formatted 1 files (1 changed) in 29ms
________________________________________________________
Executed in 3.78 secs fish external
usr time 1.84 secs 615.00 micros 1.84 secs
sys time 0.79 secs 896.00 micros 0.78 secs This results in a pretty terrible experience when editing your I personally like @roberth's suggestion to add 2 flags to both
I'll give this a shot. I don't know if my C++ is up to the task of trying to share this code between the implementations, though. |
You don't necessarily need to add the |
Notes from team meeting:
|
22c2578
to
79390c9
Compare
I've updated this PR in light of today's discussion at the nix team meeting. Thanks for the help, everyone! |
--print-command
option to nix fmt
nix formatter build
and nix formatter run
commands
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Urg, this diff is impossible to see read with the file renames. I'll split the renames into a separate commit, standby...
fcd24f7
to
3978cd2
Compare
This refactor shouldn't change much except add a new `nix formatter run` command. This creates space for the new `nix formatter build` command, which I'll be introducing in the next commit.
0847316
to
67d22c7
Compare
Ok, this should be ready to review now. |
67d22c7
to
c292904
Compare
Installables installableContext; | ||
for (auto & ctxElt : unresolvedApp.unresolved.context) | ||
installableContext.push_back(make_ref<InstallableDerivedPath>(store, DerivedPath{ctxElt})); | ||
auto buildables = Installable::build(evalStore, store, Realise::Outputs, installableContext); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if there's a less awkward way of doing this. I basically copied this logic from here: https://github.com/jfly/nix/blob/7706cff51871449d27b96e528b784a4eb630031d/src/nix/app.cc#L137-L143
`nix formatter build` is sort of like `nix build`: it builds, links, and prints a path to the formatter program: $ nix formatter build /nix/store/cb9w44vkhk2x4adfxwgdkkf5gjmm856j-treefmt/bin/treefmt Note that unlike `nix build`, this prints the full path to the program, not just the store path (in the example above that would be `/nix/store/cb9w44vkhk2x4adfxwgdkkf5gjmm856j-treefmt`). Motivation ---------- I maintain a vim plugin that automatically runs `nix fmt` on files on save. Since `nix fmt` can be quite slow due to nix evaluation, I choose to cache the `nix fmt `entrypoint. This was very awkward to do, see the implementation for details: https://github.com/nvimtools/none-ls.nvim/blob/786460723170bda9e9f95c55a382d21436575297/lua/null-ls/builtins/formatting/nix_flake_fmt.lua#L83-L110. I recently discovered that my implementation was buggy (it didn't handle flakes that expose a `formatter` package, such as nixpkgs), so I had to rework the implementation: nvimtools/none-ls.nvim#272. With the new `nix formatter build` command, I can delete all this akward code, and it will be easier for other folks to build performant editor integrations for `nix fmt`.
c292904
to
e3ed704
Compare
nix formatter run
is an alias fornix fmt
. Nothing new there.nix formatter build
is sort of likenix build
: it builds, links, andprints a path to the formatter program:
Note that unlike
nix build
, this prints the full path to the program,not just the store path (in the example above that would be
/nix/store/cb9w44vkhk2x4adfxwgdkkf5gjmm856j-treefmt
).Motivation
I maintain a vim plugin that automatically runs
nix fmt
on files onsave. Since
nix fmt
can be quite slow due to nix evaluation, I chooseto cache the
nix fmt
entrypoint. This was very awkward to do, see theimplementation for details:
https://github.com/nvimtools/none-ls.nvim/blob/786460723170bda9e9f95c55a382d21436575297/lua/null-ls/builtins/formatting/nix_flake_fmt.lua#L83-L110.
I recently discovered that my implementation was buggy (it didn't handle
flakes that expose a
formatter
package, such as nixpkgs), so I had torework the implementation:
nvimtools/none-ls.nvim#272.
With the new
nix formatter build
command, I can delete all this akwardcode, and it will be easier for other folks to build performant editor
integrations for
nix fmt
.Add 👍 to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.