The Uncompromising Nix Code Formatter

Hey @kamadorueda, don’t worry about it.

How I see it, nixpkgs-fmt is 99% there but it’s always the last tiny percentage that takes a lot of energy. Personally, I am a bit burned out on the project, and so far nobody stepped up to take over the nixpkgs-fmt maintenance.

If it’s easier for you to rewrite rather than contribute, that’s fine by me. Sometimes it takes less energy to write things from scratch. You own the whole design, rather than slowly moving a project to the desired state. Plus you’re re-using the rnix-parser so that counts as a win to me :slight_smile:

I don’t know what you wrote but I would assume that it was coming from a place of being enthusiastic. I don’t know for others but I’d rather you keep your enthusiasm and not worry about roughing a few feathers. Keep up the good work!

21 Likes

Could you please help me understand what the expected outcome/user experience would be?

If it improves the project, let’s do it!

Hey, i’m sorry you feel burned out on the project, it happens… Me being a cybernetic robot from the future, a majority people don’t understand even robots from skynet, have energy levels.

6 Likes

I’m adding a text-user interface:

asciicast

In this PR:
https://github.com/kamadorueda/alejandra/pull/164

Would be very happy if you help me test it in your own terminal or operative system before merging :heart:

4 Likes

Thanks @kamadorueda for the nice words.
I think alejandra’s current rules-based formatting is more inviting to collaborators and more maintainable, and that going for Rust will easy adoption.

We spent a while looking for bugs and found a few, which I’ll put on the github issue tracker. Sadly, they are mostly rnix-parser related, and I think that project will need some contributions to make alejandra the bug-free formatter it aspires to be :wink: .

Another thing that’s very useful to do (and that we did in nixfmt development) is looking at formatted nixpkgs diffs, prioritizing the files that have different outputs on nix-instantiate --parse.

3 Likes

Thank you! any type of engagement with the project is highly appreciated.
Besides, it’s helping us improve things and that’s awesome!

I frequently ask myself if it would be more valuable (as community effort) to just rewrite that component of Nix to allow other programs to see the code as Nix would see it. Instead of creating a non-official library that just tries to mimic the Nix parsing behaviour (and will by definition differ from the official one)

6 Likes

I think a good idea would be an increased modularization of Nix as a whole (this would also make it easier for partial reimplementations of Nix, so that components can be swapped out); some of this is also a goal of https://riir-nix.github.io/, which I initiated with some enthusiasm, but some adjacent projects proved to be more difficult than expected (e.g. GitHub - YZITE/nix2js: [not yet usable] transpile Nix to Javascript using Rust, also uses rnix-parser, and I also reported some bugs…, and fixed one or so). My proposal would be to provide a shared interface, such that the lexer-parser part (it’s complex, because of the string handling in Nix, it needs to toggle between lexing and parsing) of nix can be swapped out with some wrapper built on top of rnix-parser.

It would then be possible to build a fuzzer which makes sure that the implementations handle all valid input the same way, or such.

1 Like

This is the only way forward once you pass certain lines of code threshold, and it’s a good idea from an architectural and cognitive overhead point of view

I migrated a big codebase in the past. My two cents is that the best approach is putting lines of code directly in the general public hands, i.e. on Nix’s master, no feature flags, and it’s more valuable to have 1 line of code migrated this way than to have 1000 “migrated” under a feature flag (i.e. duplicated), or separated from the general public hands (i.e. a fork)

I believe a refactor like this needs an RFC and getting the approval from the code owners. If we could get that, I would personally put time into migrating code

4 Likes

Coolest, fastest, and nicer release of all!

Formatting Nixpkgs in 3 seconds:

Peek 2022-02-28 19-07

And even code simplification:

--- a/lib/customisation.nix
+++ b/lib/customisation.nix
@@ -167,7 +167,7 @@
     commonAttrs =
       drv
       // (builtins.listToAttrs outputsList)
-      // ({all = map (x: x.value) outputsList;})
+      // {all = map (x: x.value) outputsList;}
       // passthru;
--- a/lib/generators.nix
+++ b/lib/generators.nix
@@ -15,7 +15,7 @@
  * Documentation in the manual, #sec-generators
  */
 {lib}:
-with (lib).trivial; let
+with lib.trivial; let
   libStr = lib.strings;
   libAttr = lib.attrsets;

More expressive code with inline comments:

    inherit
      (callPackage ../development/tools/ocaml/ocamlformat {})
-      ocamlformat
-      # latest version
+      ocamlformat # latest version
       ocamlformat_0_11_0

And many more!

5 Likes

In the last example, how do you know the comment was not referring to the line below?

8 Likes

Agreed, I think the universal convention in code I’ve read in any other language is to write the comment before the line it describes, not after.

4 Likes

Looking at the code, this doesn’t pull comments up before the previous line, but actually just keeps comments inline if they already were inline (which was a frequently requested feature; I do this a lot too when writing nix for some reason; maybe because lists are so common and tall?).

I imagine the diffs are for formatting before and after the 7.0 release, rather than directly on nix code, but that could be stated more clearly :wink:

3 Likes

Wow this has come such a long way! It’s amazing what not even 2 months of actually listening to constructive feedback can bring. Great job @kamadorueda and thanks for your work on this! And everyone who helped in some way or another, of course.

11 Likes

The smell of freshly baked bread is always good for the body!

8 Likes

Which elements should the Alejandra CLI have?

  • Path of changed files
  • Error messages, if any
  • Colored output
  • Progress bar
  • Stats at the end
  • Minimal output, Unix philosophy

0 voters

“Show the code context of an error message, so that I can quickly find the issue in the file.”

I wonder if that is meant by error messages?

Just wanted to say that the README and website for this project were A+ in describing the intent and motivation.

1 Like

Some improvements to the CLI have landed the main branch in order to make it more pleasant to use:

In particular, the elements that people identified as less useful were removed, the elements people identified as useful were polished, the screen is not cleared anymore, the output is more minimalistic by default, and Vim users can now use :%!alejandra -qq (double q) to format the current buffer, even if it contains syntax errors

Also, now certain sponsor tiers allow companies to advertise their offerings to active Nix users by placing a small ad at the end of Alejandra’s terminal output, and also some thank you messages were included for the sponsors and contributors of the project.

Congratulations! Your code complies with the Alejandra style.

👉 [Sponsored] Advertise your company here, reach lots of active Nix users!
More information at: https://github.com/sponsors/kamadorueda

It would be nice if you help me test these changes before cutting a 3.0 release,

Thank you!

2 Likes

While I understand the sponsorship advertisement on Github, being shown one on CLI is bit tough to swallow. Even then, it would be acceptable for Alejandra the standalone tool. If Alejandra gets accepted as de-jure formatter via RFC I would not like an advertisement in default Nix behavior.

9 Likes

That’s a really cool feature :smiley:

1 Like