@@ -5,7 +5,7 @@ let g:autoloaded_copilot_agent = 1
55
66scriptencoding utf- 8
77
8- let s: plugin_version = ' 1.8.0 '
8+ let s: plugin_version = ' 1.8.1 '
99
1010let s: error_exit = -1
1111
@@ -117,10 +117,69 @@ function! s:SetUpRequest(agent, id, method, params, ...) abort
117117 return request
118118endfunction
119119
120+ function ! s: UrlEncode (str) abort
121+ return substitute (iconv (a: str , ' latin1' , ' utf-8' ),' [^A-Za-z0-9._~!$&'' ()*+,;=:@/-]' ,' \="%".printf("%02X",char2nr(submatch(0)))' ,' g' )
122+ endfunction
123+
124+ let s: slash = exists (' +shellslash' ) ? ' \' : ' /'
125+ function ! s: UriFromBufnr (bufnr ) abort
126+ let absolute = tr (bufname (a: bufnr ), s: slash , ' /' )
127+ if absolute !~# ' ^\a\+:\|^/\|^$' && getbufvar (a: bufnr , ' buftype' ) = ~# ' ^\%(nowrite\)\=$'
128+ let absolute = substitute (tr (getcwd (), s: slash , ' /' ), ' /\=$' , ' /' , ' ' ) . absolute
129+ endif
130+ if has (' win32' ) && absolute = ~# ' ^\a://\@!'
131+ return ' file:///' . strpart (absolute, 0 , 2 ) . s: UrlEncode (strpart (absolute, 2 ))
132+ elseif absolute = ~# ' ^/'
133+ return ' file://' . s: UrlEncode (absolute)
134+ elseif absolute = ~# ' ^\a[[:alnum:].+-]*:\|^$'
135+ return absolute
136+ else
137+ return ' '
138+ endif
139+ endfunction
140+
141+ function ! s: BufferText (bufnr ) abort
142+ return join (getbufline (a: bufnr , 1 , ' $' ), " \n " ) . " \n "
143+ endfunction
144+
120145function ! s: AgentRequest (method, params, ... ) dict abort
121146 let s: id += 1
122- let request = {' method' : a: method , ' params' : a: params , ' id' : s: id }
123- call s: Send (self , request)
147+ let request = {' method' : a: method , ' params' : deepcopy (a: params ), ' id' : s: id }
148+ for doc in filter ([get (request.params, ' doc' , {}), get (request.params, ' textDocument' ,{})], ' type(get(v:val, "uri", "")) == v:t_number' )
149+ let bufnr = doc.uri
150+ let doc.uri = s: UriFromBufnr (doc.uri)
151+ let uri = doc.uri
152+ let languageId = copilot#doc#LanguageForFileType (getbufvar (bufnr , ' &filetype' ))
153+ let doc_version = getbufvar (bufnr , ' changedtick' )
154+ if has_key (self .open_buffers, bufnr ) && (
155+ \ self .open_buffers[bufnr ].uri !=# doc.uri ||
156+ \ self .open_buffers[bufnr ].languageId !=# languageId)
157+ call remove (self .open_buffers, bufnr )
158+ sleep 1 m
159+ endif
160+ if ! has_key (self .open_buffers, bufnr )
161+ let td_item = {
162+ \ ' uri' : doc.uri,
163+ \ ' version' : doc_version,
164+ \ ' languageId' : languageId,
165+ \ ' text' : s: BufferText (bufnr )}
166+ call self .Notify (' textDocument/didOpen' , {' textDocument' : td_item})
167+ let self .open_buffers[bufnr ] = {
168+ \ ' uri' : doc.uri,
169+ \ ' version' : doc_version,
170+ \ ' languageId' : languageId}
171+ else
172+ let vtd_id = {
173+ \ ' uri' : doc.uri,
174+ \ ' version' : getbufvar (bufnr , ' changedtick' )}
175+ call self .Notify (' textDocument/didChange' , {
176+ \ ' textDocument' : vtd_id,
177+ \ ' contentChanges' : [{' text' : s: BufferText (bufnr )}]})
178+ let self .open_buffers[bufnr ].version = version
179+ endif
180+ let doc.version = doc_version
181+ endfor
182+ call timer_start (0 , { _ - > s: Send (self , request) })
124183 return call (' s:SetUpRequest' , [self , s: id , a: method , a: params ] + a: 000 )
125184endfunction
126185
@@ -468,6 +527,7 @@ function! copilot#agent#New(...) abort
468527 let instance.id = instance.client_id
469528 else
470529 let state = {' headers' : {}, ' mode' : ' headers' , ' buffer' : ' ' }
530+ let instance.open_buffers = {}
471531 let instance.job = copilot#job#Stream (command ,
472532 \ function (' s:OnOut' , [instance, state ]),
473533 \ function (' s:OnErr' , [instance]),
@@ -507,3 +567,23 @@ function! copilot#agent#Error(request, callback) abort
507567 let a: request .waiting[timer_start (0 , function (' s:Callback' , [a: request , ' error' , a: callback ]))] = 1
508568 endif
509569endfunction
570+
571+ function ! s: CloseBuffer (bufnr ) abort
572+ for instance in values (s: instances )
573+ try
574+ if has_key (instance, ' job' ) && has_key (instance.open_buffers, a: bufnr )
575+ let buffer = remove (instance.open_buffers, a: bufnr )
576+ call instance.Notify (' textDocument/didClose' , {' textDocument' : {' uri' : buffer .uri}})
577+ endif
578+ catch
579+ call copilot#logger#Exception ()
580+ endtry
581+ endfor
582+ endfunction
583+
584+ augroup copilot_agent
585+ autocmd !
586+ if ! has (' nvim' )
587+ autocmd BufUnload * call s: CloseBuffer (+ expand (' <abuf>' ))
588+ endif
589+ augroup END
0 commit comments