-
Notifications
You must be signed in to change notification settings - Fork 425
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
Implement "intelligent" breaking for records & objects. #1697
base: master
Are you sure you want to change the base?
Conversation
cbbe679
to
1c3ccd4
Compare
@andreypopp @jordwalke circleci seems to have problems with esy, any hints on what might be wrong? |
@IwanKaramazow |
Nice! Does this logic help e.g. not removing braces for functions? |
If you rebase, and update the diff the tests should pass now (I updated master branch of |
The idea is that a line break in input should signify an intent to format a record/object with line breaks. Refmt "relaxes" its hard coded rules in favour of checking the input for possible breaks. Since the start & begin location are part of the ast, we simply have to check if the line height of start & end loc are the same. If they are, then everything was on one line. This has the benefit that `type point = {x: int, y: int}`, can be printed one line. type t = { a: int, b: int}; type t = {a: int, b: int}; type t = {a: int, b: int }; => Since the structures above have been put on multiple lines, everything will be formatted as: type t = { a: int, b: int };
1c3ccd4
to
ed73060
Compare
Rebased, thanks for the pr. |
@jordwalke if we follow the same idea of this PR, then we probably don't need the regex hack for function braces. It's just a matter of printing a If the programmer put the fun body on a separate line, he wants braces: /* a + b sits on line 2*/
let f = (a, b) =>
a + b;
/* becomes */
let f = (a, b) => {
a + b;
};
vs
/* same line */
let f = (a,b) => a + b;
/* becomes */
let f = (a,b) => a + b; |
@IwanKaramazow |
@rauschma Yes this woudn't apply to let f = (a, b) => {
a + b;
}; |
@IwanKaramazow I meant that the following function expression should stay as is (no braces should be wrapped around the
|
Ah yes, good catch 😄 I'll address the function expr in a different PR. |
One question I have: Suppose someone has a record like this: type point = {
x: int,
y: int,
reallyLongNameHere: int
}; And then someone refactors to delete the long final item: type point = {
x: int,
y: int
}; What if I want these to be automatically reprinted on one line? In this case, the presence of newlines doesn't convey my intent. How can we distinguish between additional newlines that we want the printer to clean up, and ones that we don't? |
When was the last time you removed a row from a record? |
@IwanKaramazow About a week ago! While refactoring some code to work with a new version of an external API. |
Perhaps it's not always removing a row, but more commonly changing the name of one or more fields to be significantly shorter (so my whole code base becomes more concise). A change like that can bring the text size under the breaking threshold. |
I get the feeling that a more systematic process may make sense for refmt. Maybe collect code examples that reflect the preferred style and then extract rules? I have collected a few examples myself where refmt seemed off. |
I prefer this behaviour over the current one, I find it a lot clearer to be able to control if each items are on a separate line, especially when working with something like RN StyleSheets or CSS in JS libs. Of course it won't format back to one line automatically when removing fields or renaming like it was mentioned before but I still think it's a good tradeoff. It's also easy to reformat it back to a single line when refactoring if you really want to. This is also the same behaviour as pretty which is somewhat popular / proven. |
Fixes #1620 #1207
The idea is that a line break in input should signify an intent to format a record/object with line breaks. Refmt "relaxes" its hard coded rules in favour of checking the input for possible breaks. Since the start & begin location are part of the ast, we simply have to check if the line height of start & end loc are the same. If they are, then everything was on one line.
This has the benefit that
type point = {x: int, y: int}
, can be printed one line if desired.On the other hand:
Since the structures above have been put on multiple lines,
everything will be formatted as:
This behaviour is the same as in Prettier.