commit 6ef996a082e373eac1ac0f32092d28814b31d2cd
parent 4019d3050d1955d86e461c1e1e20fe5fb60bd7e5
Author: zeertzjq <zeertzjq@outlook.com>
Date: Sat, 23 Aug 2025 20:08:01 +0800
vim-patch:9.1.1657: Autocompletion adds delay
Problem: Autocompletion adds delay
(gcanat, char101, after v9.1.1638)
Solution: Temporarily disable autocomplation (Girish Palya).
related: vim/vim#17960
fixes: vim/vim#18022
closes: vim/vim#18048
https://github.com/vim/vim/commit/196c376682f9ebad0d13a8d5458accfb33372537
Co-authored-by: Girish Palya <girishji@gmail.com>
Diffstat:
4 files changed, 91 insertions(+), 11 deletions(-)
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
@@ -581,6 +581,10 @@ static int insert_execute(VimState *state, int key)
return 1; // continue
}
+ if (p_ac) {
+ ins_compl_set_autocomplete(true);
+ }
+
// A non-white character that fits in with the current
// completion: Add to "compl_leader".
if (ins_compl_accept_char(s->c)) {
@@ -598,6 +602,10 @@ static int insert_execute(VimState *state, int key)
return 1; // continue
}
+ if (p_ac) {
+ ins_compl_set_autocomplete(false);
+ }
+
// Pressing CTRL-Y selects the current match. When
// compl_enter_selects is set the Enter key does the same.
if ((s->c == Ctrl_Y
@@ -849,10 +857,11 @@ static int insert_handle_key(InsertState *s)
auto_format(false, true);
if (s->did_backspace && p_ac && !char_avail() && curwin->w_cursor.col > 0) {
s->c = char_before_cursor();
- if (ins_compl_setup_autocompl(s->c)) {
+ if (vim_isprintc(s->c)) {
redraw_later(curwin, UPD_VALID);
update_screen(); // Show char deletion immediately
ui_flush();
+ ins_compl_set_autocomplete(true);
insert_do_complete(s); // Trigger autocompletion
return 1;
}
@@ -1233,10 +1242,11 @@ normalchar:
// closed fold.
foldOpenCursor();
// Trigger autocompletion
- if (p_ac && !char_avail() && ins_compl_setup_autocompl(s->c)) {
+ if (p_ac && !char_avail() && vim_isprintc(s->c)) {
redraw_later(curwin, UPD_VALID);
update_screen(); // Show character immediately
ui_flush();
+ ins_compl_set_autocomplete(true);
insert_do_complete(s);
}
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
@@ -6027,6 +6027,7 @@ int ins_complete(int c, bool enable_pum)
if (!compl_started) {
if (ins_compl_start() == FAIL) {
+ compl_autocomplete = false;
return FAIL;
}
} else if (insert_match && stop_arrow() == FAIL) {
@@ -6109,19 +6110,15 @@ int ins_complete(int c, bool enable_pum)
}
compl_was_interrupted = compl_interrupted;
compl_interrupted = false;
+ compl_autocomplete = false;
return OK;
}
-/// Returns true if the given character 'c' can be used to trigger
-/// autocompletion.
-bool ins_compl_setup_autocompl(int c)
+/// Enable/disable autocompletion
+void ins_compl_set_autocomplete(bool value)
{
- if (vim_isprintc(c)) {
- compl_autocomplete = true;
- return true;
- }
- return false;
+ compl_autocomplete = value;
}
/// Remove (if needed) and show the popup menu
diff --git a/test/functional/editor/completion_spec.lua b/test/functional/editor/completion_spec.lua
@@ -1417,6 +1417,14 @@ describe('completion', function()
set autocomplete
]])
screen:try_resize(60, 10)
+ screen:expect([[
+ ^foo |
+ foobar |
+ foobarbaz |
+ {1:~ }|*6
+ |
+ ]])
+ screen.timeout = 200
feed('Gof')
screen:expect([[
@@ -1501,6 +1509,57 @@ describe('completion', function()
{5:-- Keyword completion (^N^P) }{6:match 1 of 3} |
]])
+ -- After the menu is open, ^N/^P and Up/Down should not delay
+ feed('<Esc>')
+ command('set completeopt=menu')
+ feed('Sf')
+ screen:expect([[
+ foo |
+ foobar |
+ foobarbaz |
+ f^ |
+ {1:~ }|*5
+ {5:-- INSERT --} |
+ ]])
+ vim.uv.sleep(500)
+ feed('<C-N>')
+ screen:expect([[
+ foo |
+ foobar |
+ foobarbaz |
+ foobarbaz^ |
+ {12:foobarbaz }{1: }|
+ {4:foobar }{1: }|
+ {4:foo }{1: }|
+ {1:~ }|*2
+ {5:-- INSERT --} |
+ ]])
+ feed('<Down>')
+ screen:expect([[
+ foo |
+ foobar |
+ foobarbaz |
+ foobarbaz^ |
+ {4:foobarbaz }{1: }|
+ {12:foobar }{1: }|
+ {4:foo }{1: }|
+ {1:~ }|*2
+ {5:-- INSERT --} |
+ ]])
+
+ -- When menu is not open Up/Down moves cursor to different line
+ feed('<Esc>Sf')
+ screen:expect([[
+ foo |
+ foobar |
+ foobarbaz |
+ f^ |
+ {1:~ }|*5
+ {5:-- INSERT --} |
+ ]])
+ feed('<Down>')
+ screen:expect_unchanged()
+
feed('<esc>')
end)
end)
diff --git a/test/old/testdir/test_ins_complete.vim b/test/old/testdir/test_ins_complete.vim
@@ -5471,7 +5471,7 @@ func Test_autocomplete_timer()
call assert_equal(['abc', 'ab'], b:matches->mapnew('v:val.word'))
call assert_equal(0, b:selected)
call assert_equal(1, g:CallCount)
- call assert_equal('abc', getline(4))
+ call assert_equal('ab', getline(4))
set completeopt&
" Test 8: {func} completes after space, but not '.'
@@ -5603,6 +5603,20 @@ func Test_autocompletedelay()
call term_sendkeys(buf, "Sf\<C-N>")
call VerifyScreenDump(buf, 'Test_autocompletedelay_7', {})
+ " After the menu is open, ^N/^P and Up/Down should not delay
+ call term_sendkeys(buf, "\<Esc>:set completeopt=menu noruler\<CR>")
+ call term_sendkeys(buf, "\<Esc>Sf")
+ sleep 500ms
+ call term_sendkeys(buf, "\<C-N>")
+ call VerifyScreenDump(buf, 'Test_autocompletedelay_8', {})
+ call term_sendkeys(buf, "\<Down>")
+ call VerifyScreenDump(buf, 'Test_autocompletedelay_9', {})
+
+ " When menu is not open Up/Down moves cursor to different line
+ call term_sendkeys(buf, "\<Esc>Sf")
+ call term_sendkeys(buf, "\<Down>")
+ call VerifyScreenDump(buf, 'Test_autocompletedelay_10', {})
+
call term_sendkeys(buf, "\<esc>")
call StopVimInTerminal(buf)
endfunc