packages feed

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 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"