Skip to content

Last line removed unexpectly when doing whole file range formatting with stylish-haskell. #3847

Closed
@BurningLutz

Description

@BurningLutz

Your environment

Which OS do you use?
Ubuntu on WSL2 on Windows
Which version of GHC do you use and how did you install it?
9.6.3 from ghcup
Which LSP client (editor/plugin) do you use?
Neovim + lspconfig
Which version of HLS do you use and how did you install it?
2.4.0.0 from ghcup

Steps to reproduce

  1. Config stylish-haskell as format provider.
  2. Select all lines and do a range formatting, you'll see the last line get removed.

Expected behaviour

The last line should not be removed.

Actual behaviour

The last line get removed unexpectly.

Debug information

After some investigation(took a look at messages passed between client & server and hls's source code), I'm quite sure it is caused by Ide.PluginUtils.extractTextInRange

-- | Extracts exact matching text in the range.
extractTextInRange :: Range -> T.Text -> T.Text
extractTextInRange (Range (Position sl sc) (Position el ec)) s = newS
  where
    focusLines = take (fromIntegral $ el - sl + 1) $ drop (fromIntegral sl) $ T.lines s
    -- NOTE: We have to trim the last line first to handle the single-line case
    newS =
      focusLines
        & _last %~ T.take (fromIntegral ec)
        & _head %~ T.drop (fromIntegral sc)
        -- NOTE: We cannot use unlines here, because we don't want to add trailing newline!
        & T.intercalate "\n"

Now, let me explain.

Suppose we have codes like:

module Main where

main :: IO ()
main = do
  putStrLn "Hello, World"

When I select all lines and call format in neovim, it sends a range formatting message with the range (0, 0) ~ (4, 25), and after range normalization, extractTextInRange received the range (0, 0) ~ (5, 0) along with the whole file content.

And then, T.lines returned a List with 5 Text inside an further been dropped by 0 and taken by 6. It's taken by 6 but there are only 5 Text available. And when creating newS the last Text is removed by (T.take (fromIntegral 0)).

Note that this bug is only triggered by a whole file range formatting, in the example above, if I select only the top 4 lines, T.lines will be dropped by 0 and taken by 5, and there are 5 Text available so no trouble at all.

Metadata

Metadata

Assignees

No one assigned

    Labels

    component: formatterstype: bugSomething isn't right: doesn't work as intended, documentation is missing/outdated, etc..

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions