-
-
Notifications
You must be signed in to change notification settings - Fork 40
feat: format via alejandra when feature is set #89
base: master
Are you sure you want to change the base?
Conversation
Why did you close this? |
I tried it and it didn't work, pushing a fix! |
cb71399
to
f99332e
Compare
|
f99332e
to
9189b50
Compare
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work!
Added a few minor remarks, also a test would be nice :)
Cargo.toml
Outdated
@@ -24,15 +24,16 @@ rnix = "0.10.2" | |||
rowan = "0.12.6" | |||
serde = "1.0.104" | |||
serde_json = "1.0.44" | |||
nixpkgs-fmt-rnix = "1.2.0" | |||
nixpkgs-fmt-rnix = { version = "1.2.0", optional = true } | |||
alejandra = { version = "1.5.0", optional = true } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you checked how much it would increase the closure size if we just added both by default and make it configurable via e.g. the environment which formatter to use. I'm asking for two reasons:
- I think it's realistic that it depends on a project which formatter is used (i.e. nixpkgs uses de-facto nixpkgs-fmt and a hypothetical other project may use alejandra).
- I don't want users to recompile rnix-lsp just because they prefer alejandra (and I also don't want to expose multiple attributes for
rnix-lsp
innixpkgs
depending on the feature-set).
Also cc @kamadorueda for opinions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I laid out in the description, I think that and ideal solution would infer the formatter to use from the flake.nix
file and maybe even directly rely on nix fmt
to do that. In that case neither of these two dependencies would be necessary and nix
would be the only dependency.
Until then, this would need to be configurable by the user via LSP config, such that it could be overriden on a per-project basis and for that we'd need to compile these in.
So until (and if) nix
is integrated here directly, I think the project should absolutely include both by default. Of course, if more formatters emerge (https://xkcd.com/927/) that could become an issue. For just two I'd say it should be fine.
I did not implement handling this via LSP config to minimize the diff, but I am happy to do so if you prefer, although it does seem that the PR would be quite a bit bigger, since I'd have to implement LSP config handling from scratch, there's no existing functionality for that in the project yet, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with the LSP, but I can throw here that there is a third approach: using an environment variable pointing to the formatter binary, and just feeding the code via stdin and getting the output via stdout. That way the closure would decrease substantially as we would be reusing the binaries already present in the user system (instead of compiling and linking them here), we would not need to implement a configuration handler for this LSP, and we would unify the interface and allow for more formatters to be chosen in the future (including nix fmt
)
Just an idea, you both are more familiar with this project than me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course, if more formatters emerge (https://xkcd.com/927/) that could become an issue
Well, the primary reason why I even consider this is because Alejandra seems to be used by quite a bunch of people and is IIRC even a candidate for the nixpkgs formatting RFC, so integrating it is justifiable IMHO.
That way the closure would decrease substantially as we would be reusing the binaries already present in the user system
Admittedly I haven't checked the actual impact on closure size of both alejandra and nixpkgs-fmt, but an LSP server is something that's only running on developer machines anyways, so I wouldn't consider a slight (i.e. non-optimal, but not "bad") increase of closure-size much of an issue.
I'm not familiar with the LSP, but I can throw here that there is a third approach: using an environment variable pointing to the formatter binary, and just feeding the code via stdin and getting the output via stdout.
As described in #87 partial reformats are desirable and something I'd like to see here as well. If we get somewhat reasonable APIs from formatters for that, I'd prefer that solution over having to parse stdout from a formatter. I could imagine that we'd also run into funny quoting or encoding issues when reformatting files with weird stuff in it and parse the (structured) output of the (incremental) edits from stdout.
code.to_string(), | ||
) { | ||
(alejandra::format::Status::Changed(true), new_text) => { | ||
self.reply(Response::new_ok(id, vec![TextEdit { range, new_text }])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're implementing "partial" edits in #87 for nixpkgs-fmt, i.e. only the actual diffs, but not the reformatted file is returned.
AFAIU this also returns the entire file.
If we add a new formatter we should do it properly from the beginning, i.e. only return diffs. Otherwise it might be painful in the editor if e.g. all-packages.nix
is attempted to be reformatted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that would require changes in alejandra to support this in the first place.
@kamadorueda https://github.com/kamadorueda/alejandra/blob/c685879cda91934f29f42574b8eb367496b09df1/src/alejandra/src/format.rs#L13-L40 is the only functionality I found for formatting text in-memory, is there something else I am not aware of?
If such functionality does not exist:
- would you be open to having that feature implemented in the first place?
- how difficult do you think it would be to implement?
- do you have the capacity and willing to do this and if not, would you be open to a PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rvolosatovs alejandra::format::in_memory
is all we have
I understand why sending small TextEdit
s instead of a TextEdit
with the whole file can be a good thing. The most simple approach I can think of is:
- Use
alejandra::format::in_memory
to get a string with the formatted text - Use a diffing library to see which lines are equal in the input text and in the formatted text
- Emit
TextEdit
s for the ranges that are different
I'm not sure if that is good enough for this use case, I'm not familiar with LSP
would you be open to having that feature implemented in the first place?
That feature is more related to this repository than to Alejandra, so it would be better to have it here and let Alejandra just focus on being good at formatting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much of a change would that be to Alejandra actually? The change in nixpkgs-fmt seemed rather trivial: nix-community/nixpkgs-fmt#296.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Ma27 Would it be possible to land this even without partial reformatting? I'm working on projects that use alejandra, and my workflow ends up: edit, :w
, :!nix run nixpkgs\#alejandra -- %
, test, edit, start again. Even without partial reformatting this change will make my workflow much better. Could it be done separately later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a maintainer of this anymore, so I don't have a strong opinion. Please discuss that with the current maintainers :)
Applying patch from nix-community/rnix-lsp#89 directly on top of current rnix-lsp and providing UseAlejandra command to switch to in when Vim is already running.
Signed-off-by: Roman Volosatovs <[email protected]>
9189b50
to
936ae39
Compare
Refs #80
Refs #81
Summary & Motivation
It's nice to give users freedom of choosing the formatter to use. I think that the correct approach would be to parse this from
flake.nix
formatter
and/or expose this via LSP config.For now, just added a simple solution, which is fully backwards-compatible and does not introduce additional dependencies.
When
--features alejandra
is specified, https://github.com/kamadorueda/alejandra is used as the formatter.https://github.com/nix-community/nixpkgs-fmt is still the default, but can be disabled at compile-time via
--no-default-features
Until merged this can be consumed via NixOS/nixpkgs@5ddf7f7 in
nixpkgs