oxalica / nil

NIx Language server, an incremental analysis assistant for writing in Nix.
Apache License 2.0
1.38k stars 40 forks source link

suggestion: Packing/unpacking attrsets as a code action #29

Closed TLATER closed 1 year ago

TLATER commented 1 year ago

Sorry for throwing a raw idea in here, but this hit me as a useful suggestion in this discussion on the discourse, and I wanted to feel the waters for whether this is the right place for such a thing: https://discourse.nixos.org/t/looking-for-nix-formatter-which-can-convert-nested-attrests-into-path-style-notation/23163

I find myself often wanting to "pack" attribute sets like this:

{
  inputs.nixpkgs.url = "nixpkgs";
  inputs.flake-utils.url = "flake-utils";
  inputs.flake-utils.inputs.nixpkgs.follows = "nixpkgs";
}

to attribute sets like this:

{
  inputs = {
    nixpkgs.url = "nixpkgs";
    flake-utils = {
      url = "flake-utils";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
}

Flake inputs are an extreme example where the latter is clearly more structured and readable, but there are counter-examples where the opposite is true, and you would really rather want the attribute set split. Therefore I don't think this is suitable as a feature for autoformatters.

I think it fits right in with a language server, though, since they're designed to help developers with little bits of automation like this.

Further considerations:

oxalica commented 1 year ago

Packing and unpacking (flattening) are implemented since 9794a2eb977d872e5eee19187e74d8bf7c48e400

oxalica commented 1 year ago

Currently spaces and comments are preserved, including indentations. So manual reformatting is usually needed. It would be easier if you have a formatter configured.

Sorting of these "packed" attrsets

This is hard if you take trivia into account. It's unclear what a comment is attached to. Empty lines may also be meaningful.

{
  # head
  a = 1;
  b.c = 2;
  # tail

  c = 3; # tail
  # middle
  b.d = 4;

  #end
}

If you are still interested in field sorting and have some ideas, please open a new issue.