Skip to content

Commit 83444e6

Browse files
committed
触发改成异步
1 parent 3fe5202 commit 83444e6

File tree

1 file changed

+90
-12
lines changed

1 file changed

+90
-12
lines changed

plugin/fittencode.vim

Lines changed: 90 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ let g:loaded_fittencode = 1
88
let g:accept_just_now = 0
99

1010
let s:hlgroup = 'FittenSuggestion'
11+
let s:virtual_text_line = 0
12+
let s:virtual_text_start_col = 0
13+
let s:virtual_text_updated = 0
1114
function! SetSuggestionStyle() abort
1215
if &t_Co == 256
1316
hi FittenSuggestion guifg=#808080 ctermfg=244
@@ -76,23 +79,34 @@ function! CheckLoginStatus()
7679
endif
7780
endfunction
7881

79-
function! ClearCompletion()
80-
if exists('b:fitten_suggestion')
81-
unlet! b:fitten_suggestion
82-
call prop_remove({'type': s:hlgroup, 'all': v:true})
82+
function! ClearCompletion(clear_state=1)
83+
call prop_remove({'type': s:hlgroup, 'all': v:true})
84+
if a:clear_state == 1
85+
if exists('b:fitten_suggestion')
86+
unlet! b:fitten_suggestion
87+
endif
88+
if exists('s:job') && job_status(s:job) == 'run'
89+
call job_stop(s:job)
90+
unlet! s:job
91+
endif
92+
let s:virtual_text_line = 0
93+
let s:virtual_text_start_col = 0
8394
endif
8495
endfunction
8596

8697
function! ClearCompletionByCursorMoved()
8798
if exists('g:accept_just_now') && g:accept_just_now == 2
8899
let g:accept_just_now = 1
89100
endif
90-
if exists('b:fitten_suggestion')
91-
call ClearCompletion()
101+
if exists('b:fitten_suggestion') && !s:virtual_text_updated
102+
call ClearCompletion(0)
92103
endif
93104
endfunction
94105

95106
function! CodeCompletion()
107+
if exists('b:fitten_suggestion') && s:virtual_text_line == line('.')
108+
return
109+
endif
96110
call ClearCompletion()
97111

98112
let l:filename = substitute(expand('%'), '\\', '/', 'g')
@@ -128,15 +142,24 @@ function! CodeCompletion()
128142
let l:server_addr = 'https://fc.fittenlab.cn/codeapi/completion/generate_one_stage/'
129143

130144
let l:cmd = 'curl -s -X POST -H "Content-Type: application/json" -d @' . l:tempfile . ' "' . l:server_addr . l:token . '?ide=vim&v=0.2.1"'
131-
let l:response = system(l:cmd)
145+
"let l:response = system(l:cmd)
146+
147+
let result = []
148+
let s:job = job_start(l:cmd, {
149+
\ 'out_mode': 'raw',
150+
\ 'out_cb': { channel, data -> add(result, data) },
151+
\ 'exit_cb': { job, status -> s:OnExit(result, status, tempfile, col_num) }
152+
\ })
132153

133-
call delete(l:tempfile)
154+
endfunction
134155

135-
if v:shell_error
136-
echow "Request failed"
156+
fu s:OnExit(out, status, tempfile, col_num) abort
157+
call delete(a:tempfile)
158+
if a:status != 0
137159
return
138160
endif
139-
let l:completion_data = json_decode(l:response)
161+
162+
let l:completion_data = json_decode(join(a:out, "\n"))
140163

141164
if !has_key(l:completion_data, 'generated_text')
142165
return
@@ -164,13 +187,67 @@ function! CodeCompletion()
164187
endif
165188
if l:is_first_line is v:true
166189
let l:is_first_line = v:false
167-
call prop_add(line('.'), l:col_num, {'type': s:hlgroup, 'text': line})
190+
call prop_add(line('.'), a:col_num, {'type': s:hlgroup, 'text': line})
168191
else
169192
call prop_add(line('.'), 0, {'type': s:hlgroup, 'text_align': 'below', 'text': line})
170193
endif
171194
endfor
172195

173196
let b:fitten_suggestion = l:generated_text
197+
let s:virtual_text_updated = 0
198+
let s:virtual_text_line = line('.')
199+
let s:virtual_text_start_col = a:col_num
200+
endf
201+
202+
function! s:UpdateVirtualTextOnInput() abort
203+
if !exists('b:fitten_suggestion')
204+
\ || s:virtual_text_line != line('.')
205+
return 0
206+
endif
207+
if s:virtual_text_start_col > getcurpos()[2]
208+
call ClearCompletion()
209+
return 0
210+
endif
211+
let l:cur_col = getcurpos()[2]
212+
let l:line_content = getline('.')
213+
let l:input_content = strpart(l:line_content, s:virtual_text_start_col - 1, l:cur_col - s:virtual_text_start_col)
214+
let l:input_len = len(l:input_content)
215+
216+
if l:input_len == 0
217+
return 0
218+
endif
219+
let l:virtual_prefix = strpart(b:fitten_suggestion, 0, l:input_len)
220+
if l:virtual_prefix !=? l:input_content
221+
call ClearCompletion()
222+
return 0
223+
endif
224+
let l:remaining_text = strpart(b:fitten_suggestion, l:input_len)
225+
if empty(l:remaining_text)
226+
call ClearCompletion()
227+
return 1
228+
endif
229+
call ClearCompletion(0)
230+
let l:text_lines = split(l:remaining_text, "\n", 1)
231+
if empty(l:text_lines[-1])
232+
call remove(l:text_lines, -1)
233+
endif
234+
let l:text_lines = map(l:text_lines, 'substitute(v:val, "\t", repeat(" ", &ts), "g")')
235+
let l:is_first_line = v:true
236+
for line in l:text_lines
237+
if empty(line)
238+
let line = " "
239+
endif
240+
if l:is_first_line
241+
let l:is_first_line = v:false
242+
call prop_add(line('.'), l:cur_col, {'type': s:hlgroup, 'text': line})
243+
else
244+
call prop_add(line('.'), 0, {'type': s:hlgroup, 'text_align': 'below', 'text': line})
245+
endif
246+
endfor
247+
let b:fitten_suggestion = l:remaining_text
248+
let s:virtual_text_updated = 1
249+
let s:virtual_text_start_col = l:cur_col
250+
return 1
174251
endfunction
175252

176253
function! CodeAutoCompletion()
@@ -270,4 +347,5 @@ augroup fittencode
270347
autocmd VimEnter * call FittenMapping()
271348
set updatetime=1500
272349
autocmd CursorHoldI * if g:fitten_auto_completion == 1 | call CodeAutoCompletion() | endif
350+
autocmd TextChangedI * call s:UpdateVirtualTextOnInput()
273351
augroup END

0 commit comments

Comments
 (0)