fix(edit): handle cindent properly with completion (#36711)

Don't handle cindent in insert_check(). Instead, do that just before
returning from insert_execute() if required.
This also makes the in_cinkeys() change from #12894 unnecessary.
This commit is contained in:
zeertzjq
2025-11-27 11:30:02 +08:00
committed by GitHub
parent 2c97ea3f04
commit 9a864d0a3c
3 changed files with 39 additions and 29 deletions

View File

@@ -396,31 +396,6 @@ static int insert_check(VimState *state)
{
InsertState *s = (InsertState *)state;
// If typed something may trigger CursorHoldI again.
if (s->c != K_EVENT
// but not in CTRL-X mode, a script can't restore the state
&& ctrl_x_mode_normal()) {
did_cursorhold = false;
}
// Check if we need to cancel completion mode because the window
// or tab page was changed
if (ins_compl_active() && !ins_compl_win_active(curwin)) {
ins_compl_cancel();
}
// If the cursor was moved we didn't just insert a space
if (arrow_used) {
s->inserted_space = false;
}
if (can_cindent
&& cindent_on()
&& ctrl_x_mode_normal()
&& !ins_compl_active()) {
insert_do_cindent(s);
}
if (!revins_legal) {
revins_scol = -1; // reset on illegal motions
} else {
@@ -565,6 +540,7 @@ static int insert_check(VimState *state)
ins_compl_enable_autocomplete();
ins_compl_init_get_longest();
insert_do_complete(s);
insert_handle_key_post(s);
return 1;
}
}
@@ -648,7 +624,7 @@ static int insert_execute(VimState *state, int key)
if (ins_compl_preinsert_longest() && !ins_compl_is_match_selected()) {
ins_compl_insert(false, true);
ins_compl_init_get_longest();
return 1;
return 1; // continue
} else {
ins_compl_insert(false, false);
}
@@ -697,6 +673,7 @@ static int insert_execute(VimState *state, int key)
if ((s->c == Ctrl_V || s->c == Ctrl_Q) && ctrl_x_mode_cmdline()) {
insert_do_complete(s);
insert_handle_key_post(s);
return 1;
}
@@ -715,7 +692,6 @@ static int insert_execute(VimState *state, int key)
do_c_expr_indent();
return 1; // continue
}
// A key name preceded by a star means that indenting has to be
// done before inserting the key.
if (can_cindent && in_cinkeys(s->c, '*', s->line_is_white)
@@ -1285,6 +1261,7 @@ normalchar:
break;
} // end of switch (s->c)
insert_handle_key_post(s);
return 1; // continue
}
@@ -1311,6 +1288,31 @@ static void insert_do_cindent(InsertState *s)
}
}
static void insert_handle_key_post(InsertState *s)
{
// If typed something may trigger CursorHoldI again.
if (s->c != K_EVENT
// but not in CTRL-X mode, a script can't restore the state
&& ctrl_x_mode_normal()) {
did_cursorhold = false;
}
// Check if we need to cancel completion mode because the window
// or tab page was changed
if (ins_compl_active() && !ins_compl_win_active(curwin)) {
ins_compl_cancel();
}
// If the cursor was moved we didn't just insert a space
if (arrow_used) {
s->inserted_space = false;
}
if (can_cindent && cindent_on() && ctrl_x_mode_normal()) {
insert_do_cindent(s);
}
}
/// edit(): Start inserting text.
///
/// "cmdchar" can be:

View File

@@ -3760,7 +3760,7 @@ static int find_match(int lookfor, linenr_T ourscope)
/// Check that "cinkeys" contains the key "keytyped",
/// when == '*': Only if key is preceded with '*' (indent before insert)
/// when == '!': Only if key is preceded with '!' (don't insert)
/// when == ' ': Only if key is not preceded with '*' or '!' (indent afterwards)
/// when == ' ': Only if key is not preceded with '*' (indent afterwards)
///
/// "keytyped" can have a few special values:
/// KEY_OPEN_FORW :
@@ -3797,7 +3797,7 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
case '!':
try_match = (*look == '!'); break;
default:
try_match = (*look != '*') && (*look != '!'); break;
try_match = (*look != '*'); break;
}
if (*look == '*' || *look == '!') {
look++;

View File

@@ -24,6 +24,14 @@ describe('insert-mode', function()
eq(' x', curbuf_contents())
end)
it('indent works properly with autocompletion enabled #35381', function()
command('set autoindent cindent autocomplete')
feed('ivoid func(void) {<CR>')
expect('void func(void) {\n\t')
feed('}')
expect('void func(void) {\n}')
end)
it('CTRL-@', function()
-- Inserts last-inserted text, leaves insert-mode.
insert('hello')