X-Git-Url: http://git.lukelau.me/?a=blobdiff_plain;f=src%2FLanguage%2FHaskell%2FLSP%2FTest%2FSession.hs;h=641077c83ccaeca38d67990ac6cb056498d5e7fe;hb=d8e460543b7cbc32550bed20d20ef4b13d6705a5;hp=6a9a6d50d51ef738c37b0250a9a9744add532049;hpb=600388d3b0320b4f9374e8a781743877f4e263c7;p=opengl.git diff --git a/src/Language/Haskell/LSP/Test/Session.hs b/src/Language/Haskell/LSP/Test/Session.hs index 6a9a6d5..641077c 100644 --- a/src/Language/Haskell/LSP/Test/Session.hs +++ b/src/Language/Haskell/LSP/Test/Session.hs @@ -40,7 +40,7 @@ import qualified Data.HashMap.Strict as HashMap import Data.Maybe import Language.Haskell.LSP.Messages import Language.Haskell.LSP.TH.ClientCapabilities -import Language.Haskell.LSP.Types +import Language.Haskell.LSP.Types hiding (error) import Language.Haskell.LSP.VFS import Language.Haskell.LSP.Test.Compat import Language.Haskell.LSP.Test.Decoding @@ -66,10 +66,11 @@ data SessionConfig = SessionConfig { capabilities :: ClientCapabilities -- ^ Specific capabilities the client should advertise. Default is yes to everything. , timeout :: Int -- ^ Maximum time to wait for a request in seconds. Defaults to 60. + , logStdErr :: Bool -- ^ When True redirects the servers stderr output to haskell-lsp-test's stdout. Defaults to False } instance Default SessionConfig where - def = SessionConfig def 60 + def = SessionConfig def 60 False class Monad m => MonadSessionConfig m where sessionConfig :: m SessionConfig @@ -91,6 +92,7 @@ data SessionState = SessionState { curReqId :: LspId , vfs :: VFS + , curDiagnostics :: Map.Map Uri [Diagnostic] } type ParserStateReader a s r m = ConduitParser a (StateT s (ReaderT r m)) @@ -161,7 +163,7 @@ runSessionWithHandles serverIn serverOut serverHandler config rootDir session = initRsp <- newEmptyMVar let context = SessionContext serverIn absRootDir messageChan reqMap initRsp config - initState = SessionState (IdInt 0) mempty + initState = SessionState (IdInt 0) mempty mempty threadId <- forkIO $ void $ runSession meaninglessChan processor context initState (serverHandler serverOut) (result, _) <- runSession messageChan processor context initState session @@ -177,14 +179,30 @@ runSessionWithHandles serverIn serverOut serverHandler config rootDir session = processTextChanges :: FromServerMessage -> SessionProcessor () +processTextChanges (NotPublishDiagnostics n) = do + let List diags = n ^. params . diagnostics + doc = n ^. params . uri + lift $ State.modify (\s -> + let newDiags = Map.insert doc diags (curDiagnostics s) + in s { curDiagnostics = newDiags }) + processTextChanges (ReqApplyWorkspaceEdit r) = do - changeParams <- case r ^. params . edit . documentChanges of - Just (List cs) -> mapM applyTextDocumentEdit cs + + allChangeParams <- case r ^. params . edit . documentChanges of + Just (List cs) -> do + mapM_ (checkIfNeedsOpened . (^. textDocument . uri)) cs + return $ map getParams cs Nothing -> case r ^. params . edit . changes of - Just cs -> concat <$> mapM (uncurry applyChange) (HashMap.toList cs) - Nothing -> return [] + Just cs -> do + mapM_ checkIfNeedsOpened (HashMap.keys cs) + return $ concatMap (uncurry getChangeParams) (HashMap.toList cs) + Nothing -> error "No changes!" + + oldVFS <- vfs <$> lift State.get + newVFS <- liftIO $ changeFromServerVFS oldVFS r + lift $ State.modify (\s -> s { vfs = newVFS }) - let groupedParams = groupBy (\a b -> (a ^. textDocument == b ^. textDocument)) changeParams + let groupedParams = groupBy (\a b -> (a ^. textDocument == b ^. textDocument)) allChangeParams mergedParams = map mergeParams groupedParams ctx <- lift $ lift Reader.ask @@ -195,14 +213,13 @@ processTextChanges (ReqApplyWorkspaceEdit r) = do msg = NotificationMessage "2.0" TextDocumentDidChange p liftIO $ B.hPut h $ addHeader (encode msg) - where applyTextDocumentEdit (TextDocumentEdit docId (List edits)) = do + where checkIfNeedsOpened uri = do oldVFS <- vfs <$> lift State.get ctx <- lift $ lift Reader.ask - -- if its not open, open it - unless ((docId ^. uri) `Map.member` oldVFS) $ do - let fp = fromJust $ uriToFilePath (docId ^. uri) + unless (uri `Map.member` oldVFS) $ do + let fp = fromJust $ uriToFilePath uri contents <- liftIO $ T.readFile fp let item = TextDocumentItem (filePathToUri fp) "" 0 contents msg = NotificationMessage "2.0" TextDocumentDidOpen (DidOpenTextDocumentParams item) @@ -212,21 +229,15 @@ processTextChanges (ReqApplyWorkspaceEdit r) = do newVFS <- liftIO $ openVFS oldVFS msg lift $ State.modify (\s -> s { vfs = newVFS }) - -- we might have updated it above - oldVFS <- vfs <$> lift State.get - + getParams (TextDocumentEdit docId (List edits)) = let changeEvents = map (\e -> TextDocumentContentChangeEvent (Just (e ^. range)) Nothing (e ^. newText)) edits - params = DidChangeTextDocumentParams docId (List changeEvents) - newVFS <- liftIO $ changeVFS oldVFS (fmClientDidChangeTextDocumentNotification params) - lift $ State.modify (\s -> s { vfs = newVFS }) - - return params + in DidChangeTextDocumentParams docId (List changeEvents) textDocumentVersions uri = map (VersionedTextDocumentIdentifier uri) [0..] textDocumentEdits uri edits = map (\(v, e) -> TextDocumentEdit v (List [e])) $ zip (textDocumentVersions uri) edits - applyChange uri (List edits) = mapM applyTextDocumentEdit (textDocumentEdits uri (reverse edits)) + getChangeParams uri (List edits) = map getParams (textDocumentEdits uri (reverse edits)) mergeParams :: [DidChangeTextDocumentParams] -> DidChangeTextDocumentParams mergeParams params = let events = concat (toList (map (toList . (^. contentChanges)) params))