-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
erlfmt_format: preserve empty lines between values in containers #83
Conversation
8e9e582
to
3c070a4
Compare
3c070a4
to
10f2661
Compare
src/erlfmt_format.erl
Outdated
@@ -421,6 +519,8 @@ fa_groups([{op, Meta, '/', {atom, _, HeadFunction}, _} = Head0 | Tail]) -> | |||
[Head0 | fa_groups(Rest)]; | |||
{Group, Rest} -> | |||
Head = erlfmt_scan:delete_annos([pre_comments, post_comments], Head0), | |||
EndLoc = erlfmt_scan:get_end_location(lists:last(Group)), | |||
Meta = erlfmt_scan:set_end_location(EndLoc, Meta0), |
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.
In the parser we have a ?range_anno
macro that does something similar. What do you think about having a similar function in erlfmt_scan
? Something like:
range_anno(First, Last) when is_tuple(First), is_tuple(Last) ->
(element(2, First))#{end_location := get_end_location(Last)}.
We could call it here as:
Meta = erlfmt_scan:range_anno(Head, lists:last(Group))
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.
That sounds great :)
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 should probably also set the inner_end_location
, right?
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.
Hmm... potentially. Do we really need it? It would need some case
ing to only add it if it was there in Last
in the first place.
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 added range_anno, but I needed to pass in Meta, otherwise, we lose the comments.
Looking at all the complexity trailing comments introduce, I started thinking if maybe we should change how we represent them in the AST. My proposal would be to use the |
I guess I have always thought the pre_comments were too attached. I would expect to have more standalone comments in the ast. Basically if there is an empty line between this and the next element, then the comment is intuitively not attached to the next element. But to be pragmatic we could also embrace the aggressive attachment of comments and consistently say that all comments are attached. This would attach these trailing comments as post comments. Which ever way we go, I think we can do this in a follow up pull request, and possibly pair on it together. |
The problem of standalone comments is that they don't behave syntactically like other elements, for example inside lists they don't have |
Yes so I am happy to go with the pragmatic route, in a follow up commit. |
What happens if the way the container was initially laid out didn't include the "force breaks" space between [ 1
, 2
, 3
] Do we collapse it into a single line [
1,
2,
3
] Either choice is fine by me, I think we should have a test that explores this, though. |
Great catch :) ?assertFormat(
"[ 1\n"
", 2\n"
"\n"
", 3\n"
"]\n",
"[1, 2,\n"
"\n"
"3]\n"
). I also agree, that either case would be great, except the one that is happening now. |
Have to say it is very tough to get this and other containers like tuples, to place nice together
This is now fixed, it was quite tricky :) |
README.md
Outdated
[ | ||
Foo, | ||
Bar | ||
] |
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.
Hmm.... We should probably re-write the guide because it no longer works as advertised. It's not enough to just remove the newline between [
and first element.
This is so much complexity in here 😢
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.
Good catch.
I fixed the guide.
I think it makes sense to not only take a hint from the first newline, but rather from any newline in the container.
Yeah, there's a lot of complexity in the rules for different containers. We probably need to rethink the general approach of keeping everything together after merging this code. |
Fixes #72
This preserves empty lines between values in containers, like exports and records.
This required some refactoring, since the simple fold_doc now needed to not only be aware of the break, but also needed to have the original value, to be able to check for empty lines to preserve.
Really struggled to make this refactoring more readable and I guess it is debatable, whether I achieved that, so looking forward to ideas in the review.
Also needed to preserve the end line for better empty line detection.
Should probably do the same for inner end line, so maybe we can think of a better function name.