Skip to content

Commit f45ecd9

Browse files
committed
Copilot.vim 1.28.0
1 parent 7097b09 commit f45ecd9

File tree

10 files changed

+477
-495
lines changed

10 files changed

+477
-495
lines changed

autoload/copilot.vim

Lines changed: 46 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -131,20 +131,7 @@ function! copilot#Clear() abort
131131
return ''
132132
endfunction
133133

134-
function! s:Reject(bufnr) abort
135-
try
136-
let dict = getbufvar(a:bufnr, '_copilot')
137-
if type(dict) == v:t_dict && !empty(get(dict, 'shown_choices', {}))
138-
call copilot#Request('notifyRejected', {'uuids': keys(dict.shown_choices)})
139-
let dict.shown_choices = {}
140-
endif
141-
catch
142-
call copilot#logger#Exception()
143-
endtry
144-
endfunction
145-
146134
function! copilot#Dismiss() abort
147-
call s:Reject('%')
148135
call copilot#Clear()
149136
call s:UpdatePreview()
150137
return ''
@@ -189,20 +176,30 @@ function! copilot#Enabled() abort
189176
\ && empty(s:BufferDisabled())
190177
endfunction
191178

179+
let s:inline_invoked = 0
180+
let s:inline_automatic = 1
181+
192182
function! copilot#Complete(...) abort
193183
if exists('g:_copilot_timer')
194184
call timer_stop(remove(g:, '_copilot_timer'))
195185
endif
196-
let params = copilot#doc#Params()
197-
if !exists('b:_copilot.params') || b:_copilot.params !=# params
186+
let target = [bufnr(''), getbufvar('', 'changedtick'), line('.'), col('.')]
187+
if !exists('b:_copilot.target') || b:_copilot.target !=# target
198188
if exists('b:_copilot.first')
199189
call copilot#agent#Cancel(b:_copilot.first)
200190
endif
201191
if exists('b:_copilot.cycling')
202192
call copilot#agent#Cancel(b:_copilot.cycling)
203193
endif
204-
let b:_copilot = {'params': params, 'first':
205-
\ copilot#Request('getCompletions', params)}
194+
let params = {
195+
\ 'textDocument': {'uri': bufnr('')},
196+
\ 'position': copilot#util#AppendPosition(),
197+
\ 'formattingOptions': {'insertSpaces': &expandtab ? v:true : v:false, 'tabSize': shiftwidth()},
198+
\ 'context': {'triggerKind': s:inline_automatic}}
199+
let b:_copilot = {
200+
\ 'target': target,
201+
\ 'params': params,
202+
\ 'first': copilot#Request('textDocument/inlineCompletion', params)}
206203
let g:_copilot_last = b:_copilot
207204
endif
208205
let completion = b:_copilot.first
@@ -221,37 +218,37 @@ function! s:HideDuringCompletion() abort
221218
endfunction
222219

223220
function! s:SuggestionTextWithAdjustments() abort
221+
let empty = ['', 0, 0, {}]
224222
try
225223
if mode() !~# '^[iR]' || (s:HideDuringCompletion() && pumvisible()) || !exists('b:_copilot.suggestions')
226-
return ['', 0, 0, '']
224+
return empty
227225
endif
228226
let choice = get(b:_copilot.suggestions, b:_copilot.choice, {})
229-
if !has_key(choice, 'range') || choice.range.start.line != line('.') - 1 || type(choice.text) !=# v:t_string
230-
return ['', 0, 0, '']
227+
if !has_key(choice, 'range') || choice.range.start.line != line('.') - 1 || type(choice.insertText) !=# v:t_string
228+
return empty
231229
endif
232230
let line = getline('.')
233231
let offset = col('.') - 1
234-
let choice_text = strpart(line, 0, copilot#doc#UTF16ToByteIdx(line, choice.range.start.character)) . substitute(choice.text, "\n*$", '', '')
232+
let choice_text = strpart(line, 0, copilot#util#UTF16ToByteIdx(line, choice.range.start.character)) . substitute(choice.insertText, "\n*$", '', '')
235233
let typed = strpart(line, 0, offset)
236-
let end_offset = copilot#doc#UTF16ToByteIdx(line, choice.range.end.character)
234+
let end_offset = copilot#util#UTF16ToByteIdx(line, choice.range.end.character)
237235
if end_offset < 0
238236
let end_offset = len(line)
239237
endif
240238
let delete = strpart(line, offset, end_offset - offset)
241-
let uuid = get(choice, 'uuid', '')
242239
if typed =~# '^\s*$'
243240
let leading = matchstr(choice_text, '^\s\+')
244241
let unindented = strpart(choice_text, len(leading))
245242
if strpart(typed, 0, len(leading)) == leading && unindented !=# delete
246-
return [unindented, len(typed) - len(leading), strchars(delete), uuid]
243+
return [unindented, len(typed) - len(leading), strchars(delete), choice]
247244
endif
248245
elseif typed ==# strpart(choice_text, 0, offset)
249-
return [strpart(choice_text, offset), 0, strchars(delete), uuid]
246+
return [strpart(choice_text, offset), 0, strchars(delete), choice]
250247
endif
251248
catch
252249
call copilot#logger#Exception()
253250
endtry
254-
return ['', 0, 0, '']
251+
return empty
255252
endfunction
256253

257254

@@ -271,12 +268,12 @@ function! s:GetSuggestionsCyclingCallback(context, result) abort
271268
let callbacks = remove(a:context, 'cycling_callbacks')
272269
let seen = {}
273270
for suggestion in a:context.suggestions
274-
let seen[suggestion.text] = 1
271+
let seen[suggestion.insertText] = 1
275272
endfor
276-
for suggestion in get(a:result, 'completions', [])
277-
if !has_key(seen, suggestion.text)
273+
for suggestion in get(a:result, 'items', [])
274+
if !has_key(seen, suggestion.insertText)
278275
call add(a:context.suggestions, suggestion)
279-
let seen[suggestion.text] = 1
276+
let seen[suggestion.insertText] = 1
280277
endif
281278
endfor
282279
for Callback in callbacks
@@ -290,9 +287,11 @@ function! s:GetSuggestionsCycling(callback) abort
290287
elseif exists('b:_copilot.cycling')
291288
call a:callback(b:_copilot)
292289
elseif exists('b:_copilot.suggestions')
290+
let params = deepcopy(b:_copilot.first.params)
291+
let params.context.triggerKind = s:inline_invoked
293292
let b:_copilot.cycling_callbacks = [a:callback]
294-
let b:_copilot.cycling = copilot#Request('getCompletionsCycling',
295-
\ b:_copilot.first.params,
293+
let b:_copilot.cycling = copilot#Request('textDocument/inlineCompletion',
294+
\ params,
296295
\ function('s:GetSuggestionsCyclingCallback', [b:_copilot]),
297296
\ function('s:GetSuggestionsCyclingCallback', [b:_copilot]),
298297
\ )
@@ -310,10 +309,10 @@ function! copilot#Previous() abort
310309
endfunction
311310

312311
function! copilot#GetDisplayedSuggestion() abort
313-
let [text, outdent, delete, uuid] = s:SuggestionTextWithAdjustments()
312+
let [text, outdent, delete, item] = s:SuggestionTextWithAdjustments()
314313

315314
return {
316-
\ 'uuid': uuid,
315+
\ 'item': item,
317316
\ 'text': text,
318317
\ 'outdentSize': outdent,
319318
\ 'deleteSize': delete}
@@ -330,7 +329,7 @@ endfunction
330329

331330
function! s:UpdatePreview() abort
332331
try
333-
let [text, outdent, delete, uuid] = s:SuggestionTextWithAdjustments()
332+
let [text, outdent, delete, item] = s:SuggestionTextWithAdjustments()
334333
let text = split(text, "\n", 1)
335334
if empty(text[-1])
336335
call remove(text, -1)
@@ -370,10 +369,7 @@ function! s:UpdatePreview() abort
370369
call prop_add(line('.'), col('$'), {'type': s:annot_hlgroup, 'text': ' ' . annot})
371370
endif
372371
endif
373-
if !has_key(b:_copilot.shown_choices, uuid)
374-
let b:_copilot.shown_choices[uuid] = v:true
375-
call copilot#Request('notifyShown', {'uuid': uuid})
376-
endif
372+
call copilot#Notify('textDocument/didShowCompletion', {'item': item})
377373
catch
378374
return copilot#logger#Exception()
379375
endtry
@@ -383,9 +379,8 @@ function! s:HandleTriggerResult(result) abort
383379
if !exists('b:_copilot')
384380
return
385381
endif
386-
let b:_copilot.suggestions = get(a:result, 'completions', [])
382+
let b:_copilot.suggestions = type(a:result) == type([]) ? a:result : get(empty(a:result) ? {} : a:result, 'items', [])
387383
let b:_copilot.choice = 0
388-
let b:_copilot.shown_choices = {}
389384
call s:UpdatePreview()
390385
endfunction
391386

@@ -446,8 +441,9 @@ function! copilot#OnBufEnter() abort
446441
call copilot#util#Defer(function('s:Focus'), bufnr)
447442
endfunction
448443

449-
function! copilot#OnInsertLeave() abort
450-
return copilot#Clear()
444+
function! copilot#OnInsertLeavePre() abort
445+
call copilot#Clear()
446+
call s:ClearPreview()
451447
endfunction
452448

453449
function! copilot#OnInsertEnter() abort
@@ -467,7 +463,6 @@ function! copilot#OnCursorMovedI() abort
467463
endfunction
468464

469465
function! copilot#OnBufUnload() abort
470-
call s:Reject(+expand('<abuf>'))
471466
endfunction
472467

473468
function! copilot#OnVimLeavePre() abort
@@ -492,11 +487,14 @@ function! copilot#Accept(...) abort
492487
if empty(text)
493488
let text = s.text
494489
endif
495-
let acceptance = {'uuid': s.uuid}
496-
if text !=# s.text
497-
let acceptance.acceptedLength = copilot#doc#UTF16Width(text)
490+
if text ==# s.text && has_key(s.item, 'command')
491+
call copilot#Request('workspace/executeCommand', s.item.command)
492+
else
493+
let line_text = strpart(getline('.'), 0, col('.') - 1) . text
494+
call copilot#Notify('textDocument/didPartiallyAcceptCompletion', {
495+
\ 'item': s.item,
496+
\ 'acceptedLength': copilot#util#UTF16Width(line_text) - s.item.range.start.character})
498497
endif
499-
call copilot#Request('notifyAccepted', acceptance)
500498
call s:ClearPreview()
501499
let s:suggestion_text = text
502500
return repeat("\<Left>\<Del>", s.outdentSize) . repeat("\<Del>", s.deleteSize) .

autoload/copilot/agent.vim

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,11 @@ endfunction
105105
if !exists('s:id')
106106
let s:id = 0
107107
endif
108+
if !exists('s:progress_token_id')
109+
let s:progress_token_id = 0
110+
endif
108111

109-
function! s:SetUpRequest(agent, id, method, params, ...) abort
112+
function! s:SetUpRequest(agent, id, method, params, progress, ...) abort
110113
let request = {
111114
\ 'agent_id': a:agent.id,
112115
\ 'id': a:id,
@@ -118,6 +121,7 @@ function! s:SetUpRequest(agent, id, method, params, ...) abort
118121
\ 'Cancel': function('s:RequestCancel'),
119122
\ 'resolve': [],
120123
\ 'reject': [],
124+
\ 'progress': a:progress,
121125
\ 'status': 'running'}
122126
let a:agent.requests[a:id] = request
123127
let args = a:000[2:-1]
@@ -190,14 +194,21 @@ endfunction
190194

191195
function! s:PreprocessParams(agent, params) abort
192196
let bufnr = v:null
193-
for doc in filter([get(a:params, 'doc', {}), get(a:params, 'textDocument', {})], 'type(get(v:val, "uri", "")) == v:t_number')
197+
for doc in filter([get(a:params, 'textDocument', {})], 'type(get(v:val, "uri", "")) == v:t_number')
194198
let bufnr = doc.uri
195199
call s:RegisterWorkspaceFolderForBuffer(a:agent, bufnr)
196-
let synced = a:agent.Attach(bufnr)
197-
let doc.uri = synced.uri
198-
let doc.version = get(synced, 'version', 0)
200+
call extend(doc, a:agent.Attach(bufnr))
201+
endfor
202+
let progress_tokens = []
203+
for key in keys(a:params)
204+
if key =~# 'Token$' && type(a:params[key]) == v:t_func
205+
let s:progress_token_id += 1
206+
let a:agent.progress[s:progress_token_id] = a:params[key]
207+
call add(progress_tokens, s:progress_token_id)
208+
let a:params[key] = s:progress_token_id
209+
endif
199210
endfor
200-
return bufnr
211+
return [bufnr, progress_tokens]
201212
endfunction
202213

203214
function! s:VimAttach(bufnr) dict abort
@@ -208,7 +219,7 @@ function! s:VimAttach(bufnr) dict abort
208219
let doc = {
209220
\ 'uri': s:UriFromBufnr(bufnr),
210221
\ 'version': getbufvar(bufnr, 'changedtick', 0),
211-
\ 'languageId': copilot#doc#LanguageForFileType(getbufvar(bufnr, '&filetype')),
222+
\ 'languageId': getbufvar(bufnr, '&filetype'),
212223
\ }
213224
if has_key(self.open_buffers, bufnr) && (
214225
\ self.open_buffers[bufnr].uri !=# doc.uri ||
@@ -235,14 +246,14 @@ endfunction
235246
function! s:AgentRequest(method, params, ...) dict abort
236247
let s:id += 1
237248
let params = deepcopy(a:params)
238-
call s:PreprocessParams(self, params)
249+
let [_, progress] = s:PreprocessParams(self, params)
239250
let request = {'method': a:method, 'params': params, 'id': s:id}
240251
if has_key(self, 'initialization_pending')
241252
call add(self.initialization_pending, request)
242253
else
243254
call copilot#util#Defer(function('s:SendRequest'), self, request)
244255
endif
245-
return call('s:SetUpRequest', [self, s:id, a:method, params] + a:000)
256+
return call('s:SetUpRequest', [self, s:id, a:method, params, progress] + a:000)
246257
endfunction
247258

248259
function! s:AgentCall(method, params, ...) dict abort
@@ -313,6 +324,11 @@ function! s:OnResponse(agent, response, ...) abort
313324
return
314325
endif
315326
let request = remove(a:agent.requests, id)
327+
for progress_token in request.progress
328+
if has_key(a:agent.progress, progress_token)
329+
call remove(a:agent.progress, progress_token)
330+
endif
331+
endfor
316332
if request.status ==# 'canceled'
317333
return
318334
endif
@@ -388,10 +404,10 @@ endfunction
388404

389405
function! s:LspRequest(method, params, ...) dict abort
390406
let params = deepcopy(a:params)
391-
let bufnr = s:PreprocessParams(self, params)
407+
let [bufnr, progress] = s:PreprocessParams(self, params)
392408
let id = eval("v:lua.require'_copilot'.lsp_request(self.id, a:method, params, bufnr)")
393409
if id isnot# v:null
394-
return call('s:SetUpRequest', [self, id, a:method, params] + a:000)
410+
return call('s:SetUpRequest', [self, id, a:method, params, progress] + a:000)
395411
endif
396412
if has_key(self, 'client_id')
397413
call copilot#agent#LspExit(self.client_id, -1, -1)
@@ -564,7 +580,14 @@ function! s:Nop(...) abort
564580
return v:null
565581
endfunction
566582

583+
function! s:Progress(params, agent) abort
584+
if has_key(a:agent.progress, a:params.token)
585+
call a:agent.progress[a:params.token](a:params.value)
586+
endif
587+
endfunction
588+
567589
let s:common_handlers = {
590+
\ '$/progress': function('s:Progress'),
568591
\ 'featureFlagsNotification': function('s:Nop'),
569592
\ 'statusNotification': function('s:StatusNotification'),
570593
\ 'window/logMessage': function('copilot#handlers#window_logMessage'),
@@ -583,6 +606,7 @@ let s:vim_capabilities = {
583606
function! copilot#agent#New(...) abort
584607
let opts = a:0 ? a:1 : {}
585608
let instance = {'requests': {},
609+
\ 'progress': {},
586610
\ 'workspaceFolders': {},
587611
\ 'status': {'status': 'Starting', 'message': ''},
588612
\ 'Close': function('s:AgentClose'),

0 commit comments

Comments
 (0)