diff --git a/lsp-types/lsp-types.cabal b/lsp-types/lsp-types.cabal index 7992cb666..2cedf072b 100644 --- a/lsp-types/lsp-types.cabal +++ b/lsp-types/lsp-types.cabal @@ -88,10 +88,10 @@ library , mtl , network-uri , mod - , rope-utf16-splay >= 0.3.1.0 , scientific , some , text + , text-rope , template-haskell , temporary , unordered-containers diff --git a/lsp-types/src/Language/LSP/VFS.hs b/lsp-types/src/Language/LSP/VFS.hs index f6ce7a026..19c1819bd 100644 --- a/lsp-types/src/Language/LSP/VFS.hs +++ b/lsp-types/src/Language/LSP/VFS.hs @@ -52,8 +52,8 @@ import Data.Ord import qualified Data.HashMap.Strict as HashMap import qualified Data.Map.Strict as Map import Data.Maybe -import Data.Rope.UTF16 ( Rope ) -import qualified Data.Rope.UTF16 as Rope +import Data.Text.Utf16.Rope ( Rope ) +import qualified Data.Text.Utf16.Rope as Rope import qualified Language.LSP.Types as J import qualified Language.LSP.Types.Lens as J import System.FilePath @@ -136,7 +136,7 @@ applyCreateFile (J.CreateFile uri options _ann) = updateVFS $ Map.insertWith (\ new old -> if shouldOverwrite then new else old) (J.toNormalizedUri uri) - (VirtualFile 0 0 (Rope.fromText "")) + (VirtualFile 0 0 mempty) where shouldOverwrite :: Bool shouldOverwrite = case options of @@ -260,7 +260,7 @@ persistFileVFS vfs uri = action = do exists <- doesFileExist tfn unless exists $ do - let contents = Rope.toString (_text vf) + let contents = T.unpack (Rope.toText (_text vf)) writeRaw h = do -- We honour original file line endings hSetNewlineMode h noNewlineTranslation @@ -291,26 +291,18 @@ applyChanges = foldl' applyChange applyChange :: Rope -> J.TextDocumentContentChangeEvent -> Rope applyChange _ (J.TextDocumentContentChangeEvent Nothing Nothing str) = Rope.fromText str -applyChange str (J.TextDocumentContentChangeEvent (Just (J.Range (J.Position sl sc) _to)) (Just len) txt) - = changeChars str start (fromIntegral len) txt - where - start = Rope.rowColumnCodeUnits (Rope.RowColumn (fromIntegral sl) (fromIntegral sc)) str -applyChange str (J.TextDocumentContentChangeEvent (Just (J.Range (J.Position sl sc) (J.Position el ec))) Nothing txt) - = changeChars str start len txt - where - start = Rope.rowColumnCodeUnits (Rope.RowColumn (fromIntegral sl) (fromIntegral sc)) str - end = Rope.rowColumnCodeUnits (Rope.RowColumn (fromIntegral el) (fromIntegral ec)) str - len = end - start +applyChange str (J.TextDocumentContentChangeEvent (Just (J.Range (J.Position sl sc) (J.Position fl fc))) _ txt) + = changeChars str (Rope.Position (fromIntegral sl) (fromIntegral sc)) (Rope.Position (fromIntegral fl) (fromIntegral fc)) txt applyChange str (J.TextDocumentContentChangeEvent Nothing (Just _) _txt) = str -- --------------------------------------------------------------------- -changeChars :: Rope -> Int -> Int -> Text -> Rope -changeChars str start len new = mconcat [before, Rope.fromText new, after'] +changeChars :: Rope -> Rope.Position -> Rope.Position -> Text -> Rope +changeChars str start finish new = mconcat [before', Rope.fromText new, after] where - (before, after) = Rope.splitAt start str - after' = Rope.drop len after + (before, after) = fromJust $ Rope.splitAtPosition finish str + (before', _) = fromJust $ Rope.splitAtPosition start before -- --------------------------------------------------------------------- @@ -336,14 +328,11 @@ data PosPrefixInfo = PosPrefixInfo getCompletionPrefix :: (Monad m) => J.Position -> VirtualFile -> m (Maybe PosPrefixInfo) getCompletionPrefix pos@(J.Position l c) (VirtualFile _ _ ropetext) = return $ Just $ fromMaybe (PosPrefixInfo "" "" "" pos) $ do -- Maybe monad - let headMaybe [] = Nothing - headMaybe (x:_) = Just x - lastMaybe [] = Nothing + let lastMaybe [] = Nothing lastMaybe xs = Just $ last xs - curLine <- headMaybe $ T.lines $ Rope.toText - $ fst $ Rope.splitAtLine 1 $ snd $ Rope.splitAtLine (fromIntegral l) ropetext - let beforePos = T.take (fromIntegral c) curLine + let curRope = fst $ Rope.splitAtLine 1 $ snd $ Rope.splitAtLine (fromIntegral l) ropetext + beforePos <- Rope.toText . fst <$> Rope.splitAt (fromIntegral c) curRope curWord <- if | T.null beforePos -> Just "" | T.last beforePos == ' ' -> Just "" -- don't count abc as the curword in 'abc ' @@ -357,6 +346,8 @@ getCompletionPrefix pos@(J.Position l c) (VirtualFile _ _ ropetext) = let modParts = dropWhile (not . isUpper . T.head) $ reverse $ filter (not .T.null) xs modName = T.intercalate "." modParts + -- curRope is already a single line, but it may include an enclosing '\n' + let curLine = T.dropWhileEnd (== '\n') $ Rope.toText curRope return $ PosPrefixInfo curLine modName x pos -- --------------------------------------------------------------------- diff --git a/lsp/lsp.cabal b/lsp/lsp.cabal index 4c7d1ac7a..aa2f85ede 100644 --- a/lsp/lsp.cabal +++ b/lsp/lsp.cabal @@ -122,9 +122,9 @@ test-suite unit-test , lens >= 4.15.2 , network-uri , quickcheck-instances - , rope-utf16-splay >= 0.2 , sorted-list == 0.2.1.* , text + , text-rope , unordered-containers -- For GHCI tests -- , async diff --git a/lsp/test/VspSpec.hs b/lsp/test/VspSpec.hs index 2909995f9..e4d691062 100644 --- a/lsp/test/VspSpec.hs +++ b/lsp/test/VspSpec.hs @@ -1,9 +1,8 @@ {-# LANGUAGE OverloadedStrings #-} module VspSpec where - import Data.String -import qualified Data.Rope.UTF16 as Rope +import qualified Data.Text.Utf16.Rope as Rope import Language.LSP.VFS import qualified Language.LSP.Types as J import qualified Data.Text as T @@ -65,7 +64,7 @@ vspSpec = do ] new = applyChange (fromString orig) $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 2 1 2 5) (Just 4) "" - lines (Rope.toString new) `shouldBe` + Rope.lines new `shouldBe` [ "abcdg" , "module Foo where" , "-oo" @@ -82,7 +81,7 @@ vspSpec = do ] new = applyChange (fromString orig) $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 2 1 2 5) Nothing "" - lines (Rope.toString new) `shouldBe` + Rope.lines new `shouldBe` [ "abcdg" , "module Foo where" , "-oo" @@ -102,7 +101,7 @@ vspSpec = do ] new = applyChange (fromString orig) $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 2 0 3 0) (Just 8) "" - lines (Rope.toString new) `shouldBe` + Rope.lines new `shouldBe` [ "abcdg" , "module Foo where" , "foo :: Int" @@ -119,7 +118,7 @@ vspSpec = do ] new = applyChange (fromString orig) $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 2 0 3 0) Nothing "" - lines (Rope.toString new) `shouldBe` + Rope.lines new `shouldBe` [ "abcdg" , "module Foo where" , "foo :: Int" @@ -137,7 +136,7 @@ vspSpec = do ] new = applyChange (fromString orig) $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 1 0 3 0) (Just 19) "" - lines (Rope.toString new) `shouldBe` + Rope.lines new `shouldBe` [ "module Foo where" , "foo = bb" ] @@ -153,7 +152,7 @@ vspSpec = do ] new = applyChange (fromString orig) $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 1 0 3 0) Nothing "" - lines (Rope.toString new) `shouldBe` + Rope.lines new `shouldBe` [ "module Foo where" , "foo = bb" ] @@ -170,7 +169,7 @@ vspSpec = do ] new = applyChange (fromString orig) $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 1 16 1 16) (Just 0) "\n-- fooo" - lines (Rope.toString new) `shouldBe` + Rope.lines new `shouldBe` [ "abcdg" , "module Foo where" , "-- fooo" @@ -188,7 +187,7 @@ vspSpec = do ] new = applyChange (fromString orig) $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 1 8 1 8) Nothing "\n-- fooo\nfoo :: Int" - lines (Rope.toString new) `shouldBe` + Rope.lines new `shouldBe` [ "module Foo where" , "foo = bb" , "-- fooo" @@ -215,7 +214,7 @@ vspSpec = do -- new = changeChars (fromString orig) (J.Position 7 0) (J.Position 7 8) "baz =" new = applyChange (fromString orig) $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 7 0 7 8) (Just 8) "baz =" - lines (Rope.toString new) `shouldBe` + Rope.lines new `shouldBe` [ "module Foo where" , "-- fooo" , "foo :: Int" @@ -243,7 +242,7 @@ vspSpec = do -- new = changeChars (fromString orig) (J.Position 7 0) (J.Position 7 8) "baz =" new = applyChange (fromString orig) $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 7 0 7 8) Nothing "baz =" - lines (Rope.toString new) `shouldBe` + Rope.lines new `shouldBe` [ "module Foo where" , "-- fooo" , "foo :: Int" @@ -262,7 +261,7 @@ vspSpec = do ] new = applyChange (fromString orig) $ J.TextDocumentContentChangeEvent (Just $ J.mkRange 1 0 1 3) (Just 3) "𐐀𐐀" - lines (Rope.toString new) `shouldBe` + Rope.lines new `shouldBe` [ "a𐐀b" , "𐐀𐐀b" ] @@ -285,13 +284,13 @@ vspSpec = do ] (left,right) = Rope.splitAtLine 4 (fromString orig) - lines (Rope.toString left) `shouldBe` + Rope.lines left `shouldBe` [ "module Foo where" , "-- fooo" , "foo :: Int" , "foo = bb" ] - lines (Rope.toString right) `shouldBe` + Rope.lines right `shouldBe` [ "" , "bb = 5" , ""