-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathteikalsp.ml
74 lines (67 loc) · 2.6 KB
/
teikalsp.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
open Lsp_error
let on_request (type response) context _channel
(request : response Lsp.Client_request.t) : response =
let open Lsp_request in
let open Lsp.Client_request in
(* TODO: use channel? *)
match request with
| Initialize params -> Server_life_cycle.initialize context ~params
| _request ->
(* TODO: print which requests are not supported *)
fail Error_unsupported_request
let on_request_error _context _channel error =
let open Jsonrpc.Response.Error in
(* TODO: maybe error should show to user? *)
(* TODO: better errors *)
let message =
match error with
| Lsp_error { error } -> Lsp_error.show error
| error -> Printexc.to_string error
in
Jsonrpc.Response.Error.make ~code:Code.InternalError ~message ()
let on_notification context _channel notification =
let open Lsp_notification in
let open Lsp.Client_notification in
(* TODO: use channel? *)
match notification with
| Initialized -> Server_life_cycle.initialized context
| TextDocumentDidOpen params -> Text_document_sync.did_open context ~params
| TextDocumentDidChange params ->
Text_document_sync.did_change context ~params
| TextDocumentDidClose params -> Text_document_sync.did_close context ~params
| _notification ->
(* TODO: print which notifications are not supported *)
fail Error_unsupported_notification
let on_notification context channel notification =
(* TODO: notification error handling *)
match Lsp_context.status context with
| Handshake ->
(* TODO: log *)
(* TODO: server can send some notifications during handshake *)
fail Error_notification_before_initialize
| Running -> on_notification context channel notification
let on_notification_error _context channel error =
let open Lsp.Types in
let open Lsp.Server_notification in
let message =
match error with
| Lsp_error { error } -> Lsp_error.show error
| error -> Printexc.to_string error
in
(* TODO: maybe error should show to user? *)
let message = LogMessageParams.create ~type_:Error ~message in
Lsp_channel.notify channel @@ LogMessage message
let main () =
Eio_main.run @@ fun env ->
let context = Lsp_context.create () in
let on_request channel request =
try Ok (on_request context channel request)
with error -> Error (on_request_error context channel error)
in
let on_notification channel notification =
try on_notification context channel notification
with error -> on_notification_error context channel error
in
Lsp_channel.listen ~input:env#stdin ~output:env#stdout
~on_request:{ f = on_request } ~on_notification
let () = main ()