Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pretty printer can break match expression into multiple lines, breaking edit round-trip #1744

Closed
samgqroberts opened this issue Nov 6, 2020 · 2 comments
Assignees

Comments

@samgqroberts
Copy link
Contributor

I have the following function in my codebase:

._rummikub.trunk.engine> view newGame

  newGame : Nat -> GameConfig -> Either GameCreationError GameState
  newGame seed config =
    match config with
      GameConfig numPlayers tileDuplicates startingPlayerTileCount initialPlayPointMinimum ->
        use Universal <
        match numPlayers with
          x | x < 1 -> Left ZeroPlayers
          _         ->
            match tileDuplicates with
              x | x < 1 -> Left ZeroTiles
              _         ->
                use Nat *
                use Universal >
                allTiles = generateAllTiles tileDuplicates
                numTilesTotal = List.size allTiles
                match numPlayers * startingPlayerTileCount with
                  x | x > numTilesTotal -> Left CannotAllocateEnoughTiles
                  _                     ->
                    shuffledTiles = shuffleList seed allTiles
                    unflippedAndPlayerHands =
                      List.foldl
                        (acc _ ->
                          (match acc with
                            (currUnflipped, currPlayerHands) ->
                              match takeTiles currUnflipped startingPlayerTileCount with
                                (newUnflipped, newPlayerHand) ->
                                  (newUnflipped, newPlayerHand +: currPlayerHands)))
                        (shuffledTiles, [])
                        (List.range 0 numPlayers)
                    match unflippedAndPlayerHands with
                      (unflipped, playerHands) ->
                        board = []
                        playerStates = List.map (hand -> newPlayer hand) playerHands
                        playerTurn = 0
                        Right (GameState unflipped board playerStates playerTurn config)

Note that the match takeTiles currUnflipped startingPlayerTileCount with does not have a line break in the match expression.

For some reason when I edit this term out, the following gets written:

newGame : Nat -> GameConfig -> Either GameCreationError GameState
newGame seed config =
  match config with
    GameConfig
      numPlayers tileDuplicates startingPlayerTileCount initialPlayPointMinimum ->
      use Universal <
      match numPlayers with
        x | x < 1 -> Left ZeroPlayers
        _         ->
          match tileDuplicates with
            x | x < 1 -> Left ZeroTiles
            _         ->
              use Nat *
              use Universal >
              allTiles = generateAllTiles tileDuplicates
              numTilesTotal = List.size allTiles
              match numPlayers * startingPlayerTileCount with
                x | x > numTilesTotal -> Left CannotAllocateEnoughTiles
                _                     ->
                  shuffledTiles = shuffleList seed allTiles
                  unflippedAndPlayerHands =
                    List.foldl
                      (acc _ ->
                        (match acc with
                          (currUnflipped, currPlayerHands) ->
                            match takeTiles
                              currUnflipped startingPlayerTileCount with
                              (newUnflipped, newPlayerHand) ->
                                (newUnflipped,
                                newPlayerHand +: currPlayerHands)))
                      (shuffledTiles, [])
                      (List.range 0 numPlayers)
                  match unflippedAndPlayerHands with
                    (unflipped, playerHands) ->
                      board = []
                      playerStates =
                        List.map (hand -> newPlayer hand) playerHands
                      playerTurn = 0
                      Right
                        (GameState
                          unflipped board playerStates playerTurn config)

Note that there is now a line break in that match expression mentioned before, leading to an immediate parsing error:

._rummikub.trunk.engine> 

  I was expecting an indented block following the `with` keyword
  but instead found this token:
     27 |                               currUnflipped startingPlayerTileCount with

No matter how I change the screen sizes, both of the terminal ucm is running in or of my open text file, the edit result in the text file always has that line break. However, If I change the terminal width to be small enough then view will show that line break.

I tried reproducing this with a smaller example:

longTermName1 b = b && true
longTermName2 b = b && true
longTermName3 b = b && true
longTermName4 = true

longMatchLine = match (longTermName1 (longTermName2 (longTermName3 longTermName4))) with
  true -> true
  false -> false

And with small enough terminal widths I can observe the line break behavior there:

.> view longMatchLine

  longMatchLine : Boolean
  longMatchLine =
    match longTermName1
      (longTermName1 (longTermName1 longTermName4)) with
      true  -> true
      false -> false

However, I cannot reproduce the linebreak in what edit writes, even with this contrived example:

longMatchLine : Boolean
longMatchLine =
  match longTermName1 (longTermName1 (longTermName1 longTermName4)) with
    true  -> true
    false ->
      match longTermName1 (longTermName1 (longTermName1 longTermName4)) with
        true  -> true
        false ->
          match longTermName1 (longTermName1 (longTermName1 longTermName4)) with
            true  -> true
            false ->
              match longTermName1 (longTermName1 (longTermName1 longTermName4)) with
                true  -> true
                false ->
                  match longTermName1 (longTermName1 (longTermName1 longTermName4)) with
                    true  -> true
                    false ->
                      match longTermName1 (longTermName1 (longTermName1 longTermName4)) with
                        true  -> true
                        false ->
                          match longTermName1 (longTermName1 (longTermName1 longTermName4)) with
                            true  -> true
                            false ->
                              match longTermName1 (longTermName1 (longTermName1 longTermName4)) with
                                true  -> true
                                false ->
                                  match longTermName1 (longTermName1 (longTermName1 longTermName4)) with
                                    true  -> true
                                    false ->
                                      match longTermName1 (longTermName1 (longTermName1 longTermName4)) with
                                        true  -> true
                                        false ->
                                          match longTermName1 (longTermName1 (longTermName1 longTermName4)) with
                                            true  -> true
                                            false ->
                                              match longTermName1 (longTermName1 (longTermName1 longTermName4)) with
                                                true  -> true
                                                false ->
                                                  match longTermName1 (longTermName1 (longTermName1 longTermName4)) with
                                                    true  -> true
                                                    false ->
                                                      match longTermName1 (longTermName1 (longTermName1 longTermName4)) with
                                                        true  -> true
                                                        false ->
                                                          match longTermName1 (longTermName1 (longTermName1 longTermName4)) with
                                                            true  -> true
                                                            false ->
                                                              match longTermName1 (longTermName1 (longTermName1 longTermName4)) with
                                                                true  -> true
                                                                false -> false

I'm not sure what about my newGame function above triggers this, so I hope you don't mind that I've provided it in its entirety.

@runarorama
Copy link
Contributor

Looks like this is related to the width of the pattern. I'll either allow line breaks in patterns or prevent the pretty printer breaking patterns into multiple lines.

@runarorama runarorama self-assigned this Sep 30, 2021
@runarorama
Copy link
Contributor

This appears to parse fine now. Closing as "can't reproduce."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants