Skip to content

Switch to using the rope-utf16-splay library for ropes #70

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions example/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import qualified Language.Haskell.LSP.Utility as U
import Language.Haskell.LSP.VFS
import System.Exit
import qualified System.Log.Logger as L
import qualified Yi.Rope as Yi
import qualified Data.Rope.UTF16 as Rope


-- ---------------------------------------------------------------------
Expand Down Expand Up @@ -195,7 +195,7 @@ reactor lf inp = do
mdoc <- liftIO $ Core.getVirtualFileFunc lf doc
case mdoc of
Just (VirtualFile _version str) -> do
liftIO $ U.logs $ "reactor:processing NotDidChangeTextDocument: vf got:" ++ (show $ Yi.toString str)
liftIO $ U.logs $ "reactor:processing NotDidChangeTextDocument: vf got:" ++ (show $ Rope.toString str)
Nothing -> do
liftIO $ U.logs "reactor:processing NotDidChangeTextDocument: vf returned Nothing"

Expand Down
6 changes: 3 additions & 3 deletions haskell-lsp.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ library
, mtl
, network-uri
, parsec
, rope-utf16-splay >= 0.2
, sorted-list == 0.2.1.*
, stm
, text
, time
, unordered-containers
, yi-rope
hs-source-dirs: src
default-language: Haskell2010

Expand All @@ -77,13 +77,13 @@ executable lsp-hello
, mtl
, network-uri
, parsec
, rope-utf16-splay >= 0.2
, stm
, text
, time
, transformers
, unordered-containers
, vector
, yi-rope
-- the package library. Comment this out if you want repl changes to propagate
, haskell-lsp

Expand Down Expand Up @@ -112,8 +112,8 @@ test-suite haskell-lsp-test
-- , hspec-jenkins
, lens >= 4.15.2
, network-uri
, rope-utf16-splay >= 0.2
, sorted-list == 0.2.1.*
, yi-rope
, haskell-lsp
, text
, stm
Expand Down
97 changes: 21 additions & 76 deletions src/Language/Haskell/LSP/VFS.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ module Language.Haskell.LSP.VFS
-- * for tests
, applyChanges
, applyChange
, deleteChars , addChars
, changeChars
, yiSplitAt
) where

import Control.Lens
Expand All @@ -37,10 +35,11 @@ import Data.Monoid
import qualified Data.HashMap.Strict as HashMap
import qualified Data.Map as Map
import Data.Maybe
import Data.Rope.UTF16 ( Rope )
import qualified Data.Rope.UTF16 as Rope
import qualified Language.Haskell.LSP.Types as J
import qualified Language.Haskell.LSP.Types.Lens as J
import Language.Haskell.LSP.Utility
import qualified Yi.Rope as Yi

-- ---------------------------------------------------------------------
{-# ANN module ("hlint: ignore Eta reduce" :: String) #-}
Expand All @@ -50,7 +49,7 @@ import qualified Yi.Rope as Yi
data VirtualFile =
VirtualFile {
_version :: Int
, _text :: Yi.YiString
, _text :: Rope
} deriving (Show)

type VFS = Map.Map J.Uri VirtualFile
Expand All @@ -61,7 +60,7 @@ openVFS :: VFS -> J.DidOpenTextDocumentNotification -> IO VFS
openVFS vfs (J.NotificationMessage _ _ params) = do
let J.DidOpenTextDocumentParams
(J.TextDocumentItem uri _ version text) = params
return $ Map.insert uri (VirtualFile version (Yi.fromText text)) vfs
return $ Map.insert uri (VirtualFile version (Rope.fromText text)) vfs

-- ---------------------------------------------------------------------

Expand Down Expand Up @@ -132,87 +131,33 @@ data TextDocumentContentChangeEvent =
-- | Apply the list of changes.
-- Changes should be applied in the order that they are
-- received from the client.
applyChanges :: Yi.YiString -> [J.TextDocumentContentChangeEvent] -> Yi.YiString
applyChanges :: Rope -> [J.TextDocumentContentChangeEvent] -> Rope
applyChanges = foldl' applyChange

-- ---------------------------------------------------------------------

applyChange :: Yi.YiString -> J.TextDocumentContentChangeEvent -> Yi.YiString
applyChange :: Rope -> J.TextDocumentContentChangeEvent -> Rope
applyChange _ (J.TextDocumentContentChangeEvent Nothing Nothing str)
= Yi.fromText str
applyChange str (J.TextDocumentContentChangeEvent (Just (J.Range fm _to)) (Just len) txt) =
if txt == ""
then -- delete len chars from fm
deleteChars str fm len
else -- add or change, based on length
if len == 0
then addChars str fm txt
-- Note: changeChars comes from applyEdit, emacs will split it into a
-- delete and an add
else changeChars str fm len txt
applyChange str (J.TextDocumentContentChangeEvent (Just r@(J.Range (J.Position sl sc) (J.Position el ec))) Nothing txt)
= applyChange str (J.TextDocumentContentChangeEvent (Just r) (Just len) txt)
where len = Yi.length region
(beforeEnd, afterEnd) = Yi.splitAtLine el str
lastLine = Yi.take ec afterEnd
lastLine' | sl == el = Yi.drop sc lastLine
| otherwise = lastLine
(_beforeStart, afterStartBeforeEnd) = Yi.splitAtLine sl beforeEnd
region = Yi.drop sc afterStartBeforeEnd <> lastLine'
applyChange str (J.TextDocumentContentChangeEvent Nothing (Just _) _txt)
= str

-- ---------------------------------------------------------------------

deleteChars :: Yi.YiString -> J.Position -> Int -> Yi.YiString
deleteChars str (J.Position l c) len = str'
= Rope.fromText str
applyChange str (J.TextDocumentContentChangeEvent (Just (J.Range (J.Position sl sc) _to)) (Just len) txt)
= changeChars str start len txt
where
(before,after) = Yi.splitAtLine l str
-- after contains the area we care about, starting with the selected line.
-- Due to LSP zero-based coordinates
beforeOnLine = Yi.take c after
after' = Yi.drop (c + len) after
str' = Yi.append before (Yi.append beforeOnLine after')

-- ---------------------------------------------------------------------

addChars :: Yi.YiString -> J.Position -> Text -> Yi.YiString
addChars str (J.Position l c) new = str'
start = Rope.rowColumnCodeUnits (Rope.RowColumn sl 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
(before,after) = Yi.splitAtLine l str
-- after contains the area we care about, starting with the selected line.
-- Due to LSP zero-based coordinates
beforeOnLine = Yi.take c after
after' = Yi.drop c after
str' = Yi.concat [before, beforeOnLine, (Yi.fromText new), after']

-- ---------------------------------------------------------------------

changeChars :: Yi.YiString -> J.Position -> Int -> Text -> Yi.YiString
changeChars str (J.Position ls cs) len new = str'
where
(before,after) = yiSplitAt ls cs str
after' = Yi.drop len after

str' = Yi.concat [before, (Yi.fromText new), after']

-- changeChars :: Yi.YiString -> J.Position -> J.Position -> String -> Yi.YiString
-- changeChars str (J.Position ls cs) (J.Position le ce) new = str'
-- where
-- (before,_after) = yiSplitAt ls cs str
-- (_before,after) = yiSplitAt le ce str

-- str' = Yi.concat [before, (Yi.fromString new), after]
-- -- str' = Yi.concat [before]
-- -- str' = Yi.concat [_before]
start = Rope.rowColumnCodeUnits (Rope.RowColumn sl sc) str
end = Rope.rowColumnCodeUnits (Rope.RowColumn el ec) str
len = end - start
applyChange str (J.TextDocumentContentChangeEvent Nothing (Just _) _txt)
= str

-- ---------------------------------------------------------------------

yiSplitAt :: Int -> Int -> Yi.YiString -> (Yi.YiString, Yi.YiString)
yiSplitAt l c str = (before,after)
changeChars :: Rope -> Int -> Int -> Text -> Rope
changeChars str start len new = mconcat [before, Rope.fromText new, after']
where
(b,a) = Yi.splitAtLine l str
before = Yi.concat [b,Yi.take c a]
after = Yi.drop c a
(before, after) = Rope.splitAt start str
after' = Rope.drop len after

-- ---------------------------------------------------------------------
1 change: 1 addition & 0 deletions stack-8.0.2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ packages:
extra-deps:
- sorted-list-0.2.1.0
- aeson-1.2.4.0
- rope-utf16-splay-0.2.0.0
flags: {}
extra-package-dbs: []
nix:
Expand Down
1 change: 1 addition & 0 deletions stack-8.2.2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ packages:
- ./haskell-lsp-types
extra-deps:
- sorted-list-0.2.1.0
- rope-utf16-splay-0.2.0.0
flags: {}
extra-package-dbs: []
nix:
Expand Down
2 changes: 1 addition & 1 deletion stack-8.4.2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ packages:
- ./haskell-lsp-types

extra-deps:
- yi-rope-0.11
- rope-utf16-splay-0.2.0.0

flags: {}
extra-package-dbs: []
Expand Down
1 change: 1 addition & 0 deletions stack-8.4.3.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ packages:
- ./haskell-lsp-types

extra-deps:
- rope-utf16-splay-0.2.0.0

flags: {}
extra-package-dbs: []
Expand Down
1 change: 1 addition & 0 deletions stack-8.6.1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ packages:
- ./haskell-lsp-types

extra-deps:
- rope-utf16-splay-0.2.0.0

flags: {}
extra-package-dbs: []
Expand Down
1 change: 1 addition & 0 deletions stack-8.6.3.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ packages:
- ./haskell-lsp-types

extra-deps:
- rope-utf16-splay-0.2.0.0

flags: {}
extra-package-dbs: []
Expand Down
Loading