Skip to content

WIP: Format expression chains #216

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

Merged
merged 11 commits into from
Sep 10, 2015
Merged

WIP: Format expression chains #216

merged 11 commits into from
Sep 10, 2015

Conversation

marcusklaas
Copy link
Contributor

This PR tries to deal with formatting expression chains. It is still very much a work in progress!

The basic idea is to not look at one point in the expression tree, but look at chains of certain operations, those separated by dots. When all these expression parts fit on a single line, we format them as such, and otherwise put each on their own line. This is not unlike the formatting of function arguments.

I think this generally looks fairly decent, but they are some ugly corner cases. I'd love to receive input on how we could deal with those, as well as the general case.

@marcusklaas
Copy link
Contributor Author

Updated. I am now relatively content with the output.

Still needs tests, a big refactoring and a rebase.

I believe this also addressed https://github.com/nrc/rustfmt/issues/194 and https://github.com/nrc/rustfmt/issues/195 to some extent.

@marcusklaas
Copy link
Contributor Author

Rebased, cleaned up and tested!

@nrc
Copy link
Member

nrc commented Aug 30, 2015

Could you squash some of the commits please?

bbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccc.ddddddddddddddddddddddddddd();

bbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccc
.ddddddddddddddddddddddddddd
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should try to line up the dots if there is space, i.e.,

+    bbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccc
+                       .ddddddddddddddddddddddddddd

@marcusklaas
Copy link
Contributor Author

Updated and rebased once again.

let mut def_config = String::new();
def_config_file.read_to_string(&mut def_config).ok().expect("Couldn't read config.");
def_config_file.read_to_string(&mut def_config).ok().expect("Couldn\'t read config.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an odd change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, but it's not a direct result of this PR. The string is being reformatted where it wasn't earlier.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add FIXMEs please?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. I believe https://github.com/nrc/rustfmt/pull/248 will fix this.

@marcusklaas
Copy link
Contributor Author

r? @cassiersg @nrc

})
regex.captures_iter(&line)
.next()
.map(|capture| {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

THis seems like an unnecessary link breaking.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's quite a few places where do this pattern of line breaking. I do think we should fix it before landing this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm.. it's similar to what we do for function arguments, is it not? There we do not let the last argument spill over either.

I agree that it's not the most dense formatting, but I do think it adds clarity.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it is personal prejudice, but some how a chain of fields/methods feels more unitary and less like a splitable list than function arguments. To me it feels like somewhere where we should only line-break where we have to. I do agree that it often adds clarity, but I think those cases are exceptional enough that having a heuristic to take into account the original formatting would be optimal.

I'd be happy to have an option with different heuristic levels - avoid line breaks, eagerly break, and avoid unless already multi-line.

@nrc
Copy link
Member

nrc commented Sep 6, 2015

This is a cool PR - it means we format a lot of code we didn't before and we can do a better job too. I'd like to get the tweeks to the heuristics in before landing though - I can imagine that this could cause some big changes to users, so I want to get it as close to perfect as possible first go.

@marcusklaas
Copy link
Contributor Author

Yea, sounds good. Thanks for the review.

@marcusklaas
Copy link
Contributor Author

This has been updated and (monster) rebased. All comments have been addressed, except for the one about non breaking chains after function calls.

I've tried this, but it generally gives pretty poor results.

Some examples:

+    let line_regex = regex::Regex::new(r"(^\s*$)|(^\s*//\s*rustfmt-[^:]+:\s*\S+)")⏎
+                         .ok()⏎
+                         .expect("Failed creating pattern 2.");⏎
-    let line_regex =⏎
-        regex::Regex::new(r"(^\s*$)|(^\s*//\s*rustfmt-[^:]+:\s*\S+)").ok()⏎
-                                                                     .expect("Failed creating \⏎
-                                                                              pattern 2.");
+        CharClasses::new(text.chars())⏎
+            .filter_map(|(s, c)| {⏎
+                match s {⏎
+                    CodeCharKind::Normal => Some(c),⏎
+                    CodeCharKind::Comment => None,⏎
+                }⏎
+            })⏎
+            .collect()⏎
-        CharClasses::new(text.chars()).filter_map(|(s, c)| {⏎
-                                          match s {⏎
-                                              CodeCharKind::Normal => Some(c),⏎
-                                              CodeCharKind::Comment => None,⏎
-                                          }⏎
-                                      })⏎
-                                      .collect()

@nrc
Copy link
Member

nrc commented Sep 10, 2015

Which is before and which after?

@marcusklaas
Copy link
Contributor Author

+ before, - after

The fact that you have to ask shows that you don't feel as strongly about those as I do! :p

// Test chain formatting.

fn main() {
// Don't put chains on a single list if it wasn't so in source.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo list -> line

@nrc
Copy link
Member

nrc commented Sep 10, 2015

Awesome, thanks for the changes! r+ with the few nits cleared up.

Don't make a single line chain when it is was multi line in the source; allow overflow of the last chain element onto the next lines without breaking the chain.
marcusklaas added a commit that referenced this pull request Sep 10, 2015
@marcusklaas marcusklaas merged commit 0b7b3c8 into rust-lang:master Sep 10, 2015
@marcusklaas marcusklaas deleted the format-fields branch September 10, 2015 22:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants