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>
This commit is contained in:
Girish Palya
2025-10-12 14:37:02 +00:00
committed by Christian Brabandt
parent fcf4c435af
commit da2dabc6f7
4 changed files with 84 additions and 24 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1850,
/**/
1849,
/**/