add functions in jsonrpc2 to send queries/notifs directly from server

This commit is contained in:
Simon Cruanes 2023-10-06 09:55:31 -04:00
parent bb92d7d73b
commit 498c62d46f
3 changed files with 33 additions and 10 deletions

View file

@ -9,18 +9,20 @@ module type S = sig
module IO : IO
type t
(** A jsonrpc2 connection. *)
include module type of Server.Make (IO)
val create : ic:IO.in_channel -> oc:IO.out_channel -> server -> t
(** Create a connection from the pair of channels *)
val create_stdio : server -> t
(** Create a connection using stdin/stdout *)
val send_server_notification : t -> Lsp.Server_notification.t -> unit IO.t
val send_server_request :
t ->
'from_server Lsp.Server_request.t ->
(('from_server, Jsonrpc.Response.Error.t) result -> unit IO.t) ->
Req_id.t IO.t
val run : ?shutdown:(unit -> bool) -> t -> unit IO.t
(** Listen for incoming messages and responses *)
end
module Make (IO : IO) : S with module IO = IO = struct
@ -116,8 +118,8 @@ module Make (IO : IO) : S with module IO = IO = struct
(fun e -> IO.return (Error e))
(** Sends a server notification to the LSP client. *)
let server_notification (self : t) (n : Lsp.Server_notification.t) : unit IO.t
=
let send_server_notification (self : t) (n : Lsp.Server_notification.t) :
unit IO.t =
let msg = Lsp.Server_notification.to_jsonrpc n in
send_server_notif self msg
@ -156,7 +158,8 @@ module Make (IO : IO) : S with module IO = IO = struct
match Lsp.Client_notification.of_jsonrpc n with
| Ok n ->
with_error_handler self (fun () ->
self.s#on_notification n ~notify_back:(server_notification self)
self.s#on_notification n
~notify_back:(send_server_notification self)
~server_request:(server_request self))
| Error e -> IO.failwith (spf "cannot decode notification: %s" e)
@ -182,7 +185,8 @@ module Make (IO : IO) : S with module IO = IO = struct
| Ok (Lsp.Client_request.E r) ->
protect ~id (fun () ->
let* reply =
self.s#on_request r ~id ~notify_back:(server_notification self)
self.s#on_request r ~id
~notify_back:(send_server_notification self)
~server_request:(server_request self)
in
let reply_json = Lsp.Client_request.yojson_of_result r reply in
@ -302,6 +306,11 @@ module Make (IO : IO) : S with module IO = IO = struct
IO.return
@@ Error (E (ErrorCode.InvalidRequest, "content-type must be 'utf-8'"))
let send_server_request (self : t) (req : 'from_server Lsp.Server_request.t)
(cb : ('from_server, Jsonrpc.Response.Error.t) result -> unit IO.t) :
Req_id.t IO.t =
server_request self (Request_and_handler (req, cb))
(** [shutdown ()] is called after processing each request to check if the server
could wait for new messages.
When launching an LSP server using [Server.Make.server], the

View file

@ -20,6 +20,19 @@ module type S = sig
val create_stdio : server -> t
(** Create a connection using stdin/stdout *)
val send_server_notification : t -> Lsp.Server_notification.t -> unit IO.t
(** Send a notification from the server.
@since NEXT_RELEASE *)
val send_server_request :
t ->
'from_server Lsp.Server_request.t ->
(('from_server, Jsonrpc.Response.Error.t) result -> unit IO.t) ->
Req_id.t IO.t
(** Send a request from the server, and pass a callback that will be
called with the result in the future.
@since NEXT_RELEASE *)
val run : ?shutdown:(unit -> bool) -> t -> unit IO.t
(** Listen for incoming messages and responses.
@param shutdown if true, tells the server to shut down *)

View file

@ -131,7 +131,8 @@ module Make (IO : IO) = struct
{ value = Lsp.Server_notification.Progress.End p; token }
| None -> IO.return ()
method send_notification (n : Lsp.Server_notification.t) = notify_back n
method send_notification (n : Lsp.Server_notification.t) : unit IO.t =
notify_back n
(** Send a notification from the server to the client (general purpose method) *)
method send_request