@@ -15,24 +15,19 @@ if has('nvim')
1515 lua package.loaded._copilot = nil
1616endif
1717
18- let s: jobstop = function (exists (' *jobstop' ) ? ' jobstop' : ' job_stop' )
19- function ! s: Kill (agent, ... ) abort
20- if has_key (a: agent , ' job' )
21- call s: jobstop (a: agent .job)
22- endif
23- endfunction
24-
2518function ! s: AgentClose () dict abort
2619 if ! has_key (self , ' job' )
2720 return
2821 endif
29- if exists (' *chanclose' )
30- call chanclose (self .job, ' stdin' )
31- else
32- call ch_close_in (self .job)
22+ let job = self .job
23+ if has_key (self , ' shutdown' )
24+ call job_stop (job, ' kill' )
25+ call copilot#logger#Warn (' agent forcefully terminated' )
26+ return
3327 endif
34- call copilot#logger#Info (' agent stopped' )
35- call timer_start (2000 , function (' s:Kill' , [self ]))
28+ let self .shutdown = self .Request (' shutdown' , {}, function (self .Notify, [' exit' ]))
29+ call timer_start (2000 , { _ - > job_stop (job, ' kill' ) })
30+ call copilot#logger#Debug (' agent shutdown initiated' )
3631endfunction
3732
3833function ! s: LogSend (request, line ) abort
@@ -320,7 +315,7 @@ function! copilot#agent#LspInit(agent_id, initialize_result) abort
320315 return
321316 endif
322317 let instance = s: instances [a: agent_id ]
323- call timer_start (0 , { _ - > s: GetCapabilitiesResult (a: initialize_result , instance)})
318+ call timer_start (0 , { _ - > s: InitializeResult (a: initialize_result , instance)})
324319endfunction
325320
326321function ! copilot#agent#LspExit (agent_id, code, signal) abort
@@ -385,11 +380,16 @@ function! s:Command() abort
385380 return [v: null , ' ' , ' Vim version too old' ]
386381 endif
387382 let agent = get (g: , ' copilot_agent_command' , ' ' )
388- if empty (agent) || ! filereadable (agent)
389- let agent = s: root . ' /dist/agent.js'
390- if ! filereadable (agent)
383+ if type (agent) == type (' ' )
384+ let agent = [expand (agent)]
385+ endif
386+ if empty (agent) || ! filereadable (agent[0 ])
387+ let agent = [s: root . ' /dist/agent.js' ]
388+ if ! filereadable (agent[0 ])
391389 return [v: null , ' ' , ' Could not find dist/agent.js (bad install?)' ]
392390 endif
391+ elseif agent[0 ] !~# ' \.js$'
392+ return [agent + [' --stdio' ], ' ' , ' ' ]
393393 endif
394394 let node = get (g: , ' copilot_node_command' , ' ' )
395395 if empty (node)
@@ -405,7 +405,7 @@ function! s:Command() abort
405405 endif
406406 endif
407407 if get (g: , ' copilot_ignore_node_version' )
408- return [node + [ agent, ' --stdio' ], ' ' , ' ' ]
408+ return [node + agent + [ ' --stdio' ], ' ' , ' ' ]
409409 endif
410410 let node_version = s: GetNodeVersion (node)
411411 let warning = ' '
@@ -435,50 +435,43 @@ function! s:UrlDecode(str) abort
435435 return substitute (a: str , ' %\(\x\x\)' , ' \=iconv(nr2char("0x".submatch(1)), "utf-8", "latin1")' , ' g' )
436436endfunction
437437
438- function ! copilot#agent# EditorInfo () abort
438+ function ! s: EditorInfo () abort
439439 if ! exists (' s:editor_version' )
440440 if has (' nvim' )
441441 let s: editor_version = matchstr (execute (' version' ), ' NVIM v\zs[^[:space:]]\+' )
442442 else
443443 let s: editor_version = (v: version / 100 ) . ' .' . (v: version % 100 ) . (exists (' v:versionlong' ) ? printf (' .%04d' , v: versionlong % 1000 ) : ' ' )
444444 endif
445445 endif
446- let info = {
447- \ ' editorInfo' : {' name' : has (' nvim' ) ? ' Neovim' : ' Vim' , ' version' : s: editor_version },
448- \ ' editorPluginInfo' : {' name' : ' copilot.vim' , ' version' : s: plugin_version }}
449- if type (get (g: , ' copilot_proxy' )) == v: t_string
450- let proxy = g: copilot_proxy
451- else
452- let proxy = ' '
453- endif
454- let match = matchlist (proxy, ' \c^\%([^:]\+://\)\=\%(\([^/#]\+@\)\)\=\%(\([^/:#]\+\)\|\[\([[:xdigit:]:]\+\)\]\)\%(:\(\d\+\)\)\=\%(/\|$\|?strict_\=ssl=\(.*\)\)' )
455- if ! empty (match )
456- let info.networkProxy = {' host' : match [2 ] . match [3 ], ' port' : empty (match [4 ]) ? 80 : + match [4 ]}
457- if match [5 ] = ~? ' ^[0f]'
458- let info.networkProxy.rejectUnauthorized = v: false
459- elseif match [5 ] = ~? ' ^[1t]'
460- let info.networkProxy.rejectUnauthorized = v: true
461- elseif exists (' g:copilot_proxy_strict_ssl' )
462- let info.networkProxy.rejectUnauthorized = empty (g: copilot_proxy_strict_ssl ) ? v: false : v: true
463- endif
464- if ! empty (match [1 ])
465- let info.networkProxy.username = s: UrlDecode (matchstr (match [1 ], ' ^[^:@]*' ))
466- let info.networkProxy.password = s: UrlDecode (matchstr (match [1 ], ' :\zs[^@]*' ))
467- endif
446+ return {' name' : has (' nvim' ) ? ' Neovim' : ' Vim' , ' version' : s: editor_version }
447+ endfunction
448+
449+ function ! copilot#agent#Settings () abort
450+ let settings = {
451+ \ ' http' : {
452+ \ ' proxy' : get (g: , ' copilot_proxy' , v: null ),
453+ \ ' proxyStrictSSL' : get (g: , ' copilot_proxy_strict_ssl' , v: null )},
454+ \ ' github-enterprise' : {' uri' : get (g: , ' copilot_auth_provider_url' , v: null )},
455+ \ }
456+ if type (settings.http.proxy) == # v: t_string && settings.http.proxy = ~# ' ^[^/]\+$'
457+ let settings.http.proxy = ' http://' . settings.http.proxy
468458 endif
469- if type (get (g: , ' copilot_auth_provider_url ' )) == v: t_string
470- let info.authProvider = { ' url ' : g: copilot_auth_provider_url }
459+ if type (get (g: , ' copilot_settings ' )) == v: t_dict
460+ call extend (settings, g: copilot_settings )
471461 endif
472- return info
462+ return settings
473463endfunction
474464
475- function ! s: GetCapabilitiesResult (result, agent) abort
465+ function ! s: InitializeResult (result, agent) abort
476466 let a: agent .capabilities = get (a: result , ' capabilities' , {})
477- let info = copilot#agent#EditorInfo ()
478- call a: agent .Request (' setEditorInfo' , extend ({' editorConfiguration' : a: agent .editorConfiguration}, info))
467+ let info = {
468+ \ ' editorInfo' : s: EditorInfo (),
469+ \ ' editorPluginInfo' : {' name' : ' copilot.vim' , ' version' : s: plugin_version },
470+ \ ' editorConfiguration' : extend (copilot#agent#Settings (), a: agent .editorConfiguration)}
471+ call a: agent .Request (' setEditorInfo' , info)
479472endfunction
480473
481- function ! s: GetCapabilitiesError (error , agent) abort
474+ function ! s: InitializeError (error , agent) abort
482475 if a: error .code == s: error_exit
483476 let a: agent .startup_error = ' Agent exited with status ' . a: error .data.status
484477 else
@@ -525,12 +518,18 @@ function! copilot#agent#New(...) abort
525518 if ! empty (node_version)
526519 let instance.node_version = node_version
527520 endif
521+ let initializationOptions = {' copilotCapabilities' : {}}
522+ for name in keys (instance.methods)
523+ if name = ~# ' ^copilot/'
524+ let initializationOptions.copilotCapabilities[matchstr (name, ' /\zs.*' )] = v: true
525+ endif
526+ endfor
528527 if has (' nvim' )
529528 call extend (instance, {
530529 \ ' Close' : function (' s:LspClose' ),
531530 \ ' Notify' : function (' s:LspNotify' ),
532531 \ ' Request' : function (' s:LspRequest' )})
533- let instance.client_id = eval (" v:lua.require'_copilot'.lsp_start_client(command, keys(instance.methods))" )
532+ let instance.client_id = eval (" v:lua.require'_copilot'.lsp_start_client(command, keys(instance.methods), initializationOptions )" )
534533 let instance.id = instance.client_id
535534 else
536535 let state = {' headers' : {}, ' mode' : ' headers' , ' buffer' : ' ' }
@@ -544,14 +543,13 @@ function! copilot#agent#New(...) abort
544543 \ ' err_cb' : { j , d - > timer_start (0 , function (' s:OnErr' , [instance, d ])) },
545544 \ ' exit_cb' : { j , d - > timer_start (0 , function (' s:OnExit' , [instance, d ])) },
546545 \ })
547- let instance.id = exists (' *jobpid' ) ? jobpid (instance.job) : job_info (instance.job).process
548- let capabilities = {' workspace' : {' workspaceFolders' : v: true }, ' copilot' : {}}
549- for name in keys (instance.methods)
550- if name = ~# ' ^copilot/'
551- let capabilities.copilot[matchstr (name, ' /\zs.*' )] = v: true
552- endif
553- endfor
554- let request = instance.Request (' initialize' , {' capabilities' : capabilities}, function (' s:GetCapabilitiesResult' ), function (' s:GetCapabilitiesError' ), instance)
546+ let instance.id = job_info (instance.job).process
547+ let opts = {
548+ \ ' capabilities' : {' workspace' : {' workspaceFolders' : v: true }},
549+ \ ' initializationOptions' : initializationOptions,
550+ \ ' processId' : getpid (),
551+ \ }
552+ let request = instance.Request (' initialize' , opts, function (' s:InitializeResult' ), function (' s:InitializeError' ), instance)
555553 endif
556554 let s: instances [instance.id] = instance
557555 return instance
0 commit comments