Closed ghorn closed 4 years ago
It's an intentional decision. From the README:
Let some whitespace be programmable. [...] This makes the implementation simpler and leaves some control to the user while still guaranteeing that the formatted code is stylistically consistent.
If we had a line length limit, we would have to decide which one. We would have to do something in case the line exceeds the limit, like choose where in the line to break. That might in turn be not sufficient so then we have to break again. The end result will likely look pretty ugly, unless we use elaborate heuristics about how to do good line breaking. That's what Brittany does. The design choice in Ormolu is to have a formatter that's simple to hack on, that leaves line breaking to the programmer.
It would be interesting to see where Ormolu increases the line lengths of the input. I would expect Ormolu to rarely increase line lengths, because if you broke an expression into multiple lines, Ormolu will respect that. If the expression holds on one line, it will not change that - but in that case the premise is that the original expression held on one line within the length limit to start with.
For a simple example of increasing line length, Ormolu changes
_ <- primFun (PrimWord8 tag) -- count tag
-- count maximum number of each type in the union
tell (maxUnionConLengths cunion :: Arrays ArrayCount)
into
_ <- primFun (PrimWord8 tag) -- count tag
-- count maximum number of each type in the union
tell (maxUnionConLengths cunion :: Arrays ArrayCount)
The comment now doesn't seem to be aligned with anything in particular.
Speaking generally, increasing indentation can cause a line-length violation. This becomes more likely if the line is nested within a few constructs (e.g. let
inside do
inside a function), all of whose indentation Ormolu increases.
Here are two indentation increases in code that are less obvious (to me, at least) than simply padding out everything in a where
- or let
-clause:
err <- unsafeNewNamed
"err"
(CTypeBackdoor "CborError")
(cborEncoderCreateArray
(encoder, TakeAddress array_encoder, LiteralInt 1 :+ numFields_)
)
is Ormolified (?) to
err <-
unsafeNewNamed
"err"
(CTypeBackdoor "CborError")
( cborEncoderCreateArray
(encoder, TakeAddress array_encoder, LiteralInt 1 :+ numFields_)
)
so that
unsafeNewNamed
is granted its own line, so all its arguments are indented by two spacescborEncoderCreateArray
by a new space, which causes not only its line to grow longer but also the line below it to be indented further and thus grow longer as wellI am OK with ormolu not having a concept of line length, as long as ormolu is compatible with line length limits with some user finessing. An artificial example would be if ormolu always took multi-line type signatures and put them on one line, then there would be no way to satisfy a length limit for large type signatures.
Would it be considered a bug if ormolu combined multi-line expressions into one long line, for example?
Would it be considered a bug if ormolu combined multi-line expressions into one long line, for example?
I'm tempted to say that yes, if this happens, it's arguably a bug. I'm not sure to what extent Ormolu currently sticks to this. But there ought to be a very simple rule for the benefit of the programmer. Something like: if the input is single line, the output is always single line, and if the output is multi-line, the output is always multi-line (although the line breaks might be in different places).
I concur, yet I can also imagine that in same special cases when such combining of lines happens and the result is still fitting on a line and look reasonable, it is OK. Maybe the original input was too "spread" and Ormolu just did performed the necessary normalization.
when such combining of lines happens and the result is still fitting on a line and look reasonable
How do you know if it fits on a line if you don't know low long a line is?
@mrkkrp do you have a concrete example where this might occur?
For example, this
class
Foo
x
where
foo :: Int
is currently transformed into
class
Foo
x where
foo :: Int
Which deletes the line break before where
. I think it is still OK though.
But come think of it, in this particular case there should be a newline before where
I think.
Agreed.
where
placement was fixed in #510.
I think this can be closed now.
We're switching a large work code base to ormolu and finding that ormolu doesn't seem to have a concept of maximum line length. We are having to disable our line length checker because for some modules we can't get ormolu to produce code that short enough.
Is this on the project's radar? Is it an intentional decision to not address line length?