lsp-test-0.11.0.7: test/dummy-server/Main.hs
{-# LANGUAGE OverloadedStrings #-}
import Data.Aeson
import Data.Default
import Data.List (isSuffixOf)
import qualified Data.HashMap.Strict as HM
import Language.Haskell.LSP.Core
import Language.Haskell.LSP.Control
import Language.Haskell.LSP.Messages
import Language.Haskell.LSP.Types
import Control.Concurrent
import Control.Monad
import System.Directory
import System.FilePath
main = do
lfvar <- newEmptyMVar
let initCbs = InitializeCallbacks
{ onInitialConfiguration = const $ Right ()
, onConfigurationChange = const $ Right ()
, onStartup = \lf -> do
putMVar lfvar lf
return Nothing
}
options = def
{ executeCommandCommands = Just ["doAnEdit"]
}
run initCbs (handlers lfvar) options Nothing
handlers :: MVar (LspFuncs ()) -> Handlers
handlers lfvar = def
{ initializedHandler = pure $ \_ -> send $ NotLogMessage $ fmServerLogMessageNotification MtLog "initialized"
, hoverHandler = pure $ \req -> send $
RspHover $ makeResponseMessage req (Just (Hover (HoverContents (MarkupContent MkPlainText "hello")) Nothing))
, documentSymbolHandler = pure $ \req -> send $
RspDocumentSymbols $ makeResponseMessage req $ DSDocumentSymbols $
List [ DocumentSymbol "foo"
Nothing
SkObject
Nothing
(mkRange 0 0 3 6)
(mkRange 0 0 3 6)
Nothing
]
, didOpenTextDocumentNotificationHandler = pure $ \noti -> do
let NotificationMessage _ _ (DidOpenTextDocumentParams doc) = noti
TextDocumentItem uri _ _ _ = doc
Just fp = uriToFilePath uri
diag = Diagnostic (mkRange 0 0 0 1)
(Just DsWarning)
(Just (NumberValue 42))
(Just "dummy-server")
"Here's a warning"
Nothing
Nothing
when (".hs" `isSuffixOf` fp) $ void $ forkIO $ do
threadDelay (2 * 10^6)
send $ NotPublishDiagnostics $
fmServerPublishDiagnosticsNotification $ PublishDiagnosticsParams uri $ List [diag]
-- also act as a registerer for workspace/didChangeWatchedFiles
when (".register" `isSuffixOf` fp) $ do
reqId <- readMVar lfvar >>= getNextReqId
send $ ReqRegisterCapability $ fmServerRegisterCapabilityRequest reqId $
RegistrationParams $ List $
[ Registration "0" WorkspaceDidChangeWatchedFiles $ Just $ toJSON $
DidChangeWatchedFilesRegistrationOptions $ List
[ FileSystemWatcher "*.watch" (Just (WatchKind True True True)) ]
]
when (".register.abs" `isSuffixOf` fp) $ do
curDir <- getCurrentDirectory
reqId <- readMVar lfvar >>= getNextReqId
send $ ReqRegisterCapability $ fmServerRegisterCapabilityRequest reqId $
RegistrationParams $ List $
[ Registration "1" WorkspaceDidChangeWatchedFiles $ Just $ toJSON $
DidChangeWatchedFilesRegistrationOptions $ List
[ FileSystemWatcher (curDir </> "*.watch") (Just (WatchKind True True True)) ]
]
-- also act as an unregisterer for workspace/didChangeWatchedFiles
when (".unregister" `isSuffixOf` fp) $ do
reqId <- readMVar lfvar >>= getNextReqId
send $ ReqUnregisterCapability $ fmServerUnregisterCapabilityRequest reqId $
UnregistrationParams $ List [ Unregistration "0" "workspace/didChangeWatchedFiles" ]
when (".unregister.abs" `isSuffixOf` fp) $ do
reqId <- readMVar lfvar >>= getNextReqId
send $ ReqUnregisterCapability $ fmServerUnregisterCapabilityRequest reqId $
UnregistrationParams $ List [ Unregistration "1" "workspace/didChangeWatchedFiles" ]
, executeCommandHandler = pure $ \req -> do
send $ RspExecuteCommand $ makeResponseMessage req Null
reqId <- readMVar lfvar >>= getNextReqId
let RequestMessage _ _ _ (ExecuteCommandParams "doAnEdit" (Just (List [val])) _) = req
Success docUri = fromJSON val
edit = List [TextEdit (mkRange 0 0 0 5) "howdy"]
send $ ReqApplyWorkspaceEdit $ fmServerApplyWorkspaceEditRequest reqId $
ApplyWorkspaceEditParams $ WorkspaceEdit (Just (HM.singleton docUri edit))
Nothing
, codeActionHandler = pure $ \req -> do
let RequestMessage _ _ _ params = req
CodeActionParams _ _ cactx _ = params
CodeActionContext diags _ = cactx
caresults = fmap diag2caresult diags
diag2caresult d = CACodeAction $
CodeAction "Delete this"
Nothing
(Just (List [d]))
Nothing
(Just (Command "" "deleteThis" Nothing))
send $ RspCodeAction $ makeResponseMessage req caresults
, didChangeWatchedFilesNotificationHandler = pure $ \_ ->
send $ NotLogMessage $ fmServerLogMessageNotification MtLog "got workspace/didChangeWatchedFiles"
, completionHandler = pure $ \req -> do
let res = CompletionList (CompletionListType False (List [item]))
item =
CompletionItem "foo" (Just CiConstant) (Just (List [])) Nothing
Nothing Nothing Nothing Nothing Nothing Nothing Nothing
Nothing Nothing Nothing Nothing Nothing
send $ RspCompletion $ makeResponseMessage req res
}
where send msg = readMVar lfvar >>= \lf -> (sendFunc lf) msg
mkRange sl sc el ec = Range (Position sl sc) (Position el ec)