Skip to content

Commit da2dabc

Browse files
girishjichrisbra
authored andcommitted
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 <girishji@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
1 parent fcf4c43 commit da2dabc

4 files changed

Lines changed: 84 additions & 24 deletions

File tree

runtime/doc/insert.txt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*insert.txt* For Vim version 9.1. Last change: 2025 Sep 16
1+
*insert.txt* For Vim version 9.1. Last change: 2025 Oct 12
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -80,10 +80,11 @@ CTRL-W Delete the word before the cursor (see |i_backspacing| about
8080
joining lines). See the section "word motions",
8181
|word-motions|, for the definition of a word.
8282
*i_CTRL-U*
83-
CTRL-U Delete all entered characters before the cursor in the current
84-
line. If there are no newly entered characters and
85-
'backspace' is not empty, delete all characters before the
86-
cursor in the current line.
83+
CTRL-U Delete all characters that were entered after starting Insert
84+
mode and before the cursor in the current line.
85+
If there are no newly entered characters and 'backspace' is
86+
not empty, delete all characters before the cursor in the
87+
current line.
8788
If C-indenting is enabled the indent will be adjusted if the
8889
line becomes blank.
8990
See |i_backspacing| about joining lines.

src/edit.c

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,25 @@ static int ins_need_undo; // call u_save() before inserting a
100100
static int dont_sync_undo = FALSE; // CTRL-G U prevents syncing undo for
101101
// the next left/right cursor key
102102

103+
#define TRIGGER_AUTOCOMPLETE() \
104+
do { \
105+
update_screen(UPD_VALID); /* Show char (deletion) immediately */ \
106+
out_flush(); \
107+
ins_compl_enable_autocomplete(); \
108+
goto docomplete; \
109+
} while (0)
110+
111+
#define MAY_TRIGGER_AUTOCOMPLETE(c) \
112+
do { \
113+
if (ins_compl_has_autocomplete() && !char_avail() \
114+
&& curwin->w_cursor.col > 0) \
115+
{ \
116+
(c) = char_before_cursor(); \
117+
if (vim_isprintc(c)) \
118+
TRIGGER_AUTOCOMPLETE(); \
119+
} \
120+
} while (0)
121+
103122
/*
104123
* edit(): Start inserting text.
105124
*
@@ -146,6 +165,7 @@ edit(
146165
#ifdef FEAT_CONCEAL
147166
int cursor_line_was_concealed;
148167
#endif
168+
int ins_just_started = TRUE;
149169

150170
// Remember whether editing was restarted after CTRL-O.
151171
did_restart_edit = restart_edit;
@@ -593,6 +613,30 @@ edit(
593613
// Got here from normal mode when bracketed paste started.
594614
c = K_PS;
595615
else
616+
{
617+
// Trigger autocomplete when entering Insert mode, either directly
618+
// or via change commands like 'ciw', 'cw', etc., before the first
619+
// character is typed.
620+
if (ins_just_started)
621+
{
622+
ins_just_started = FALSE;
623+
if (ins_compl_has_autocomplete() && !char_avail()
624+
&& curwin->w_cursor.col > 0)
625+
{
626+
c = char_before_cursor();
627+
if (vim_isprintc(c))
628+
{
629+
ins_compl_enable_autocomplete();
630+
ins_compl_init_get_longest();
631+
#ifdef FEAT_RIGHTLEFT
632+
if (p_hkmap)
633+
c = hkmap(c); // Hebrew mode mapping
634+
#endif
635+
goto docomplete;
636+
}
637+
}
638+
}
639+
596640
do
597641
{
598642
c = safe_vgetc();
@@ -622,6 +666,7 @@ edit(
622666
goto doESCkey;
623667
}
624668
} while (c == K_IGNORE || c == K_NOP);
669+
}
625670

626671
// Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V.
627672
did_cursorhold = TRUE;
@@ -991,18 +1036,8 @@ edit(
9911036
case Ctrl_H:
9921037
did_backspace = ins_bs(c, BACKSPACE_CHAR, &inserted_space);
9931038
auto_format(FALSE, TRUE);
994-
if (did_backspace && ins_compl_has_autocomplete() && !char_avail()
995-
&& curwin->w_cursor.col > 0)
996-
{
997-
c = char_before_cursor();
998-
if (vim_isprintc(c))
999-
{
1000-
update_screen(UPD_VALID); // Show char deletion immediately
1001-
out_flush();
1002-
ins_compl_enable_autocomplete();
1003-
goto docomplete; // Trigger autocompletion
1004-
}
1005-
}
1039+
if (did_backspace)
1040+
MAY_TRIGGER_AUTOCOMPLETE(c);
10061041
break;
10071042

10081043
case Ctrl_W: // delete word before the cursor
@@ -1020,6 +1055,8 @@ edit(
10201055
#endif
10211056
did_backspace = ins_bs(c, BACKSPACE_WORD, &inserted_space);
10221057
auto_format(FALSE, TRUE);
1058+
if (did_backspace)
1059+
MAY_TRIGGER_AUTOCOMPLETE(c);
10231060
break;
10241061

10251062
case Ctrl_U: // delete all inserted text in current line
@@ -1031,6 +1068,8 @@ edit(
10311068
did_backspace = ins_bs(c, BACKSPACE_LINE, &inserted_space);
10321069
auto_format(FALSE, TRUE);
10331070
inserted_space = FALSE;
1071+
if (did_backspace)
1072+
MAY_TRIGGER_AUTOCOMPLETE(c);
10341073
break;
10351074

10361075
case K_LEFTMOUSE: // mouse keys
@@ -1424,12 +1463,7 @@ edit(
14241463
// Trigger autocompletion
14251464
if (ins_compl_has_autocomplete() && !char_avail()
14261465
&& vim_isprintc(c))
1427-
{
1428-
update_screen(UPD_VALID); // Show character immediately
1429-
out_flush();
1430-
ins_compl_enable_autocomplete();
1431-
goto docomplete;
1432-
}
1466+
TRIGGER_AUTOCOMPLETE();
14331467

14341468
break;
14351469
} // end of switch (c)

src/testdir/test_ins_complete.vim

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5416,10 +5416,33 @@ func Test_autocomplete_trigger()
54165416
call assert_equal(['fodabc', 'fodxyz'], b:matches->mapnew('v:val.word'))
54175417
call assert_equal(-1, b:selected)
54185418

5419+
" Test 8: Ctrl_W / Ctrl_U (delete word/line) should restart autocompletion
5420+
func! TestComplete(findstart, base)
5421+
if a:findstart
5422+
return col('.') - 1
5423+
endif
5424+
return ['fooze', 'faberge']
5425+
endfunc
5426+
set omnifunc=TestComplete
5427+
set complete+=o
5428+
call feedkeys("Sprefix->fo\<F2>\<Esc>0", 'tx!')
5429+
call assert_equal(['fodabc', 'fodxyz', 'foobar', 'fooze'], b:matches->mapnew('v:val.word'))
5430+
call feedkeys("Sprefix->fo\<C-W>\<F2>\<Esc>0", 'tx!')
5431+
call assert_equal(['fooze', 'faberge'], b:matches->mapnew('v:val.word'))
5432+
call feedkeys("Sprefix->\<Esc>afo\<C-U>\<F2>\<Esc>0", 'tx!')
5433+
call assert_equal(['fooze', 'faberge'], b:matches->mapnew('v:val.word'))
5434+
5435+
" Test 9: Trigger autocomplete immediately upon entering Insert mode
5436+
call feedkeys("Sprefix->foo\<Esc>a\<F2>\<Esc>0", 'tx!')
5437+
call assert_equal(['foobar', 'fooze', 'faberge'], b:matches->mapnew('v:val.word'))
5438+
call feedkeys("Sprefix->fooxx\<Esc>hcw\<F2>\<Esc>0", 'tx!')
5439+
call assert_equal(['foobar', 'fooze', 'faberge'], b:matches->mapnew('v:val.word'))
5440+
54195441
bw!
54205442
call test_override("char_avail", 0)
54215443
delfunc NonKeywordComplete
5422-
set autocomplete&
5444+
delfunc TestComplete
5445+
set autocomplete& omnifunc& complete&
54235446
unlet g:CallCount
54245447
endfunc
54255448

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+
1850,
732734
/**/
733735
1849,
734736
/**/

0 commit comments

Comments
 (0)