mozilla/rust — pull request #3179 by dbp (2012-08-11 01:31:44+00:00)
Title: Pretty printing for closures - much better.

The way the pretty printer currently handles closures is distinctly unsatisfying (the elipsis are to indicate that there is enough content so that the entire expression cannot fit on a single line; if it could, things would look fine):

fn main() {
do foo(bar) |a|
{
baa...z;
}
for foo(bar) |a|
{
baz;
...
baz;
}
let f =
|a|
{
foo;
...
foo;
};
}

What is happening is that the entire closure is wrapped in a pretty printing box; since it can't fit on the line with the do / for, it starts printing it and then has to break the line, and it indents relative to that, so the block is 4 spaces in from the beginning of the closure. A lot better, in my opinion (and how I think a person would write it), is:

fn main() {
do foo(bar) |a| {
baa...z;
}
for foo(bar) |a| {
baz;
...
baz;
}
let f = |a| {
foo;
...
foo;
};
}

That is, the indentation is keyed on the beginning of the expression. Ideally, the way the boxes would be arranged is that the closure argument would be absorbed into the "head" box that has the do/for/let, but writing the code that way seemed to involve more code complexity, as we need to be looking for closures before we actually see the AST expression for them.

What I did, and this pull request implements, fixes the formatting for do and for expressions (they look exactly like the "desired" output). It does this by eliminating the surrounding block (which involved a little bit of refactoring to allow you to close brackets without having a surrounding box to close). It does not fix the let expression - the arguments for the closure start on the following line. I'm actually not sure why this is happening; it might be something with an easy fix. The output of the code that this pull request adds is the following:

fn main() {
do foo(bar) |a| {
baa...z;
}
for foo(bar) |a| {
baz;
...
baz;
}
let f =
|a| {
foo;
...
foo;
};
}

I'm not sure if this is the best approach - this is the first that I've dealt with the AST or the pretty printer, so I could be doing something non-optimally. Hopefully people can given feedback on the code / how it works.

The diff includes some changes to libsyntax/print/pp.rs to make the debug output more verbose - this was helpful to me as someone unfamiliar with the code, and so seem to make sense. The rest is changes to libsyntax/print/pprust.rs, based on the changes described.