refactor(core): group insert-mode globals in InsState #40712

Problem:
Insert-mode globals are scattered.

Solution:
Group them into one struct. Besides improving readability and
discoverability, this greatly helps with save/restore of an insert-mode
session.
This commit is contained in:
Justin M. Keyes
2026-07-13 09:06:04 -04:00
committed by GitHub
parent 07144616ca
commit 6ea01d37f8
15 changed files with 353 additions and 363 deletions

View File

@@ -472,7 +472,7 @@ struct file_buffer {
garray_T b_ucmds;
// start and end of an operator, also used for '[ and ']
pos_T b_op_start;
pos_T b_op_start_orig; // used for Insstart_orig
pos_T b_op_start_orig; // used for Ins.start_orig
pos_T b_op_end;
bool b_marks_read; // Have we read ShaDa marks yet?

View File

@@ -1007,7 +1007,7 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
char saved_char = NUL; // init for GCC
pos_T *pos;
bool do_si = may_do_si();
bool no_si = false; // reset did_si afterwards
bool no_si = false; // reset Ins.did_si afterwards
int first_char = NUL; // init for GCC
int vreplace_mode;
bool did_append; // appended a new line
@@ -1058,13 +1058,13 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
}
u_clearline(curbuf); // cannot do "U" command when adding lines
did_si = false;
ai_col = 0;
Ins.did_si = false;
Ins.ai_col = 0;
// If we just did an auto-indent, then we didn't type anything on
// the prior line, and it should be truncated. Do this even if 'ai' is not
// set because automatically inserting a comment leader also sets did_ai.
if (dir == FORWARD && did_ai) {
// set because automatically inserting a comment leader also sets Ins.did_ai.
if (dir == FORWARD && Ins.did_ai) {
trunc_line = true;
}
@@ -1169,14 +1169,14 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
// If last character is '{' do indent, without
// checking for "if" and the like.
if (last_char == '{') {
did_si = true; // do indent
Ins.did_si = true; // do indent
no_si = true; // don't delete it when '{' typed
// Look for "if" and the like, use 'cinwords'.
// Don't do this if the previous line ended in ';' or
// '}'.
} else if (last_char != ';' && last_char != '}'
&& cin_is_cinword(ptr)) {
did_si = true;
Ins.did_si = true;
}
}
} else { // dir == BACKWARD
@@ -1202,18 +1202,18 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
}
p = skipwhite(ptr);
if (*p == '}') { // if line starts with '}': do indent
did_si = true;
Ins.did_si = true;
} else { // can delete indent when '{' typed
can_si_back = true;
Ins.can_si_back = true;
}
}
curwin->w_cursor = old_cursor;
}
if (do_si) {
can_si = true;
Ins.can_si = true;
}
did_ai = true;
Ins.did_ai = true;
}
// May do indenting after opening a new line.
@@ -1224,7 +1224,7 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
// Find out if the current line starts with a comment leader.
// This may then be inserted in front of the new line.
end_comment_pending = NUL;
Ins.end_comment_pending = NUL;
if (flags & OPENLINE_DO_COM) {
lead_len = get_leader_len(saved_line, &lead_flags, dir == BACKWARD, true);
if (lead_len == 0 && curbuf->b_p_cin && do_cindent && dir == FORWARD
@@ -1288,14 +1288,14 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
while (*p && p[-1] != ':') { // find end of end flags
// Check whether we allow automatic ending of comments
if (*p == COM_AUTO_END) {
end_comment_pending = -1; // means we want to set it
Ins.end_comment_pending = -1; // means we want to set it
}
p++;
}
size_t n = copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
if (end_comment_pending == -1) { // we can set it now
end_comment_pending = (unsigned char)lead_end[n - 1];
if (Ins.end_comment_pending == -1) { // we can set it now
Ins.end_comment_pending = (unsigned char)lead_end[n - 1];
}
// If the end of the comment is in the same line, don't use
@@ -1357,15 +1357,15 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
// Check whether we allow automatic ending of comments
for (p2 = p; *p2 && *p2 != ':'; p2++) {
if (*p2 == COM_AUTO_END) {
end_comment_pending = -1; // means we want to set it
Ins.end_comment_pending = -1; // means we want to set it
}
}
if (end_comment_pending == -1) {
if (Ins.end_comment_pending == -1) {
// Find last character in end-comment string
while (*p2 && *p2 != ',') {
p2++;
}
end_comment_pending = (unsigned char)p2[-1];
Ins.end_comment_pending = (unsigned char)p2[-1];
}
break;
}
@@ -1558,14 +1558,14 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
// if a new indent will be set below, remove the indent that
// is in the comment leader
if (newindent || did_si) {
if (newindent || Ins.did_si) {
while (lead_len && ascii_iswhite(*leader)) {
lead_len--;
newcol--;
leader++;
}
}
did_si = can_si = false;
Ins.did_si = Ins.can_si = false;
} else if (comment_end != NULL) {
// We have finished a comment, so we don't use the leader.
// If this was a C-comment and 'ai' or 'si' is set do a normal
@@ -1633,10 +1633,10 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
}
strcat(leader, p_extra);
p_extra = leader;
did_ai = true; // So truncating blanks works with comments
Ins.did_ai = true; // So truncating blanks works with comments
less_cols -= lead_len;
} else {
end_comment_pending = NUL; // turns out there was no leader
Ins.end_comment_pending = NUL; // turns out there was no leader
}
curbuf_splice_pending++;
@@ -1675,7 +1675,7 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
} else {
// In MODE_VREPLACE state we are starting to replace the next line.
curwin->w_cursor.lnum++;
if (curwin->w_cursor.lnum >= Insstart.lnum + vr_lines_changed) {
if (curwin->w_cursor.lnum >= Ins.start.lnum + vr_lines_changed) {
// In case we NL to a new line, BS to the previous one, and NL
// again, we don't want to save the new line for undo twice.
u_save_cursor(); // errors are ignored!
@@ -1689,9 +1689,9 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
}
inhibit_delete_count++;
if (newindent || did_si) {
if (newindent || Ins.did_si) {
curwin->w_cursor.lnum++;
if (did_si) {
if (Ins.did_si) {
int sw = get_sw_value(curbuf);
if (p_sr) {
@@ -1712,7 +1712,7 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
}
less_cols -= curwin->w_cursor.col;
ai_col = curwin->w_cursor.col;
Ins.ai_col = curwin->w_cursor.col;
// In MODE_REPLACE state, for each character in the new indent, there
// must be a NUL on the replace stack, for when it is deleted with BS
@@ -1723,7 +1723,7 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
}
newcol += curwin->w_cursor.col;
if (no_si) {
did_si = false;
Ins.did_si = false;
}
}
inhibit_delete_count--;
@@ -1815,11 +1815,11 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
&& curbuf->b_p_ai) {
// do lisp indenting
fixthisline(get_lisp_indent);
ai_col = (colnr_T)getwhitecols_curline();
Ins.ai_col = (colnr_T)getwhitecols_curline();
} else if (do_cindent || (curbuf->b_p_ai && use_indentexpr_for_lisp())) {
// do 'cindent' or 'indentexpr' indenting
do_c_expr_indent();
ai_col = (colnr_T)getwhitecols_curline();
Ins.ai_col = (colnr_T)getwhitecols_curline();
}
}

View File

@@ -7431,7 +7431,7 @@ static void ex_startinsert(exarg_T *eap)
static void ex_stopinsert(exarg_T *eap)
{
restart_edit = 0;
stop_insert_mode = true;
Ins.stop_insert_mode = true;
clearmode();
}

View File

@@ -10,6 +10,7 @@
#include "nvim/ex_eval_defs.h"
#include "nvim/iconv_defs.h"
#include "nvim/input_defs.h"
#include "nvim/insert_defs.h"
#include "nvim/macros_defs.h"
#include "nvim/menu_defs.h"
#include "nvim/os/os_defs.h"
@@ -477,56 +478,22 @@ EXTERN linenr_T resel_VIsual_line_count; // number of lines
EXTERN colnr_T resel_VIsual_vcol; // nr of cols or end col
/// When pasting text with the middle mouse button in visual mode with
/// restart_edit set, remember where it started so we can set Insstart.
/// restart_edit set, remember where it started so we can set Ins.start.
EXTERN pos_T where_paste_started;
// This flag is used to make auto-indent work right on lines where only a
// <RETURN> or <ESC> is typed. It is set when an auto-indent is done, and
// reset when any other editing is done on the line. If an <ESC> or <RETURN>
// is received, and did_ai is true, the line is truncated.
EXTERN bool did_ai INIT( = false);
// Column of first char after autoindent. 0 when no autoindent done. Used
// when 'backspace' is 0, to avoid backspacing over autoindent.
EXTERN colnr_T ai_col INIT( = 0);
// This is a character which will end a start-middle-end comment when typed as
// the first character on a new line. It is taken from the last character of
// the "end" comment leader when the COM_AUTO_END flag is given for that
// comment end in 'comments'. It is only valid when did_ai is true.
EXTERN int end_comment_pending INIT( = NUL);
// This flag is set after a ":syncbind" to let the check_scrollbind() function
// know that it should not attempt to perform scrollbinding due to the scroll
// that was a result of the ":syncbind." (Otherwise, check_scrollbind() will
// undo some of the work done by ":syncbind.") -ralston
EXTERN bool did_syncbind INIT( = false);
// This flag is set when a smart indent has been performed. When the next typed
// character is a '{' the inserted tab will be deleted again.
EXTERN bool did_si INIT( = false);
// This flag is set after an auto indent. If the next typed character is a '}'
// one indent will be removed.
EXTERN bool can_si INIT( = false);
// This flag is set after an "O" command. If the next typed character is a '{'
// one indent will be removed.
EXTERN bool can_si_back INIT( = false);
EXTERN int old_indent INIT( = 0); ///< for ^^D command in insert mode
// w_cursor before formatting text.
EXTERN pos_T saved_cursor INIT( = { 0, 0, 0 });
// Stuff for insert mode.
EXTERN pos_T Insstart; // This is where the latest
// insert/append mode started.
// This is where the latest insert/append mode started. In contrast to
// Insstart, this won't be reset by certain keys and is needed for
// op_insert(), to detect correctly where inserting by the user started.
EXTERN pos_T Insstart_orig;
// Stuff for insert mode: the current insert session.
EXTERN InsState Ins;
// Stuff for MODE_VREPLACE state.
EXTERN linenr_T orig_line_count INIT( = 0); // Line count when "gR" started
@@ -593,10 +560,6 @@ EXTERN int u_sync_once INIT( = 0); // Call u_sync() once when evaluating
EXTERN bool force_restart_edit INIT( = false); // force restart_edit after
// ex_normal returns
EXTERN int restart_edit INIT( = 0); // call edit when next cmd finished
EXTERN bool arrow_used; // Normally false, set to true after
// hitting cursor key in insert mode.
// Used by vgetorpeek() to decide when
// to call u_sync()
EXTERN bool ins_at_eol INIT( = false); // put cursor after eol when
// restarting edit after CTRL-O
@@ -651,7 +614,6 @@ EXTERN bool typebuf_was_empty INIT( = false);
EXTERN int ex_normal_busy INIT( = 0); // recursiveness of ex_normal()
EXTERN int expr_map_lock INIT( = 0); // running expr mapping, prevent use of ex_normal() and text changes
EXTERN bool ignore_script INIT( = false); // ignore script input
EXTERN bool stop_insert_mode; // for ":stopinsert"
EXTERN bool KeyTyped; // true if user typed current char
EXTERN int KeyStuffed; // true if current char from stuffbuf
EXTERN int maptick INIT( = 0); // tick for each non-mapped char

View File

@@ -1082,7 +1082,7 @@ void ins_try_si(int c)
pos_T *pos;
// do some very smart indenting when entering '{' or '}'
if (((did_si || can_si_back) && c == '{') || (can_si && c == '}' && inindent(0))) {
if (((Ins.did_si || Ins.can_si_back) && c == '{') || (Ins.can_si && c == '}' && inindent(0))) {
pos_T old_pos;
char *ptr;
int i;
@@ -1116,7 +1116,7 @@ void ins_try_si(int c)
// when inserting '{' after "O" reduce indent, but not
// more than indent of previous line
temp = true;
if (c == '{' && can_si_back && curwin->w_cursor.lnum > 1) {
if (c == '{' && Ins.can_si_back && curwin->w_cursor.lnum > 1) {
old_pos = curwin->w_cursor;
i = get_indent();
while (curwin->w_cursor.lnum > 1) {
@@ -1139,14 +1139,14 @@ void ins_try_si(int c)
}
// set indent of '#' always to 0
if (curwin->w_cursor.col > 0 && can_si && c == '#' && inindent(0)) {
if (curwin->w_cursor.col > 0 && Ins.can_si && c == '#' && inindent(0)) {
// remember current indent for next line
old_indent = get_indent();
set_indent(0, SIN_CHANGED);
}
// Adjust ai_col, the char at this position can be deleted.
ai_col = MIN(ai_col, curwin->w_cursor.col);
// Adjust Ins.ai_col, the char at this position can be deleted.
Ins.ai_col = MIN(Ins.ai_col, curwin->w_cursor.col);
}
/// Insert an indent (for <Tab> or CTRL-T) or delete an indent (for CTRL-D).
@@ -1159,7 +1159,7 @@ void ins_try_si(int c)
/// @param call_changed_bytes call changed_bytes()
void change_indent(int type, int amount, int round, bool call_changed_bytes)
{
int insstart_less; // reduction for Insstart.col
int insstart_less; // reduction for Ins.start.col
colnr_T orig_col = 0; // init for GCC
char *orig_line = NULL; // init for GCC
@@ -1280,17 +1280,17 @@ void change_indent(int type, int amount, int round, bool call_changed_bytes)
// May have to adjust the start of the insert.
if (State & MODE_INSERT) {
if (curwin->w_cursor.lnum == Insstart.lnum && Insstart.col != 0) {
if ((int)Insstart.col <= insstart_less) {
Insstart.col = 0;
if (curwin->w_cursor.lnum == Ins.start.lnum && Ins.start.col != 0) {
if ((int)Ins.start.col <= insstart_less) {
Ins.start.col = 0;
} else {
Insstart.col -= insstart_less;
Ins.start.col -= insstart_less;
}
}
if ((int)ai_col <= insstart_less) {
ai_col = 0;
if ((int)Ins.ai_col <= insstart_less) {
Ins.ai_col = 0;
} else {
ai_col -= insstart_less;
Ins.ai_col -= insstart_less;
}
}
@@ -1921,7 +1921,7 @@ void fixthisline(IndentGetter get_the_indent)
change_indent(INDENT_SET, amount, false, true);
if (linewhite(curwin->w_cursor.lnum)) {
did_ai = true; // delete the indent if the line stays empty
Ins.did_ai = true; // delete the indent if the line stays empty
}
}

View File

@@ -1311,7 +1311,7 @@ static void ungetchars(int len, bool recorded)
/// - When no_u_sync is non-zero.
void may_sync_undo(void)
{
if ((!(State & (MODE_INSERT | MODE_CMDLINE)) || arrow_used)
if ((!(State & (MODE_INSERT | MODE_CMDLINE)) || Ins.arrow_used)
&& curscript < 0) {
u_sync(false);
}
@@ -2868,7 +2868,7 @@ static int vgetorpeek(bool advance)
// we are expecting to truncate the trailing
// white-space, so find the last non-white
// character -- webb
if (did_ai && *skipwhite(get_cursor_line_ptr() + curwin->w_cursor.col) == NUL) {
if (Ins.did_ai && *skipwhite(get_cursor_line_ptr() + curwin->w_cursor.col) == NUL) {
curwin->w_wcol = 0;
ptr = get_cursor_line_ptr();
char *endptr = ptr + curwin->w_cursor.col;

File diff suppressed because it is too large Load Diff

50
src/nvim/insert_defs.h Normal file
View File

@@ -0,0 +1,50 @@
#pragma once
#include <stdbool.h>
#include "nvim/pos_defs.h"
#include "nvim/types_defs.h"
/// Insert-mode session state: the in-progress insert session, as one global "group" (Ins), so the
/// insert session can be saved/restored as a whole around nested edit() mini-sessions (e.g.
/// a future multicursor live-mirror).
typedef struct {
pos_T start; ///< Where the latest insert/append mode started
pos_T start_orig; ///< Where the latest insert/append mode started. In contrast to
///< "start", this won't be reset by certain keys and is needed for
///< op_insert(), to detect correctly where inserting by the user
///< started.
colnr_T start_textlen; ///< length of line when insert started
colnr_T start_blank_vcol; ///< vcol for first inserted blank
bool arrow_used; ///< Normally false, set to true after hitting a cursor key in insert
///< mode. Used by vgetorpeek() to decide when to call u_sync().
bool stop_insert_mode; ///< for ":stopinsert"
bool can_cindent; ///< may do cindenting on this line
bool need_undo; ///< call u_save() before inserting a char. Set when edit() is
///< called; after that arrow_used is used.
bool did_ai; ///< Makes auto-indent work right on lines where only a <CR> or
///< <Esc> is typed: set when an auto-indent is done, reset when any
///< other editing is done on the line. If an <Esc> or <CR> is
///< received and did_ai is true, the line is truncated.
colnr_T ai_col; ///< Column of first char after autoindent. 0 when no autoindent
///< done. Used when 'backspace' is 0, to avoid backspacing over
///< autoindent.
int end_comment_pending; ///< A character which will end a start-middle-end comment when
///< typed as the first character on a new line. Taken from the last
///< character of the "end" comment leader when the COM_AUTO_END
///< flag is given for that comment end in 'comments'. Only valid
///< when did_ai is true.
bool did_si; ///< Set when a smart indent has been performed: when the next
///< typed character is a '{' the inserted tab will be deleted again.
bool can_si; ///< after an auto indent: a typed '}' removes one indent
bool can_si_back; ///< after an "O" command: a typed '{' removes one indent
bool update_start_orig; ///< set start_orig to start
int new_insert_skip; ///< number of chars in front of the current insert
int did_restart_edit; ///< "restart_edit" when edit() was called
bool revins_on; ///< reverse insert mode on
int revins_chars; ///< how much to skip after edit
int revins_legal; ///< was the last char "legal"?
int revins_scol; ///< start column of revins session
TriState dont_sync_undo; ///< CTRL-G U prevents syncing undo for the next left/right cursor key
linenr_T o_lnum; ///< "o" command's line, for "CTRL-O ." that adds a line (ins_at_eol)
} InsState;

View File

@@ -2673,7 +2673,7 @@ static bool ins_compl_stop(const int c, const int prev_mode, bool retval)
}
// only format when something was inserted
if (!arrow_used && !ins_need_undo_get() && c != Ctrl_E) {
if (!Ins.arrow_used && !ins_need_undo_get() && c != Ctrl_E) {
insertchar(NUL, 0, -1);
}
@@ -6064,16 +6064,16 @@ static void ins_compl_continue_search(char *line)
/// start insert mode completion
static int ins_compl_start(void)
{
const bool save_did_ai = did_ai;
const bool save_did_ai = Ins.did_ai;
// First time we hit ^N or ^P (in a row, I mean)
did_ai = false;
did_si = false;
can_si = false;
can_si_back = false;
Ins.did_ai = false;
Ins.did_si = false;
Ins.can_si = false;
Ins.can_si_back = false;
if (stop_arrow() == FAIL) {
did_ai = save_did_ai;
Ins.did_ai = save_did_ai;
return FAIL;
}
@@ -6109,8 +6109,8 @@ static int ins_compl_start(void)
if (compl_get_info(line, startcol, curs_col, &line_invalid) == FAIL) {
if (ctrl_x_mode_function() || ctrl_x_mode_omni()
|| thesaurus_func_complete(ctrl_x_mode)) {
// restore did_ai, so that adding comment leader works
did_ai = save_did_ai;
// restore Ins.did_ai, so that adding comment leader works
Ins.did_ai = save_did_ai;
}
return FAIL;
}
@@ -6168,7 +6168,7 @@ static int ins_compl_start(void)
API_CLEAR_STRING(compl_pattern);
API_CLEAR_STRING(compl_orig_text);
kv_destroy(compl_orig_extmarks);
did_ai = save_did_ai;
Ins.did_ai = save_did_ai;
return FAIL;
}
@@ -6183,7 +6183,7 @@ static int ins_compl_start(void)
ui_flush();
}
did_ai = save_did_ai;
Ins.did_ai = save_did_ai;
return OK;
}

View File

@@ -867,7 +867,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent)
}
prep_redo(regname, count, NUL, c1, NUL, c2, NUL);
// Remember where the paste started, so in edit() Insstart can be set to this position
// Remember where the paste started, so in edit() Ins.start can be set to this position
if (restart_edit != 0) {
where_paste_started = curwin->w_cursor;
}

View File

@@ -5786,7 +5786,7 @@ static void nv_dot(cmdarg_T *cap)
// If "restart_edit" is true, the last but one command is repeated
// instead of the last command (inserting text). This is used for
// CTRL-O <.> in insert mode.
if (start_redo(cap->count0, restart_edit != 0 && !arrow_used) == false) {
if (start_redo(cap->count0, restart_edit != 0 && !Ins.arrow_used) == false) {
clearopbeep(cap->oap);
}
}

View File

@@ -883,8 +883,8 @@ int op_delete(oparg_T *oap)
}
if (curbuf->b_p_ai) { // don't delete indent
beginline(BL_WHITE); // cursor on first non-white
did_ai = true; // delete the indent when ESC hit
ai_col = curwin->w_cursor.col;
Ins.did_ai = true; // delete the indent when ESC hit
Ins.ai_col = curwin->w_cursor.col;
} else {
beginline(0); // cursor in column 0
}
@@ -1637,8 +1637,8 @@ void op_insert(oparg_T *oap, int count1)
if (oap->op_type == OP_APPEND) {
add += bd.textlen;
// account for pressing cursor in insert mode when '$' was used
if (bd.is_MAX && start_insert.lnum == Insstart.lnum && start_insert.col > Insstart.col) {
offset = start_insert.col - Insstart.col;
if (bd.is_MAX && start_insert.lnum == Ins.start.lnum && start_insert.col > Ins.start.col) {
offset = start_insert.col - Ins.start.col;
add -= offset;
if (oap->end_vcol > offset) {
oap->end_vcol -= offset + 1;
@@ -1679,7 +1679,7 @@ int op_change(oparg_T *oap)
colnr_T l = oap->start.col;
if (oap->motion_type == kMTLineWise) {
l = 0;
can_si = may_do_si(); // Like opening a new line, do smart indent
Ins.can_si = may_do_si(); // Like opening a new line, do smart indent
}
// First delete the text in the region. In an empty buffer only need to

View File

@@ -905,7 +905,7 @@ bool terminal_enter(void)
TerminalState s[1] = { 0 };
s->term = buf->terminal;
s->cursor_visible = true; // Assume visible; may change via refresh_cursor later.
stop_insert_mode = false;
Ins.stop_insert_mode = false;
// Ensure the terminal is properly sized. Ideally window size management
// code should always have resized the terminal already, but check here to
@@ -1053,7 +1053,7 @@ static int terminal_check(VimState *state)
// Shouldn't reach here when pressing a key to close the terminal buffer.
assert(!s->close || (s->term->buf_handle == 0 && s->term != curbuf->terminal));
if (stop_insert_mode || !terminal_check_focus(s)) {
if (Ins.stop_insert_mode || !terminal_check_focus(s)) {
return 0;
}

View File

@@ -164,8 +164,8 @@ void internal_format(int textwidth, int second_indent, int flags, bool format_on
// Stop at first entered white when 'formatoptions' has 'v'
while ((!fo_ins_blank && !has_format_option(FO_INS_VI))
|| (flags & INSCHAR_FORMAT)
|| curwin->w_cursor.lnum != Insstart.lnum
|| curwin->w_cursor.col >= Insstart.col) {
|| curwin->w_cursor.lnum != Ins.start.lnum
|| curwin->w_cursor.col >= Ins.start.col) {
if (curwin->w_cursor.col == startcol && c != NUL) {
cc = c;
} else {
@@ -438,10 +438,10 @@ void internal_format(int textwidth, int second_indent, int flags, bool format_on
haveto_redraw = true;
set_can_cindent(true);
// moved the cursor, don't autoindent or cindent now
did_ai = false;
did_si = false;
can_si = false;
can_si_back = false;
Ins.did_ai = false;
Ins.did_si = false;
Ins.can_si = false;
Ins.can_si_back = false;
line_breakcheck();
}

View File

@@ -2517,8 +2517,8 @@ void leaving_window(win_T *const win)
// When leaving the window (or closing the window) was done from a
// callback we need to break out of the Insert mode loop and restart Insert
// mode when entering the window again.
if ((State & MODE_INSERT) && !stop_insert_mode) {
stop_insert_mode = true;
if ((State & MODE_INSERT) && !Ins.stop_insert_mode) {
Ins.stop_insert_mode = true;
if (win->w_buffer->b_prompt_insert == NUL) {
win->w_buffer->b_prompt_insert = 'A';
}
@@ -2540,7 +2540,7 @@ void entering_window(win_T *const win)
// When switching to a prompt buffer that was in Insert mode, don't stop
// Insert mode, it may have been set in leaving_window().
if (win->w_buffer->b_prompt_insert != NUL) {
stop_insert_mode = false;
Ins.stop_insert_mode = false;
}
// When entering the prompt window restart Insert mode if we were in Insert