1
+ ---
2
+ --- Nvim msgpack-RPC protocol session. Manages requests/notifications/responses.
3
+ ---
4
+
1
5
local uv = vim .uv
2
- local MsgpackRpcStream = require (' test.client.msgpack_rpc_stream ' )
6
+ local RpcStream = require (' test.client.rpc_stream ' )
3
7
8
+ --- Nvim msgpack-RPC protocol session. Manages requests/notifications/responses.
9
+ ---
4
10
--- @class test.Session
5
- --- @field private _pending_messages string[]
6
- --- @field private _msgpack_rpc_stream test.MsgpackRpcStream
11
+ --- @field private _pending_messages string[] Requests / notifications received from the remote end.
12
+ --- @field private _rpc_stream test.RpcStream
7
13
--- @field private _prepare uv.uv_prepare_t
8
14
--- @field private _timer uv.uv_timer_t
9
- --- @field private _is_running boolean
15
+ --- @field private _is_running boolean true during ` Session:run() ` scope.
10
16
--- @field exec_lua_setup boolean
11
17
local Session = {}
12
18
Session .__index = Session
@@ -51,9 +57,10 @@ local function coroutine_exec(func, ...)
51
57
end ))
52
58
end
53
59
60
+ --- Creates a new msgpack-RPC session.
54
61
function Session .new (stream )
55
62
return setmetatable ({
56
- _msgpack_rpc_stream = MsgpackRpcStream .new (stream ),
63
+ _rpc_stream = RpcStream .new (stream ),
57
64
_pending_messages = {},
58
65
_prepare = uv .new_prepare (),
59
66
_timer = uv .new_timer (),
@@ -91,10 +98,13 @@ function Session:next_message(timeout)
91
98
return table.remove (self ._pending_messages , 1 )
92
99
end
93
100
101
+ --- Sends a notification to the RPC endpoint.
94
102
function Session :notify (method , ...)
95
- self ._msgpack_rpc_stream :write (method , { ... })
103
+ self ._rpc_stream :write (method , { ... })
96
104
end
97
105
106
+ --- Sends a request to the RPC endpoint.
107
+ ---
98
108
--- @param method string
99
109
--- @param ... any
100
110
--- @return boolean , table
@@ -114,8 +124,16 @@ function Session:request(method, ...)
114
124
return true , result
115
125
end
116
126
117
- --- Runs the event loop.
127
+ --- Processes incoming RPC requests/notifications until exhausted.
128
+ ---
129
+ --- TODO(justinmk): luaclient2 avoids this via uvutil.cb_wait() + uvutil.add_idle_call()?
130
+ ---
131
+ --- @param request_cb function Handles requests from the sever to the local end.
132
+ --- @param notification_cb function Handles notifications from the sever to the local end.
133
+ --- @param setup_cb function
134
+ --- @param timeout number
118
135
function Session :run (request_cb , notification_cb , setup_cb , timeout )
136
+ --- Handles an incoming request.
119
137
local function on_request (method , args , response )
120
138
coroutine_exec (request_cb , method , args , function (status , result , flag )
121
139
if status then
@@ -126,6 +144,7 @@ function Session:run(request_cb, notification_cb, setup_cb, timeout)
126
144
end )
127
145
end
128
146
147
+ --- Handles an incoming notification.
129
148
local function on_notification (method , args )
130
149
coroutine_exec (notification_cb , method , args )
131
150
end
@@ -160,39 +179,45 @@ function Session:close(signal)
160
179
if not self ._prepare :is_closing () then
161
180
self ._prepare :close ()
162
181
end
163
- self ._msgpack_rpc_stream :close (signal )
182
+ self ._rpc_stream :close (signal )
164
183
self .closed = true
165
184
end
166
185
186
+ --- Sends a request to the RPC endpoint, without blocking (schedules a coroutine).
167
187
function Session :_yielding_request (method , args )
168
188
return coroutine.yield (function (co )
169
- self ._msgpack_rpc_stream :write (method , args , function (err , result )
189
+ self ._rpc_stream :write (method , args , function (err , result )
170
190
resume (co , err , result )
171
191
end )
172
192
end )
173
193
end
174
194
195
+ --- Sends a request to the RPC endpoint, and blocks (polls event loop) until a response is received.
175
196
function Session :_blocking_request (method , args )
176
197
local err , result
177
198
199
+ -- Invoked when a request is received from the remote end.
178
200
local function on_request (method_ , args_ , response )
179
201
table.insert (self ._pending_messages , { ' request' , method_ , args_ , response })
180
202
end
181
203
204
+ -- Invoked when a notification is received from the remote end.
182
205
local function on_notification (method_ , args_ )
183
206
table.insert (self ._pending_messages , { ' notification' , method_ , args_ })
184
207
end
185
208
186
- self ._msgpack_rpc_stream :write (method , args , function (e , r )
209
+ self ._rpc_stream :write (method , args , function (e , r )
187
210
err = e
188
211
result = r
189
212
uv .stop ()
190
213
end )
191
214
215
+ -- Poll for incoming requests/notifications received from the remote end.
192
216
self :_run (on_request , on_notification )
193
217
return (err or self .eof_err ), result
194
218
end
195
219
220
+ --- Polls for incoming requests/notifications received from the remote end.
196
221
function Session :_run (request_cb , notification_cb , timeout )
197
222
if type (timeout ) == ' number' then
198
223
self ._prepare :start (function ()
@@ -202,14 +227,21 @@ function Session:_run(request_cb, notification_cb, timeout)
202
227
self ._prepare :stop ()
203
228
end )
204
229
end
205
- self ._msgpack_rpc_stream :read_start (request_cb , notification_cb , function ()
230
+ self ._rpc_stream :read_start (request_cb , notification_cb , function ()
206
231
uv .stop ()
207
- self .eof_err = { 1 , ' EOF was received from Nvim. Likely the Nvim process crashed.' }
232
+
233
+ --- @diagnostic disable-next-line : invisible
234
+ local stderr = self ._rpc_stream ._stream .stderr --[[ @as string?]]
235
+ -- See if `ProcStream.stderr` has anything useful.
236
+ stderr = ' ' ~= ((stderr or ' ' ):match (' ^%s*(.*%S)' ) or ' ' ) and ' stderr:\n ' .. stderr or ' '
237
+
238
+ self .eof_err = { 1 , ' EOF was received from Nvim. Likely the Nvim process crashed.' .. stderr }
208
239
end )
209
240
uv .run ()
210
241
self ._prepare :stop ()
211
242
self ._timer :stop ()
212
- self ._msgpack_rpc_stream :read_stop ()
243
+ self ._rpc_stream :read_stop ()
213
244
end
214
245
246
+ --- Nvim msgpack-RPC session.
215
247
return Session
0 commit comments