Skip to content

Commit 23913c2

Browse files
committed
Debounce CursorMoved handler (autozimu#1152)
1 parent 52b8c0e commit 23913c2

File tree

1 file changed

+47
-7
lines changed

1 file changed

+47
-7
lines changed

autoload/LanguageClient.vim

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,6 +1312,9 @@ endfunction
13121312
" there will Mutex poison error.
13131313
let s:last_cursor_line = -1
13141314
function! LanguageClient#handleCursorMoved() abort
1315+
call s:timer_stop('LanguageClient#handleCursorMoved')
1316+
1317+
function! DebounceHandleCursorMoved() abort
13151318
let l:cursor_line = getcurpos()[1] - 1
13161319
if l:cursor_line == s:last_cursor_line
13171320
return
@@ -1328,6 +1331,9 @@ function! LanguageClient#handleCursorMoved() abort
13281331
catch
13291332
call s:Debug('LanguageClient caught exception: ' . string(v:exception))
13301333
endtry
1334+
endfunction
1335+
1336+
call s:timer_start_store(100, { -> DebounceHandleCursorMoved() }, 'LanguageClient#handleCursorMoved')
13311337
endfunction
13321338

13331339
function! LanguageClient#handleCompleteDone() abort
@@ -1711,14 +1717,18 @@ endfunction
17111717

17121718
" receives the v:event from the CompleteChanged autocmd
17131719
function! LanguageClient#handleCompleteChanged(event) abort
1714-
" this timer is just to stop textlock from locking our changes
1715-
call timer_start(0, funcref('s:ClosePopups'))
1716-
1717-
if has_key(s:timers, 'LanguageClient#handleCompleteChanged')
1718-
call timer_stop(s:timers['LanguageClient#handleCompleteChanged'])
1720+
" this function needs timer_start because by the time it is called the
1721+
" `textlock` lock is set, so calling something (ClosePopups in this case) in
1722+
" a timer basically unsets that lock.
1723+
if !exists('*timer_start')
1724+
return
17191725
endif
17201726

1721-
function! Debounced(event) abort
1727+
" this timer is just to stop textlock from locking our changes
1728+
call s:timer_start(0, funcref('s:ClosePopups'))
1729+
call s:timer_stop('LanguageClient#handleCompleteChanged')
1730+
1731+
function! DebounceHandleCompleteChanged(event) abort
17221732
let l:user_data = get(v:completed_item, 'user_data', '')
17231733
if len(l:user_data) ==# 0
17241734
return
@@ -1751,7 +1761,7 @@ function! LanguageClient#handleCompleteChanged(event) abort
17511761
endif
17521762
endfunction
17531763

1754-
let s:timers['LanguageClient#handleCompleteChanged'] = timer_start(100, { -> Debounced(a:event) })
1764+
call s:timer_start_store(100, { -> DebounceHandleCompleteChanged(a:event) }, 'LanguageClient#handleCompleteChanged')
17551765
endfunction
17561766

17571767
function! s:ShowCompletionItemDocumentation(doc, completion_event) abort
@@ -1785,4 +1795,34 @@ function! s:ShowCompletionItemDocumentation(doc, completion_event) abort
17851795
call s:OpenHoverPreview('CompletionItemDocumentation', l:lines, l:kind, l:x_pos, l:pos['row'])
17861796
endfunction
17871797

1798+
" s:timer_stop tries to stop the timer with the given name by calling vim's
1799+
" timer_stop. If vim's timer_stop function does not exist it just returns.
1800+
function! s:timer_stop(name) abort
1801+
if !exists('*timer_stop')
1802+
return
1803+
endif
1804+
1805+
if has_key(s:timers, a:name)
1806+
call timer_stop(s:timers[a:name])
1807+
endif
1808+
endfunction
1809+
1810+
" s:timer_start tries to start a timer by calling vim's timer_start function,
1811+
" if it does not exist it just calls the function given in the second
1812+
" argument.
1813+
function! s:timer_start(delay, func) abort
1814+
if !exists('*timer_start')
1815+
return a:func()
1816+
endif
1817+
1818+
return timer_start(a:delay, a:func)
1819+
endfunction
1820+
1821+
" s:timer_start_store calls s:timer_start and stores the returned timer_id in
1822+
" a script scoped s:timers variable that we can use to debounce function
1823+
" calls.
1824+
function! s:timer_start_store(delay, func, name) abort
1825+
let s:timers[a:name] = s:timer_start(a:delay, a:func)
1826+
endfunction
1827+
17881828
let g:LanguageClient_loaded = s:Launch()

0 commit comments

Comments
 (0)