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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
open Eio
open Lsp.Import
module RPC = Jsonrpc
type io = {
input: Buf_read.t;
output: Eio_unix.sink_ty Eio.Resource.t;
}
(** See https://microsoft.github.io/language-server-protocol/specifications/specification-current/#headerPart *)
module Message = struct
let read io =
try
let = Header.read io in
let len = header.content_length in
let json = Json.of_string @@ Buf_read.take len io.input in
Some (RPC.Packet.t_of_yojson json)
with
| Sys_error _
| End_of_file ->
None
let write io packet =
let json = RPC.Packet.yojson_of_t packet in
let data = Json.to_string json in
let content_length = String.length data in
let = Header.create ~content_length in
Header.write io header;
Flow.copy_string data io.output
end
let init (env : Eio_unix.Stdenv.base) = {
input = Buf_read.of_flow ~max_size: 1_000_000 @@ Eio.Stdenv.stdin env;
output = Eio.Stdenv.stdout env
}
let recv io =
Message.read io
let send io packet =
Message.write io packet