haskell / haskell-language-server

Official haskell ide support via language server (LSP). Successor of ghcide & haskell-ide-engine.
Apache License 2.0
2.61k stars 352 forks source link

`documentChanges` always contains `"version": 0` (e.g. via an `workspace/applyEdit` code action or a rename request) #3883

Open FichteFoll opened 7 months ago

FichteFoll commented 7 months ago

Your environment

Which OS do you use? ArchLinux Which version of GHC do you use and how did you install it? 9.0.2 via Arch repositories How is your project built (alternative: link to the project)? Just a file.

Which LSP client (editor/plugin) do you use? Sublime Text's LSP package (as documented) Which version of HLS do you use and how did you install it?

haskell-language-server version: 1.9.1.0 (GHC: 9.0.2) (PATH: /usr/bin/haskell-language-server-wrapper)

Have you configured HLS in any way (especially: a hie.yaml file)? No.

Steps to reproduce

https://github.com/sublimelsp/LSP/issues/2368 Basically request a code action, e.g. for the code part1 = sum . map (liftA2 (+) fst last . filter isDigit).

Prompting to rename a variable also uses the wrong version.

Expected behaviour

The resulting workspace/applyEdit should either have the correct version set or none.

Actual behaviour

The version in the resulting workspace/applyEdit is always 0 and the SublimeText LSP package rejects the edit because of a version mis-match.

Debug information

:: [11:33:42.609] --> haskell-language-server textDocument/codeAction (298): {'range': {'start': {'line': 0, 'character': 19}, 'end': {'line': 0, 'character': 40}}, 'textDocument': {'uri': 'file:///home/mhm/code/advent-of-code/2023/haskell/day-01/test.hs'}, 'context': {'triggerKind': 1, 'diagnostics': [{'severity': 3, 'range': {'start': {'character': 19, 'line': 0}, 'end': {'character': 40, 'line': 0}}, 'code': 'refact:Redundant bracket', 'source': 'hlint', 'message': 'Redundant bracket\nFound:\n  (liftA2 (+) fst last) . filter isDigit\nWhy not:\n  liftA2 (+) fst last . filter isDigit\n'}]}}
:: [11:33:42.619] <<< haskell-language-server (298) (duration: 9ms): [{'command': {'command': '1785903:hlint:applyOne', 'title': 'Apply hint "Redundant bracket"', 'arguments': [{'hintTitle': 'Redundant bracket', 'file': 'file:///home/mhm/code/advent-of-code/2023/haskell/day-01/test.hs', 'start_pos': {'character': 19, 'line': 0}}]}, 'title': 'Apply hint "Redundant bracket"', 'kind': 'quickfix', 'diagnostics': [{'severity': 3, 'range': {'start': {'character': 19, 'line': 0}, 'end': {'character': 40, 'line': 0}}, 'code': 'refact:Redundant bracket', 'source': 'hlint', 'message': 'Redundant bracket\nFound:\n  (liftA2 (+) fst last) . filter isDigit\nWhy not:\n  liftA2 (+) fst last . filter isDigit\n'}], 'isPreferred': True}, {'isPreferred': False, 'title': 'Ignore hint "Redundant bracket" in this module', 'kind': 'quickfix', 'diagnostics': [{'severity': 3, 'range': {'start': {'character': 19, 'line': 0}, 'end': {'character': 40, 'line': 0}}, 'code': 'refact:Redundant bracket', 'source': 'hlint', 'message': 'Redundant bracket\nFound:\n  (liftA2 (+) fst last) . filter isDigit\nWhy not:\n  liftA2 (+) fst last . filter isDigit\n'}], 'edit': {'changes': {'file:///home/mhm/code/advent-of-code/2023/haskell/day-01/test.hs': [{'range': {'start': {'character': 0, 'line': 0}, 'end': {'character': 0, 'line': 0}}, 'newText': '{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}\n{-# HLINT ignore "Redundant bracket" #-}\n'}]}}}]
:: [11:33:44.227] --> haskell-language-server workspace/executeCommand (299): {'command': '1785903:hlint:applyOne', 'arguments': [{'hintTitle': 'Redundant bracket', 'file': 'file:///home/mhm/code/advent-of-code/2023/haskell/day-01/test.hs', 'start_pos': {'character': 19, 'line': 0}}]}
:: [11:33:44.228] <-- haskell-language-server window/workDoneProgress/create (90): {'token': 11}
:: [11:33:44.228] >>> haskell-language-server (90) (duration: 0ms): None
:: [11:33:44.228] <-  haskell-language-server $/progress: {'token': 11, 'value': {'cancellable': True, 'kind': 'begin', 'title': 'Applying hint: Redundant bracket'}}
:: [11:33:44.255] <-- haskell-language-server workspace/applyEdit (91): {'edit': {'documentChanges': [{'textDocument': {'uri': 'file:///home/mhm/code/advent-of-code/2023/haskell/day-01/test.hs', 'version': 0}, 'edits': [{'range': {'start': {'character': 0, 'line': 0}, 'end': {'character': 58, 'line': 0}}, 'newText': 'part1 = sum . map (liftA2 (+) fst last . filter isDigit)'}]}]}}
:: [11:33:44.255] <-  haskell-language-server $/progress: {'token': 11, 'value': {'kind': 'end'}}
:: [11:33:44.256] <<< haskell-language-server (299) (duration: 28ms): None
:: [11:33:44.258] >>> haskell-language-server (91) (duration: 3ms): {'applied': True}

(via https://github.com/sublimelsp/LSP/issues/2368)

FichteFoll commented 7 months ago

Note that this also applies to the response after a rename request:

:: [14:34:16.154] --> haskell-language-server textDocument/rename (138): {'newName': 'part30', 'workDoneToken': '$ublime-work-done-progress-138', 'textDocument': {'uri': 'file:///home/mhm/code/advent-of-code/2023/haskell/day01/Main.hs'}, 'position': {'line': 42, 'character': 3}}
:: [14:34:16.193] <<< haskell-language-server (138) (duration: 38ms): {'documentChanges': [{'textDocument': {'uri': 'file:///home/mhm/code/advent-of-code/2023/haskell/day01/Main.hs', 'version': 0}, 'edits': [{'range': {'start': {'character': 0, 'line': 42}, 'end': {'character': 58, 'line': 42}}, 'newText': 'part30 = sum . map ((liftA2 (+) fst last) . filter isDigit)'}]}]}
michaelpj commented 5 months ago

I'm surprised this isn't a bigger problem, tbh.

FichteFoll commented 5 months ago

I think VSCode (or rather the integration inside of it) just ignores the version. I also added a local change to the Sublime Text LSP package to ignore the version when it is 0 to work around this issue, but that is obviously not desirable.