diff --git a/src/insexpand.c b/src/insexpand.c index c231aa41b8..38b2095632 100644 --- a/src/insexpand.c +++ b/src/insexpand.c @@ -7690,17 +7690,26 @@ remove_old_matches(void) static void get_cpt_func_completion_matches(callback_T *cb UNUSED) { - int startcol = cpt_sources_array[cpt_sources_index].cs_startcol; + cpt_source_T *cpt_src = &cpt_sources_array[cpt_sources_index]; + int startcol = cpt_src->cs_startcol; if (startcol == -2 || startcol == -3) return; if (set_compl_globals(startcol, curwin->w_cursor.col, TRUE) == OK) { + // Insert the leader string (previously removed) before expansion. + // This prevents flicker when `func` (e.g. an LSP client) is slow and + // calls 'sleep', which triggers out_flush(). + if (!cpt_src->cs_refresh_always) + ins_compl_insert_bytes(ins_compl_leader(), -1); + expand_by_function(0, cpt_compl_pattern.string, cb); - cpt_sources_array[cpt_sources_index].cs_refresh_always = - compl_opt_refresh_always; + if (!cpt_src->cs_refresh_always) + ins_compl_delete(); + + cpt_src->cs_refresh_always = compl_opt_refresh_always; compl_opt_refresh_always = FALSE; } } diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim index b10e07433a..c2465030dd 100644 --- a/src/testdir/test_ins_complete.vim +++ b/src/testdir/test_ins_complete.vim @@ -586,15 +586,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 endfunc @@ -602,17 +606,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\2hRxy\", "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\", "tx") set completeopt=longest @@ -4128,7 +4128,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('.') diff --git a/src/version.c b/src/version.c index 48241d3ddc..01a0dd08a5 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1825, /**/ 1824, /**/