Skip to content

Commit c51d1cc

Browse files
girishjichrisbra
authored andcommitted
patch 9.1.1825: completion: flicker when LSP server is slow
Problem: completion: flicker when LSP server is slow Solution: reinsert leader text before invoking user function (Girish Palya) Reference: girishji/vimcomplete#101 (comment) 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: #18468 Signed-off-by: Girish Palya <[email protected]> Signed-off-by: Christian Brabandt <[email protected]>
1 parent 420923c commit c51d1cc

File tree

3 files changed

+27
-17
lines changed

3 files changed

+27
-17
lines changed

src/insexpand.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7690,17 +7690,26 @@ remove_old_matches(void)
76907690
static void
76917691
get_cpt_func_completion_matches(callback_T *cb UNUSED)
76927692
{
7693-
int startcol = cpt_sources_array[cpt_sources_index].cs_startcol;
7693+
cpt_source_T *cpt_src = &cpt_sources_array[cpt_sources_index];
7694+
int startcol = cpt_src->cs_startcol;
76947695

76957696
if (startcol == -2 || startcol == -3)
76967697
return;
76977698

76987699
if (set_compl_globals(startcol, curwin->w_cursor.col, TRUE) == OK)
76997700
{
7701+
// Insert the leader string (previously removed) before expansion.
7702+
// This prevents flicker when `func` (e.g. an LSP client) is slow and
7703+
// calls 'sleep', which triggers out_flush().
7704+
if (!cpt_src->cs_refresh_always)
7705+
ins_compl_insert_bytes(ins_compl_leader(), -1);
7706+
77007707
expand_by_function(0, cpt_compl_pattern.string, cb);
77017708

7702-
cpt_sources_array[cpt_sources_index].cs_refresh_always =
7703-
compl_opt_refresh_always;
7709+
if (!cpt_src->cs_refresh_always)
7710+
ins_compl_delete();
7711+
7712+
cpt_src->cs_refresh_always = compl_opt_refresh_always;
77047713
compl_opt_refresh_always = FALSE;
77057714
}
77067715
}

src/testdir/test_ins_complete.vim

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -586,33 +586,33 @@ func Test_completefunc_info()
586586
set completefunc&
587587
endfunc
588588

589-
func Test_cpt_func_cursorcol()
589+
" For ^N completion, `completefunc` receives the same leader string in both the
590+
" 'info' and 'expansion' phases (the leader is not removed before expansion).
591+
" This avoids flicker when `completefunc` (e.g. an LSP client) is slow and calls
592+
" 'sleep', which triggers out_flush().
593+
func Test_completefunc_leader()
590594
func CptColTest(findstart, query)
591595
if a:findstart
592-
call assert_equal(b:info_compl_line, getline(1))
593-
call assert_equal(b:info_cursor_col, col('.'))
596+
call assert_equal(b:compl_line, getline(1))
597+
call assert_equal(b:cursor_col, col('.'))
594598
return col('.')
595599
endif
596-
call assert_equal(b:expn_compl_line, getline(1))
597-
call assert_equal(b:expn_cursor_col, col('.'))
600+
call assert_equal(b:compl_line, getline(1))
601+
call assert_equal(b:cursor_col, col('.'))
598602
return v:none
599603
endfunc
600604

601605
set complete=FCptColTest
602606
new
603607

604608
" Replace mode
605-
let b:info_compl_line = "foo barxyz"
606-
let b:expn_compl_line = "foo barbaz"
607-
let b:info_cursor_col = 10
608-
let b:expn_cursor_col = 5
609+
let b:compl_line = "foo barxyz"
610+
let b:cursor_col = 10
609611
call feedkeys("ifoo barbaz\<Esc>2hRxy\<C-N>", "tx")
610612

611613
" Insert mode
612-
let b:info_compl_line = "foo bar"
613-
let b:expn_compl_line = "foo "
614-
let b:info_cursor_col = 8
615-
let b:expn_cursor_col = 5
614+
let b:compl_line = "foo bar"
615+
let b:cursor_col = 8
616616
call feedkeys("Sfoo bar\<C-N>", "tx")
617617

618618
set completeopt=longest
@@ -4128,7 +4128,6 @@ func Test_autocomplete_completeopt_preinsert()
41284128
endfunc
41294129
set omnifunc=Omni_test complete+=o
41304130
set completeopt=preinsert autocomplete
4131-
" set completeopt=preinsert,menuone autocomplete
41324131
func GetLine()
41334132
let g:line = getline('.')
41344133
let g:col = col('.')

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,8 @@ static char *(features[]) =
729729

730730
static int included_patches[] =
731731
{ /* Add new patch number below this line */
732+
/**/
733+
1825,
732734
/**/
733735
1824,
734736
/**/

0 commit comments

Comments
 (0)