Skip to content

sort attrsets and lists if annotated to do so #331

@quantenzitrone

Description

@quantenzitrone

Description

some sort of way to sort code would be really helpful for stuff like lib/licenses.nix, maintainers/maintainer-list.nix or pkgs/top-level/aliases.nix.

Existing thingy

maintainers/maintainer-list.nix already has a comment at the beginning and the end, which is probably used with https://github.com/google/keep-sorted

{
  # keep-sorted start case=no numeric=no block=yes
  ...
  # keep-sorted end
}

Suggested Syntax

I don't think the way this is annotated is very feasable tho, instead i would suggest putting it directly before the attrset or list like this:
This would only allow sorting whole attribute sets or lists instead of ranges.

{
# either directly before the attribute
sorted-attr = 
  # nixfmt: sort
  {
     ...
  };
sorted-list = 
  # nixfmt: sort
  [
    ...
  ];
# or optionally before the binding of the attribute
# nixfmt: sort
sorted-attrs = {
  ...
};
# nixfmt: sort
sorted-list = [
  ...
];
}

Problems and solutions

  1. Comments

    • Solution: remove all top-level comments or fail if there are top-level comments in a sorted attribute
  2. Empty lines

    • Solution: remove all empty lines between sorted attributes
      Extra syntax for adding one-empty line between every attribute like
      # nixfmt: sort empty-line=true
  3. Order of list changes the output conflicting with the principles of a formatter

    • this is kinda tricky because on one hand having the sorting would reduce possible rebuilds due to order changes due to everything being forced to be ordered in the first place.
      Even the possibility to auto-sort attribute sets would be awesome so if that is too conflicting we can do attrsets only.
  4. inherit expressions in attrsets

    • Solutions: either fail or have a special case like moving them to the top.
  5. determine order of different types in lists

    • Solution: only allow mono type lists to be sorted.
      A "type" here could also be a global attribute like pkgs.hello so we can sort lists of packages for example.

Small example input

# nixfmt: sort
{
  foo = "bar";
  bar = "baz";
}

Expected output

# nixfmt: sort
{
  bar = "baz";
  foo = "bar";
}

Actual output

# nixfmt: sort
{
  foo = "bar";
  bar = "baz";
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions