lsp 1.2.0.1 → 1.4.0.0
raw patch · 11 files changed
+75/−81 lines, 11 filesdep −dependent-mapdep −directorydep −unliftiodep ~basedep ~lsp-typesdep ~mtlnew-uploader
Dependencies removed: dependent-map, directory, unliftio
Dependency ranges changed: base, lsp-types, mtl, transformers
Files
- ChangeLog.md +5/−0
- example/Reactor.hs +6/−6
- lsp.cabal +5/−14
- src/Language/LSP/Diagnostics.hs +1/−1
- src/Language/LSP/Server/Core.hs +22/−23
- src/Language/LSP/Server/Processing.hs +6/−6
- test/CapabilitiesSpec.hs +2/−2
- test/JsonSpec.hs +3/−0
- test/SemanticTokensSpec.hs +5/−5
- test/TypesSpec.hs +3/−3
- test/VspSpec.hs +17/−21
ChangeLog.md view
@@ -1,5 +1,10 @@ # Revision history for lsp +## 1.4.0.0++* Fix extraneous `asdf` in `withProgress` output (#372) (@heitor-lassarote)+* Use appropriate number types (#366) (@michaelpj)+ ## 1.2.0.1 * Add exception instances to LspT (#315) (@pepeiborra)
example/Reactor.hs view
@@ -30,7 +30,7 @@ import Control.Monad.IO.Class import Control.Monad.STM import qualified Data.Aeson as J-import qualified Data.HashMap.Strict as H+import Data.Int (Int32) import qualified Data.Text as T import GHC.Generics (Generic) import Language.LSP.Server@@ -119,7 +119,7 @@ -- | Analyze the file and send any diagnostics to the client in a -- "textDocument/publishDiagnostics" notification-sendDiagnostics :: J.NormalizedUri -> Maybe Int -> LspM Config ()+sendDiagnostics :: J.NormalizedUri -> Maybe Int32 -> LspM Config () sendDiagnostics fileUri version = do let diags = [J.Diagnostic@@ -227,7 +227,7 @@ newName = params ^. J.newName vdoc <- getVersionedTextDoc (params ^. J.textDocument) -- Replace some text at the position with what the user entered- let edit = J.InL $ J.TextEdit (J.mkRange l c l (c + T.length newName)) newName+ let edit = J.InL $ J.TextEdit (J.mkRange l c l (c + fromIntegral (T.length newName))) newName tde = J.TextDocumentEdit vdoc (J.List [edit]) -- "documentChanges" field is preferred over "changes" rsp = J.WorkspaceEdit Nothing (Just (J.List [J.InL tde])) Nothing@@ -263,8 +263,8 @@ cmd = "lsp-hello-command" -- need 'file' and 'start_pos' args = J.List- [ J.Object $ H.fromList [("file", J.Object $ H.fromList [("textDocument",J.toJSON doc)])]- , J.Object $ H.fromList [("start_pos",J.Object $ H.fromList [("position", J.toJSON start)])]+ [ J.object [("file", J.object [("textDocument",J.toJSON doc)])]+ , J.object [("start_pos",J.object [("position", J.toJSON start)])] ] cmdparams = Just args makeCommand (J.Diagnostic _r _s _c _source _m _t _l) = []@@ -280,7 +280,7 @@ responder (Right (J.Object mempty)) -- respond to the request void $ withProgress "Executing some long running command" Cancellable $ \update ->- forM [(0 :: Double)..10] $ \i -> do+ forM [(0 :: J.UInt)..10] $ \i -> do update (ProgressAmount (Just (i * 10)) (Just "Doing stuff")) liftIO $ threadDelay (1 * 1000000) ]
lsp.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: lsp-version: 1.2.0.1+version: 1.4.0.0 synopsis: Haskell library for the Microsoft Language Server Protocol description: An implementation of the types, and basic message server to@@ -31,7 +31,7 @@ , Language.LSP.Server.Control , Language.LSP.Server.Processing ghc-options: -Wall- build-depends: base >= 4.11 && < 4.16+ build-depends: base >= 4.11 && < 5 , async , aeson >=1.0.0.0 , attoparsec@@ -41,8 +41,7 @@ , exceptions , hslogger , hashable- , lsp-types == 1.3.*- , dependent-map+ , lsp-types == 1.4.* , lens >= 4.15.2 , mtl , network-uri@@ -67,20 +66,12 @@ default-language: Haskell2010 ghc-options: -Wall -Wno-unticked-promoted-constructors - build-depends: base >= 4.11 && < 4.16+ build-depends: base , aeson- , bytestring- , containers- , directory- , filepath , hslogger , lens >= 4.15.2- , mtl , stm , text- , transformers- , unordered-containers- , unliftio -- the package library. Comment this out if you want repl changes to propagate , lsp if !flag(demo)@@ -91,7 +82,7 @@ hs-source-dirs: example default-language: Haskell2010 ghc-options: -Wall -Wno-unticked-promoted-constructors- build-depends: base >= 4.11 && < 5+ build-depends: base -- the package library. Comment this out if you want repl changes to propagate , lsp , text
src/Language/LSP/Diagnostics.hs view
@@ -92,6 +92,6 @@ case HM.lookup uri ds of Nothing -> Nothing Just (StoreItem mv diags) ->- Just $ J.PublishDiagnosticsParams (J.fromNormalizedUri uri) mv (J.List (take maxDiagnostics $ SL.fromSortedList $ mconcat $ Map.elems diags))+ Just $ J.PublishDiagnosticsParams (J.fromNormalizedUri uri) (fmap fromIntegral mv) (J.List (take maxDiagnostics $ SL.fromSortedList $ mconcat $ Map.elems diags)) -- ---------------------------------------------------------------------
src/Language/LSP/Server/Core.hs view
@@ -42,8 +42,6 @@ import Data.Default import Data.Functor.Product import Data.IxMap-import qualified Data.Dependent.Map as DMap-import Data.Dependent.Map (DMap) import qualified Data.HashMap.Strict as HM import Data.Kind import qualified Data.List as L@@ -56,6 +54,8 @@ import qualified Data.UUID as UUID import qualified Language.LSP.Types.Capabilities as J import Language.LSP.Types as J+import Language.LSP.Types.SMethodMap (SMethodMap)+import qualified Language.LSP.Types.SMethodMap as SMethodMap import qualified Language.LSP.Types.Lens as J import Language.LSP.VFS import Language.LSP.Diagnostics@@ -131,8 +131,8 @@ -- @ data Handlers m = Handlers- { reqHandlers :: !(DMap SMethod (ClientMessageHandler m Request))- , notHandlers :: !(DMap SMethod (ClientMessageHandler m Notification))+ { reqHandlers :: !(SMethodMap (ClientMessageHandler m Request))+ , notHandlers :: !(SMethodMap (ClientMessageHandler m Notification)) } instance Semigroup (Handlers config) where Handlers r1 n1 <> Handlers r2 n2 = Handlers (r1 <> r2) (n1 <> n2)@@ -140,10 +140,10 @@ mempty = Handlers mempty mempty notificationHandler :: forall (m :: Method FromClient Notification) f. SMethod m -> Handler f m -> Handlers f-notificationHandler m h = Handlers mempty (DMap.singleton m (ClientMessageHandler h))+notificationHandler m h = Handlers mempty (SMethodMap.singleton m (ClientMessageHandler h)) requestHandler :: forall (m :: Method FromClient Request) f. SMethod m -> Handler f m -> Handlers f-requestHandler m h = Handlers (DMap.singleton m (ClientMessageHandler h)) mempty+requestHandler m h = Handlers (SMethodMap.singleton m (ClientMessageHandler h)) mempty -- | Wrapper to restrict 'Handler's to 'FromClient' 'Method's newtype ClientMessageHandler f (t :: MethodType) (m :: Method FromClient t) = ClientMessageHandler (Handler f m)@@ -170,8 +170,8 @@ -> Handlers m -> Handlers n mapHandlers mapReq mapNot (Handlers reqs nots) = Handlers reqs' nots' where- reqs' = DMap.map (\(ClientMessageHandler i) -> ClientMessageHandler $ mapReq i) reqs- nots' = DMap.map (\(ClientMessageHandler i) -> ClientMessageHandler $ mapNot i) nots+ reqs' = SMethodMap.map (\(ClientMessageHandler i) -> ClientMessageHandler $ mapReq i) reqs+ nots' = SMethodMap.map (\(ClientMessageHandler i) -> ClientMessageHandler $ mapNot i) nots -- | state used by the LSP dispatcher to manage the message loop data LanguageContextState config =@@ -184,18 +184,18 @@ , resPendingResponses :: !(TVar ResponseMap) , resRegistrationsNot :: !(TVar (RegistrationMap Notification)) , resRegistrationsReq :: !(TVar (RegistrationMap Request))- , resLspId :: !(TVar Int)+ , resLspId :: !(TVar Int32) } type ResponseMap = IxMap LspId (Product SMethod ServerResponseCallback) -type RegistrationMap (t :: MethodType) = DMap SMethod (Product RegistrationId (ClientMessageHandler IO t))+type RegistrationMap (t :: MethodType) = SMethodMap (Product RegistrationId (ClientMessageHandler IO t)) data RegistrationToken (m :: Method FromClient t) = RegistrationToken (SMethod m) (RegistrationId m) newtype RegistrationId (m :: Method FromClient t) = RegistrationId Text deriving Eq -data ProgressData = ProgressData { progressNextId :: !(TVar Int)+data ProgressData = ProgressData { progressNextId :: !(TVar Int32) , progressCancel :: !(TVar (Map.Map ProgressToken (IO ()))) } data VFSData =@@ -267,7 +267,7 @@ -- an optional message to go with it during a 'withProgress' -- -- @since 0.10.0.0-data ProgressAmount = ProgressAmount (Maybe Double) (Maybe Text)+data ProgressAmount = ProgressAmount (Maybe UInt) (Maybe Text) -- | Thrown if the user cancels a 'Cancellable' 'withProgress'/'withIndefiniteProgress'/ session --@@ -442,7 +442,7 @@ -- --------------------------------------------------------------------- -freshLspId :: MonadLsp config m => m Int+freshLspId :: MonadLsp config m => m Int32 freshLspId = do stateState resLspId $ \cur -> let !next = cur+1 in (cur, next)@@ -473,7 +473,7 @@ getWorkspaceFolders = do clientCaps <- getClientCapabilities let clientSupportsWfs = fromMaybe False $ do- let (J.ClientCapabilities mw _ _ _) = clientCaps+ let (J.ClientCapabilities mw _ _ _ _) = clientCaps (J.WorkspaceClientCapabilities _ _ _ _ _ _ mwf _ _) <- mw mwf if clientSupportsWfs@@ -496,8 +496,8 @@ clientCaps <- resClientCapabilities <$> getLspEnv handlers <- resHandlers <$> getLspEnv let alreadyStaticallyRegistered = case splitClientMethod method of- IsClientNot -> DMap.member method $ notHandlers handlers- IsClientReq -> DMap.member method $ reqHandlers handlers+ IsClientNot -> SMethodMap.member method $ notHandlers handlers+ IsClientReq -> SMethodMap.member method $ reqHandlers handlers IsClientEither -> error "Cannot register capability for custom methods" go clientCaps alreadyStaticallyRegistered where@@ -515,10 +515,10 @@ ~() <- case splitClientMethod method of IsClientNot -> modifyState resRegistrationsNot $ \oldRegs -> let pair = Pair regId (ClientMessageHandler (unliftIO rio . f))- in DMap.insert method pair oldRegs+ in SMethodMap.insert method pair oldRegs IsClientReq -> modifyState resRegistrationsReq $ \oldRegs -> let pair = Pair regId (ClientMessageHandler (\msg k -> unliftIO rio $ f msg (liftIO . k)))- in DMap.insert method pair oldRegs+ in SMethodMap.insert method pair oldRegs IsClientEither -> error "Cannot register capability for custom methods" -- TODO: handle the scenario where this returns an error@@ -572,8 +572,8 @@ unregisterCapability :: MonadLsp config f => RegistrationToken m -> f () unregisterCapability (RegistrationToken m (RegistrationId uuid)) = do ~() <- case splitClientMethod m of- IsClientReq -> modifyState resRegistrationsReq $ DMap.delete m- IsClientNot -> modifyState resRegistrationsNot $ DMap.delete m+ IsClientReq -> modifyState resRegistrationsReq $ SMethodMap.delete m+ IsClientNot -> modifyState resRegistrationsNot $ SMethodMap.delete m IsClientEither -> error "Cannot unregister capability for custom methods" let unregistration = J.Unregistration uuid (J.SomeClientMethod m)@@ -649,13 +649,12 @@ return res where updater progId (ProgressAmount percentage msg) = do- liftIO $ putStrLn "asdf" sendNotification SProgress $ fmap Report $ ProgressParams progId $ WorkDoneProgressReportParams Nothing msg percentage clientSupportsProgress :: J.ClientCapabilities -> Bool-clientSupportsProgress (J.ClientCapabilities _ _ wc _) = fromMaybe False $ do- (J.WindowClientCapabilities mProgress) <- wc+clientSupportsProgress (J.ClientCapabilities _ _ wc _ _) = fromMaybe False $ do+ (J.WindowClientCapabilities mProgress _ _) <- wc mProgress {-# INLINE clientSupportsProgress #-}
src/Language/LSP/Server/Processing.hs view
@@ -22,6 +22,8 @@ import Language.LSP.Types import Language.LSP.Types.Capabilities import qualified Language.LSP.Types.Lens as LSP+import Language.LSP.Types.SMethodMap (SMethodMap)+import qualified Language.LSP.Types.SMethodMap as SMethodMap import Language.LSP.Server.Core import Language.LSP.VFS import Data.Functor.Product@@ -34,9 +36,7 @@ import Control.Monad.Reader import Data.IxMap import System.Log.Logger-import qualified Data.Dependent.Map as DMap import Data.Maybe-import Data.Dependent.Map (DMap) import qualified Data.Map.Strict as Map import System.Exit import Data.Default (def)@@ -185,8 +185,8 @@ supported_b :: forall m. SClientMethod m -> Bool supported_b m = case splitClientMethod m of- IsClientNot -> DMap.member m $ notHandlers h- IsClientReq -> DMap.member m $ reqHandlers h+ IsClientNot -> SMethodMap.member m $ notHandlers h+ IsClientReq -> SMethodMap.member m $ reqHandlers h IsClientEither -> error "capabilities depend on custom method" singleton :: a -> [a]@@ -335,8 +335,8 @@ where -- | Checks to see if there's a dynamic handler, and uses it in favour of the -- static handler, if it exists.- pickHandler :: RegistrationMap t -> DMap SMethod (ClientMessageHandler IO t) -> Maybe (Handler IO m)- pickHandler dynHandlerMap staticHandler = case (DMap.lookup m dynHandlerMap, DMap.lookup m staticHandler) of+ pickHandler :: RegistrationMap t -> SMethodMap (ClientMessageHandler IO t) -> Maybe (Handler IO m)+ pickHandler dynHandlerMap staticHandler = case (SMethodMap.lookup m dynHandlerMap, SMethodMap.lookup m staticHandler) of (Just (Pair _ (ClientMessageHandler h)), _) -> Just h (Nothing, Just (ClientMessageHandler h)) -> Just h (Nothing, Nothing) -> Nothing
test/CapabilitiesSpec.hs view
@@ -7,10 +7,10 @@ spec :: Spec spec = describe "capabilities" $ do it "gives 3.10 capabilities" $- let ClientCapabilities _ (Just tdcs) _ _ = capsForVersion (LSPVersion 3 10)+ let ClientCapabilities _ (Just tdcs) _ _ _ = capsForVersion (LSPVersion 3 10) Just (DocumentSymbolClientCapabilities _ _ mHierarchical _ _ ) = _documentSymbol tdcs in mHierarchical `shouldBe` Just True it "gives pre 3.10 capabilities" $- let ClientCapabilities _ (Just tdcs) _ _ = capsForVersion (LSPVersion 3 9)+ let ClientCapabilities _ (Just tdcs) _ _ _ = capsForVersion (LSPVersion 3 9) Just (DocumentSymbolClientCapabilities _ _ mHierarchical _ _) = _documentSymbol tdcs in mHierarchical `shouldBe` Nothing
test/JsonSpec.hs view
@@ -99,6 +99,9 @@ , HoverContents <$> arbitrary ] +instance Arbitrary UInt where+ arbitrary = fromInteger <$> arbitrary+ instance Arbitrary Uri where arbitrary = Uri <$> arbitrary
test/SemanticTokensSpec.hs view
@@ -21,7 +21,7 @@ , SemanticTokenAbsolute 6 2 7 SttClass [] ] - bigNumber :: Int+ bigNumber :: UInt bigNumber = 100000 bigTokens = unfoldr (\i -> if i == bigNumber then Nothing else Just (SemanticTokenAbsolute i 1 1 SttType [StmUnknown "private", StmStatic], i+1)) 0@@ -31,12 +31,12 @@ -- One more order of magnitude makes diffing more-or-less hang - possibly we need a better diffing algorithm, since this is only ~= 200 tokens at 5 ints per token -- (I checked and it is the diffing that's slow, not turning it into edits)- smallerBigNumber :: Int+ smallerBigNumber :: UInt smallerBigNumber = 1000- bigInts :: [Int]+ bigInts :: [UInt] bigInts = unfoldr (\i -> if i == smallerBigNumber then Nothing else Just (1, i+1)) 0- bigInts2 :: [Int]+ bigInts2 :: [UInt] bigInts2 = unfoldr (\i -> if i == smallerBigNumber then Nothing else Just (if even i then 2 else 1, i+1)) 0 @@ -71,4 +71,4 @@ computeEdits @Int [1,2,3,4,5] [1,6,3,7,7,5] `shouldBe` [Edit 1 1 [6], Edit 3 1 [7,7]] it "handles big tokens" $ -- It's a little hard to specify a useful predicate here, the main point is that it should not take too long- computeEdits @Int bigInts bigInts2 `shouldSatisfy` (not . null)+ computeEdits @UInt bigInts bigInts2 `shouldSatisfy` (not . null)
test/TypesSpec.hs view
@@ -21,10 +21,10 @@ J.unmarkedUpContent "string1\n" <> J.unmarkedUpContent "string2\n" `shouldBe` J.unmarkedUpContent "string1\nstring2\n" it "appends a marked up and a plain string" $ do- J.markedUpContent "haskell" "foo :: Int" <> J.unmarkedUpContent "string2\n"- `shouldBe` J.MarkupContent J.MkMarkdown "\n```haskell\nfoo :: Int\n```\nstring2\n"+ J.markedUpContent "haskell" "foo :: Int" <> J.unmarkedUpContent "string2\nstring3\n"+ `shouldBe` J.MarkupContent J.MkMarkdown "\n```haskell\nfoo :: Int\n```\nstring2 \nstring3 \n" it "appends a plain string and a marked up string" $ do J.unmarkedUpContent "string2\n" <> J.markedUpContent "haskell" "foo :: Int"- `shouldBe` J.MarkupContent J.MkMarkdown "string2\n\n```haskell\nfoo :: Int\n```\n"+ `shouldBe` J.MarkupContent J.MkMarkdown "string2 \n\n```haskell\nfoo :: Int\n```\n" -- ---------------------------------------------------------------------
test/VspSpec.hs view
@@ -26,10 +26,6 @@ -- --------------------------------------------------------------------- --mkRange :: Int -> Int -> Int -> Int -> Maybe J.Range-mkRange ls cs le ce = Just $ J.Range (J.Position ls cs) (J.Position le ce)- vfsFromText :: T.Text -> VirtualFile vfsFromText text = VirtualFile 0 0 (Rope.fromText text) @@ -41,17 +37,17 @@ it "handles vscode style undos" $ do let orig = "abc" changes =- [ J.TextDocumentContentChangeEvent (mkRange 0 2 0 3) Nothing ""- , J.TextDocumentContentChangeEvent (mkRange 0 1 0 2) Nothing ""- , J.TextDocumentContentChangeEvent (mkRange 0 0 0 1) Nothing ""+ [ J.TextDocumentContentChangeEvent (Just $ J.mkRange 0 2 0 3) Nothing ""+ , J.TextDocumentContentChangeEvent (Just $ J.mkRange 0 1 0 2) Nothing ""+ , J.TextDocumentContentChangeEvent (Just $ J.mkRange 0 0 0 1) Nothing "" ] applyChanges orig changes `shouldBe` "" it "handles vscode style redos" $ do let orig = "" changes =- [ J.TextDocumentContentChangeEvent (mkRange 0 1 0 1) Nothing "a"- , J.TextDocumentContentChangeEvent (mkRange 0 2 0 2) Nothing "b"- , J.TextDocumentContentChangeEvent (mkRange 0 3 0 3) Nothing "c"+ [ J.TextDocumentContentChangeEvent (Just $ J.mkRange 0 1 0 1) Nothing "a"+ , J.TextDocumentContentChangeEvent (Just $ J.mkRange 0 2 0 2) Nothing "b"+ , J.TextDocumentContentChangeEvent (Just $ J.mkRange 0 3 0 3) Nothing "c" ] applyChanges orig changes `shouldBe` "abc" @@ -68,7 +64,7 @@ , "foo :: Int" ] new = applyChange (fromString orig)- $ J.TextDocumentContentChangeEvent (mkRange 2 1 2 5) (Just 4) ""+ $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 2 1 2 5) (Just 4) "" lines (Rope.toString new) `shouldBe` [ "abcdg" , "module Foo where"@@ -85,7 +81,7 @@ , "foo :: Int" ] new = applyChange (fromString orig)- $ J.TextDocumentContentChangeEvent (mkRange 2 1 2 5) Nothing ""+ $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 2 1 2 5) Nothing "" lines (Rope.toString new) `shouldBe` [ "abcdg" , "module Foo where"@@ -105,7 +101,7 @@ , "foo :: Int" ] new = applyChange (fromString orig)- $ J.TextDocumentContentChangeEvent (mkRange 2 0 3 0) (Just 8) ""+ $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 2 0 3 0) (Just 8) "" lines (Rope.toString new) `shouldBe` [ "abcdg" , "module Foo where"@@ -122,7 +118,7 @@ , "foo :: Int" ] new = applyChange (fromString orig)- $ J.TextDocumentContentChangeEvent (mkRange 2 0 3 0) Nothing ""+ $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 2 0 3 0) Nothing "" lines (Rope.toString new) `shouldBe` [ "abcdg" , "module Foo where"@@ -140,7 +136,7 @@ , "foo = bb" ] new = applyChange (fromString orig)- $ J.TextDocumentContentChangeEvent (mkRange 1 0 3 0) (Just 19) ""+ $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 1 0 3 0) (Just 19) "" lines (Rope.toString new) `shouldBe` [ "module Foo where" , "foo = bb"@@ -156,7 +152,7 @@ , "foo = bb" ] new = applyChange (fromString orig)- $ J.TextDocumentContentChangeEvent (mkRange 1 0 3 0) Nothing ""+ $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 1 0 3 0) Nothing "" lines (Rope.toString new) `shouldBe` [ "module Foo where" , "foo = bb"@@ -173,7 +169,7 @@ , "foo :: Int" ] new = applyChange (fromString orig)- $ J.TextDocumentContentChangeEvent (mkRange 1 16 1 16) (Just 0) "\n-- fooo"+ $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 1 16 1 16) (Just 0) "\n-- fooo" lines (Rope.toString new) `shouldBe` [ "abcdg" , "module Foo where"@@ -191,7 +187,7 @@ , "foo = bb" ] new = applyChange (fromString orig)- $ J.TextDocumentContentChangeEvent (mkRange 1 8 1 8) Nothing "\n-- fooo\nfoo :: Int"+ $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 1 8 1 8) Nothing "\n-- fooo\nfoo :: Int" lines (Rope.toString new) `shouldBe` [ "module Foo where" , "foo = bb"@@ -218,7 +214,7 @@ ] -- new = changeChars (fromString orig) (J.Position 7 0) (J.Position 7 8) "baz =" new = applyChange (fromString orig)- $ J.TextDocumentContentChangeEvent (mkRange 7 0 7 8) (Just 8) "baz ="+ $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 7 0 7 8) (Just 8) "baz =" lines (Rope.toString new) `shouldBe` [ "module Foo where" , "-- fooo"@@ -246,7 +242,7 @@ ] -- new = changeChars (fromString orig) (J.Position 7 0) (J.Position 7 8) "baz =" new = applyChange (fromString orig)- $ J.TextDocumentContentChangeEvent (mkRange 7 0 7 8) Nothing "baz ="+ $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 7 0 7 8) Nothing "baz =" lines (Rope.toString new) `shouldBe` [ "module Foo where" , "-- fooo"@@ -265,7 +261,7 @@ , "a𐐀b" ] new = applyChange (fromString orig)- $ J.TextDocumentContentChangeEvent (mkRange 1 0 1 3) (Just 3) "𐐀𐐀"+ $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 1 0 1 3) (Just 3) "𐐀𐐀" lines (Rope.toString new) `shouldBe` [ "a𐐀b" , "𐐀𐐀b"