mirror of
https://github.com/neovim/neovim.git
synced 2025-10-16 14:56:08 +00:00
vim-patch:9.1.1850: completion: not triggered after i_Ctrl-W/i_Ctrl-U (#36156)
Problem: completion: not triggered after i_Ctrl-W/i_Ctrl-U
Solution: Trigger autocomplete when entering Insert mode
(Girish Palya).
fixes: vim/vim#18535
closes: vim/vim#18543
da2dabc6f7
Co-authored-by: Girish Palya <girishji@gmail.com>
This commit is contained in:
@@ -69,10 +69,11 @@ CTRL-W Delete the word before the cursor (see |i_backspacing| about
|
|||||||
By default, sets a new undo point before deleting.
|
By default, sets a new undo point before deleting.
|
||||||
|default-mappings|
|
|default-mappings|
|
||||||
*i_CTRL-U*
|
*i_CTRL-U*
|
||||||
CTRL-U Delete all entered characters before the cursor in the current
|
CTRL-U Delete all characters that were entered after starting Insert
|
||||||
line. If there are no newly entered characters and
|
mode and before the cursor in the current line.
|
||||||
'backspace' is not empty, delete all characters before the
|
If there are no newly entered characters and 'backspace' is
|
||||||
cursor in the current line.
|
not empty, delete all characters before the cursor in the
|
||||||
|
current line.
|
||||||
If C-indenting is enabled the indent will be adjusted if the
|
If C-indenting is enabled the indent will be adjusted if the
|
||||||
line becomes blank.
|
line becomes blank.
|
||||||
See |i_backspacing| about joining lines.
|
See |i_backspacing| about joining lines.
|
||||||
|
@@ -88,6 +88,7 @@ typedef struct {
|
|||||||
int mincol;
|
int mincol;
|
||||||
int cmdchar;
|
int cmdchar;
|
||||||
int cmdchar_todo; // cmdchar to handle once in init_prompt
|
int cmdchar_todo; // cmdchar to handle once in init_prompt
|
||||||
|
bool ins_just_started;
|
||||||
int startln;
|
int startln;
|
||||||
int count;
|
int count;
|
||||||
int c;
|
int c;
|
||||||
@@ -144,12 +145,33 @@ static linenr_T o_lnum = 0;
|
|||||||
|
|
||||||
static kvec_t(char) replace_stack = KV_INITIAL_VALUE;
|
static kvec_t(char) replace_stack = KV_INITIAL_VALUE;
|
||||||
|
|
||||||
|
#define TRIGGER_AUTOCOMPLETE() \
|
||||||
|
do { \
|
||||||
|
redraw_later(curwin, UPD_VALID); \
|
||||||
|
update_screen(); /* Show char deletion immediately */ \
|
||||||
|
ui_flush(); \
|
||||||
|
ins_compl_enable_autocomplete(); \
|
||||||
|
insert_do_complete(s); \
|
||||||
|
break; \
|
||||||
|
} 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)
|
||||||
|
|
||||||
static void insert_enter(InsertState *s)
|
static void insert_enter(InsertState *s)
|
||||||
{
|
{
|
||||||
s->did_backspace = true;
|
s->did_backspace = true;
|
||||||
s->old_topfill = -1;
|
s->old_topfill = -1;
|
||||||
s->replaceState = MODE_REPLACE;
|
s->replaceState = MODE_REPLACE;
|
||||||
s->cmdchar_todo = s->cmdchar;
|
s->cmdchar_todo = s->cmdchar;
|
||||||
|
s->ins_just_started = true;
|
||||||
// Remember whether editing was restarted after CTRL-O
|
// Remember whether editing was restarted after CTRL-O
|
||||||
did_restart_edit = restart_edit;
|
did_restart_edit = restart_edit;
|
||||||
// sleep before redrawing, needed for "CTRL-O :" that results in an
|
// sleep before redrawing, needed for "CTRL-O :" that results in an
|
||||||
@@ -532,6 +554,22 @@ static int insert_check(VimState *state)
|
|||||||
dont_sync_undo = kFalse;
|
dont_sync_undo = kFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Trigger autocomplete when entering Insert mode, either directly
|
||||||
|
// or via change commands like 'ciw', 'cw', etc., before the first
|
||||||
|
// character is typed.
|
||||||
|
if (s->ins_just_started) {
|
||||||
|
s->ins_just_started = false;
|
||||||
|
if (ins_compl_has_autocomplete() && !char_avail() && curwin->w_cursor.col > 0) {
|
||||||
|
s->c = char_before_cursor();
|
||||||
|
if (vim_isprintc(s->c)) {
|
||||||
|
ins_compl_enable_autocomplete();
|
||||||
|
ins_compl_init_get_longest();
|
||||||
|
insert_do_complete(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -855,17 +893,8 @@ static int insert_handle_key(InsertState *s)
|
|||||||
case Ctrl_H:
|
case Ctrl_H:
|
||||||
s->did_backspace = ins_bs(s->c, BACKSPACE_CHAR, &s->inserted_space);
|
s->did_backspace = ins_bs(s->c, BACKSPACE_CHAR, &s->inserted_space);
|
||||||
auto_format(false, true);
|
auto_format(false, true);
|
||||||
if (s->did_backspace && ins_compl_has_autocomplete() && !char_avail()
|
if (s->did_backspace) {
|
||||||
&& curwin->w_cursor.col > 0) {
|
MAY_TRIGGER_AUTOCOMPLETE(s->c);
|
||||||
s->c = char_before_cursor();
|
|
||||||
if (vim_isprintc(s->c)) {
|
|
||||||
redraw_later(curwin, UPD_VALID);
|
|
||||||
update_screen(); // Show char deletion immediately
|
|
||||||
ui_flush();
|
|
||||||
ins_compl_enable_autocomplete();
|
|
||||||
insert_do_complete(s); // Trigger autocompletion
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -881,6 +910,9 @@ static int insert_handle_key(InsertState *s)
|
|||||||
}
|
}
|
||||||
s->did_backspace = ins_bs(s->c, BACKSPACE_WORD, &s->inserted_space);
|
s->did_backspace = ins_bs(s->c, BACKSPACE_WORD, &s->inserted_space);
|
||||||
auto_format(false, true);
|
auto_format(false, true);
|
||||||
|
if (s->did_backspace) {
|
||||||
|
MAY_TRIGGER_AUTOCOMPLETE(s->c);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Ctrl_U: // delete all inserted text in current line
|
case Ctrl_U: // delete all inserted text in current line
|
||||||
@@ -891,6 +923,9 @@ static int insert_handle_key(InsertState *s)
|
|||||||
s->did_backspace = ins_bs(s->c, BACKSPACE_LINE, &s->inserted_space);
|
s->did_backspace = ins_bs(s->c, BACKSPACE_LINE, &s->inserted_space);
|
||||||
auto_format(false, true);
|
auto_format(false, true);
|
||||||
s->inserted_space = false;
|
s->inserted_space = false;
|
||||||
|
if (s->did_backspace) {
|
||||||
|
MAY_TRIGGER_AUTOCOMPLETE(s->c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1244,11 +1279,7 @@ normalchar:
|
|||||||
foldOpenCursor();
|
foldOpenCursor();
|
||||||
// Trigger autocompletion
|
// Trigger autocompletion
|
||||||
if (ins_compl_has_autocomplete() && !char_avail() && vim_isprintc(s->c)) {
|
if (ins_compl_has_autocomplete() && !char_avail() && vim_isprintc(s->c)) {
|
||||||
redraw_later(curwin, UPD_VALID);
|
TRIGGER_AUTOCOMPLETE();
|
||||||
update_screen(); // Show character immediately
|
|
||||||
ui_flush();
|
|
||||||
ins_compl_enable_autocomplete();
|
|
||||||
insert_do_complete(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@@ -5528,10 +5528,33 @@ func Test_autocomplete_trigger()
|
|||||||
call assert_equal(['fodabc', 'fodxyz'], b:matches->mapnew('v:val.word'))
|
call assert_equal(['fodabc', 'fodxyz'], b:matches->mapnew('v:val.word'))
|
||||||
call assert_equal(-1, b:selected)
|
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!
|
bw!
|
||||||
call Ntest_override("char_avail", 0)
|
call Ntest_override("char_avail", 0)
|
||||||
delfunc NonKeywordComplete
|
delfunc NonKeywordComplete
|
||||||
set autocomplete&
|
delfunc TestComplete
|
||||||
|
set autocomplete& omnifunc& complete&
|
||||||
unlet g:CallCount
|
unlet g:CallCount
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user