@hackage lsp1.0.0.0
Haskell library for the Microsoft Language Server Protocol
Categories
License
MIT
Maintainer
alan.zimm@gmail.com
Links
Versions
Installation
Dependencies (26)
- aeson >=1.0.0.0
- async
- attoparsec
- base >=4.12 && <4.15
- bytestring
- containers Show all…
Dependents (41)
@hackage/hls-module-name-plugin, @hackage/hls-explicit-fixity-plugin, @hackage/hls-hlint-plugin, @hackage/swarm, @hackage/glean-lsp, @hackage/futhark, Show all…
Package Flags
demo
(off by default)
Build the demo executables
lsp
Haskell library for the Microsoft Language Server Protocol. It currently implements all of the 3.15 specification.
It is split into two separate packages, lsp and lsp-types
lsp-typesprovides type-safe definitions that match up with the typescript definitions laid out in the specificationlspis a library for building language servers, handling:- JSON-RPC transport
- Keeping track of the document state in memory with the Virtual File System (VFS)
- Responding to notifications and requests via handlers
- Setting the server capabilities in the initialize request based on registered handlers
- Dynamic registration of capabilities
- Cancellable requests and progress notifications
- Publishing and flushing of diagnostics
Language servers built on lsp
Example language servers
There are two example language servers in the example/ folder. Simple.hs provides a minimal example:
{-# LANGUAGE OverloadedStrings #-}
import Language.LSP.Server
import Language.LSP.Types
import Control.Monad.IO.Class
import qualified Data.Text as T
handlers :: Handlers (LspM ())
handlers = mconcat
[ notificationHandler SInitialized $ \_not -> do
let params = ShowMessageRequestParams MtInfo "Turn on code lenses?"
(Just [MessageActionItem "Turn on", MessageActionItem "Don't"])
_ <- sendRequest SWindowShowMessageRequest params $ \res ->
case res of
Right (Just (MessageActionItem "Turn on")) -> do
let regOpts = CodeLensRegistrationOptions Nothing Nothing (Just False)
_ <- registerCapability STextDocumentCodeLens regOpts $ \_req responder -> do
let cmd = Command "Say hello" "lsp-hello-command" Nothing
rsp = List [CodeLens (mkRange 0 0 0 100) (Just cmd) Nothing]
responder (Right rsp)
pure ()
Right _ ->
sendNotification SWindowShowMessage (ShowMessageParams MtInfo "Not turning on code lenses")
Left err ->
sendNotification SWindowShowMessage (ShowMessageParams MtError $ "Something went wrong!\n" <> T.pack (show err))
pure ()
, requestHandler STextDocumentHover $ \req responder -> do
let RequestMessage _ _ _ (HoverParams _doc pos _workDone) = req
Position _l _c' = pos
rsp = Hover ms (Just range)
ms = HoverContents $ markedUpContent "lsp-demo-simple-server" "Hello world"
range = Range pos pos
responder (Right $ Just rsp)
]
main :: IO Int
main = runServer $ ServerDefinition
{ onConfigurationChange = const $ pure $ Right ()
, doInitialize = \env _req -> pure $ Right env
, staticHandlers = handlers
, interpretHandler = \env -> Iso (runLspT env) liftIO
, options = defaultOptions
}
Whilst Reactor.hs shows how a reactor design can be used to handle all
requests on a separate thread, such in a way that we could then execute them on
multiple threads without blocking server communication. They can be installed
from source with
cabal install lsp-demo-simple-server lsp-demo-reactor-server
stack install :lsp-demo-simple-server :lsp-demo-reactor-server --flag haskell-lsp:demo
Useful links
Other resources
See #haskell-ide-engine on IRC freenode