lsp: Haskell library for the Microsoft Language Server Protocol

[ development, library, mit ] [ Propose Tags ]

An implementation of the types, and basic message server to allow language implementors to support the Language Server Protocol for their specific language.

An example of this is for Haskell via the Haskell IDE Engine, at

[Skip to Readme]
Versions [faq],
Change log
Dependencies aeson (>=, async, attoparsec, base (>=4.11 && <4.15), bytestring, containers, data-default, dependent-map, directory, filepath, hashable, hslogger, lens (>=4.15.2), lsp, lsp-types (==1.0.*), mtl, network-uri, random, scientific, sorted-list (==0.2.1.*), stm (==2.5.*), text, time, transformers (>=0.5.6 && <0.6), unliftio, unliftio-core, unordered-containers, uuid (>=1.3) [details]
License MIT
Copyright Alan Zimmerman, 2016-2020
Author Alan Zimmerman
Category Development
Home page
Source repo head: git clone
Uploaded by luke_ at 2020-11-26T14:12:28Z
Distributions NixOS:
Executables lsp-demo-simple-server, lsp-demo-reactor-server
Downloads 112 total (9 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs available [build log]
Last success reported on 2020-11-26 [all 1 reports]


[Index] [Quick Jump]



Build the demo executables


Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info


Maintainer's Corner

For package maintainers and hackage trustees

Readme for lsp-

[back to package description]

CircleCI Hackage


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-types provides type-safe definitions that match up with the typescript definitions laid out in the specification
  • lsp is 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