Files
Yasuhiro Matsumoto a7132f901e Optimize performance of completion pipeline
- Replace exists('l:startcol') with a boolean flag in s:on_change()
- Avoid full asyncomplete#context() in textchangedp change detection; use lightweight line()/col()/getline() instead
- Build context dict directly from local vars instead of intermediate dict lookups
- Skip s:strip_pair_characters() call when base doesn't start with a pair character
- Bulk-append items when base is empty instead of per-item add
- Use add() instead of += [val] for startcols list building
- Fix redundant getcurpos() call in timer.vim s:maybe_notify_on_change()
- Early return in asyncomplete#log() when log file is empty
2026-03-20 19:01:38 +09:00

84 lines
2.2 KiB
VimL

let s:callbacks = []
let s:change_timer = -1
let s:last_tick = []
function! asyncomplete#utils#_on_change#timer#init() abort
call s:setup_if_required()
return {
\ 'name': 'timer',
\ 'register': function('s:register'),
\ 'unregister': function('s:unregister'),
\ }
endfunction
function! s:setup_if_required() abort
augroup asyncomplete_utils_on_change_timer
autocmd!
autocmd InsertEnter * call s:on_insert_enter()
autocmd InsertLeave * call s:on_insert_leave()
autocmd TextChangedI * call s:on_text_changed_i()
augroup END
endfunction
function! s:register(cb) abort
call add(s:callbacks , a:cb)
endfunction
function! s:unregister(obj, cb) abort
" TODO: remove from s:callbacks
endfunction
function! s:on_insert_enter() abort
let s:previous_position = getcurpos()
call s:change_tick_start()
endfunction
function! s:on_insert_leave() abort
unlet s:previous_position
call s:change_tick_stop()
endfunction
function! s:on_text_changed_i() abort
call s:check_changes()
endfunction
function! s:change_tick_start() abort
if !exists('s:change_timer')
let s:last_tick = s:change_tick()
" changes every 30ms, which is 0.03s, it should be fast enough
let s:change_timer = timer_start(30, function('s:check_changes'), { 'repeat': -1 })
endif
endfunction
function! s:change_tick_stop() abort
if exists('s:change_timer')
call timer_stop(s:change_timer)
unlet s:change_timer
let s:last_tick = []
endif
endfunction
function! s:check_changes(...) abort
let l:tick = s:change_tick()
if l:tick != s:last_tick
let s:last_tick = l:tick
call s:maybe_notify_on_change()
endif
endfunction
function! s:maybe_notify_on_change() abort
" enter to new line or backspace to previous line shouldn't cause change trigger
let l:previous_position = s:previous_position
let s:previous_position = getcurpos()
if l:previous_position[1] ==# s:previous_position[1]
for l:Cb in s:callbacks
call l:Cb()
endfor
endif
endfunction
function! s:change_tick() abort
return [b:changedtick, getcurpos()]
endfunction