commit 963ead29d9f0f6660da2268a8a32cb2ee7f49ac6
parent 1c0465bec650966f5c5b4d6d25b1b80c1a0b920c
Author: zeertzjq <zeertzjq@outlook.com>
Date: Sat, 23 Aug 2025 20:20:43 +0800
vim-patch:9.1.1670: completion: autocomplete breaks second completion
Problem: completion: autocomplete breaks second completion
(gravndal)
Solution: Fix the autocomplete bug (Girish Palya)
fixes: vim/vim#18044
closes: vim/vim#18068
https://github.com/vim/vim/commit/b4e0bd93a9c09377b684c5bdf12c5c2eeb46aada
Co-authored-by: Girish Palya <girishji@gmail.com>
Diffstat:
3 files changed, 13 insertions(+), 20 deletions(-)
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
@@ -581,10 +581,6 @@ 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)) {
@@ -602,10 +598,6 @@ 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
@@ -861,7 +853,7 @@ static int insert_handle_key(InsertState *s)
redraw_later(curwin, UPD_VALID);
update_screen(); // Show char deletion immediately
ui_flush();
- ins_compl_set_autocomplete(true);
+ ins_compl_enable_autocomplete();
insert_do_complete(s); // Trigger autocompletion
return 1;
}
@@ -1246,7 +1238,7 @@ normalchar:
redraw_later(curwin, UPD_VALID);
update_screen(); // Show character immediately
ui_flush();
- ins_compl_set_autocomplete(true);
+ ins_compl_enable_autocomplete();
insert_do_complete(s);
}
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
@@ -6022,21 +6022,23 @@ static void ins_compl_show_statusmsg(void)
/// Returns OK if completion was done, FAIL if something failed.
int ins_complete(int c, bool enable_pum)
{
+ const bool disable_ac_delay = compl_started && ctrl_x_mode_normal()
+ && (c == Ctrl_N || c == Ctrl_P || c == Ctrl_R
+ || ins_compl_pum_key(c));
+
compl_direction = ins_compl_key2dir(c);
int insert_match = ins_compl_use_match(c);
if (!compl_started) {
if (ins_compl_start() == FAIL) {
- compl_autocomplete = false;
return FAIL;
}
} else if (insert_match && stop_arrow() == FAIL) {
return FAIL;
}
- // Timestamp when match collection starts
- uint64_t compl_start_tv = 0;
- if (compl_autocomplete && p_acl > 0) {
+ uint64_t compl_start_tv = 0; ///< Time when match collection starts
+ if (compl_autocomplete && p_acl > 0 && !disable_ac_delay) {
compl_start_tv = os_hrtime();
}
compl_curr_win = curwin;
@@ -6089,7 +6091,7 @@ int ins_complete(int c, bool enable_pum)
}
// Wait for the autocompletion delay to expire
- if (compl_autocomplete && p_acl > 0 && !no_matches_found
+ if (compl_autocomplete && p_acl > 0 && !disable_ac_delay && !no_matches_found
&& (os_hrtime() - compl_start_tv) / 1000000 < (uint64_t)p_acl) {
setcursor();
ui_flush();
@@ -6110,15 +6112,14 @@ int ins_complete(int c, bool enable_pum)
}
compl_was_interrupted = compl_interrupted;
compl_interrupted = false;
- compl_autocomplete = false;
return OK;
}
-/// Enable/disable autocompletion
-void ins_compl_set_autocomplete(bool value)
+/// Enable autocompletion
+void ins_compl_enable_autocomplete(void)
{
- compl_autocomplete = value;
+ compl_autocomplete = true;
}
/// Remove (if needed) and show the popup menu
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('ab', getline(4))
+ call assert_equal('abc', getline(4))
set completeopt&
" Test 8: {func} completes after space, but not '.'