[Job] Implement a `nix fmt` formatter

Our community needs a blessed and universal code formatter for the Nix code. It’s important because it removes any argument about formatting. Code becomes more uniform which makes it easier to read and skip around. Editors can now format the code on save. Copy-and-pasting code is now much easier.

Life is short and I don’t want to spend another minute of my life indenting code again.

Some goals:

  • implement (or re-use) a comment-preserving Nix parser in the language of your choice
  • collect code samples
  • discuss with the community on the desired indentation of these samples
  • implement nix fmt
  • make sure that the output is stable (running nix fmt twice should give the same output)
  • the program should be a single binary that can be copied around

In the end we want this tool to be accepted by the community and run on nixpkgs by ofborg. It needs to run fast so it can be called by the Editor on save.

And here are some anti-goals:

  • create a perfect diamond made of types (sorry Haskell). I care that it works and is fast.
  • have configuration options for the formatted output. It’s very tempting and has to be resisted at any cost.

For this to work, I am looking for somebody who is already comfortable with their target language. Ideally it’s a domain you already thought about and maybe even already started implementing something.

PM me and we can discuss more of the details.

FAQ updates from PM

  • Is it going to be open source? : YES please
  • What type of engagement is it? : Freelance / consulting. We can discuss if other options are needed.
29 Likes

Another goal to consider:

  • Write it in C++ or Rust so it can be integrated in (i.e. shipped as part of) Nix. Something written in Haskell or most other languages will pull in a lot of additional dependencies that would make this infeasible.
13 Likes

I have been pointed to GitHub - justinwoo/format-nix: A simple formatter for Nix using tree-sitter-nix. by a few people. It’s written in JavaScript PureScript but could be a good start to experiment with the output format.

2 Likes

It’s written in PureScript, but the actual problem is that it uses a tree-sitter parser instead of the existing Nix parser.

1 Like

I think even Haskell is OK for the first iteration, because there will be disagreement on formating style and the second revision of the formatter.
It is not obvious that C++ → С++ rewriting will be easier than Haskell → C++

1 Like

Just putting rnix here as shameless self-advertising.

10 Likes

HNix does have a formatter (though comment preservation is still WIP). So I would say don’t write it in Haskell not because it can’t be linked with Nix (I’ve seen it done) but because it’s already written in Haskell.

If we end up with complete Haskell and Rust versions of Nix (with the C++ all gone), I’ll be happy.

1 Like

Oh oops re-reading the OP I see that money is involved. I think whoever can get the job done cheapest should get the purse, so we shouldn’t discount the hnix approach.

1 Like

It makes sense. For the first phase where the format is being defined, let’s use whatever tool is at our disposal that allows for quick iterations.

@jD91mZM2 rnix looks great for a foundation of that formatter!

3 Likes

I created GitHub - nix-community/nixpkgs-fmt: Nix code formatter for nixpkgs [maintainer=@zimbatm] if you want to submit PRs of code samples to be formatted.

3 Likes

I really don’t understand Haskell FUD. It’s much easier to statically link a Haskell executable with musl to 10MB than Nix itself.

Actually I might just spend a few hours on this and upstream a few patches then anyone can get it for free with haskellPackages.musl.hnix.

Given that the whole editor space is moving towards tree-sitter and editor integration is one of the goals of this project, I’d highly encourage to consider it.

13 Likes

Regarding the format: my two cents would be that it should focus on generating nice diffs rather than being pretty. More concretely, prefer vertical layouts to inlining things.

I’m happy to have a crack at building something on top of rnix assuming nobody else is doing so already? @justinw

7 Likes

Vertical layout makes it harder to actually read and work with code. I realize nice diffs are, well, nice, but given that diffing tools can do intra-line diffs, I would put a higher priority on producing code that is actually readable and enjoyable to work with.

2 Likes

Is this the same project in Github?

1 Like

Why is that a problem? IIUC focusing on the tree-sitter parser means that we can leverage one parser that’s used in both formatters and editors.

@domenkozar does the formatter in hnix use tree-sitter?

1 Like

No, that is GitHub - nix-community/rnix-parser: A Nix parser written in Rust [maintainer=@oberblastmeister].

1 Like

Uncrustify is easy to extend ive been wanted to add nix to it once the semester ends for me. ( in a week )
Ill poke my head back in then. Id love to help whoever picks it up. I love parsers :joy:

1 Like

A quick update to let you know that the position has been taken.

Once we have a prototype in place that allows us to iterate on the format I will broadcast about it again in case you want to be involved in the formatting discussions.

12 Likes

Related nixfmt alpha release

I suspect I’m gonna get left behind a bit as I don’t have much time to give to this, but my WIP rust formatter is: GitHub - jmackie/nix-fmt

It’s using rnix for parsing and an efficient imperative pretty printer from rust’s libsyntax (even though I’m more familiar with the Wadler/functional pretty printer, that seemed more appropriate).

2 Likes