avh4 / elm-format

elm-format formats Elm source code according to a standard set of rules based on the official Elm Style Guide
BSD 3-Clause "New" or "Revised" License
1.31k stars 147 forks source link

revisiting "Complex Conditionals" #676

Open BrianHicks opened 4 years ago

BrianHicks commented 4 years ago

When writing conditionals, I frequently want to format using newlines. Say I have the following snippet from using elm/parser:

chompWhile (\c -> c /= '[' && c/= '*' && c /= '~')

That formats OK but I don't feel the formatting is clear enough, so I want to put one conditional on each line, like this:

chompWhile
    (\c ->
        c /= '['
            && c /= '*'
            && c /= '~'
    )

But the current version of elm-format does this:

chompWhile
    (\c ->
        c
            /= '['
            && c
            /= '*'
            && c
            /= '~'
    )

which is… not very readable, at least not to me.

(BTW I know in this particular case I could do chompWhile (\c -> List.member c [ '[', '*', '~' ]); this is just the motivating example closest to hand!)

I did some research on this and found #170. Back when that issue was written in 2016, custom infix operators were possible/common, so it didn't make sense to provide special formatting rules for them. That meant that the best tradeoff between readability and consistency was to sometimes format strangely to avoid having to figure out precedence. But here in 2020, we have only: + - / // * ^ == /= ++ || && |> <| >> << in elm/core, |= |. in elm/parser, and </> <?> in elm/url. Maybe it makes sense to create special rules to format each of these across multiple lines!

As a start, I think it might be reasonable to do these:

(n.b. I may have missed some infix operators here… point is that now that they're finite it may make sense to treat them specially!)

BrianHicks commented 4 years ago

oh, and just to have it written down: I'm aware that I can format my example how I want by adding parentheses around the inequality expressions, but all things being equal I would rather not have to add more syntax so the syntax formatting tool can do the right thing.

avh4 commented 4 years ago

yep! this is possible now in Elm 0.19+

Implementing it requires reworking the binary expression parser to use knowledge of the operator associativity and precedence.

Related issues are https://github.com/avh4/elm-format/issues/201 and https://github.com/avh4/elm-format/issues/375. I guess beyond those, your also suggesting here that certain operators could force newlines to be added?

BrianHicks commented 4 years ago

I guess beyond those, your also suggesting here that certain operators could force newlines to be added?

no, definitely not! The suggestions above include the clause "if there are newlines in the expression" to avoid that.