[Job] Implement a `nix fmt` formatter

#1

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.
24 Likes
#2

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.
8 Likes
#3

I have been pointed to https://github.com/justinwoo/format-nix by a few people. It’s written in JavaScript PureScript but could be a good start to experiment with the output format.

1 Like
#4

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

#5

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++

#6

Just putting rnix here as shameless self-advertising.

11 Likes
#7

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.

#8

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.

#9

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!

2 Likes
#10

I created https://github.com/nix-community/nix-fmt if you want to submit PRs of code samples to be formatted.

1 Like
#11

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.

10 Likes
#12

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

6 Likes
#13

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.

#14

Is this the same project in Github?

#15

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?

#16

No, that is https://github.com/jD91mZM2/rnix.

#17

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:

#18

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.

10 Likes
#19

Related nixfmt alpha release

#20

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: https://github.com/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