Support "interactive" formatting

Since I take a good deal of inspiration from elm-format, it would be nice to follow its lead with how it handles newlines. I'm not entirely sure of its algorithm, but as a user of elm-format this is how I think about it:

  • If I write a multi-line thing on one line, it keeps it on one line
  • If I make at least one line break on a multi-line thing, it formats everything in the scope of that line break as multi-line

That might be confusing to read. How it should work in purty is that if I write:

foo :: Int -> String -> Boolean

it should become

foo :: Int -> String -> Boolean

If I write:

foo :: Int -> String -> 
  Boolean

or

foo :: Int -> String
 -> Boolean

or

foo
 :: Int -> String -> Boolean

or

foo :: 
  Int -> String -> 
  Boolean

or any other combination that introduces multiple lines, it should become

foo ::
  Int ->
  String ->
  Boolean

Other constructs should behave similarly. E.g. If you have:

foo x = let y = {z: x + 1} in [y.z - 1, y.z, y.z + 1]

and you make a newline in the record:

foo x = let y = {z: x + 1
 } in [y.z - 1, y.z, y.z + 1]

it should become:

foo x =
  let y = { z: x + 1
          }
  in [y.z - 1, y.z, y.z + 1]

But, if you make a newline in the array:

foo x = let y = {z: x + 1} in [y.z - 1, y.z, y.z
 + 1]

it should become

foo x =
  let y = {z: x + 1}
  in [ y.z - 1
     , y.z
     , y.z 
         + 1
     ]

It means that you can format a bunch for a very small change. But since you're in control of it, it works out pretty well in practice. It tends to feel like you're having a conversation with the computer.

You have a bit more control over how purty formats your file. It's not a static format in that one area of the code might be formatted slightly different (even with the same characters). It's not a dynamic format in that line length isn't taken into account. It's more of an "interactive" formatting, since you tell purty how to format blocks of code.

Most of this is predicated on the parser giving us enough information to make these decisions in purty. So we probably want to see if we have enough source location information first.

Edited by Hardy Jones
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information