Haskell library for the Microsoft Language Server Protocol
Bot releases are hidden (Show)
Published by wz1000 over 3 years ago
Published by wz1000 over 3 years ago
Published by lukel97 over 3 years ago
data WorkspaceEdit =
WorkspaceEdit
{ _changes :: Maybe WorkspaceEditMap
, _documentChanges :: Maybe (List TextDocumentEdit)
} deriving (Show, Read, Eq)
It is now replaced by a new type called DocumentChange
data WorkspaceEdit =
WorkspaceEdit
{ _changes :: Maybe WorkspaceEditMap
, _documentChanges :: Maybe (List DocumentChange)
} deriving (Show, Read, Eq)
Which is just a synonym of union of WorkspaceEdit and other operations
type DocumentChange = TextDocumentEdit |? CreateFile |? RenameFile |? DeleteFile
Published by lukel97 almost 4 years ago
This contains fixes for building on GHC 8.4.4
Published by lukel97 almost 4 years ago
1.0.0.0 is a major rework with both internal and external facing changes, and
will require manual migration.
haskell-lsp
to lsp
, and similarly for haskell-lsp-types
to lsp-types
Language.LSP.X
rather than Language.Haskell.X
.lsp
and lsp-types
have been reworked to be much more type safe
lsp
can now handle dynamic registration through the registerCapability
andunregisterCapability
functionsThere are three types of concrete messages, NotificationMessage
,
RequestMessage
and ResponseMessage
. They are parameterised by their
Method
, which determines what type their parameters or response result must be.
data RequestMessage (m :: Method f Request) = RequestMessage
{ _jsonrpc :: Text
, _id :: LspId m
, _method :: SMethod m
, _params :: MessageParams m
}
A Method
in turn is parameterised by whether it originates from the client or
the server, and whether it is used for notifications or requests:
TextDocumentFoldingRange :: Method FromClient Request
TextDocumentSelectionRange :: Method FromClient Request
WindowShowMessage :: Method FromServer Notification
WindowShowMessageRequest :: Method FromServer Request
Each Method
also has a singleton counterpart which allows it to be used at the
term level, for example in RequestMessage._method
:
STextDocumentFoldingRange :: SMethod TextDocumentFoldingRange
STextDocumentSelectionRange :: SMethod TextDocumentSelectionRange
SWindowShowMessage :: SMethod WindowShowMessage
SWindowShowMessageRequest :: SMethod WindowShowMessageRequest
The type families MessageParams
and ResponseResult
map each Method
to the
appropriate type to be used in a response:
ResponseResult TextDocumentRename = WorkspaceEdit
ResponseResult TextDocumentPrepareRename = Range |? RangeWithPlaceholder
Also new is the |?
type which represents union types in
TypeScript,
and is used throughout the specification where a field can accept several
different types.
As an example of this in action, the types of your handlers will now depend on
whether or not they are a request or a notification. They will pass along the
precise type for the parameters the method you are handling, and in the case of
a request handler, will expect that the response you give back is of the correct
type as well.
type family Handler (f :: Type -> Type) (m :: Method from t) = (result :: Type) | result -> f t m where
Handler f (m :: Method _from Request) = RequestMessage m -> (Either ResponseError (ResponseResult m) -> f ()) -> f ()
Handler f (m :: Method _from Notification) = NotificationMessage m -> f ()
LspFuncs
has been removed and instead functionality is exposed through
functions in the MonadLsp
class.
getVirtualFile :: MonadLsp config m => NormalizedUri -> m (Maybe VirtualFile)
sendRequest :: forall (m :: Method FromServer Request) f config. MonadLsp config f
=> SServerMethod m
-> MessageParams m
-> (Either ResponseError (ResponseResult m) -> f ())
-> f (LspId m)
It is parameterised over the server's LSP configuration type and the underlying
monad.
We recommend that you build your own monad for your server on top of the LspT
transformer, so it will automatically become an instance of MonadLsp
.
Inside the new ServerDefinition
data type which gets passed to runServer
,
you need to specify how to convert from IO to your monad and back in
interpretHandler
so that lsp
can execute your monad inside the handlers. You
can use the result returned from doInitialize
to pass along the
LanguageContextEnv
needed to run an LspT
, as well as anything else your
monad needs.
type
ServerDefinition { ...
, doInitialize = \env _req -> pure $ Right env
, interpretHandler = \env -> Iso
(runLspT env) -- how to convert from IO ~> m
liftIO -- how to convert from m ~> IO
}
.cabal
file change any haskell-lsp
dependencies to lsp
Haskell.LSP.Server
interpretHandler
notificationHandler
and requestHandler
,SMethod
(See example/Simple.hs
)LspFuncs
and instead call the correspondingIO
Published by lukel97 about 4 years ago
Published by lukel97 over 4 years ago
Published by alanz over 4 years ago
Published by lukel97 almost 5 years ago
Published by lukel97 about 5 years ago
textDocument/prepareRename
request (@thomasjm)Published by lorenzo over 5 years ago
ResponseMessage
to account for null
messages (@cocreature)Published by lukel97 over 5 years ago
Published by lukel97 over 5 years ago
withProgress
and withIndefiniteProgress
withProgress
and withIndefiniteProgress
types to be in IO
like the rest of the library (Look at using monad-control
and unliftio
if you need to use them with a Monad transformer stack)window/progress/cancel
notification being a from server notification when it should be a from client notificationPublished by lukel97 over 5 years ago
MarkupContent
to HoverResponse
, and (some) json roundtrip tests.Published by lukel97 over 5 years ago
withProgress
and withIndefiniteProgress
functions for sending window/progress
notifications.Published by lukel97 over 5 years ago
applyTextEdit
and editTextEdit
helpersPublished by lukel97 over 5 years ago
Published by lukel97 about 6 years ago
Published by lukel97 about 6 years ago