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]


[Index] [Quick Jump]


Automatic Flags

Build the demo executables


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


Note: This package has metadata revisions in the cabal description newer than included in the tarball. To unpack the package including the revisions, use 'cabal get'.

Maintainer's Corner

For package maintainers and hackage trustees


Versions [RSS],,,,,,,
Change log
Dependencies aeson (>=, async, attoparsec, base (>=4.12 && <4.15), bytestring, containers, data-default, dependent-map, directory, filepath, hashable, hslogger, lens (>=4.15.2), lsp, lsp-types (>=1.0 && <1.1), mtl (<2.3), network-uri, random, scientific, sorted-list (>=0.2.1 && <0.2.2), stm (>=2.5 && <2.6), 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
Revised Revision 2 made by sjakobi at 2022-05-10T13:35:35Z
Category Development
Home page
Source repo head: git clone
Uploaded by luke_ at 2020-10-15T17:59:26Z
Distributions Arch:, LTSHaskell:, NixOS:
Executables lsp-demo-simple-server, lsp-demo-reactor-server
Downloads 6649 total (174 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2020-10-15 [all 1 reports]

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

Other resources

See #haskell-ide-engine on IRC freenode