diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 33e9f5a7e9..b5c83572c8 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -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? diff --git a/src/nvim/change.c b/src/nvim/change.c index 3c940788a9..bdc6b614c8 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -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(); } } diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index fea7eafc9d..cf0e7137a3 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -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(); } diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 964eb9cce4..9f74783aeb 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -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 -// or is typed. It is set when an auto-indent is done, and -// reset when any other editing is done on the line. If an or -// 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 diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 005a4ec579..98d150680f 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -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 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 } } diff --git a/src/nvim/input.c b/src/nvim/input.c index f96af3ca4b..347a3b726c 100644 --- a/src/nvim/input.c +++ b/src/nvim/input.c @@ -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; diff --git a/src/nvim/insert.c b/src/nvim/insert.c index 7cfa94f4a0..1bf544d8ef 100644 --- a/src/nvim/insert.c +++ b/src/nvim/insert.c @@ -119,31 +119,9 @@ enum { /// which is not allowed. static bool compl_busy = false; -static colnr_T Insstart_textlen; // length of line when insert started -static colnr_T Insstart_blank_vcol; // vcol for first inserted blank -static bool update_Insstart_orig = true; // set Insstart_orig to Insstart - /// the text of the previous insert, K_SPECIAL is escaped static String last_insert = STRING_INIT; static int last_insert_skip; // nr of chars in front of previous insert -static int new_insert_skip; // nr of chars in front of current insert -static int did_restart_edit; // "restart_edit" when calling edit() - -static bool can_cindent; // may do cindenting on this line - -static bool revins_on; // reverse insert mode on -static int revins_chars; // how much to skip after edit -static int revins_legal; // was the last char 'legal'? -static int revins_scol; // start column of revins session - -static bool ins_need_undo; // call u_save() before inserting a - // char. Set when edit() is called. - // after that arrow_used is used. - -static TriState dont_sync_undo = kFalse; // CTRL-G U prevents syncing undo - // for the next left/right cursor key - -static linenr_T o_lnum = 0; static kvec_t(char) replace_stack = KV_INITIAL_VALUE; @@ -180,12 +158,12 @@ static void insert_enter(InsertState *s) s->cmdchar_todo = s->cmdchar; s->ins_just_started = true; // Remember whether editing was restarted after CTRL-O - did_restart_edit = restart_edit; + Ins.did_restart_edit = restart_edit; // sleep before redrawing, needed for "CTRL-O :" that results in an // error message msg_check_for_delay(true); - // set Insstart_orig to Insstart - update_Insstart_orig = true; + // set Ins.start_orig to Ins.start + Ins.update_start_orig = true; ins_compl_clear(); // clear stuff for CTRL-X mode @@ -221,22 +199,22 @@ static void insert_enter(InsertState *s) } } - // When doing a paste with the middle mouse button, Insstart is set to + // When doing a paste with the middle mouse button, Ins.start is set to // where the paste started. if (where_paste_started.lnum != 0) { - Insstart = where_paste_started; + Ins.start = where_paste_started; } else { - Insstart = curwin->w_cursor; + Ins.start = curwin->w_cursor; if (s->startln) { - Insstart.col = 0; + Ins.start.col = 0; } } - Insstart_textlen = linetabsize_str(get_cursor_line_ptr()); - Insstart_blank_vcol = MAXCOL; + Ins.start_textlen = linetabsize_str(get_cursor_line_ptr()); + Ins.start_blank_vcol = MAXCOL; - if (!did_ai) { - ai_col = 0; + if (!Ins.did_ai) { + Ins.ai_col = 0; } if (s->cmdchar != NUL && restart_edit == 0) { @@ -268,7 +246,7 @@ static void insert_enter(InsertState *s) } may_trigger_modechanged(); - stop_insert_mode = false; + Ins.stop_insert_mode = false; // need to position cursor again when on a TAB and // when on a char with inline virtual text @@ -287,13 +265,13 @@ static void insert_enter(InsertState *s) setmouse(); clear_showcmd(); // there is no reverse replace mode - revins_on = (State == MODE_INSERT && p_ri); - if (revins_on) { + Ins.revins_on = (State == MODE_INSERT && p_ri); + if (Ins.revins_on) { undisplay_dollar(); } - revins_chars = 0; - revins_legal = 0; - revins_scol = -1; + Ins.revins_chars = 0; + Ins.revins_legal = 0; + Ins.revins_scol = -1; // Handle restarting Insert mode. // Don't do this for "CTRL-O ." (repeat an insert): we get here with @@ -301,7 +279,7 @@ static void insert_enter(InsertState *s) if (restart_edit != 0 && stuff_empty()) { // After a paste we consider text typed to be part of the insert for // the pasted text. You can backspace over the pasted text too. - arrow_used = where_paste_started.lnum == 0; + Ins.arrow_used = where_paste_started.lnum == 0; restart_edit = 0; // If the cursor was after the end-of-line before the CTRL-O and it is @@ -312,7 +290,7 @@ static void insert_enter(InsertState *s) validate_virtcol(curwin); update_curswant(); const char *ptr; - if (((ins_at_eol && curwin->w_cursor.lnum == o_lnum) + if (((ins_at_eol && curwin->w_cursor.lnum == Ins.o_lnum) || curwin->w_curswant > curwin->w_virtcol) && *(ptr = get_cursor_line_ptr() + curwin->w_cursor.col) != NUL) { if (ptr[1] == NUL) { @@ -326,19 +304,19 @@ static void insert_enter(InsertState *s) } ins_at_eol = false; } else { - arrow_used = false; + Ins.arrow_used = false; } // we are in insert mode now, don't need to start it anymore need_start_insertmode = false; // Need to save the line for undo before inserting the first char. - ins_need_undo = true; + Ins.need_undo = true; where_paste_started.lnum = 0; - can_cindent = true; + Ins.can_cindent = true; // The cursor line is not in a closed fold, unless restarting. - if (did_restart_edit == 0) { + if (Ins.did_restart_edit == 0) { foldOpenCursor(); } @@ -350,7 +328,7 @@ static void insert_enter(InsertState *s) s->i = showmode(); } - if (did_restart_edit == 0) { + if (Ins.did_restart_edit == 0) { change_warning(curbuf, s->i == 0 ? 0 : s->i + 1); } @@ -360,7 +338,7 @@ static void insert_enter(InsertState *s) // Get the current length of the redo buffer, those characters have to be // skipped if we want to get to the inserted characters. String inserted = get_inserted(); - new_insert_skip = (int)inserted.size; + Ins.new_insert_skip = (int)inserted.size; if (inserted.data != NULL) { xfree(inserted.data); } @@ -375,10 +353,10 @@ static void insert_enter(InsertState *s) // Drop a pending autocomplete so it does not outlive Insert mode. ins_compl_clear_autocomplete_delay(); - // Always update o_lnum, so that a "CTRL-O ." that adds a line + // Always update Ins.o_lnum, so that a "CTRL-O ." that adds a line // still puts the cursor back after the inserted text. if (ins_at_eol) { - o_lnum = curwin->w_cursor.lnum; + Ins.o_lnum = curwin->w_cursor.lnum; } pum_check_clear(); @@ -405,35 +383,35 @@ static int insert_check(VimState *state) { InsertState *s = (InsertState *)state; - if (!revins_legal) { - revins_scol = -1; // reset on illegal motions + if (!Ins.revins_legal) { + Ins.revins_scol = -1; // reset on illegal motions } else { - revins_legal = 0; + Ins.revins_legal = 0; } - if (arrow_used) { // don't repeat insert when arrow key used + if (Ins.arrow_used) { // don't repeat insert when arrow key used s->count = 0; } - if (update_Insstart_orig) { - Insstart_orig = Insstart; + if (Ins.update_start_orig) { + Ins.start_orig = Ins.start; } - if (curbuf->terminal && !stop_insert_mode) { + if (curbuf->terminal && !Ins.stop_insert_mode) { // Exit Insert mode and go to Terminal mode. - stop_insert_mode = true; + Ins.stop_insert_mode = true; restart_edit = 'I'; stuffcharReadbuff(K_NOP); } - if (stop_insert_mode && !ins_compl_active()) { + if (Ins.stop_insert_mode && !ins_compl_active()) { // ":stopinsert" used s->count = 0; return 0; // exit insert mode } // set curwin->w_curswant for next K_DOWN or K_UP - if (!arrow_used) { + if (!Ins.arrow_used) { curwin->w_set_curswant = true; } @@ -532,10 +510,10 @@ static int insert_check(VimState *state) } // After using CTRL-G U the next cursor key will not break undo. - if (dont_sync_undo == kNone) { - dont_sync_undo = kTrue; + if (Ins.dont_sync_undo == kNone) { + Ins.dont_sync_undo = kTrue; } else { - dont_sync_undo = kFalse; + Ins.dont_sync_undo = kFalse; } // Trigger autocomplete when entering Insert mode, either directly @@ -565,7 +543,7 @@ static int insert_check(VimState *state) static int insert_execute(VimState *state, int key) { InsertState *const s = (InsertState *)state; - if (stop_insert_mode) { + if (Ins.stop_insert_mode) { // Insert mode ended, possibly from a callback. if (key != K_IGNORE && key != K_NOP) { vungetc(key); @@ -711,7 +689,7 @@ static int insert_execute(VimState *state, int key) } // 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) + if (Ins.can_cindent && in_cinkeys(s->c, '*', s->line_is_white) && stop_arrow() == OK) { do_c_expr_indent(); } @@ -973,8 +951,8 @@ static int insert_handle_key(InsertState *s) } else if (s->c == K_EVENT) { state_handle_k_event(); // If CTRL-G U was used apply it to the next typed key. - if (dont_sync_undo == kTrue) { - dont_sync_undo = kNone; + if (Ins.dont_sync_undo == kTrue) { + Ins.dont_sync_undo = kNone; } } else if (s->c == K_COMMAND) { do_cmdline(NULL, getcmdkeycmd, NULL, 0); @@ -1006,15 +984,15 @@ static int insert_handle_key(InsertState *s) && tick != buf_get_changedtick(curbuf))) { // The K_EVENT, K_COMMAND, or K_LUA synced undo or changed this buffer. // Save the cursor line before the next typed edit. - ins_need_undo = true; + Ins.need_undo = true; } break; } case K_COMPLETE_DELAY: // 'autocompletedelay' expired // If CTRL-G U was used apply it to the next typed key. - if (dont_sync_undo == kTrue) { - dont_sync_undo = kNone; + if (Ins.dont_sync_undo == kTrue) { + Ins.dont_sync_undo = kNone; } ins_compl_clear_autocomplete_delay(); if (!ins_compl_has_autocomplete() || char_avail() || curwin->w_cursor.col == 0) { @@ -1266,11 +1244,11 @@ normalchar: if (s->c == ' ') { s->inserted_space = true; if (inindent(0)) { - can_cindent = false; + Ins.can_cindent = false; } - if (Insstart_blank_vcol == MAXCOL - && curwin->w_cursor.lnum == Insstart.lnum) { - Insstart_blank_vcol = get_nolist_virtcol(); + if (Ins.start_blank_vcol == MAXCOL + && curwin->w_cursor.lnum == Ins.start.lnum) { + Ins.start_blank_vcol = get_nolist_virtcol(); } } @@ -1283,8 +1261,8 @@ normalchar: || (!echeck_abbr((s->c >= 0x100) ? (s->c + ABBR_OFF) : s->c) && s->c != Ctrl_RSB)) { insert_special(s->c, false, false); - revins_legal++; - revins_chars++; + Ins.revins_legal++; + Ins.revins_chars++; } auto_format(false, true); @@ -1314,7 +1292,7 @@ static void insert_do_complete(InsertState *s) } disable_fold_update--; compl_busy = false; - can_si = may_do_si(); // allow smartindenting + Ins.can_si = may_do_si(); // allow smartindenting } static void insert_do_cindent(InsertState *s) @@ -1345,11 +1323,11 @@ static void insert_handle_key_post(InsertState *s) } // If the cursor was moved we didn't just insert a space - if (arrow_used) { + if (Ins.arrow_used) { s->inserted_space = false; } - if (can_cindent && cindent_on() && ctrl_x_mode_normal()) { + if (Ins.can_cindent && cindent_on() && ctrl_x_mode_normal()) { insert_do_cindent(s); } } @@ -1418,7 +1396,7 @@ bool edit(int cmdchar, bool startln, int count) bool ins_need_undo_get(void) { - return ins_need_undo; + return Ins.need_undo; } /// Redraw for Insert mode. @@ -1539,8 +1517,8 @@ static void ins_ctrl_v(void) } clear_showcmd(); insert_special(c, true, true); - revins_chars++; - revins_legal++; + Ins.revins_chars++; + Ins.revins_legal++; } // Put a character directly onto the screen. It's not stored in a buffer. @@ -1660,14 +1638,14 @@ static void init_prompt(int cmdchar_todo) } // Insert always starts after the prompt, allow editing text after it. - if (Insstart_orig.lnum != curbuf->b_prompt_start.mark.lnum - || Insstart_orig.col != curbuf->b_prompt_start.mark.col) { - Insstart.lnum = curbuf->b_prompt_start.mark.lnum; - Insstart.col = curbuf->b_prompt_start.mark.col; - Insstart_orig = Insstart; - Insstart_textlen = Insstart.col; - Insstart_blank_vcol = MAXCOL; - arrow_used = false; + if (Ins.start_orig.lnum != curbuf->b_prompt_start.mark.lnum + || Ins.start_orig.col != curbuf->b_prompt_start.mark.col) { + Ins.start.lnum = curbuf->b_prompt_start.mark.lnum; + Ins.start.col = curbuf->b_prompt_start.mark.col; + Ins.start_orig = Ins.start; + Ins.start_textlen = Ins.start.col; + Ins.start_blank_vcol = MAXCOL; + Ins.arrow_used = false; } if (cmdchar_todo == 'A') { @@ -1991,11 +1969,11 @@ void insertchar(int c, int flags, int second_indent) && !((State & REPLACE_FLAG) && !(State & VREPLACE_FLAG) && *get_cursor_pos_ptr() != NUL) - && (curwin->w_cursor.lnum != Insstart.lnum + && (curwin->w_cursor.lnum != Ins.start.lnum || ((!has_format_option(FO_INS_LONG) - || Insstart_textlen <= (colnr_T)textwidth) + || Ins.start_textlen <= (colnr_T)textwidth) && (!fo_ins_blank - || Insstart_blank_vcol <= (colnr_T)textwidth)))))) { + || Ins.start_blank_vcol <= (colnr_T)textwidth)))))) { // Format with 'formatexpr' when it's set. Use internal formatting // when 'formatexpr' isn't set or it returns non-zero. bool do_internal = true; @@ -2007,7 +1985,7 @@ void insertchar(int c, int flags, int second_indent) do_internal = (fex_format(curwin->w_cursor.lnum, 1, c) != 0); // It may be required to save for undo again, e.g. when setline() // was called. - ins_need_undo = true; + Ins.need_undo = true; } if (do_internal) { internal_format(textwidth, second_indent, flags, c == NUL, c); @@ -2019,7 +1997,7 @@ void insertchar(int c, int flags, int second_indent) } // Check whether this character should end a comment. - if (did_ai && c == end_comment_pending) { + if (Ins.did_ai && c == Ins.end_comment_pending) { char lead_end[COM_MAX_LEN]; // end-comment string // Need to remove existing (middle) comment leader and insert end @@ -2053,7 +2031,7 @@ void insertchar(int c, int flags, int second_indent) // Check some expected things before we go on if (i >= 0 && end_len > 0 - && (uint8_t)lead_end[end_len - 1] == end_comment_pending) { + && (uint8_t)lead_end[end_len - 1] == Ins.end_comment_pending) { // Backspace over all the stuff we want to replace backspace_until_column(i); @@ -2063,12 +2041,12 @@ void insertchar(int c, int flags, int second_indent) } } } - end_comment_pending = NUL; + Ins.end_comment_pending = NUL; - 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 there's any pending input, grab up to INPUT_BUFLEN at once. // This speeds up normal text input considerably. @@ -2189,10 +2167,10 @@ static void start_arrow_with_change(pos_T *end_insert_pos, bool end_change) /// @param end_change end undoable change static void start_arrow_common(pos_T *end_insert_pos, bool end_change) { - if (!arrow_used && end_change) { // something has been inserted + if (!Ins.arrow_used && end_change) { // something has been inserted AppendToRedobuff(ESC_STR); stop_insert(end_insert_pos, false, false); - arrow_used = true; // This means we stopped the current insert. + Ins.arrow_used = true; // This means we stopped the current insert. } check_spell_redraw(); } @@ -2214,46 +2192,46 @@ static void check_spell_redraw(void) // Returns FAIL if undo is impossible, shouldn't insert then. int stop_arrow(void) { - if (arrow_used) { - Insstart = curwin->w_cursor; // new insertion starts here - if (Insstart.col > Insstart_orig.col && !ins_need_undo) { + if (Ins.arrow_used) { + Ins.start = curwin->w_cursor; // new insertion starts here + if (Ins.start.col > Ins.start_orig.col && !Ins.need_undo) { // Don't update the original insert position when moved to the // right, except when nothing was inserted yet. - update_Insstart_orig = false; + Ins.update_start_orig = false; } - Insstart_textlen = linetabsize_str(get_cursor_line_ptr()); + Ins.start_textlen = linetabsize_str(get_cursor_line_ptr()); if (u_save_cursor() == OK) { - arrow_used = false; - ins_need_undo = false; + Ins.arrow_used = false; + Ins.need_undo = false; } - ai_col = 0; + Ins.ai_col = 0; if (State & VREPLACE_FLAG) { orig_line_count = curbuf->b_ml.ml_line_count; vr_lines_changed = 1; } ResetRedobuff(); AppendToRedobuff("1i"); // Pretend we start an insertion. - new_insert_skip = 2; - } else if (ins_need_undo) { + Ins.new_insert_skip = 2; + } else if (Ins.need_undo) { if (u_save_cursor() == OK) { // A command or event may have moved the cursor before the next - // edit. Pull Insstart back only when the cursor moved above it, + // edit. Pull Ins.start back only when the cursor moved above it, // so that later edits can properly decide whether an extra undo - // entry is needed. Advancing Insstart would mis-place '[ after a + // entry is needed. Advancing Ins.start would mis-place '[ after a // register paste. - if (lt(curwin->w_cursor, Insstart)) { - Insstart = curwin->w_cursor; - Insstart_textlen = (colnr_T)linetabsize_str(get_cursor_line_ptr()); + if (lt(curwin->w_cursor, Ins.start)) { + Ins.start = curwin->w_cursor; + Ins.start_textlen = (colnr_T)linetabsize_str(get_cursor_line_ptr()); } - ins_need_undo = false; + Ins.need_undo = false; } } // Always open fold at the cursor line when inserting something. foldOpenCursor(); - return arrow_used || ins_need_undo ? FAIL : OK; + return Ins.arrow_used || Ins.need_undo ? FAIL : OK; } /// Do a few things to stop inserting. @@ -2271,22 +2249,22 @@ static void stop_insert(pos_T *end_insert_pos, int esc, int nomove) // Don't do it when "restart_edit" was set and nothing was inserted, // otherwise CTRL-O w and then will clear "last_insert". String inserted = get_inserted(); - int added = inserted.data == NULL ? 0 : (int)inserted.size - new_insert_skip; - if (did_restart_edit == 0 || added > 0) { + int added = inserted.data == NULL ? 0 : (int)inserted.size - Ins.new_insert_skip; + if (Ins.did_restart_edit == 0 || added > 0) { xfree(last_insert.data); last_insert = inserted; // structure copy - last_insert_skip = added < 0 ? 0 : new_insert_skip; + last_insert_skip = added < 0 ? 0 : Ins.new_insert_skip; } else { xfree(inserted.data); } - if (!arrow_used && end_insert_pos != NULL) { + if (!Ins.arrow_used && end_insert_pos != NULL) { int cc; // Auto-format now. It may seem strange to do this when stopping an // insertion (or moving the cursor), but it's required when appending // a line and having it end in a space. But only do it when something // was actually inserted, otherwise undo won't work. - if (!ins_need_undo && has_format_option(FO_AUTO)) { + if (!Ins.need_undo && has_format_option(FO_AUTO)) { pos_T tpos = curwin->w_cursor; // When the cursor is at the end of the line after a space the @@ -2325,9 +2303,9 @@ static void stop_insert(pos_T *end_insert_pos, int esc, int nomove) // Do this when ESC was used or moving the cursor up/down. // Check for the old position still being valid, just in case the text // got changed unexpectedly. - if (!nomove && did_ai && (esc || (vim_strchr(p_cpo, CPO_INDENT) == NULL - && curwin->w_cursor.lnum != - end_insert_pos->lnum)) + if (!nomove && Ins.did_ai && (esc || (vim_strchr(p_cpo, CPO_INDENT) == NULL + && curwin->w_cursor.lnum != + end_insert_pos->lnum)) && end_insert_pos->lnum <= curbuf->b_ml.ml_line_count) { pos_T tpos = curwin->w_cursor; colnr_T prev_col = end_insert_pos->col; @@ -2379,16 +2357,16 @@ static void stop_insert(pos_T *end_insert_pos, int esc, int nomove) } } } - 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; // Set '[ and '] to the inserted text. When end_insert_pos is NULL we are // now in a different buffer. if (end_insert_pos != NULL) { - curbuf->b_op_start = Insstart; - curbuf->b_op_start_orig = Insstart_orig; + curbuf->b_op_start = Ins.start; + curbuf->b_op_start_orig = Ins.start_orig; curbuf->b_op_end = *end_insert_pos; } } @@ -2747,12 +2725,12 @@ static bool echeck_abbr(int c) { // Don't check for abbreviation in paste mode, when disabled and just // after moving around with cursor keys. - if (p_paste || no_abbr || arrow_used) { + if (p_paste || no_abbr || Ins.arrow_used) { return false; } return check_abbr(c, get_cursor_line_ptr(), curwin->w_cursor.col, - curwin->w_cursor.lnum == Insstart.lnum ? Insstart.col : 0); + curwin->w_cursor.lnum == Ins.start.lnum ? Ins.start.col : 0); } // replace-stack functions @@ -2981,7 +2959,7 @@ static void ins_reg(void) } else if (insert_reg(regname, NULL, !!literally) == FAIL) { vim_beep(kOptBoFlagRegister); need_redraw = true; // remove the '"' - } else if (stop_insert_mode) { + } else if (Ins.stop_insert_mode) { // When the '=' register was used and a function was invoked that // did ":stopinsert" then stuff_empty() returns false but we won't // insert anything, need to remove the '"' @@ -2990,7 +2968,7 @@ static void ins_reg(void) } no_u_sync--; if (u_sync_once == 1) { - ins_need_undo = true; + Ins.need_undo = true; } u_sync_once = 0; @@ -3021,14 +2999,14 @@ static void ins_ctrl_g(void) no_mapping--; allow_keys--; switch (c) { - // CTRL-G k and CTRL-G : cursor up to Insstart.col + // CTRL-G k and CTRL-G : cursor up to Ins.start.col case K_UP: case Ctrl_K: case 'k': ins_up(true); break; - // CTRL-G j and CTRL-G : cursor down to Insstart.col + // CTRL-G j and CTRL-G : cursor down to Ins.start.col case K_DOWN: case Ctrl_J: case 'j': @@ -3038,19 +3016,19 @@ static void ins_ctrl_g(void) // CTRL-G u: start new undoable edit case 'u': u_sync(true); - ins_need_undo = true; + Ins.need_undo = true; - // Need to reset Insstart, esp. because a BS that joins + // Need to reset Ins.start, esp. because a BS that joins // a line to the previous one must save for undo. - update_Insstart_orig = false; - Insstart = curwin->w_cursor; + Ins.update_start_orig = false; + Ins.start = curwin->w_cursor; break; // CTRL-G U: do not break undo with the next char. case 'U': // Allow one left/right cursor movement with the next char, // without breaking undo. - dont_sync_undo = kNone; + Ins.dont_sync_undo = kNone; break; case ESC: @@ -3101,7 +3079,7 @@ static bool ins_esc(int *count, int cmdchar, bool nomove) RedrawingDisabled--; disabled_redraw = false; } - if (!arrow_used) { + if (!Ins.arrow_used) { // Don't append the ESC for "r" and "grx". if (cmdchar != 'r' && cmdchar != 'v') { AppendToRedobuff(ESC_STR); @@ -3156,7 +3134,7 @@ static bool ins_esc(int *count, int cmdchar, bool nomove) if (!nomove && (curwin->w_cursor.col != 0 || curwin->w_cursor.coladd > 0) && (restart_edit == NUL || (gchar_cursor() == NUL && !VIsual_active)) - && !revins_on) { + && !Ins.revins_on) { if (curwin->w_cursor.coladd > 0 || get_ve_flags(curwin) == kOptVeFlagAll) { oneleft(); if (restart_edit != NUL) { @@ -3193,24 +3171,24 @@ static bool ins_esc(int *count, int cmdchar, bool nomove) return true; } -// Toggle language: revins_on. +// Toggle language: Ins.revins_on. // Move to end of reverse inserted text. static void ins_ctrl_(void) { - if (revins_on && revins_chars && revins_scol >= 0) { - while (gchar_cursor() != NUL && revins_chars--) { + if (Ins.revins_on && Ins.revins_chars && Ins.revins_scol >= 0) { + while (gchar_cursor() != NUL && Ins.revins_chars--) { curwin->w_cursor.col++; } } p_ri = !p_ri; - revins_on = (State == MODE_INSERT && p_ri); - if (revins_on) { - revins_scol = curwin->w_cursor.col; - revins_legal++; - revins_chars = 0; + Ins.revins_on = (State == MODE_INSERT && p_ri); + if (Ins.revins_on) { + Ins.revins_scol = curwin->w_cursor.col; + Ins.revins_legal++; + Ins.revins_chars = 0; undisplay_dollar(); } else { - revins_scol = -1; + Ins.revins_scol = -1; } showmode(); } @@ -3325,13 +3303,13 @@ static void ins_shift(int c, int lastc) change_indent(c == Ctrl_D ? INDENT_DEC : INDENT_INC, 0, true, true); } - if (did_ai && *skipwhite(get_cursor_line_ptr()) != NUL) { - did_ai = false; + if (Ins.did_ai && *skipwhite(get_cursor_line_ptr()) != NUL) { + Ins.did_ai = false; } - did_si = false; - can_si = false; - can_si_back = false; - can_cindent = false; // no cindenting after ^D or ^T + Ins.did_si = false; + Ins.can_si = false; + Ins.can_si_back = false; + Ins.can_cindent = false; // no cindenting after ^D or ^T } static void ins_del(void) @@ -3357,10 +3335,10 @@ static void ins_del(void) } else if (del_char(false) == FAIL) { // delete char under cursor vim_beep(kOptBoFlagBackspace); } - 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; AppendCharToRedobuff(K_DEL); } @@ -3385,14 +3363,14 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) // can't backup past starting point unless 'backspace' > 1 // can backup to a previous line if 'backspace' == 0 if (buf_is_empty(curbuf) - || (!revins_on + || (!Ins.revins_on && ((curwin->w_cursor.lnum == 1 && curwin->w_cursor.col == 0) || (!can_bs(BS_START) - && ((arrow_used && !bt_prompt(curbuf)) - || (curwin->w_cursor.lnum == Insstart_orig.lnum - && curwin->w_cursor.col <= Insstart_orig.col))) - || (!can_bs(BS_INDENT) && !arrow_used && ai_col > 0 - && curwin->w_cursor.col <= ai_col) + && ((Ins.arrow_used && !bt_prompt(curbuf)) + || (curwin->w_cursor.lnum == Ins.start_orig.lnum + && curwin->w_cursor.col <= Ins.start_orig.col))) + || (!can_bs(BS_INDENT) && !Ins.arrow_used && Ins.ai_col > 0 + && curwin->w_cursor.col <= Ins.ai_col) || (!can_bs(BS_EOL) && curwin->w_cursor.col == 0)))) { vim_beep(kOptBoFlagBackspace); return false; @@ -3403,10 +3381,10 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) } bool in_indent = inindent(0); if (in_indent) { - can_cindent = false; + Ins.can_cindent = false; } - end_comment_pending = NUL; // After BS, don't auto-end comment - if (revins_on) { // put cursor after last inserted char + Ins.end_comment_pending = NUL; // After BS, don't auto-end comment + if (Ins.revins_on) { // put cursor after last inserted char inc_cursor(); } // Virtualedit: @@ -3427,14 +3405,14 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) // Delete newline! if (curwin->w_cursor.col == 0) { - linenr_T lnum = Insstart.lnum; - if (curwin->w_cursor.lnum == lnum || revins_on) { + linenr_T lnum = Ins.start.lnum; + if (curwin->w_cursor.lnum == lnum || Ins.revins_on) { if (u_save((linenr_T)(curwin->w_cursor.lnum - 2), (linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL) { return false; } - Insstart.lnum--; - Insstart.col = ml_get_len(Insstart.lnum); + Ins.start.lnum--; + Ins.start.col = ml_get_len(Ins.start.lnum); } // In replace mode: // cc < 0: NL was inserted, delete it @@ -3502,17 +3480,17 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) State = oldState; } } - did_ai = false; + Ins.did_ai = false; } else { // Delete character(s) before the cursor. - if (revins_on) { // put cursor on last inserted char + if (Ins.revins_on) { // put cursor on last inserted char dec_cursor(); } colnr_T mincol = 0; // keep indent if (mode == BACKSPACE_LINE && (curbuf->b_p_ai || cindent_on()) - && !revins_on) { + && !Ins.revins_on) { colnr_T save_col = curwin->w_cursor.col; beginline(BL_WHITE); if (curwin->w_cursor.col < save_col) { @@ -3530,7 +3508,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) && curwin->w_cursor.col > 0 && (*(get_cursor_pos_ptr() - 1) == TAB || (*(get_cursor_pos_ptr() - 1) == ' ' - && (!*inserted_space_p || arrow_used)))))) { + && (!*inserted_space_p || Ins.arrow_used)))))) { *inserted_space_p = false; bool const use_ts = !curwin->w_p_list || curwin->w_p_lcs_chars.tab1; @@ -3582,8 +3560,8 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) dec_cursor(); if (State & REPLACE_FLAG) { // Don't delete characters before the insert point when in Replace mode. - if (curwin->w_cursor.lnum != Insstart.lnum - || curwin->w_cursor.col >= Insstart.col) { + if (curwin->w_cursor.lnum != Ins.start.lnum + || curwin->w_cursor.col >= Ins.start.col) { replace_do_bs(-1); } } else { @@ -3594,9 +3572,9 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) // Insert extra spaces until we are at want_vcol. for (; space_vcol < want_vcol; space_vcol++) { // Remember the first char we inserted. - if (curwin->w_cursor.lnum == Insstart_orig.lnum - && curwin->w_cursor.col < Insstart_orig.col) { - Insstart_orig.col = curwin->w_cursor.col; + if (curwin->w_cursor.lnum == Ins.start_orig.lnum + && curwin->w_cursor.col < Ins.start_orig.col) { + Ins.start_orig.col = curwin->w_cursor.col; } if (State & VREPLACE_FLAG) { @@ -3613,7 +3591,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) int cclass = mb_get_class(get_cursor_pos_ptr()); do { - if (!revins_on) { // put cursor on char to be deleted + if (!Ins.revins_on) { // put cursor on char to be deleted dec_cursor(); } cc = gchar_cursor(); @@ -3626,7 +3604,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) } else if (mode == BACKSPACE_WORD_NOT_SPACE && ((ascii_isspace(cc) || vim_iswordc(cc) != temp) || prev_cclass != cclass)) { // end of word? - if (!revins_on) { + if (!Ins.revins_on) { inc_cursor(); } else if (State & REPLACE_FLAG) { dec_cursor(); @@ -3647,11 +3625,11 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) if (has_composing) { inc_cursor(); } - if (revins_chars) { - revins_chars--; - revins_legal++; + if (Ins.revins_chars) { + Ins.revins_chars--; + Ins.revins_legal++; } - if (revins_on && gchar_cursor() == NUL) { + if (Ins.revins_on && gchar_cursor() == NUL) { break; } } @@ -3659,19 +3637,19 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) if (mode == BACKSPACE_CHAR) { break; } - } while (revins_on + } while (Ins.revins_on || (curwin->w_cursor.col > mincol && (can_bs(BS_NOSTOP) - || (curwin->w_cursor.lnum != Insstart_orig.lnum - || curwin->w_cursor.col != Insstart_orig.col)))); + || (curwin->w_cursor.lnum != Ins.start_orig.lnum + || curwin->w_cursor.col != Ins.start_orig.col)))); } did_backspace = true; } - did_si = false; - can_si = false; - can_si_back = false; + Ins.did_si = false; + Ins.can_si = false; + Ins.can_si_back = false; if (curwin->w_cursor.col <= 1) { - did_ai = false; + Ins.did_ai = false; } if (call_fix_indent) { @@ -3684,9 +3662,9 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) AppendCharToRedobuff(c); // If deleted before the insertion point, adjust it - if (curwin->w_cursor.lnum == Insstart_orig.lnum - && curwin->w_cursor.col < Insstart_orig.col) { - Insstart_orig.col = curwin->w_cursor.col; + if (curwin->w_cursor.lnum == Ins.start_orig.lnum + && curwin->w_cursor.col < Ins.start_orig.col) { + Ins.start_orig.col = curwin->w_cursor.col; } // vi behaviour: the cursor moves backward but the character that @@ -3711,7 +3689,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) static void ins_left(void) { - const bool end_change = dont_sync_undo == kFalse; // end undoable change + const bool end_change = Ins.dont_sync_undo == kFalse; // end undoable change if ((fdo_flags & kOptFdoFlagHor) && KeyTyped) { foldOpenCursor(); @@ -3724,10 +3702,10 @@ static void ins_left(void) AppendCharToRedobuff(K_LEFT); } // If exit reversed string, position is fixed - if (revins_scol != -1 && (int)curwin->w_cursor.col >= revins_scol) { - revins_legal++; + if (Ins.revins_scol != -1 && (int)curwin->w_cursor.col >= Ins.revins_scol) { + Ins.revins_legal++; } - revins_chars++; + Ins.revins_chars++; } else if (vim_strchr(p_ww, '[') != NULL && curwin->w_cursor.lnum > 1) { // if 'whichwrap' set for cursor in insert mode may go to previous line. // always break undo when moving upwards/downwards, else undo may break @@ -3738,7 +3716,7 @@ static void ins_left(void) } else { vim_beep(kOptBoFlagCursor); } - dont_sync_undo = kFalse; + Ins.dont_sync_undo = kFalse; } static void ins_home(int c) @@ -3775,7 +3753,7 @@ static void ins_end(int c) static void ins_s_left(void) { - const bool end_change = dont_sync_undo == kFalse; // end undoable change + const bool end_change = Ins.dont_sync_undo == kFalse; // end undoable change if ((fdo_flags & kOptFdoFlagHor) && KeyTyped) { foldOpenCursor(); } @@ -3790,13 +3768,13 @@ static void ins_s_left(void) } else { vim_beep(kOptBoFlagCursor); } - dont_sync_undo = kFalse; + Ins.dont_sync_undo = kFalse; } /// @param end_change end undoable change static void ins_right(void) { - const bool end_change = dont_sync_undo == kFalse; // end undoable change + const bool end_change = Ins.dont_sync_undo == kFalse; // end undoable change if ((fdo_flags & kOptFdoFlagHor) && KeyTyped) { foldOpenCursor(); } @@ -3813,9 +3791,9 @@ static void ins_right(void) curwin->w_cursor.col += utfc_ptr2len(get_cursor_pos_ptr()); } - revins_legal++; - if (revins_chars) { - revins_chars--; + Ins.revins_legal++; + if (Ins.revins_chars) { + Ins.revins_chars--; } } else if (vim_strchr(p_ww, ']') != NULL && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) { @@ -3828,12 +3806,12 @@ static void ins_right(void) } else { vim_beep(kOptBoFlagCursor); } - dont_sync_undo = kFalse; + Ins.dont_sync_undo = kFalse; } static void ins_s_right(void) { - const bool end_change = dont_sync_undo == kFalse; // end undoable change + const bool end_change = Ins.dont_sync_undo == kFalse; // end undoable change if ((fdo_flags & kOptFdoFlagHor) && KeyTyped) { foldOpenCursor(); } @@ -3849,10 +3827,10 @@ static void ins_s_right(void) } else { vim_beep(kOptBoFlagCursor); } - dont_sync_undo = kFalse; + Ins.dont_sync_undo = kFalse; } -/// @param startcol when true move to Insstart.col +/// @param startcol when true move to Ins.start.col static void ins_up(bool startcol) { linenr_T old_topline = curwin->w_topline; @@ -3862,14 +3840,14 @@ static void ins_up(bool startcol) pos_T tpos = curwin->w_cursor; if (cursor_up(1, true) == OK) { if (startcol) { - coladvance(curwin, getvcol_nolist(&Insstart)); + coladvance(curwin, getvcol_nolist(&Ins.start)); } if (old_topline != curwin->w_topline || old_topfill != curwin->w_topfill) { redraw_later(curwin, UPD_VALID); } start_arrow(&tpos); - can_cindent = true; + Ins.can_cindent = true; } else { vim_beep(kOptBoFlagCursor); } @@ -3891,13 +3869,13 @@ static void ins_pageup(void) pos_T tpos = curwin->w_cursor; if (pagescroll(BACKWARD, 1, false) == OK) { start_arrow(&tpos); - can_cindent = true; + Ins.can_cindent = true; } else { vim_beep(kOptBoFlagCursor); } } -/// @param startcol when true move to Insstart.col +/// @param startcol when true move to Ins.start.col static void ins_down(bool startcol) { linenr_T old_topline = curwin->w_topline; @@ -3907,14 +3885,14 @@ static void ins_down(bool startcol) pos_T tpos = curwin->w_cursor; if (cursor_down(1, true) == OK) { if (startcol) { - coladvance(curwin, getvcol_nolist(&Insstart)); + coladvance(curwin, getvcol_nolist(&Ins.start)); } if (old_topline != curwin->w_topline || old_topfill != curwin->w_topfill) { redraw_later(curwin, UPD_VALID); } start_arrow(&tpos); - can_cindent = true; + Ins.can_cindent = true; } else { vim_beep(kOptBoFlagCursor); } @@ -3936,7 +3914,7 @@ static void ins_pagedown(void) pos_T tpos = curwin->w_cursor; if (pagescroll(FORWARD, 1, false) == OK) { start_arrow(&tpos); - can_cindent = true; + Ins.can_cindent = true; } else { vim_beep(kOptBoFlagCursor); } @@ -3950,8 +3928,8 @@ static bool ins_tab(void) { int temp; - if (Insstart_blank_vcol == MAXCOL && curwin->w_cursor.lnum == Insstart.lnum) { - Insstart_blank_vcol = get_nolist_virtcol(); + if (Ins.start_blank_vcol == MAXCOL && curwin->w_cursor.lnum == Ins.start.lnum) { + Ins.start_blank_vcol = get_nolist_virtcol(); } if (echeck_abbr(TAB + ABBR_OFF)) { return false; @@ -3959,7 +3937,7 @@ static bool ins_tab(void) bool ind = inindent(0); if (ind) { - can_cindent = false; + Ins.can_cindent = false; } // When nothing special, insert TAB like a normal character. @@ -3982,10 +3960,10 @@ static bool ins_tab(void) return true; } - 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; AppendToRedobuff("\t"); if (p_sta && ind) { // insert tab in indent, use 'shiftwidth' @@ -4057,10 +4035,10 @@ static bool ins_tab(void) // In Replace mode, don't change characters before the insert point. if ((State & REPLACE_FLAG) - && fpos.lnum == Insstart.lnum - && fpos.col < Insstart.col) { - ptr += Insstart.col - fpos.col; - fpos.col = Insstart.col; + && fpos.lnum == Ins.start.lnum + && fpos.col < Ins.start.col) { + ptr += Ins.start.col - fpos.col; + fpos.col = Ins.start.col; } // compute virtual column numbers of first white and cursor @@ -4084,9 +4062,9 @@ static bool ins_tab(void) *ptr = TAB; if (change_col < 0) { change_col = fpos.col; // Column of first change - // May have to adjust Insstart - if (fpos.lnum == Insstart.lnum && fpos.col < Insstart.col) { - Insstart.col = fpos.col; + // May have to adjust Ins.start + if (fpos.lnum == Ins.start.lnum && fpos.col < Ins.start.col) { + Ins.start.col = fpos.col; } } } @@ -4197,7 +4175,7 @@ bool ins_eol(int c) } // NL in reverse insert will always start in the end of current line. - if (revins_on) { + if (Ins.revins_on) { curwin->w_cursor.col += get_cursor_pos_len(); } @@ -4206,7 +4184,7 @@ bool ins_eol(int c) has_format_option(FO_RET_COMS) ? OPENLINE_DO_COM : 0, old_indent, NULL); old_indent = 0; - can_cindent = true; + Ins.can_cindent = true; // When inserting a line the cursor line must never be in a closed fold. foldOpenCursor(); @@ -4341,8 +4319,8 @@ static int ins_ctrl_ey(int tc) curbuf->b_p_tw = -1; insert_special(c, true, false); curbuf->b_p_tw = tw_save; - revins_chars++; - revins_legal++; + Ins.revins_chars++; + Ins.revins_legal++; c = Ctrl_V; // pretend CTRL-V is last character auto_format(false, true); } @@ -4411,12 +4389,12 @@ static char *do_insert_char_pre(int c) bool get_can_cindent(void) { - return can_cindent; + return Ins.can_cindent; } void set_can_cindent(bool val) { - can_cindent = val; + Ins.can_cindent = val; } /// Trigger "event" and take care of fixing undo. diff --git a/src/nvim/insert_defs.h b/src/nvim/insert_defs.h new file mode 100644 index 0000000000..d04b732bb9 --- /dev/null +++ b/src/nvim/insert_defs.h @@ -0,0 +1,50 @@ +#pragma once + +#include + +#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 or + ///< is typed: set when an auto-indent is done, reset when any + ///< other editing is done on the line. If an or 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; diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index 3b27370750..110577e081 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -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; } diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 0339b59e63..7249469278 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -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; } diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 8004680be7..ed15474568 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -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); } } diff --git a/src/nvim/ops.c b/src/nvim/ops.c index d945ecccd7..2807c5aeca 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -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 diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 881118af8c..cb5a1efba7 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -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; } diff --git a/src/nvim/textformat.c b/src/nvim/textformat.c index 083d43af74..8bc9fcfb9c 100644 --- a/src/nvim/textformat.c +++ b/src/nvim/textformat.c @@ -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(); } diff --git a/src/nvim/window.c b/src/nvim/window.c index aeb1e53050..075c1c0493 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -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