If we can read in the AST and spit it back out again in a standard (ideally somewhat pretty) format, that'd do a reasonable job at this.
Ideally it would preserve comments and such.
nix-instantiate --parse is doing exactly that (not really pretty printing though and also not preserving comments and canonicalizing paths to absolute paths)
How much of a pain would it be to make it preserve comments? It seems like most ASTs other than these auto-formatters will typically discard comments fairly early on, and might also discard whitespace people intended to keep.
For example, the jsonnet canonicalizer will preserve single and double blank lines (under the assumption that the human author added them for a reason), but coalesce 3 or more blank lines into two.
Currently, comments are discarded already in the lexer. I'm currently thinking about changing that for an other purpose (being able to do more reflection inside nix to be able to generate documentation for functions)
That sounds awesome for several reasons :+1:
Ah, this is also currently only idempotent if done twice:
nix-instantiate --parse --expr '"1${"2" + "3"}4"'
>("1" + ("2" + "3") + "4")
nix-instantiate --parse --expr '("1" + ("2" + "3") + "4")'
>(("1" + ("2" + "3")) + "4")
nix-instantiate --parse --expr '(("1" + ("2" + "3")) + "4")'
>(("1" + ("2" + "3")) + "4")
https://github.com/Gabriel439/nixfmt is incomplete, but does exactly this. See https://github.com/Gabriel439/nixfmt/issues/3 for the current status
Would be nice to integrate nixfmt with nix-mode (emacs mode) and nixIdea (intellij's idea plugin).
Related: #1102.
Would be nice to integrate nixfmt with nix-mode (emacs mode) and nixIdea (intellij's idea plugin).
What about aiming for the LSP method here? I think there's some works on nix LSP integrations somewhere. That would give benefits for other editors as well.
https://github.com/domenkozar/hnix-lsp works, but doesn't support comments (yet)
This now exists https://github.com/justinwoo/format-nix/ but it's performance is quite slow..
$ time ./result/bin/format-nix ../nix/packages.nix
formatted ../nix/packages.nix.real 0m6.232s
user 0m6.458s
sys 0m0.261s
Against https://github.com/digital-asset/daml/blob/master/nix/packages.nix
$ \time cat nix/packages.nix | ../result/bin/canonix --pipe >/dev/null
0.00user 0.00system 0:00.00elapsed 100%CPU (0avgtext+0avgdata 3540maxresident)k
0inputs+0outputs (0major+165minor)pagefaults 0swaps
using a bit modified version of https://github.com/hercules-ci/canonix/ that is not really usable yet - might be after ZuriHac.
We have https://github.com/nix-community/nixpkgs-fmt now, the main question is if it becomes part of Nix some day.
Most helpful comment
Currently, comments are discarded already in the lexer. I'm currently thinking about changing that for an other purpose (being able to do more reflection inside nix to be able to generate documentation for functions)