@@ -5,7 +5,7 @@ let g:autoloaded_copilot_agent = 1
55
66scriptencoding utf- 8
77
8- let s: plugin_version = ' 1.12.1 '
8+ let s: plugin_version = ' 1.13.0 '
99
1010let s: error_exit = -1
1111
@@ -44,14 +44,31 @@ function! s:LogSend(request, line) abort
4444 return ' --> ' . a: line
4545endfunction
4646
47+ function ! s: RejectRequest (request, error ) abort
48+ if a: request .status == # ' canceled'
49+ return
50+ endif
51+ let a: request .waiting = {}
52+ call remove (a: request , ' resolve' )
53+ let reject = remove (a: request , ' reject' )
54+ let a: request .status = ' error'
55+ let a: request .error = a: error
56+ for Cb in reject
57+ let a: request .waiting[timer_start (0 , function (' s:Callback' , [a: request , ' error' , Cb]))] = 1
58+ endfor
59+ endfunction
60+
4761function ! s: Send (agent, request) abort
48- call ch_sendexpr (a: agent .job, a: request )
49- return a: request
62+ try
63+ call ch_sendexpr (a: agent .job, a: request )
64+ return v: true
65+ catch /^Vim\%((\a\+)\)\=:E631:/
66+ return v: false
67+ endtry
5068endfunction
5169
5270function ! s: AgentNotify (method, params) dict abort
53- call s: Send (self , {' method' : a: method , ' params' : a: params })
54- return v: true
71+ return s: Send (self , {' method' : a: method , ' params' : a: params })
5572endfunction
5673
5774function ! s: RequestWait () dict abort
@@ -138,12 +155,22 @@ function! s:BufferText(bufnr) abort
138155 return join (getbufline (a: bufnr , 1 , ' $' ), " \n " ) . " \n "
139156endfunction
140157
158+ function ! s: LogMessage (params) abort
159+ call copilot#logger#Raw (get (a: params , ' level' , 3 ), get (a: params , ' message' , ' ' ))
160+ endfunction
161+
141162function ! s: ShowMessageRequest (params) abort
142163 let choice = inputlist ([a: params .message . " \n\n Request Actions:" ] +
143164 \ map (copy (get (a: params , ' actions' , [])), { i , v - > (i + 1 ) . ' . ' . v .title }))
144165 return choice > 0 ? get (a: params .actions, choice - 1 , v: null ) : v: null
145166endfunction
146167
168+ function ! s: SendRequest (agent, request) abort
169+ if empty (s: Send (a: agent , a: request )) && has_key (a: agent .requests, a: request .id)
170+ call s: RejectRequest (remove (a: agent .requests, a: request .id), {' code' : 257 , ' message' : ' Write failed' })
171+ endif
172+ endfunction
173+
147174function ! s: AgentRequest (method, params, ... ) dict abort
148175 let s: id += 1
149176 let request = {' method' : a: method , ' params' : deepcopy (a: params ), ' id' : s: id }
@@ -173,15 +200,15 @@ function! s:AgentRequest(method, params, ...) dict abort
173200 else
174201 let vtd_id = {
175202 \ ' uri' : doc.uri,
176- \ ' version' : getbufvar ( bufnr , ' changedtick ' ) }
203+ \ ' version' : doc_version }
177204 call self .Notify (' textDocument/didChange' , {
178205 \ ' textDocument' : vtd_id,
179206 \ ' contentChanges' : [{' text' : s: BufferText (bufnr )}]})
180- let self .open_buffers[bufnr ].version = version
207+ let self .open_buffers[bufnr ].version = doc_version
181208 endif
182209 let doc.version = doc_version
183210 endfor
184- call timer_start (0 , { _ - > s: Send (self , request) })
211+ call timer_start (0 , { _ - > s: SendRequest (self , request) })
185212 return call (' s:SetUpRequest' , [self , s: id , a: method , a: params ] + a: 000 )
186213endfunction
187214
@@ -216,13 +243,17 @@ endfunction
216243function ! s: DispatchMessage (agent, handler, id, params, ... ) abort
217244 try
218245 let response = {' result' : call (a: handler , [a: params ])}
246+ if response.result is # 0
247+ let response.result = v: null
248+ endif
219249 catch
220250 call copilot#logger#Exception ()
221251 let response = {' error' : {' code' : -32000 , ' message' : v: exception }}
222252 endtry
223253 if ! empty (a: id )
224254 call s: Send (a: agent , extend ({' id' : a: id }, response))
225255 endif
256+ return response
226257endfunction
227258
228259function ! s: OnMessage (agent, body, ... ) abort
@@ -232,16 +263,10 @@ function! s:OnMessage(agent, body, ...) abort
232263 let request = a: body
233264 let id = get (request, ' id' , v: null )
234265 let params = get (request, ' params' , v: null )
235- if empty (id)
236- if has_key (a: agent .notifications, request.method)
237- call timer_start (0 , { _ - > a: agent .notifications[request.method](params) })
238- elseif request.method == # ' LogMessage'
239- call copilot#logger#Raw (get (params, ' level' , 3 ), get (params, ' message' , ' ' ))
240- endif
241- elseif has_key (a: agent .methods, request.method)
242- call timer_start (0 , function (' s:DispatchMessage' , [a: agent , a: agent .methods[request.method], id, params]))
243- else
244- return s: Send (a: agent , {" id" : id, " error" : {" code" : -32700 , " message" : " Method not found: " . request.method}})
266+ if has_key (a: agent .methods, request.method)
267+ return s: DispatchMessage (a: agent , a: agent .methods[request.method], id, params)
268+ elseif ! empty (id)
269+ call s: Send (a: agent , {" id" : id, " error" : {" code" : -32700 , " message" : " Method not found: " . request.method}})
245270 endif
246271endfunction
247272
@@ -285,20 +310,9 @@ function! s:OnExit(agent, code, ...) abort
285310 if has_key (a: agent , ' client_id' )
286311 call remove (a: agent , ' client_id' )
287312 endif
313+ let code = a: code < 0 || a: code > 255 ? 256 : a: code
288314 for id in sort (keys (a: agent .requests), { a , b - > + a > + b })
289- let request = remove (a: agent .requests, id)
290- if request.status == # ' canceled'
291- return
292- endif
293- let request.waiting = {}
294- call remove (request, ' resolve' )
295- let reject = remove (request, ' reject' )
296- let request.status = ' error'
297- let code = a: code < 0 || a: code > 255 ? 256 : a: code
298- let request.error = {' code' : code, ' message' : ' Agent exited' , ' data' : {' status' : a: code }}
299- for Cb in reject
300- let request.waiting[timer_start (0 , function (' s:Callback' , [request, ' error' , Cb]))] = 1
301- endfor
315+ call s: RejectRequest (remove (a: agent .requests, id), {' code' : code, ' message' : ' Agent exited' , ' data' : {' status' : a: code }})
302316 endfor
303317 call timer_start (0 , { _ - > get (s: instances , a: agent .id) is # a: agent ? remove (s: instances , a: agent .id) : {} })
304318 call copilot#logger#Info (' agent exited with status ' . a: code )
@@ -353,7 +367,7 @@ function! copilot#agent#LspHandle(agent_id, request) abort
353367 if ! has_key (s: instances , a: agent_id )
354368 return
355369 endif
356- call s: OnMessage (s: instances [a: agent_id ], a: request )
370+ return s: OnMessage (s: instances [a: agent_id ], a: request )
357371endfunction
358372
359373function ! s: GetNodeVersion (command ) abort
@@ -484,8 +498,6 @@ endfunction
484498function ! copilot#agent#New (... ) abort
485499 let opts = a: 0 ? a: 1 : {}
486500 let instance = {' requests' : {},
487- \ ' methods' : get (opts, ' methods' , {}),
488- \ ' notifications' : get (opts, ' notifications' , {}),
489501 \ ' editorConfiguration' : get (opts, ' editorConfiguration' , {}),
490502 \ ' Close' : function (' s:AgentClose' ),
491503 \ ' Notify' : function (' s:AgentNotify' ),
@@ -494,6 +506,10 @@ function! copilot#agent#New(...) abort
494506 \ ' Cancel' : function (' s:AgentCancel' ),
495507 \ ' StartupError' : function (' s:AgentStartupError' ),
496508 \ }
509+ let instance.methods = extend ({
510+ \ ' LogMessage' : function (' s:LogMessage' ),
511+ \ ' window/logMessage' : function (' s:LogMessage' ),
512+ \ }, get (opts, ' methods' , {}))
497513 let [command , node_version, command_error] = s: Command ()
498514 if len (command_error)
499515 if empty (command )
@@ -510,7 +526,7 @@ function! copilot#agent#New(...) abort
510526 \ ' Close' : function (' s:LspClose' ),
511527 \ ' Notify' : function (' s:LspNotify' ),
512528 \ ' Request' : function (' s:LspRequest' )})
513- let instance.client_id = v: lua .require' _copilot' .lsp_start_client (command , keys (instance.notifications) + keys (instance. methods) + [ ' LogMessage ' ] )
529+ let instance.client_id = v: lua .require' _copilot' .lsp_start_client (command , keys (instance.methods))
514530 let instance.id = instance.client_id
515531 else
516532 let state = {' headers' : {}, ' mode' : ' headers' , ' buffer' : ' ' }
@@ -525,7 +541,13 @@ function! copilot#agent#New(...) abort
525541 \ ' exit_cb' : { j , d - > timer_start (0 , function (' s:OnExit' , [instance, d ])) },
526542 \ })
527543 let instance.id = exists (' *jobpid' ) ? jobpid (instance.job) : job_info (instance.job).process
528- let request = instance.Request (' initialize' , {' capabilities' : {' workspace' : {' workspaceFolders' : v: true }}}, function (' s:GetCapabilitiesResult' ), function (' s:GetCapabilitiesError' ), instance)
544+ let capabilities = {' workspace' : {' workspaceFolders' : v: true }, ' copilot' : {}}
545+ for name in keys (instance.methods)
546+ if name = ~# ' ^copilot/'
547+ let capabilities.copilot[matchstr (name, ' /\zs.*' )] = v: true
548+ endif
549+ endfor
550+ let request = instance.Request (' initialize' , {' capabilities' : capabilities}, function (' s:GetCapabilitiesResult' ), function (' s:GetCapabilitiesError' ), instance)
529551 endif
530552 let s: instances [instance.id] = instance
531553 return instance
0 commit comments