Skip to content

Commit b12d145

Browse files
authored
Merge branch 'github:release' into release
2 parents 99a7a64 + a12fd56 commit b12d145

File tree

14 files changed

+1673
-1050
lines changed

14 files changed

+1673
-1050
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ request access from your enterprise admin.
2020

2121
1. Install [Neovim][] or the latest patch of [Vim][] (9.0.0185 or newer).
2222

23-
2. Install [Node.js][].
23+
2. Install [Node.js][]. If you use a package manager, make sure to install
24+
NPM as well (e.g., `apt install nodejs npm` on Debian/Ubuntu).
2425

2526
3. Install `github/copilot.vim` using vim-plug, lazy.nvim, or any other
2627
plugin manager. Or to install manually, run one of the following

autoload/copilot.vim

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -536,10 +536,6 @@ function! copilot#AcceptLine(...) abort
536536
return copilot#Accept(a:0 ? a:1 : "\r", "[^\n]\\+")
537537
endfunction
538538

539-
function! s:BrowserCallback(into, code) abort
540-
let a:into.code = a:code
541-
endfunction
542-
543539
function! copilot#Browser() abort
544540
if type(get(g:, 'copilot_browser')) == v:t_list
545541
let cmd = copy(g:copilot_browser)
@@ -730,19 +726,37 @@ function! s:commands.version(opts) abort
730726
call s:EditorVersionWarning()
731727
endfunction
732728

733-
let s:feedback_url = 'https://github.com/github/copilot.vim/issues'
734-
function! s:commands.feedback(opts) abort
735-
echo s:feedback_url
736-
let browser = copilot#Browser()
737-
if len(browser)
738-
call copilot#job#Stream(browser + [s:feedback_url], v:null, v:null, v:null)
729+
function! s:commands.restart(opts) abort
730+
call s:Stop()
731+
echo 'Copilot: Restarting language server'
732+
call s:Start()
733+
endfunction
734+
735+
function! s:AfterUpgrade(old_version, client) abort
736+
if exists('a:client.serverInfo.version')
737+
call s:Echo('Copilot: Upgraded language server to ' . a:client.serverInfo.version)
738+
let g:copilot_version = '^' . a:client.serverInfo.version
739+
else
740+
call s:Echo('Copilot: Failed to upgrade language server. Check log for details')
741+
let g:copilot_version = a:old_version
742+
if a:old_version is v:null
743+
unlet g:copilot_version
744+
endif
745+
call s:Start()
739746
endif
740747
endfunction
741748

742-
function! s:commands.restart(opts) abort
749+
function! s:commands.upgrade(opts) abort
750+
if exists('s:client.serverInfo.version')
751+
echo 'Copilot: Upgrading language server from version ' . s:client.serverInfo.version
752+
else
753+
echo 'Copilot: Upgrading language server'
754+
endif
755+
let old_version = get(g:, 'copilot_version', v:null)
756+
let g:copilot_version = 'latest'
743757
call s:Stop()
744-
echo 'Copilot: Restarting language server'
745758
call s:Start()
759+
call s:client.AfterInitialized(function('s:AfterUpgrade', [old_version]))
746760
endfunction
747761

748762
function! s:commands.disable(opts) abort
@@ -759,6 +773,41 @@ function! s:commands.panel(opts) abort
759773
endif
760774
endfunction
761775

776+
function! s:FmtModel(model) abort
777+
return a:model.modelName . ' (' . a:model.id . ')'
778+
endfunction
779+
780+
function! s:commands.model(opts) abort
781+
if !s:VerifySetup()
782+
return
783+
endif
784+
let client = copilot#Client()
785+
let response = client.Request('copilot/models', {}).Wait()
786+
if response.status ==# 'error'
787+
return 'echoerr ' . string('Copilot: Error retrieving completions models: ' . response.error.message)
788+
endif
789+
let models = filter(response.result, { _, m -> index(m.scopes, 'completion') >= 0 })
790+
if len(models) == 0
791+
echo 'Copilot: Could not retrieve completions models'
792+
elseif len(models) == 1
793+
echo 'Copilot: Current/only completions model is ' . s:FmtModel(models[0])
794+
else
795+
let choices = map(copy(models), { i, m -> (i + 1) . '. ' . s:FmtModel(m) })
796+
let choice = inputlist(['Select a completions model:'] + choices)
797+
if choice < 1 || choice > len(models)
798+
return
799+
endif
800+
let model = models[choice - 1]
801+
if type(get(g:, 'copilot_settings')) != v:t_dict
802+
let g:copilot_settings = {}
803+
endif
804+
let g:copilot_settings.selectedCompletionModel = model.id
805+
redraw
806+
echo 'Copilot: Set completions model to ' . s:FmtModel(model)
807+
call client.DidChangeConfiguration()
808+
endif
809+
endfunction
810+
762811
function! s:commands.log(opts) abort
763812
return a:opts.mods . ' split +$ copilot:///log'
764813
endfunction

autoload/copilot/client.vim

Lines changed: 87 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ function! s:RejectRequest(request, error) abort
7070
endfunction
7171

7272
function! s:AfterInitialized(fn, ...) dict abort
73-
call add(self.after_initialized, function(a:fn, a:000))
73+
call add(self.after_initialized, function(a:fn, [self] + a:000))
74+
endfunction
75+
76+
function! s:AlreadyInitialized(fn, ...) dict abort
77+
return copilot#util#Defer(function(a:fn, [self] + a:000))
7478
endfunction
7579

7680
function! s:Send(instance, request) abort
@@ -94,7 +98,7 @@ endfunction
9498

9599
function! s:VimNotify(method, params) dict abort
96100
let request = {'method': a:method, 'params': a:params}
97-
call self.AfterInitialized(function('s:Send', [self, request]))
101+
call self.AfterInitialized(function('s:Send'), request)
98102
endfunction
99103

100104
function! s:RequestWait() dict abort
@@ -269,7 +273,7 @@ function! s:VimRequest(method, params, ...) dict abort
269273
let params = deepcopy(a:params)
270274
let [_, progress] = s:PreprocessParams(self, params)
271275
let request = call('s:SetUpRequest', [self, s:id, a:method, params, progress] + a:000)
272-
call self.AfterInitialized(function('s:SendRequest', [self, request]))
276+
call self.AfterInitialized(function('s:SendRequest'), request)
273277
let self.requests[s:id] = request
274278
return request
275279
endfunction
@@ -369,6 +373,15 @@ function! s:OnErr(instance, ch, line, ...) abort
369373
endif
370374
endfunction
371375

376+
function! s:FlushAfterInitialized(instance) abort
377+
if has_key(a:instance, 'after_initialized')
378+
let a:instance.AfterInitialized = function('s:AlreadyInitialized')
379+
for Fn in remove(a:instance, 'after_initialized')
380+
call copilot#util#Defer(Fn)
381+
endfor
382+
endif
383+
endfunction
384+
372385
function! s:OnExit(instance, code, ...) abort
373386
let a:instance.exit_status = a:code
374387
if has_key(a:instance, 'job')
@@ -389,12 +402,7 @@ function! s:OnExit(instance, code, ...) abort
389402
for id in sort(keys(a:instance.requests), { a, b -> +a > +b })
390403
call s:RejectRequest(remove(a:instance.requests, id), s:error_exit)
391404
endfor
392-
if has_key(a:instance, 'after_initialized')
393-
let a:instance.AfterInitialized = function('copilot#util#Defer')
394-
for Fn in remove(a:instance, 'after_initialized')
395-
call copilot#util#Defer(Fn)
396-
endfor
397-
endif
405+
call s:FlushAfterInitialized(a:instance)
398406
call copilot#util#Defer({ -> get(s:instances, a:instance.id) is# a:instance ? remove(s:instances, a:instance.id) : {} })
399407
if a:code == 0
400408
call copilot#logger#Info(message)
@@ -444,7 +452,7 @@ function! s:NvimRequest(method, params, ...) dict abort
444452
let params = deepcopy(a:params)
445453
let [bufnr, progress] = s:PreprocessParams(self, params)
446454
let request = call('s:SetUpRequest', [self, v:null, a:method, params, progress] + a:000)
447-
call self.AfterInitialized(function('s:NvimDoRequest', [self, request, bufnr]))
455+
call self.AfterInitialized(function('s:NvimDoRequest'), request, bufnr)
448456
return request
449457
endfunction
450458

@@ -473,11 +481,11 @@ function! s:NvimClose() dict abort
473481
endfunction
474482

475483
function! s:NvimNotify(method, params) dict abort
476-
call self.AfterInitialized(function('s:NvimDoNotify', [self.client_id, a:method, a:params]))
484+
call self.AfterInitialized(function('s:NvimDoNotify'), a:method, a:params)
477485
endfunction
478486

479-
function! s:NvimDoNotify(client_id, method, params) abort
480-
return eval("v:lua.require'_copilot'.rpc_notify(a:client_id, a:method, a:params)")
487+
function! s:NvimDoNotify(client, method, params) abort
488+
return eval("v:lua.require'_copilot'.rpc_notify(a:client.id, a:method, a:params)")
481489
endfunction
482490

483491
function! copilot#client#LspHandle(id, request) abort
@@ -488,7 +496,19 @@ function! copilot#client#LspHandle(id, request) abort
488496
endfunction
489497

490498
function! s:PackageVersion() abort
491-
return json_decode(join(readfile(s:root . '/copilot-language-server/package.json'))).version
499+
try
500+
return json_decode(join(readfile(s:root . '/copilot-language-server/package.json'))).version
501+
catch
502+
endtry
503+
return ''
504+
endfunction
505+
506+
function! s:GetCommand(var, default) abort
507+
let cmd = get(g:, a:var, '')
508+
if type(cmd) == type('') && !empty(cmd)
509+
return [expand(cmd)]
510+
endif
511+
return type(cmd) == v:t_list && !empty(cmd) ? copy(cmd) : a:default
492512
endfunction
493513

494514
let s:script_name = 'copilot-language-server/dist/language-server.js'
@@ -497,11 +517,14 @@ function! s:Command() abort
497517
if !has('nvim-0.8') && v:version < 900
498518
return [[], [], 'Vim version too old']
499519
endif
500-
let script = get(g:, 'copilot_command', [])
501-
if type(script) == type('')
502-
let script = empty(script) ? [] : [expand(script)]
520+
let script = s:GetCommand('copilot_command', [])
521+
let npx = get(g:, 'copilot_version', get(g:, 'copilot_npx', v:null))
522+
if npx is# v:null
523+
let npx = empty(script) && !empty(get(g:, 'copilot_npx_command', 1)) ? v:true : v:false
524+
endif
525+
if type(npx) != v:t_string && !empty(npx)
526+
let npx = ''
503527
endif
504-
let npx = get(g:, 'copilot_npx', v:false)
505528
if type(npx) == v:t_string
506529
if empty(npx)
507530
let npx = '^'
@@ -513,11 +536,17 @@ function! s:Command() abort
513536
let npx = s:pkg_name . npx
514537
endif
515538
if npx =~# '@[~<>=^]\+$'
516-
let npx .= s:PackageVersion()
539+
let pkg_version = s:PackageVersion()
540+
if pkg_version =~# '^[1-9]'
541+
let npx .= pkg_version
542+
else
543+
let npx = substitute(npx, '@[=~]$', '@^', '') . '1.0.0'
544+
endif
545+
endif
546+
let script = s:GetCommand('copilot_npx_command', ['npx']) + [npx]
547+
if !executable(script[0])
548+
let script = []
517549
endif
518-
let script = ['npx', npx]
519-
elseif !empty(npx)
520-
let script = ['npx', s:pkg_name . '@^' . s:PackageVersion()]
521550
endif
522551
if empty(script)
523552
let script = [s:root . '/' . s:script_name]
@@ -527,12 +556,7 @@ function! s:Command() abort
527556
elseif !filereadable(script[0])
528557
return [[], [], 'Could not find ' . script[0]]
529558
endif
530-
let node = get(g:, 'copilot_node_command', '')
531-
if empty(node)
532-
let node = ['node']
533-
elseif type(node) == type('')
534-
let node = [expand(node)]
535-
endif
559+
let node = s:GetCommand('copilot_node_command', ['node'])
536560
if !executable(get(node, 0, ''))
537561
if get(node, 0, '') ==# 'node'
538562
return [[], [], 'Node.js not found in PATH']
@@ -586,10 +610,7 @@ function! s:PostInit(result, instance) abort
586610
if !has_key(a:instance, 'node_version') && has_key(a:result.serverInfo, 'nodeVersion')
587611
let a:instance.node_version = a:result.serverInfo.nodeVersion
588612
endif
589-
let a:instance.AfterInitialized = function('copilot#util#Defer')
590-
for Fn in remove(a:instance, 'after_initialized')
591-
call copilot#util#Defer(Fn)
592-
endfor
613+
call s:FlushAfterInitialized(a:instance)
593614
endfunction
594615

595616
function! s:InitializeResult(result, instance) abort
@@ -615,6 +636,16 @@ function! s:StartupError() dict abort
615636
endif
616637
endfunction
617638

639+
function! s:VimDidChangeConfiguration() dict abort
640+
let settings = copilot#client#Settings()
641+
return self.Notify('workspace/didChangeConfiguration', {'settings': settings})
642+
endfunction
643+
644+
function! s:NvimDidChangeConfiguration() dict abort
645+
let settings = copilot#client#Settings()
646+
return eval("v:lua.require'_copilot'.did_change_configuration(self.id, settings)")
647+
endfunction
648+
618649
function! s:StatusNotification(params, instance) abort
619650
let a:instance.status = a:params
620651
endfunction
@@ -666,6 +697,7 @@ function! copilot#client#New() abort
666697
\ 'IsAttached': function('s:False'),
667698
\ 'Call': function('s:Call'),
668699
\ 'Cancel': function('s:Cancel'),
700+
\ 'DidChangeConfiguration': function('s:VimDidChangeConfiguration'),
669701
\ 'StartupError': function('s:StartupError'),
670702
\ }
671703
let instance.methods = copy(s:notifications)
@@ -674,6 +706,7 @@ function! copilot#client#New() abort
674706
let instance.id = -1
675707
let instance.startup_error = command_error
676708
call copilot#logger#Error(command_error)
709+
call s:FlushAfterInitialized(instance)
677710
return instance
678711
endif
679712
let instance.node = node
@@ -703,17 +736,38 @@ function! copilot#client#New() abort
703736
let instance.workspaceFolders[folder.uri] = v:true
704737
endfor
705738
call copilot#logger#Debug('Spawning ' . join(command, ' '))
739+
let is_win_shell = has('win32') && &shellcmdflag !~# '^-'
740+
if is_win_shell && command[0] !~# '[\/]'
741+
let exepath = exepath(command[0])
742+
if exepath !~? '\.exe$\|^$'
743+
let command[0] = fnamemodify(exepath, ':t')
744+
endif
745+
endif
706746
if has('nvim')
747+
if is_win_shell
748+
call map(command, { _, v -> substitute(v, '\^', '^^^^', 'g') })
749+
endif
707750
call extend(instance, {
708751
\ 'Close': function('s:NvimClose'),
709752
\ 'Notify': function('s:NvimNotify'),
710753
\ 'Request': function('s:NvimRequest'),
711754
\ 'Attach': function('s:NvimAttach'),
755+
\ 'DidChangeConfiguration': function('s:NvimDidChangeConfiguration'),
712756
\ 'IsAttached': function('s:NvimIsAttached'),
713757
\ })
714-
let instance.client_id = eval("v:lua.require'_copilot'.lsp_start_client(command, instance.name, keys(instance.methods), opts, settings)")
758+
let id = eval("v:lua.require'_copilot'.lsp_start_client(command, instance.name, keys(instance.methods), opts, settings)")
759+
if id is# v:null
760+
let instance.id = -1
761+
let instance.startup_error = 'Neovim failed to start LSP client'
762+
call s:FlushAfterInitialized(instance)
763+
return instance
764+
endif
765+
let instance.client_id = id
715766
let instance.id = instance.client_id
716767
else
768+
if is_win_shell
769+
let command = join(map(command, { _, v -> v =~# '[;&|^ ]' ? '"' . v . '"' : v }), ' ')
770+
endif
717771
call extend(instance, {
718772
\ 'Close': function('s:VimClose'),
719773
\ 'Notify': function('s:VimNotify'),

autoload/copilot/version.vim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
function! copilot#version#String() abort
2-
return '1.57.0'
2+
return '1.59.0'
33
endfunction

0 commit comments

Comments
 (0)