patch 9.1.1850: completion: not triggered after i_Ctrl-W/i_Ctrl-U
Commit:
https://github.com/vim/vim/commit/da2dabc6f740b1ed3397797af8a8b0b2ec02bc31
Author: Girish Palya <[email protected]>
Date: Sun Oct 12 14:37:02 2025 +0000
patch 9.1.1850: completion: not triggered after i_Ctrl-W/i_Ctrl-U
Problem: completion: not triggered after i_Ctrl-W/i_Ctrl-U
Solution: Trigger autocomplete when entering Insert mode
(Girish Palya).
fixes: #18535
closes: #18543
Signed-off-by: Girish Palya <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/runtime/doc/insert.txt b/runtime/doc/insert.txt
index 914e9fc83..5ed3e803a 100644
--- a/runtime/doc/insert.txt
+++ b/runtime/doc/insert.txt
@@ -1,4 +1,4 @@
-*insert.txt* For Vim version 9.1. Last change: 2025 Sep 16
+*insert.txt* For Vim version 9.1. Last change: 2025 Oct 12
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -80,10 +80,11 @@ CTRL-W Delete the word before the cursor (see
|i_backspacing| about
joining lines). See the section "word motions",
|word-motions|, for the definition of a word.
*i_CTRL-U*
-CTRL-U Delete all entered characters before the cursor in the current
- line. If there are no newly entered characters and
- 'backspace' is not empty, delete all characters before the
- cursor in the current line.
+CTRL-U Delete all characters that were entered after starting Insert
+ mode and before the cursor in the current line.
+ If there are no newly entered characters and 'backspace' is
+ not empty, delete all characters before the cursor in the
+ current line.
If C-indenting is enabled the indent will be adjusted if the
line becomes blank.
See |i_backspacing| about joining lines.
diff --git a/src/edit.c b/src/edit.c
index 2a765467d..891d51cf9 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -100,6 +100,25 @@ static int ins_need_undo; // call u_save() before
inserting a
static int dont_sync_undo = FALSE; // CTRL-G U prevents syncing undo for
// the next left/right cursor key
+#define TRIGGER_AUTOCOMPLETE() \
+ do { \
+ update_screen(UPD_VALID); /* Show char (deletion) immediately */ \
+ out_flush(); \
+ ins_compl_enable_autocomplete(); \
+ goto docomplete; \
+ } while (0)
+
+#define MAY_TRIGGER_AUTOCOMPLETE(c) \
+ do { \
+ if (ins_compl_has_autocomplete() && !char_avail() \
+ && curwin->w_cursor.col > 0) \
+ { \
+ (c) = char_before_cursor(); \
+ if (vim_isprintc(c)) \
+ TRIGGER_AUTOCOMPLETE(); \
+ } \
+ } while (0)
+
/*
* edit(): Start inserting text.
*
@@ -146,6 +165,7 @@ edit(
#ifdef FEAT_CONCEAL
int cursor_line_was_concealed;
#endif
+ int ins_just_started = TRUE;
// Remember whether editing was restarted after CTRL-O.
did_restart_edit = restart_edit;
@@ -593,6 +613,30 @@ edit(
// Got here from normal mode when bracketed paste started.
c = K_PS;
else
+ {
+ // Trigger autocomplete when entering Insert mode, either directly
+ // or via change commands like 'ciw', 'cw', etc., before the first
+ // character is typed.
+ if (ins_just_started)
+ {
+ ins_just_started = FALSE;
+ if (ins_compl_has_autocomplete() && !char_avail()
+ && curwin->w_cursor.col > 0)
+ {
+ c = char_before_cursor();
+ if (vim_isprintc(c))
+ {
+ ins_compl_enable_autocomplete();
+ ins_compl_init_get_longest();
+#ifdef FEAT_RIGHTLEFT
+ if (p_hkmap)
+ c = hkmap(c); // Hebrew mode mapping
+#endif
+ goto docomplete;
+ }
+ }
+ }
+
do
{
c = safe_vgetc();
@@ -622,6 +666,7 @@ edit(
goto doESCkey;
}
} while (c == K_IGNORE || c == K_NOP);
+ }
// Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V.
did_cursorhold = TRUE;
@@ -991,18 +1036,8 @@ doESCkey:
case Ctrl_H:
did_backspace = ins_bs(c, BACKSPACE_CHAR, &inserted_space);
auto_format(FALSE, TRUE);
- if (did_backspace && ins_compl_has_autocomplete() && !char_avail()
- && curwin->w_cursor.col > 0)
- {
- c = char_before_cursor();
- if (vim_isprintc(c))
- {
- update_screen(UPD_VALID); // Show char deletion immediately
- out_flush();
- ins_compl_enable_autocomplete();
- goto docomplete; // Trigger autocompletion
- }
- }
+ if (did_backspace)
+ MAY_TRIGGER_AUTOCOMPLETE(c);
break;
case Ctrl_W: // delete word before the cursor
@@ -1020,6 +1055,8 @@ doESCkey:
#endif
did_backspace = ins_bs(c, BACKSPACE_WORD, &inserted_space);
auto_format(FALSE, TRUE);
+ if (did_backspace)
+ MAY_TRIGGER_AUTOCOMPLETE(c);
break;
case Ctrl_U: // delete all inserted text in current line
@@ -1031,6 +1068,8 @@ doESCkey:
did_backspace = ins_bs(c, BACKSPACE_LINE, &inserted_space);
auto_format(FALSE, TRUE);
inserted_space = FALSE;
+ if (did_backspace)
+ MAY_TRIGGER_AUTOCOMPLETE(c);
break;
case K_LEFTMOUSE: // mouse keys
@@ -1424,12 +1463,7 @@ normalchar:
// Trigger autocompletion
if (ins_compl_has_autocomplete() && !char_avail()
&& vim_isprintc(c))
- {
- update_screen(UPD_VALID); // Show character immediately
- out_flush();
- ins_compl_enable_autocomplete();
- goto docomplete;
- }
+ TRIGGER_AUTOCOMPLETE();
break;
} // end of switch (c)
diff --git a/src/testdir/test_ins_complete.vim
b/src/testdir/test_ins_complete.vim
index 23c84b28b..6d492373c 100644
--- a/src/testdir/test_ins_complete.vim
+++ b/src/testdir/test_ins_complete.vim
@@ -5416,10 +5416,33 @@ func Test_autocomplete_trigger()
call assert_equal(['fodabc', 'fodxyz'], b:matches->mapnew('v:val.word'))
call assert_equal(-1, b:selected)
+ " Test 8: Ctrl_W / Ctrl_U (delete word/line) should restart autocompletion
+ func! TestComplete(findstart, base)
+ if a:findstart
+ return col('.') - 1
+ endif
+ return ['fooze', 'faberge']
+ endfunc
+ set omnifunc=TestComplete
+ set complete+=o
+ call feedkeys("Sprefix->fo\<F2>\<Esc>0", 'tx!')
+ call assert_equal(['fodabc', 'fodxyz', 'foobar', 'fooze'],
b:matches->mapnew('v:val.word'))
+ call feedkeys("Sprefix->fo\<C-W>\<F2>\<Esc>0", 'tx!')
+ call assert_equal(['fooze', 'faberge'], b:matches->mapnew('v:val.word'))
+ call feedkeys("Sprefix->\<Esc>afo\<C-U>\<F2>\<Esc>0", 'tx!')
+ call assert_equal(['fooze', 'faberge'], b:matches->mapnew('v:val.word'))
+
+ " Test 9: Trigger autocomplete immediately upon entering Insert mode
+ call feedkeys("Sprefix->foo\<Esc>a\<F2>\<Esc>0", 'tx!')
+ call assert_equal(['foobar', 'fooze', 'faberge'],
b:matches->mapnew('v:val.word'))
+ call feedkeys("Sprefix->fooxx\<Esc>hcw\<F2>\<Esc>0", 'tx!')
+ call assert_equal(['foobar', 'fooze', 'faberge'],
b:matches->mapnew('v:val.word'))
+
bw!
call test_override("char_avail", 0)
delfunc NonKeywordComplete
- set autocomplete&
+ delfunc TestComplete
+ set autocomplete& omnifunc& complete&
unlet g:CallCount
endfunc
diff --git a/src/version.c b/src/version.c
index c28ce040a..3f6baf6bb 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 */
+/**/
+ 1850,
/**/
1849,
/**/
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/vim_dev/E1v7xJn-00AIiV-Vp%40256bit.org.