Skip to content

Fix multiline pattern bind indent (#712)#798

Merged
mrkkrp merged 1 commit intomasterfrom
tbagrel1/712-fix-pattern-indent
Oct 5, 2021
Merged

Fix multiline pattern bind indent (#712)#798
mrkkrp merged 1 commit intomasterfrom
tbagrel1/712-fix-pattern-indent

Conversation

@tbagrel1
Copy link
Member

@tbagrel1 tbagrel1 commented Oct 1, 2021

Close #712.

I don't think this solution is acceptable, but it's still a starting
point to see that it can be made if we really want it.

@tbagrel1 tbagrel1 requested a review from mrkkrp October 1, 2021 08:15
@tbagrel1 tbagrel1 changed the title Internal.hs hack to "solve" the issue Fix multiline pattern bind indent (#712) Oct 1, 2021
Copy link
Member

@mrkkrp mrkkrp left a comment

Choose a reason for hiding this comment

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

Also, for every change like this a changelog entry and a new test(s) are necessary.

enterLayout,
vlayout,
getLayout,
setAnchor,
Copy link
Member

Choose a reason for hiding this comment

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

Try to solve the issue differently without introducing new primitives. We should try to keep our vocabulary of combinators from exploding and try to work within the DSL that we have. Look at my comments in #712 they should suggest how this can be solved and what layout is desirable.

Copy link
Member Author

Choose a reason for hiding this comment

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

A new primitive was required to create something like sitcc but just for the first line of each multiline block, like in

 foobarbar :: Int -> Bool
foobarbar | x <-
    5,
            y <-
    6 = case x of
  5 -> True
  _ -> False

According to your last comment on the linked issue, this is no longer what we want to achieve, so my commit doesn't make sense anymore.

Copy link
Member

@mrkkrp mrkkrp Oct 1, 2021

Choose a reason for hiding this comment

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

I'm sorry for unclear communication from my side, this alignment feature is not what I had in mind. As a rule, we do not align anything in Ormolu, so y would never have to be aligned with x because if x moved, y would also need to move—this is exactly what we try to avoid in order to help with minimization of diffs.

Copy link
Member Author

Choose a reason for hiding this comment

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

No problem, we didn't really discover the case with multiple pattern binds at first. At least, it was a fun exercise to add this functionality in ormolu, and helped me to get a better understanding of how internals work

@tbagrel1 tbagrel1 force-pushed the tbagrel1/712-fix-pattern-indent branch from c34a33d to 63beaaa Compare October 4, 2021 08:12
@tbagrel1
Copy link
Member Author

tbagrel1 commented Oct 4, 2021

Ok, I think I found a way to achieve the requested behavior, and it doesn't seem to introduce changes except in the desired place when applied to the ormolu codebase (via format.sh)
However, some tests don't pass (which is something I expected), but I don't know where to start to see whether I need to update the tests, or improve my fix.

@tbagrel1 tbagrel1 requested review from amesgen and mrkkrp October 5, 2021 07:20
@tbagrel1
Copy link
Member Author

tbagrel1 commented Oct 5, 2021

I think it works as expected now.
I also added tests and changelog entry.

then blockPlacement placer grhssGRHSs
else Normal
Just spn -> case style of
Function _ | hasGuards && any guardNeedsLineBreak grhssGRHSs -> Normal
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure if this was discussed, but is it intended that this change is only applied for the Function style? Example: Even with this PR, the input

\case x | x <-
          foo -> case x of
         5 -> True
         _ -> False

is formatted to

\case
  x | x <-
        foo -> case x of
    5 -> True
    _ -> False

(note that there is no linebreak before the |). Simply ignoring style passes all tests locally, and the output would be

\case
  x
    | x <-
        foo -> case x of
      5 -> True
      _ -> False

which now is consistent with the output for regular function match groups.

Copy link
Member Author

@tbagrel1 tbagrel1 Oct 5, 2021

Choose a reason for hiding this comment

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

That's a good point indeed, and we didn't discussed it before. However, I don't have the authority to decide whether we should extend it to all styles or not :)
But IMO, it's better to extend it!
I will make a new commit where it is extended to all styles

@tbagrel1 tbagrel1 requested a review from amesgen October 5, 2021 12:25
Copy link
Contributor

@amesgen amesgen left a comment

Choose a reason for hiding this comment

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

Implementation looks good!

@mrkkrp mrkkrp force-pushed the tbagrel1/712-fix-pattern-indent branch 3 times, most recently from f8254b5 to ab78f2a Compare October 5, 2021 16:08
Now guards are printed on a new line if at least one guard is multiline or
if all guards together occupy more than one line. The body of each guard is
also indented one level deeper in that case.
@mrkkrp mrkkrp force-pushed the tbagrel1/712-fix-pattern-indent branch from ab78f2a to 7c5aa80 Compare October 5, 2021 16:15
Copy link
Member

@mrkkrp mrkkrp left a comment

Choose a reason for hiding this comment

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

Great work! This was not an easy one to figure out. I took the liberty of adjusting this a little bit:

  • The new examples that you have added should be without the module headers and the main function, because those parts are completely optional. In fact, they only add visual noise. I removed them.
  • There is one interesting corner case that you have skipped: all guards in a single line. I added this example and it showed that we had a bug in our guard printing code! We need to separate guards with breakpoints, not with newlines.
  • Please format your code so that it fits in 80 line limit. Try to avoid very long lines.

@mrkkrp mrkkrp merged commit 714b98e into master Oct 5, 2021
@mrkkrp mrkkrp deleted the tbagrel1/712-fix-pattern-indent branch October 5, 2021 16:29
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.

Layout is sometimes indented less than the line of the layout trigger

3 participants