vim-patch:9.1.1825: completion: flicker when LSP server is slow (#36020)

Problem:  completion: flicker when LSP server is slow
Solution: reinsert leader text before invoking user function
          (Girish Palya)

Reference:
https://github.com/girishji/vimcomplete/issues/101#issuecomment-3343063245

In insert-mode completion, the leader text is temporarily removed while
searching for candidates. When the LSP server responds slowly, the
client may call `:sleep` to wait, which triggers `out_flush()`. This
causes the deleted text to disappear briefly before being redrawn,
resulting in visible flicker.

This commit reinserts the leader text before invoking the user function,
and removes it again afterward to eliminate flicker.

closes: vim/vim#18468

c51d1cc578

Co-authored-by: Girish Palya <girishji@gmail.com>
This commit is contained in:
zeertzjq
2025-10-04 20:08:28 +08:00
committed by GitHub
parent 0fca343d64
commit f8b50bf3b0
2 changed files with 28 additions and 16 deletions

View File

@@ -591,15 +591,19 @@ func Test_completefunc_info()
set completefunc&
endfunc
func Test_cpt_func_cursorcol()
" For ^N completion, `completefunc` receives the same leader string in both the
" 'info' and 'expansion' phases (the leader is not removed before expansion).
" This avoids flicker when `completefunc` (e.g. an LSP client) is slow and calls
" 'sleep', which triggers out_flush().
func Test_completefunc_leader()
func CptColTest(findstart, query)
if a:findstart
call assert_equal(b:info_compl_line, getline(1))
call assert_equal(b:info_cursor_col, col('.'))
call assert_equal(b:compl_line, getline(1))
call assert_equal(b:cursor_col, col('.'))
return col('.')
endif
call assert_equal(b:expn_compl_line, getline(1))
call assert_equal(b:expn_cursor_col, col('.'))
call assert_equal(b:compl_line, getline(1))
call assert_equal(b:cursor_col, col('.'))
" return v:none
return []
endfunc
@@ -608,17 +612,13 @@ func Test_cpt_func_cursorcol()
new
" Replace mode
let b:info_compl_line = "foo barxyz"
let b:expn_compl_line = "foo barbaz"
let b:info_cursor_col = 10
let b:expn_cursor_col = 5
let b:compl_line = "foo barxyz"
let b:cursor_col = 10
call feedkeys("ifoo barbaz\<Esc>2hRxy\<C-N>", "tx")
" Insert mode
let b:info_compl_line = "foo bar"
let b:expn_compl_line = "foo "
let b:info_cursor_col = 8
let b:expn_cursor_col = 5
let b:compl_line = "foo bar"
let b:cursor_col = 8
call feedkeys("Sfoo bar\<C-N>", "tx")
set completeopt=longest
@@ -4239,7 +4239,6 @@ func Test_autocomplete_completeopt_preinsert()
endfunc
set omnifunc=Omni_test complete+=o
set completeopt=preinsert autocomplete
" set completeopt=preinsert,menuone autocomplete
func GetLine()
let g:line = getline('.')
let g:col = col('.')