@@ -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
@@ -151,7 +146,7 @@ function! s:BufferText(bufnr) abort
151146endfunction
152147
153148function ! s: LogMessage (params) abort
154- call copilot#logger#Raw (get (a: params , ' level ' , 3 ), get (a: params , ' message' , ' ' ))
149+ call copilot#logger#Raw (get (a: params , ' type ' , 6 ), get (a: params , ' message' , ' ' ))
155150endfunction
156151
157152function ! s: ShowMessageRequest (params) abort
@@ -294,7 +289,9 @@ function! s:OnResponse(agent, response, ...) abort
294289endfunction
295290
296291function ! s: OnErr (agent, line , ... ) abort
297- call copilot#logger#Debug (' <-! ' . a: line )
292+ if ! has_key (a: agent , ' capabilities' )
293+ call copilot#logger#Bare (' <-! ' . a: line )
294+ endif
298295endfunction
299296
300297function ! s: OnExit (agent, code, ... ) abort
@@ -318,7 +315,7 @@ function! copilot#agent#LspInit(agent_id, initialize_result) abort
318315 return
319316 endif
320317 let instance = s: instances [a: agent_id ]
321- call timer_start (0 , { _ - > s: GetCapabilitiesResult (a: initialize_result , instance)})
318+ call timer_start (0 , { _ - > s: InitializeResult (a: initialize_result , instance)})
322319endfunction
323320
324321function ! copilot#agent#LspExit (agent_id, code, signal) abort
@@ -383,11 +380,16 @@ function! s:Command() abort
383380 return [v: null , ' ' , ' Vim version too old' ]
384381 endif
385382 let agent = get (g: , ' copilot_agent_command' , ' ' )
386- if empty (agent) || ! filereadable (agent)
387- let agent = s: root . ' /dist/agent.js'
388- 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 ])
389389 return [v: null , ' ' , ' Could not find dist/agent.js (bad install?)' ]
390390 endif
391+ elseif agent[0 ] !~# ' \.js$'
392+ return [agent + [' --stdio' ], ' ' , ' ' ]
391393 endif
392394 let node = get (g: , ' copilot_node_command' , ' ' )
393395 if empty (node)
@@ -403,7 +405,7 @@ function! s:Command() abort
403405 endif
404406 endif
405407 if get (g: , ' copilot_ignore_node_version' )
406- return [node + [ agent, ' --stdio' ], ' ' , ' ' ]
408+ return [node + agent + [ ' --stdio' ], ' ' , ' ' ]
407409 endif
408410 let node_version = s: GetNodeVersion (node)
409411 let warning = ' '
@@ -426,57 +428,50 @@ function! s:Command() abort
426428 return [v: null , node_version.string , ' Node.js version 18.x or newer required but found ' . node_version.string ]
427429 endif
428430 endif
429- return [node + [ agent, ' --stdio' ], node_version.string , warning]
431+ return [node + agent + [ ' --stdio' ], node_version.string , warning]
430432endfunction
431433
432434function ! s: UrlDecode (str) abort
433435 return substitute (a: str , ' %\(\x\x\)' , ' \=iconv(nr2char("0x".submatch(1)), "utf-8", "latin1")' , ' g' )
434436endfunction
435437
436- function ! copilot#agent# EditorInfo () abort
438+ function ! s: EditorInfo () abort
437439 if ! exists (' s:editor_version' )
438440 if has (' nvim' )
439441 let s: editor_version = matchstr (execute (' version' ), ' NVIM v\zs[^[:space:]]\+' )
440442 else
441443 let s: editor_version = (v: version / 100 ) . ' .' . (v: version % 100 ) . (exists (' v:versionlong' ) ? printf (' .%04d' , v: versionlong % 1000 ) : ' ' )
442444 endif
443445 endif
444- let info = {
445- \ ' editorInfo' : {' name' : has (' nvim' ) ? ' Neovim' : ' Vim' , ' version' : s: editor_version },
446- \ ' editorPluginInfo' : {' name' : ' copilot.vim' , ' version' : s: plugin_version }}
447- if type (get (g: , ' copilot_proxy' )) == v: t_string
448- let proxy = g: copilot_proxy
449- else
450- let proxy = ' '
451- endif
452- let match = matchlist (proxy, ' \c^\%([^:]\+://\)\=\%(\([^/#]\+@\)\)\=\%(\([^/:#]\+\)\|\[\([[:xdigit:]:]\+\)\]\)\%(:\(\d\+\)\)\=\%(/\|$\|?strict_\=ssl=\(.*\)\)' )
453- if ! empty (match )
454- let info.networkProxy = {' host' : match [2 ] . match [3 ], ' port' : empty (match [4 ]) ? 80 : + match [4 ]}
455- if match [5 ] = ~? ' ^[0f]'
456- let info.networkProxy.rejectUnauthorized = v: false
457- elseif match [5 ] = ~? ' ^[1t]'
458- let info.networkProxy.rejectUnauthorized = v: true
459- elseif exists (' g:copilot_proxy_strict_ssl' )
460- let info.networkProxy.rejectUnauthorized = empty (g: copilot_proxy_strict_ssl ) ? v: false : v: true
461- endif
462- if ! empty (match [1 ])
463- let info.networkProxy.username = s: UrlDecode (matchstr (match [1 ], ' ^[^:@]*' ))
464- let info.networkProxy.password = s: UrlDecode (matchstr (match [1 ], ' :\zs[^@]*' ))
465- 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
466458 endif
467- if type (get (g: , ' copilot_auth_provider_url ' )) == v: t_string
468- 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 )
469461 endif
470- return info
462+ return settings
471463endfunction
472464
473- function ! s: GetCapabilitiesResult (result, agent) abort
465+ function ! s: InitializeResult (result, agent) abort
474466 let a: agent .capabilities = get (a: result , ' capabilities' , {})
475- let info = copilot#agent#EditorInfo ()
476- 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)
477472endfunction
478473
479- function ! s: GetCapabilitiesError (error , agent) abort
474+ function ! s: InitializeError (error , agent) abort
480475 if a: error .code == s: error_exit
481476 let a: agent .startup_error = ' Agent exited with status ' . a: error .data.status
482477 else
@@ -508,7 +503,6 @@ function! copilot#agent#New(...) abort
508503 \ ' StartupError' : function (' s:AgentStartupError' ),
509504 \ }
510505 let instance.methods = extend ({
511- \ ' LogMessage' : function (' s:LogMessage' ),
512506 \ ' window/logMessage' : function (' s:LogMessage' ),
513507 \ }, get (opts, ' methods' , {}))
514508 let [command , node_version, command_error] = s: Command ()
@@ -524,12 +518,18 @@ function! copilot#agent#New(...) abort
524518 if ! empty (node_version)
525519 let instance.node_version = node_version
526520 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
527527 if has (' nvim' )
528528 call extend (instance, {
529529 \ ' Close' : function (' s:LspClose' ),
530530 \ ' Notify' : function (' s:LspNotify' ),
531531 \ ' Request' : function (' s:LspRequest' )})
532- 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 )" )
533533 let instance.id = instance.client_id
534534 else
535535 let state = {' headers' : {}, ' mode' : ' headers' , ' buffer' : ' ' }
@@ -543,14 +543,13 @@ function! copilot#agent#New(...) abort
543543 \ ' err_cb' : { j , d - > timer_start (0 , function (' s:OnErr' , [instance, d ])) },
544544 \ ' exit_cb' : { j , d - > timer_start (0 , function (' s:OnExit' , [instance, d ])) },
545545 \ })
546- let instance.id = exists (' *jobpid' ) ? jobpid (instance.job) : job_info (instance.job).process
547- let capabilities = {' workspace' : {' workspaceFolders' : v: true }, ' copilot' : {}}
548- for name in keys (instance.methods)
549- if name = ~# ' ^copilot/'
550- let capabilities.copilot[matchstr (name, ' /\zs.*' )] = v: true
551- endif
552- endfor
553- 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)
554553 endif
555554 let s: instances [instance.id] = instance
556555 return instance
0 commit comments