diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 22:39:54 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 22:39:54 +0000 |
commit | 21cb7d04c387e4198ca8098a884c78b56ffcf4c2 (patch) | |
tree | 84fe5690df1551f0bb2bdfe1a13aacd29ebc1de7 /src/nvim/edit.c | |
parent | d9c904f85a23a496df4eb6be42aa43f007b22d50 (diff) | |
parent | 4a8bf24ac690004aedf5540fa440e788459e5e34 (diff) | |
download | rneovim-colorcolchar.tar.gz rneovim-colorcolchar.tar.bz2 rneovim-colorcolchar.zip |
Merge remote-tracking branch 'upstream/master' into colorcolcharcolorcolchar
Diffstat (limited to 'src/nvim/edit.c')
-rw-r--r-- | src/nvim/edit.c | 700 |
1 files changed, 245 insertions, 455 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 095d73f53f..71a12ea1b0 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1,6 +1,3 @@ -// This is an open source non-commercial project. Dear PVS-Studio, please check -// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com - // edit.c: functions for Insert mode #include <assert.h> @@ -10,8 +7,9 @@ #include <string.h> #include <sys/types.h> -#include "nvim/ascii.h" +#include "nvim/ascii_defs.h" #include "nvim/autocmd.h" +#include "nvim/autocmd_defs.h" #include "nvim/buffer.h" #include "nvim/change.h" #include "nvim/charset.h" @@ -26,17 +24,18 @@ #include "nvim/extmark.h" #include "nvim/fileio.h" #include "nvim/fold.h" +#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/grid.h" -#include "nvim/highlight_defs.h" +#include "nvim/highlight.h" #include "nvim/highlight_group.h" #include "nvim/indent.h" #include "nvim/indent_c.h" #include "nvim/insexpand.h" #include "nvim/keycodes.h" -#include "nvim/macros.h" +#include "nvim/macros_defs.h" #include "nvim/mapping.h" #include "nvim/mark.h" #include "nvim/mbyte.h" @@ -48,11 +47,11 @@ #include "nvim/normal.h" #include "nvim/ops.h" #include "nvim/option.h" +#include "nvim/option_vars.h" #include "nvim/os/input.h" #include "nvim/plines.h" #include "nvim/popupmenu.h" -#include "nvim/pos.h" -#include "nvim/screen.h" +#include "nvim/pos_defs.h" #include "nvim/search.h" #include "nvim/state.h" #include "nvim/strings.h" @@ -60,10 +59,10 @@ #include "nvim/terminal.h" #include "nvim/textformat.h" #include "nvim/textobject.h" -#include "nvim/types.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/undo.h" -#include "nvim/vim.h" +#include "nvim/vim_defs.h" #include "nvim/window.h" typedef struct insert_state { @@ -73,7 +72,7 @@ typedef struct insert_state { int cmdchar; int cmdchar_todo; // cmdchar to handle once in init_prompt int startln; - long count; + int count; int c; int lastc; int i; @@ -138,7 +137,7 @@ static void insert_enter(InsertState *s) did_restart_edit = restart_edit; // sleep before redrawing, needed for "CTRL-O :" that results in an // error message - check_for_delay(true); + msg_check_for_delay(true); // set Insstart_orig to Insstart update_Insstart_orig = true; @@ -194,7 +193,7 @@ static void insert_enter(InsertState *s) } } - Insstart_textlen = (colnr_T)linetabsize(get_cursor_line_ptr()); + Insstart_textlen = linetabsize_str(get_cursor_line_ptr()); Insstart_blank_vcol = MAXCOL; if (!did_ai) { @@ -232,8 +231,9 @@ static void insert_enter(InsertState *s) may_trigger_modechanged(); stop_insert_mode = false; - // need to position cursor again when on a TAB - if (gchar_cursor() == TAB) { + // need to position cursor again when on a TAB and + // when on a char with inline virtual text + if (gchar_cursor() == TAB || curbuf->b_virt_text_inline > 0) { curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL); } @@ -355,6 +355,7 @@ static void insert_enter(InsertState *s) ins_apply_autocmds(EVENT_INSERTLEAVE); } did_cursorhold = false; + curbuf->b_last_changedtick = buf_get_changedtick(curbuf); } static int insert_check(VimState *state) @@ -394,6 +395,13 @@ static int insert_check(VimState *state) Insstart_orig = Insstart; } + if (curbuf->terminal) { + // Exit Insert mode and go to Terminal mode. + stop_insert_mode = true; + restart_edit = 'I'; + stuffcharReadbuff(K_NOP); + } + if (stop_insert_mode && !ins_compl_active()) { // ":stopinsert" used s->count = 0; @@ -523,10 +531,6 @@ static int insert_execute(VimState *state, int key) did_cursorhold = true; } - if (p_hkmap && KeyTyped) { - s->c = hkmap(s->c); // Hebrew mode mapping - } - // Special handling of keys while the popup menu is visible or wanted // and the cursor is still in the completed word. Only when there is // a match, skip this when no matches were found. @@ -558,10 +562,9 @@ static int insert_execute(VimState *state, int key) if (ins_compl_accept_char(s->c)) { // Trigger InsertCharPre. char *str = do_insert_char_pre(s->c); - char *p; if (str != NULL) { - for (p = str; *p != NUL; MB_PTR_ADV(p)) { + for (char *p = str; *p != NUL; MB_PTR_ADV(p)) { ins_compl_addleader(utf_ptr2char(p)); } xfree(str); @@ -615,7 +618,9 @@ static int insert_execute(VimState *state, int key) } } - s->c = do_digraph(s->c); + if (s->c != K_EVENT) { + s->c = do_digraph(s->c); + } if ((s->c == Ctrl_V || s->c == Ctrl_Q) && ctrl_x_mode_cmdline()) { insert_do_complete(s); @@ -754,7 +759,7 @@ static int insert_handle_key(InsertState *s) case Ctrl_A: // For ^@ the trailing ESC will end the insert, unless there is an // error. - if (stuff_inserted(NUL, 1L, (s->c == Ctrl_A)) == FAIL + if (stuff_inserted(NUL, 1, (s->c == Ctrl_A)) == FAIL && s->c != Ctrl_A) { return 0; // exit insert mode } @@ -880,14 +885,18 @@ static int insert_handle_key(InsertState *s) case K_EVENT: // some 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; + } goto check_pum; - case K_COMMAND: // some command + case K_COMMAND: // <Cmd>command<CR> do_cmdline(NULL, getcmdkeycmd, NULL, 0); goto check_pum; case K_LUA: - map_execute_lua(); + map_execute_lua(false); check_pum: // nvim_select_popupmenu_item() can be called from the handling of @@ -1122,12 +1131,11 @@ normalchar: if (!p_paste) { // Trigger InsertCharPre. char *str = do_insert_char_pre(s->c); - char *p; if (str != NULL) { if (*str != NUL && stop_arrow() != FAIL) { // Insert the new value of v:char literally. - for (p = str; *p != NUL; MB_PTR_ADV(p)) { + for (char *p = str; *p != NUL; MB_PTR_ADV(p)) { s->c = utf_ptr2char(p); if (s->c == CAR || s->c == K_KENTER || s->c == NL) { ins_eol(s->c); @@ -1229,7 +1237,7 @@ static void insert_do_cindent(InsertState *s) /// @param count repeat count for the command /// /// @return true if a CTRL-O command caused the return (insert mode pending). -bool edit(int cmdchar, bool startln, long count) +bool edit(int cmdchar, bool startln, int count) { if (curbuf->terminal) { if (ex_normal_busy) { @@ -1252,12 +1260,14 @@ bool edit(int cmdchar, bool startln, long count) // Don't allow changes in the buffer while editing the cmdline. The // caller of getcmdline() may get confused. // Don't allow recursive insert mode when busy with completion. - if (textlock != 0 || ins_compl_active() || compl_busy || pum_visible()) { + // Allow in dummy buffers since they are only used internally + if (textlock != 0 || ins_compl_active() || compl_busy || pum_visible() + || expr_map_locked()) { emsg(_(e_textlock)); return false; } - InsertState state, *s = &state; + InsertState s[1]; memset(s, 0, sizeof(InsertState)); s->state.execute = insert_execute; s->state.check = insert_check; @@ -1289,7 +1299,8 @@ void ins_redraw(bool ready) // Trigger CursorMoved if the cursor moved. Not when the popup menu is // visible, the command might delete it. if (ready && has_event(EVENT_CURSORMOVEDI) - && !equalpos(curwin->w_last_cursormoved, curwin->w_cursor) + && (last_cursormoved_win != curwin + || !equalpos(last_cursormoved, curwin->w_cursor)) && !pum_visible()) { // Need to update the screen first, to make sure syntax // highlighting is correct after making a change (e.g., inserting @@ -1302,12 +1313,13 @@ void ins_redraw(bool ready) // getcurpos() update_curswant(); ins_apply_autocmds(EVENT_CURSORMOVEDI); - curwin->w_last_cursormoved = curwin->w_cursor; + last_cursormoved_win = curwin; + last_cursormoved = curwin->w_cursor; } - // Trigger TextChangedI if changedtick differs. + // Trigger TextChangedI if changedtick_i differs. if (ready && has_event(EVENT_TEXTCHANGEDI) - && curbuf->b_last_changedtick != buf_get_changedtick(curbuf) + && curbuf->b_last_changedtick_i != buf_get_changedtick(curbuf) && !pum_visible()) { aco_save_T aco; varnumber_T tick = buf_get_changedtick(curbuf); @@ -1316,16 +1328,16 @@ void ins_redraw(bool ready) aucmd_prepbuf(&aco, curbuf); apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, false, curbuf); aucmd_restbuf(&aco); - curbuf->b_last_changedtick = buf_get_changedtick(curbuf); + curbuf->b_last_changedtick_i = buf_get_changedtick(curbuf); if (tick != buf_get_changedtick(curbuf)) { // see ins_apply_autocmds() u_save(curwin->w_cursor.lnum, (linenr_T)(curwin->w_cursor.lnum + 1)); } } - // Trigger TextChangedP if changedtick differs. When the popupmenu closes - // TextChangedI will need to trigger for backwards compatibility, thus use - // different b_last_changedtick* variables. + // Trigger TextChangedP if changedtick_pum differs. When the popupmenu + // closes TextChangedI will need to trigger for backwards compatibility, + // thus use different b_last_changedtick* variables. if (ready && has_event(EVENT_TEXTCHANGEDP) && curbuf->b_last_changedtick_pum != buf_get_changedtick(curbuf) && pum_visible()) { @@ -1355,13 +1367,21 @@ void ins_redraw(bool ready) curbuf->b_changed_invalid = false; } + // Trigger SafeState if nothing is pending. + may_trigger_safestate(ready + && !ins_compl_active() + && !pum_visible()); + pum_check_clear(); + show_cursor_info_later(false); if (must_redraw) { update_screen(); - } else if (clear_cmdline || redraw_cmdline) { - showmode(); // clear cmdline and show mode + } else { + redraw_statuslines(); + if (clear_cmdline || redraw_cmdline || redraw_mode) { + showmode(); // clear cmdline and show mode + } } - show_cursor_info(false); setcursor(); emsg_on_display = false; // may remove error message now } @@ -1369,7 +1389,6 @@ void ins_redraw(bool ready) // Handle a CTRL-V or CTRL-Q typed in Insert mode. static void ins_ctrl_v(void) { - int c; bool did_putchar = false; // may need to redraw when no more chars available now @@ -1384,7 +1403,7 @@ static void ins_ctrl_v(void) add_to_showcmd_c(Ctrl_V); // Do not include modifiers into the key for CTRL-SHIFT-V. - c = get_literal(mod_mask & MOD_MASK_SHIFT); + int c = get_literal(mod_mask & MOD_MASK_SHIFT); if (did_putchar) { // when the line fits in 'columns' the '^' is at the start of the next // line and will not removed by the redraw @@ -1399,20 +1418,19 @@ static void ins_ctrl_v(void) // Put a character directly onto the screen. It's not stored in a buffer. // Used while handling CTRL-K, CTRL-V, etc. in Insert mode. static int pc_status; -#define PC_STATUS_UNSET 0 // pc_bytes was not set -#define PC_STATUS_RIGHT 1 // right half of double-wide char -#define PC_STATUS_LEFT 2 // left half of double-wide char -#define PC_STATUS_SET 3 // pc_bytes was filled -static char_u pc_bytes[MB_MAXBYTES + 1]; // saved bytes +#define PC_STATUS_UNSET 0 // nothing was put on screen +#define PC_STATUS_RIGHT 1 // right half of double-wide char +#define PC_STATUS_LEFT 2 // left half of double-wide char +#define PC_STATUS_SET 3 // pc_schar was filled +static schar_T pc_schar; // saved char static int pc_attr; static int pc_row; static int pc_col; void edit_putchar(int c, bool highlight) { - int attr; - if (curwin->w_grid_alloc.chars != NULL || default_grid.chars != NULL) { + int attr; update_topline(curwin); // just in case w_topline isn't valid validate_cursor(); if (highlight) { @@ -1421,30 +1439,34 @@ void edit_putchar(int c, bool highlight) attr = 0; } pc_row = curwin->w_wrow; - pc_col = 0; pc_status = PC_STATUS_UNSET; + grid_line_start(&curwin->w_grid, pc_row); if (curwin->w_p_rl) { - pc_col += curwin->w_grid.cols - 1 - curwin->w_wcol; - const int fix_col = grid_fix_col(&curwin->w_grid, pc_col, pc_row); + pc_col = curwin->w_grid.cols - 1 - curwin->w_wcol; - if (fix_col != pc_col) { - grid_putchar(&curwin->w_grid, ' ', pc_row, fix_col, attr); + if (grid_line_getchar(pc_col, NULL) == NUL) { + grid_line_put_schar(pc_col - 1, schar_from_ascii(' '), attr); curwin->w_wcol--; pc_status = PC_STATUS_RIGHT; } } else { - pc_col += curwin->w_wcol; - if (grid_lefthalve(&curwin->w_grid, pc_row, pc_col)) { + pc_col = curwin->w_wcol; + + if (grid_line_getchar(pc_col + 1, NULL) == NUL) { + // pc_col is the left half of a double-width char pc_status = PC_STATUS_LEFT; } } // save the character to be able to put it back if (pc_status == PC_STATUS_UNSET) { - grid_getbytes(&curwin->w_grid, pc_row, pc_col, (char *)pc_bytes, &pc_attr); + pc_schar = grid_line_getchar(pc_col, &pc_attr); pc_status = PC_STATUS_SET; } - grid_putchar(&curwin->w_grid, c, pc_row, pc_col, attr); + + char buf[MB_MAXCHAR + 1]; + grid_line_puts(pc_col, buf, utf_char2bytes(c, buf), attr); + grid_line_flush(); } } @@ -1470,10 +1492,9 @@ char *prompt_text(void) static void init_prompt(int cmdchar_todo) { char *prompt = prompt_text(); - char *text; curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; - text = get_cursor_line_ptr(); + char *text = get_cursor_line_ptr(); if (strncmp(text, prompt, strlen(prompt)) != 0) { // prompt is missing, insert it or append a line with it if (*text == NUL) { @@ -1483,7 +1504,7 @@ static void init_prompt(int cmdchar_todo) } curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; coladvance(MAXCOL); - changed_bytes(curbuf->b_ml.ml_line_count, 0); + inserted_bytes(curbuf->b_ml.ml_line_count, 0, 0, (colnr_T)strlen(prompt)); } // Insert always starts after the prompt, allow editing text after it. @@ -1517,29 +1538,32 @@ bool prompt_curpos_editable(void) // Undo the previous edit_putchar(). void edit_unputchar(void) { - if (pc_status != PC_STATUS_UNSET && pc_row >= msg_scrolled) { + if (pc_status != PC_STATUS_UNSET) { if (pc_status == PC_STATUS_RIGHT) { curwin->w_wcol++; } if (pc_status == PC_STATUS_RIGHT || pc_status == PC_STATUS_LEFT) { redrawWinline(curwin, curwin->w_cursor.lnum); } else { - grid_puts(&curwin->w_grid, (char *)pc_bytes, pc_row - msg_scrolled, pc_col, pc_attr); + // TODO(bfredl): this could be smarter and also handle the dubyawidth case + grid_line_start(&curwin->w_grid, pc_row); + grid_line_put_schar(pc_col, pc_schar, pc_attr); + grid_line_flush(); } } } -// Called when p_dollar is set: display a '$' at the end of the changed text -// Only works when cursor is in the line that changes. -void display_dollar(colnr_T col) +/// Called when "$" is in 'cpoptions': display a '$' at the end of the changed +/// text. Only works when cursor is in the line that changes. +void display_dollar(colnr_T col_arg) { - colnr_T save_col; + colnr_T col = col_arg < 0 ? 0 : col_arg; if (!redrawing()) { return; } - save_col = curwin->w_cursor.col; + colnr_T save_col = curwin->w_cursor.col; curwin->w_cursor.col = col; // If on the last byte of a multi-byte move to the first byte. @@ -1574,16 +1598,9 @@ void undisplay_dollar(void) /// @param call_changed_bytes call changed_bytes() void change_indent(int type, int amount, int round, int replaced, int call_changed_bytes) { - int vcol; - int last_vcol; int insstart_less; // reduction for Insstart.col - int new_cursor_col; - char *ptr; - int save_p_list; - int start_col; - colnr_T vc; colnr_T orig_col = 0; // init for GCC - char *new_line, *orig_line = NULL; // init for GCC + char *orig_line = NULL; // init for GCC // MODE_VREPLACE state needs to know what the line was like before changing if (State & VREPLACE_FLAG) { @@ -1592,18 +1609,18 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang } // for the following tricks we don't want list mode - save_p_list = curwin->w_p_list; + int save_p_list = curwin->w_p_list; curwin->w_p_list = false; - vc = getvcol_nolist(&curwin->w_cursor); - vcol = vc; + colnr_T vc = getvcol_nolist(&curwin->w_cursor); + int vcol = vc; // For Replace mode we need to fix the replace stack later, which is only // possible when the cursor is in the indent. Remember the number of // characters before the cursor if it's possible. - start_col = curwin->w_cursor.col; + int start_col = curwin->w_cursor.col; // determine offset from first non-blank - new_cursor_col = curwin->w_cursor.col; + int new_cursor_col = curwin->w_cursor.col; beginline(BL_WHITE); new_cursor_col -= curwin->w_cursor.col; @@ -1656,8 +1673,8 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang curwin->w_virtcol = (colnr_T)((vcol < 0) ? 0 : vcol); // Advance the cursor until we reach the right screen column. - last_vcol = 0; - ptr = get_cursor_line_ptr(); + int last_vcol = 0; + char *ptr = get_cursor_line_ptr(); chartabsize_T cts; init_chartabsize_arg(&cts, curwin, 0, 0, ptr, ptr); while (cts.cts_vcol <= (int)curwin->w_virtcol) { @@ -1699,7 +1716,7 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang curwin->w_cursor.col = (colnr_T)new_cursor_col; } curwin->w_set_curswant = true; - changed_cline_bef_curs(); + changed_cline_bef_curs(curwin); // May have to adjust the start of the insert. if (State & MODE_INSERT) { @@ -1742,7 +1759,7 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang // then put it back again the way we wanted it. if (State & VREPLACE_FLAG) { // Save new line - new_line = xstrdup(get_cursor_line_ptr()); + char *new_line = xstrdup(get_cursor_line_ptr()); // We only put back the new line up to the cursor new_line[curwin->w_cursor.col] = NUL; @@ -1847,9 +1864,7 @@ static bool del_char_after_col(int limit_col) /// @param no_simplify do not include modifiers into the key int get_literal(bool no_simplify) { - int cc; int nc; - int i; bool hex = false; bool octal = false; int unicode = 0; @@ -1859,9 +1874,9 @@ int get_literal(bool no_simplify) } no_mapping++; // don't map the next key hits - cc = 0; - i = 0; - for (;;) { + int cc = 0; + int i = 0; + while (true) { nc = plain_vgetc(); if (!no_simplify) { nc = merge_modifiers(nc, &mod_mask); @@ -1949,9 +1964,6 @@ int get_literal(bool no_simplify) /// @param ctrlv `c` was typed after CTRL-V static void insert_special(int c, int allow_modmask, int ctrlv) { - char *p; - int len; - // Special function key, translate into "<Key>". Up to the last '>' is // inserted with ins_str(), so as not to replace characters in replace // mode. @@ -1961,8 +1973,8 @@ static void insert_special(int c, int allow_modmask, int ctrlv) allow_modmask = true; } if (IS_SPECIAL(c) || (mod_mask && allow_modmask)) { - p = (char *)get_special_key_name(c, mod_mask); - len = (int)strlen(p); + char *p = get_special_key_name(c, mod_mask); + int len = (int)strlen(p); c = (uint8_t)p[len - 1]; if (len > 2) { if (stop_arrow() == FAIL) { @@ -2041,7 +2053,7 @@ void insertchar(int c, int flags, int second_indent) if (*curbuf->b_p_fex != NUL && (flags & INSCHAR_NO_FEX) == 0 && (force_format || virtcol > (colnr_T)textwidth)) { - do_internal = (fex_format(curwin->w_cursor.lnum, 1L, c) != 0); + 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; @@ -2057,7 +2069,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) { - char_u lead_end[COM_MAX_LEN]; // end-comment string + char lead_end[COM_MAX_LEN]; // end-comment string // Need to remove existing (middle) comment leader and insert end // comment leader. First, check what comment leader we can find. @@ -2068,7 +2080,7 @@ void insertchar(int c, int flags, int second_indent) while (*p && p[-1] != ':') { // find end of middle flags p++; } - int middle_len = (int)copy_option_part(&p, (char *)lead_end, COM_MAX_LEN, ","); + int middle_len = (int)copy_option_part(&p, lead_end, COM_MAX_LEN, ","); // Don't count trailing white space for middle_len while (middle_len > 0 && ascii_iswhite(lead_end[middle_len - 1])) { middle_len--; @@ -2078,7 +2090,7 @@ void insertchar(int c, int flags, int second_indent) while (*p && p[-1] != ':') { // find end of end flags p++; } - int end_len = (int)copy_option_part(&p, (char *)lead_end, COM_MAX_LEN, ","); + int end_len = (int)copy_option_part(&p, lead_end, COM_MAX_LEN, ","); // Skip white space before the cursor i = curwin->w_cursor.col; @@ -2089,13 +2101,13 @@ void insertchar(int c, int flags, int second_indent) i -= middle_len; // Check some expected things before we go on - if (i >= 0 && lead_end[end_len - 1] == end_comment_pending) { + if (i >= 0 && (uint8_t)lead_end[end_len - 1] == end_comment_pending) { // Backspace over all the stuff we want to replace backspace_until_column(i); // Insert the end-comment string, except for the last // character, which will get inserted as normal later. - ins_bytes_len((char *)lead_end, (size_t)(end_len - 1)); + ins_bytes_len(lead_end, (size_t)(end_len - 1)); } } } @@ -2146,9 +2158,6 @@ void insertchar(int c, int flags, int second_indent) || (virtcol += byte2cells((uint8_t)buf[i - 1])) < (colnr_T)textwidth) && !(!no_abbr && !vim_iswordc(c) && vim_iswordc((uint8_t)buf[i - 1]))) { c = vgetc(); - if (p_hkmap && KeyTyped) { - c = hkmap(c); // Hebrew mode mapping - } buf[i++] = (char)c; } @@ -2169,7 +2178,7 @@ void insertchar(int c, int flags, int second_indent) int cc; if ((cc = utf_char2len(c)) > 1) { - char buf[MB_MAXBYTES + 1]; + char buf[MB_MAXCHAR + 1]; utf_char2bytes(c, buf); buf[cc] = NUL; @@ -2260,7 +2269,7 @@ int stop_arrow(void) // right, except when nothing was inserted yet. update_Insstart_orig = false; } - Insstart_textlen = (colnr_T)linetabsize(get_cursor_line_ptr()); + Insstart_textlen = linetabsize_str(get_cursor_line_ptr()); if (u_save_cursor() == OK) { arrow_used = false; @@ -2294,26 +2303,24 @@ int stop_arrow(void) /// @param nomove <c-\><c-o>, don't move cursor static void stop_insert(pos_T *end_insert_pos, int esc, int nomove) { - int cc; - char *ptr; - stop_redo_ins(); replace_flush(); // abandon replace stack // Save the inserted text for later redo with ^@ and CTRL-A. // Don't do it when "restart_edit" was set and nothing was inserted, // otherwise CTRL-O w and then <Left> will clear "last_insert". - ptr = get_inserted(); - if (did_restart_edit == 0 || (ptr != NULL - && (int)strlen(ptr) > new_insert_skip)) { + char *ptr = get_inserted(); + int added = ptr == NULL ? 0 : (int)strlen(ptr) - new_insert_skip; + if (did_restart_edit == 0 || added > 0) { xfree(last_insert); last_insert = ptr; - last_insert_skip = new_insert_skip; + last_insert_skip = added < 0 ? 0 : new_insert_skip; } else { xfree(ptr); } if (!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 @@ -2365,7 +2372,7 @@ static void stop_insert(pos_T *end_insert_pos, int esc, int nomove) curwin->w_cursor = *end_insert_pos; check_cursor_col(); // make sure it is not past the line - for (;;) { + while (true) { if (gchar_cursor() == NUL && curwin->w_cursor.col > 0) { curwin->w_cursor.col--; } @@ -2413,16 +2420,14 @@ static void stop_insert(pos_T *end_insert_pos, int esc, int nomove) // Used for the replace command. void set_last_insert(int c) { - char *s; - xfree(last_insert); last_insert = xmalloc(MB_MAXBYTES * 3 + 5); - s = last_insert; + char *s = last_insert; // Use the CTRL-V only when entering a special char if (c < ' ' || c == DEL) { *s++ = Ctrl_V; } - s = (char *)add_char2buf(c, (char_u *)s); + s = add_char2buf(c, s); *s++ = ESC; *s++ = NUL; last_insert_skip = 0; @@ -2449,15 +2454,16 @@ void beginline(int flags) curwin->w_cursor.coladd = 0; if (flags & (BL_WHITE | BL_SOL)) { - char_u *ptr; + char *ptr; - for (ptr = (char_u *)get_cursor_line_ptr(); ascii_iswhite(*ptr) + for (ptr = get_cursor_line_ptr(); ascii_iswhite(*ptr) && !((flags & BL_FIX) && ptr[1] == NUL); ptr++) { curwin->w_cursor.col++; } } curwin->w_set_curswant = true; } + adjust_skipcol(); } // oneright oneleft cursor_down cursor_up @@ -2469,15 +2475,14 @@ void beginline(int flags) int oneright(void) { char *ptr; - int l; if (virtual_active()) { pos_T prevpos = curwin->w_cursor; // Adjust for multi-wide char (excluding TAB) ptr = get_cursor_pos_ptr(); - coladvance(getviscol() + ((*ptr != TAB && vim_isprintc(utf_ptr2char(ptr))) ? - ptr2cells(ptr) : 1)); + coladvance(getviscol() + ((*ptr != TAB && vim_isprintc(utf_ptr2char(ptr))) + ? ptr2cells(ptr) : 1)); curwin->w_set_curswant = true; // Return OK if the cursor moved, FAIL otherwise (at window edge). return (prevpos.col != curwin->w_cursor.col @@ -2489,7 +2494,7 @@ int oneright(void) return FAIL; // already at the very end } - l = utfc_ptr2len(ptr); + int l = utfc_ptr2len(ptr); // move "l" bytes right, but don't end up on the NUL, unless 'virtualedit' // contains "onemore". @@ -2499,13 +2504,13 @@ int oneright(void) curwin->w_cursor.col += l; curwin->w_set_curswant = true; + adjust_skipcol(); return OK; } int oneleft(void) { if (virtual_active()) { - int width; int v = getviscol(); if (v == 0) { @@ -2513,8 +2518,8 @@ int oneleft(void) } // We might get stuck on 'showbreak', skip over it. - width = 1; - for (;;) { + int width = 1; + while (true) { coladvance(v - width); // getviscol() is slow, skip it when 'showbreak' is empty, // 'breakindent' is not set and there are no multi-byte @@ -2534,6 +2539,7 @@ int oneleft(void) } curwin->w_set_curswant = true; + adjust_skipcol(); return OK; } @@ -2547,20 +2553,16 @@ int oneleft(void) // if the character on the left of the current cursor is a multi-byte // character, move to its first byte mb_adjust_cursor(); + adjust_skipcol(); return OK; } /// Move the cursor up "n" lines in window "wp". /// Takes care of closed folds. -/// Returns the new cursor line or zero for failure. -linenr_T cursor_up_inner(win_T *wp, long n) +void cursor_up_inner(win_T *wp, linenr_T n) { linenr_T lnum = wp->w_cursor.lnum; - // This fails if the cursor is already in the first line. - if (lnum <= 1) { - return 0; - } if (n >= lnum) { lnum = 1; } else if (hasAnyFolding(wp)) { @@ -2586,19 +2588,20 @@ linenr_T cursor_up_inner(win_T *wp, long n) lnum = 1; } } else { - lnum -= (linenr_T)n; + lnum -= n; } wp->w_cursor.lnum = lnum; - return lnum; } /// @param upd_topline When true: update topline -int cursor_up(long n, int upd_topline) +int cursor_up(linenr_T n, int upd_topline) { - if (n > 0 && cursor_up_inner(curwin, n) == 0) { + // This fails if the cursor is already in the first line. + if (n > 0 && curwin->w_cursor.lnum <= 1) { return FAIL; } + cursor_up_inner(curwin, n); // try to advance to the column we want to be at coladvance(curwin->w_curswant); @@ -2612,18 +2615,11 @@ int cursor_up(long n, int upd_topline) /// Move the cursor down "n" lines in window "wp". /// Takes care of closed folds. -/// Returns the new cursor line or zero for failure. -linenr_T cursor_down_inner(win_T *wp, long n) +void cursor_down_inner(win_T *wp, int n) { linenr_T lnum = wp->w_cursor.lnum; linenr_T line_count = wp->w_buffer->b_ml.ml_line_count; - // Move to last line of fold, will fail if it's the end-of-file. - (void)hasFoldingWin(wp, lnum, NULL, &lnum, true, NULL); - // This fails if the cursor is already in the last line. - if (lnum >= line_count) { - return FAIL; - } if (lnum + n >= line_count) { lnum = line_count; } else if (hasAnyFolding(wp)) { @@ -2631,6 +2627,7 @@ linenr_T cursor_down_inner(win_T *wp, long n) // count each sequence of folded lines as one logical line while (n--) { + // Move to last line of fold, will fail if it's the end-of-file. if (hasFoldingWin(wp, lnum, NULL, &last, true, NULL)) { lnum = last + 1; } else { @@ -2648,15 +2645,16 @@ linenr_T cursor_down_inner(win_T *wp, long n) } wp->w_cursor.lnum = lnum; - return lnum; } /// @param upd_topline When true: update topline -int cursor_down(long n, int upd_topline) +int cursor_down(int n, int upd_topline) { - if (n > 0 && cursor_down_inner(curwin, n) == 0) { + // This fails if the cursor is already in the last line. + if (n > 0 && curwin->w_cursor.lnum >= curwin->w_buffer->b_ml.ml_line_count) { return FAIL; } + cursor_down_inner(curwin, n); // try to advance to the column we want to be at coladvance(curwin->w_curswant); @@ -2675,14 +2673,12 @@ int cursor_down(long n, int upd_topline) /// @param c Command character to be inserted /// @param count Repeat this many times /// @param no_esc Don't add an ESC at the end -int stuff_inserted(int c, long count, int no_esc) +int stuff_inserted(int c, int count, int no_esc) { char *esc_ptr; - char *ptr; - char *last_ptr; char last = NUL; - ptr = (char *)get_last_insert(); + char *ptr = get_last_insert(); if (ptr == NULL) { emsg(_(e_noinstext)); return FAIL; @@ -2700,7 +2696,7 @@ int stuff_inserted(int c, long count, int no_esc) // when the last char is either "0" or "^" it will be quoted if no ESC // comes after it OR if it will inserted more than once and "ptr" // starts with ^D. -- Acevedo - last_ptr = (esc_ptr ? esc_ptr : ptr + strlen(ptr)) - 1; + char *last_ptr = (esc_ptr ? esc_ptr : ptr + strlen(ptr)) - 1; if (last_ptr >= ptr && (*last_ptr == '0' || *last_ptr == '^') && (no_esc || (*ptr == Ctrl_D && count > 1))) { last = *last_ptr; @@ -2708,7 +2704,7 @@ int stuff_inserted(int c, long count, int no_esc) } do { - stuffReadbuff((const char *)ptr); + stuffReadbuff(ptr); // A trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^". if (last) { stuffReadbuff(last == '0' ? "\026\060\064\070" : "\026^"); @@ -2731,27 +2727,24 @@ int stuff_inserted(int c, long count, int no_esc) return OK; } -char_u *get_last_insert(void) +char *get_last_insert(void) FUNC_ATTR_PURE { if (last_insert == NULL) { return NULL; } - return (char_u *)last_insert + last_insert_skip; + return last_insert + last_insert_skip; } // Get last inserted string, and remove trailing <Esc>. // Returns pointer to allocated memory (must be freed) or NULL. char *get_last_insert_save(void) { - char *s; - int len; - if (last_insert == NULL) { return NULL; } - s = xstrdup(last_insert + last_insert_skip); - len = (int)strlen(s); + char *s = xstrdup(last_insert + last_insert_skip); + int len = (int)strlen(s); if (len > 0 && s[len - 1] == ESC) { // remove trailing ESC s[len - 1] = NUL; } @@ -2793,11 +2786,11 @@ static bool echeck_abbr(int c) // that the NL replaced. The extra one stores the characters after the cursor // that were deleted (always white space). -static char_u *replace_stack = NULL; +static uint8_t *replace_stack = NULL; static ssize_t replace_stack_nr = 0; // next entry in replace stack static ssize_t replace_stack_len = 0; // max. number of entries -/// Push character that is replaced onto the the replace stack. +/// Push character that is replaced onto the replace stack. /// /// replace_offset is normally 0, in which case replace_push will add a new /// character at the end of the stack. If replace_offset is not 0, that many @@ -2814,11 +2807,11 @@ void replace_push(int c) replace_stack_len += 50; replace_stack = xrealloc(replace_stack, (size_t)replace_stack_len); } - char_u *p = replace_stack + replace_stack_nr - replace_offset; + uint8_t *p = replace_stack + replace_stack_nr - replace_offset; if (replace_offset) { memmove(p + 1, p, (size_t)replace_offset); } - *p = (char_u)c; + *p = (uint8_t)c; replace_stack_nr++; } @@ -2829,9 +2822,8 @@ void replace_push(int c) int replace_push_mb(char *p) { int l = utfc_ptr2len(p); - int j; - for (j = l - 1; j >= 0; j--) { + for (int j = l - 1; j >= 0; j--) { replace_push(p[j]); } return l; @@ -2881,14 +2873,12 @@ static void replace_pop_ins(void) static void mb_replace_pop_ins(int cc) { int n; - char_u buf[MB_MAXBYTES + 1]; - int i; - int c; + uint8_t buf[MB_MAXBYTES + 1]; if ((n = MB_BYTE2LEN(cc)) > 1) { - buf[0] = (char_u)cc; - for (i = 1; i < n; i++) { - buf[i] = (char_u)replace_pop(); + buf[0] = (uint8_t)cc; + for (int i = 1; i < n; i++) { + buf[i] = (uint8_t)replace_pop(); } ins_bytes_len((char *)buf, (size_t)n); } else { @@ -2896,8 +2886,8 @@ static void mb_replace_pop_ins(int cc) } // Handle composing chars. - for (;;) { - c = replace_pop(); + while (true) { + int c = replace_pop(); if (c == -1) { // stack empty break; } @@ -2907,16 +2897,16 @@ static void mb_replace_pop_ins(int cc) break; } - buf[0] = (char_u)c; + buf[0] = (uint8_t)c; assert(n > 1); - for (i = 1; i < n; i++) { - buf[i] = (char_u)replace_pop(); + for (int i = 1; i < n; i++) { + buf[i] = (uint8_t)replace_pop(); } if (utf_iscomposing(utf_ptr2char((char *)buf))) { ins_bytes_len((char *)buf, (size_t)n); } else { // Not a composing char, put it back. - for (i = n - 1; i >= 0; i--) { + for (int i = n - 1; i >= 0; i--) { replace_push(buf[i]); } break; @@ -2942,18 +2932,13 @@ static void replace_flush(void) // using composing characters, use del_char_after_col() instead of del_char(). static void replace_do_bs(int limit_col) { - int cc; - int orig_len = 0; - int ins_len; - int orig_vcols = 0; colnr_T start_vcol; - char *p; - int i; - int vcol; const int l_State = State; - cc = replace_pop(); + int cc = replace_pop(); if (cc > 0) { + int orig_len = 0; + int orig_vcols = 0; if (l_State & VREPLACE_FLAG) { // Get the number of screen cells used by the character we are // going to delete. @@ -2969,10 +2954,10 @@ static void replace_do_bs(int limit_col) if (l_State & VREPLACE_FLAG) { // Get the number of screen cells used by the inserted characters - p = get_cursor_pos_ptr(); - ins_len = (int)strlen(p) - orig_len; - vcol = start_vcol; - for (i = 0; i < ins_len; i++) { + char *p = get_cursor_pos_ptr(); + int ins_len = (int)strlen(p) - orig_len; + int vcol = start_vcol; + for (int i = 0; i < ins_len; i++) { vcol += win_chartabsize(curwin, p + i, vcol); i += utfc_ptr2len(p) - 1; } @@ -3131,7 +3116,7 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) return true; } - if (keytyped == get_special_key_code((char_u *)look + 1)) { + if (keytyped == get_special_key_code(look + 1)) { return true; } } @@ -3223,105 +3208,9 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) return false; } -// Map Hebrew keyboard when in hkmap mode. -int hkmap(int c) - FUNC_ATTR_PURE -{ - if (p_hkmapp) { // phonetic mapping, by Ilya Dogolazky - enum { - hALEF = 0, BET, GIMEL, DALET, HEI, VAV, ZAIN, HET, TET, IUD, - KAFsofit, hKAF, LAMED, MEMsofit, MEM, NUNsofit, NUN, SAMEH, AIN, - PEIsofit, PEI, ZADIsofit, ZADI, KOF, RESH, hSHIN, TAV, - }; - static char_u map[26] = { - (char_u)hALEF, // a - (char_u)BET, // b - (char_u)hKAF, // c - (char_u)DALET, // d - (char_u) - 1, // e - (char_u)PEIsofit, // f - (char_u)GIMEL, // g - (char_u)HEI, // h - (char_u)IUD, // i - (char_u)HET, // j - (char_u)KOF, // k - (char_u)LAMED, // l - (char_u)MEM, // m - (char_u)NUN, // n - (char_u)SAMEH, // o - (char_u)PEI, // p - (char_u) - 1, // q - (char_u)RESH, // r - (char_u)ZAIN, // s - (char_u)TAV, // t - (char_u)TET, // u - (char_u)VAV, // v - (char_u)hSHIN, // w - (char_u) - 1, // x - (char_u)AIN, // y - (char_u)ZADI, // z - }; - - if (c == 'N' || c == 'M' || c == 'P' || c == 'C' || c == 'Z') { - return (int)(map[CHAR_ORD(c)] - 1 + p_aleph); - } else if (c == 'x') { // '-1'='sofit' - return 'X'; - } else if (c == 'q') { - return '\''; // {geresh}={'} - } else if (c == 246) { - return ' '; // \"o --> ' ' for a german keyboard - } else if (c == 228) { - return ' '; // \"a --> ' ' -- / -- - } else if (c == 252) { - return ' '; // \"u --> ' ' -- / -- - } else if (c >= 'a' && c <= 'z') { - // NOTE: islower() does not do the right thing for us on Linux so we - // do this the same was as 5.7 and previous, so it works correctly on - // all systems. Specifically, the e.g. Delete and Arrow keys are - // munged and won't work if e.g. searching for Hebrew text. - return (int)(map[CHAR_ORD_LOW(c)] + p_aleph); - } else { - return c; - } - } else { - switch (c) { - case '`': - return ';'; - case '/': - return '.'; - case '\'': - return ','; - case 'q': - return '/'; - case 'w': - return '\''; - - // Hebrew letters - set offset from 'a' - case ',': - c = '{'; break; - case '.': - c = 'v'; break; - case ';': - c = 't'; break; - default: { - static char_u str[] = "zqbcxlsjphmkwonu ydafe rig"; - - if (c < 'a' || c > 'z') { - return c; - } - c = str[CHAR_ORD_LOW(c)]; - break; - } - } - - return (int)(CHAR_ORD_LOW(c) + p_aleph); - } -} - static void ins_reg(void) { bool need_redraw = false; - int regname; int literally = 0; int vis_active = VIsual_active; @@ -3339,7 +3228,7 @@ static void ins_reg(void) // deleted when ESC is hit. no_mapping++; allow_keys++; - regname = plain_vgetc(); + int regname = plain_vgetc(); LANGMAP_ADJUST(regname, true); if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P) { // Get a third key for literal register insertion @@ -3410,8 +3299,6 @@ static void ins_reg(void) // CTRL-G commands in Insert mode. static void ins_ctrl_g(void) { - int c; - // Right after CTRL-X the cursor will be after the ruler. setcursor(); @@ -3419,7 +3306,7 @@ static void ins_ctrl_g(void) // deleted when ESC is hit. no_mapping++; allow_keys++; - c = plain_vgetc(); + int c = plain_vgetc(); no_mapping--; allow_keys--; switch (c) { @@ -3455,6 +3342,10 @@ static void ins_ctrl_g(void) dont_sync_undo = kNone; break; + case ESC: + // Esc after CTRL-G cancels it. + break; + // Unknown CTRL-G command, reserved for future expansion. default: vim_beep(BO_CTRLG); @@ -3487,7 +3378,7 @@ static void ins_ctrl_hat(void) /// @param nomove when true, don't move the cursor /// /// @return true when leaving insert mode, false when repeating the insert. -static bool ins_esc(long *count, int cmdchar, bool nomove) +static bool ins_esc(int *count, int cmdchar, bool nomove) FUNC_ATTR_NONNULL_ARG(1) { static bool disabled_redraw = false; @@ -3562,6 +3453,7 @@ static bool ins_esc(long *count, int cmdchar, bool nomove) } } else { curwin->w_cursor.col--; + curwin->w_valid &= ~(VALID_WCOL|VALID_VIRTCOL); // Correct cursor for multi-byte character. mb_adjust_cursor(); } @@ -3569,8 +3461,9 @@ static bool ins_esc(long *count, int cmdchar, bool nomove) State = MODE_NORMAL; may_trigger_modechanged(); - // need to position cursor again when on a TAB - if (gchar_cursor() == TAB) { + // need to position cursor again when on a TAB and + // when on a char with inline virtual text + if (gchar_cursor() == TAB || curbuf->b_virt_text_inline > 0) { curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL); } @@ -3581,14 +3474,15 @@ static bool ins_esc(long *count, int cmdchar, bool nomove) // Otherwise remove the mode message. if (reg_recording != 0 || restart_edit != NUL) { showmode(); - } else if (p_smd && (got_int || !skip_showmode())) { - msg(""); + } else if (p_smd && (got_int || !skip_showmode()) + && !(p_ch == 0 && !ui_has(kUIMessages))) { + msg("", 0); } // Exit Insert mode return true; } -// Toggle language: hkmap and revins_on. +// Toggle language: revins_on. // Move to end of reverse inserted text. static void ins_ctrl_(void) { @@ -3607,7 +3501,6 @@ static void ins_ctrl_(void) } else { revins_scol = -1; } - p_hkmap = curwin->w_p_rl ^ p_ri; // be consistent! showmode(); } @@ -3659,8 +3552,9 @@ static bool ins_start_select(int c) // <Insert> key in Insert mode: toggle insert/replace mode. static void ins_insert(int replaceState) { - set_vim_var_string(VV_INSERTMODE, ((State & REPLACE_FLAG) ? "i" : - replaceState == MODE_VREPLACE ? "v" : "r"), 1); + set_vim_var_string(VV_INSERTMODE, ((State & REPLACE_FLAG) + ? "i" + : replaceState == MODE_VREPLACE ? "v" : "r"), 1); ins_apply_autocmds(EVENT_INSERTCHANGE); if (State & REPLACE_FLAG) { State = MODE_INSERT | (State & MODE_LANGMAP); @@ -3676,6 +3570,7 @@ static void ins_insert(int replaceState) // Pressed CTRL-O in Insert mode. static void ins_ctrl_o(void) { + restart_VIsual_select = 0; if (State & VREPLACE_FLAG) { restart_edit = 'V'; } else if (State & REPLACE_FLAG) { @@ -3786,15 +3681,9 @@ static void ins_bs_one(colnr_T *vcolp) static bool ins_bs(int c, int mode, int *inserted_space_p) FUNC_ATTR_NONNULL_ARG(3) { - linenr_T lnum; int cc; int temp = 0; // init for GCC - colnr_T save_col; - colnr_T mincol; bool did_backspace = false; - int in_indent; - int oldState; - int cpc[MAX_MCO]; // composing characters bool call_fix_indent = false; // can't delete anything in an empty file @@ -3818,7 +3707,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) if (stop_arrow() == FAIL) { return false; } - in_indent = inindent(0); + int in_indent = inindent(0); if (in_indent) { can_cindent = false; } @@ -3844,7 +3733,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) // Delete newline! if (curwin->w_cursor.col == 0) { - lnum = Insstart.lnum; + linenr_T lnum = Insstart.lnum; if (curwin->w_cursor.lnum == lnum || revins_on) { if (u_save((linenr_T)(curwin->w_cursor.lnum - 2), (linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL) { @@ -3875,7 +3764,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) // again when auto-formatting. if (has_format_option(FO_AUTO) && has_format_option(FO_WHITE_PAR)) { - char *ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, true); + char *ptr = ml_get_buf_mut(curbuf, curwin->w_cursor.lnum); int len; len = (int)strlen(ptr); @@ -3900,11 +3789,11 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) // Do the next ins_char() in MODE_NORMAL state, to // prevent ins_char() from replacing characters and // avoiding showmatch(). - oldState = State; + int oldState = State; State = MODE_NORMAL; // restore characters (blanks) deleted after cursor while (cc > 0) { - save_col = curwin->w_cursor.col; + colnr_T save_col = curwin->w_cursor.col; mb_replace_pop_ins(cc); curwin->w_cursor.col = save_col; cc = replace_pop(); @@ -3920,12 +3809,12 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) if (revins_on) { // put cursor on last inserted char dec_cursor(); } - mincol = 0; + colnr_T mincol = 0; // keep indent if (mode == BACKSPACE_LINE && (curbuf->b_p_ai || cindent_on()) && !revins_on) { - save_col = curwin->w_cursor.col; + colnr_T save_col = curwin->w_cursor.col; beginline(BL_WHITE); if (curwin->w_cursor.col < save_col) { mincol = curwin->w_cursor.col; @@ -3944,22 +3833,20 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) && (*(get_cursor_pos_ptr() - 1) == TAB || (*(get_cursor_pos_ptr() - 1) == ' ' && (!*inserted_space_p || arrow_used)))))) { - int ts; colnr_T vcol; colnr_T want_vcol; - colnr_T start_vcol; *inserted_space_p = false; // Compute the virtual column where we want to be. Since // 'showbreak' may get in the way, need to get the last column of // the previous character. getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL); - start_vcol = vcol; + colnr_T start_vcol = vcol; dec_cursor(); getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol); inc_cursor(); if (p_sta && in_indent) { - ts = get_sw_value(curbuf); + int ts = get_sw_value(curbuf); want_vcol = (want_vcol / ts) * ts; } else { want_vcol = tabstop_start(want_vcol, @@ -3999,7 +3886,6 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) } } else { // Delete up to starting point, start of line or previous word. - int prev_cclass = 0; int cclass = mb_get_class(get_cursor_pos_ptr()); do { @@ -4008,7 +3894,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) } cc = gchar_cursor(); // look multi-byte character class - prev_cclass = cclass; + int prev_cclass = cclass; cclass = mb_get_class(get_cursor_pos_ptr()); if (mode == BACKSPACE_WORD && !ascii_isspace(cc)) { // start of word? mode = BACKSPACE_WORD_NOT_SPACE; @@ -4026,15 +3912,15 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) if (State & REPLACE_FLAG) { replace_do_bs(-1); } else { - const int l_p_deco = p_deco; - if (l_p_deco) { - (void)utfc_ptr2char(get_cursor_pos_ptr(), cpc); + bool has_composing = false; + if (p_deco) { + char *p0 = get_cursor_pos_ptr(); + has_composing = utf_composinglike(p0, p0 + utf_ptr2len(p0)); } (void)del_char(false); // If there are combining characters and 'delcombine' is set - // move the cursor back. Don't back up before the base - // character. - if (l_p_deco && cpc[0] != NUL) { + // move the cursor back. Don't back up before the base character. + if (has_composing) { inc_cursor(); } if (revins_chars) { @@ -4099,92 +3985,15 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) return did_backspace; } -static void ins_mouse(int c) -{ - pos_T tpos; - win_T *old_curwin = curwin; - - undisplay_dollar(); - tpos = curwin->w_cursor; - if (do_mouse(NULL, c, BACKWARD, 1, 0)) { - win_T *new_curwin = curwin; - - if (curwin != old_curwin && win_valid(old_curwin)) { - // Mouse took us to another window. We need to go back to the - // previous one to stop insert there properly. - curwin = old_curwin; - curbuf = curwin->w_buffer; - if (bt_prompt(curbuf)) { - // Restart Insert mode when re-entering the prompt buffer. - curbuf->b_prompt_insert = 'A'; - } - } - start_arrow(curwin == old_curwin ? &tpos : NULL); - if (curwin != new_curwin && win_valid(new_curwin)) { - curwin = new_curwin; - curbuf = curwin->w_buffer; - } - can_cindent = true; - } - - // redraw status lines (in case another window became active) - redraw_statuslines(); -} - -static void ins_mousescroll(int dir) -{ - win_T *const old_curwin = curwin; - pos_T tpos = curwin->w_cursor; - - if (mouse_row >= 0 && mouse_col >= 0) { - int row = mouse_row, col = mouse_col, grid = mouse_grid; - - // find the window at the pointer coordinates - win_T *wp = mouse_find_win(&grid, &row, &col); - if (wp == NULL) { - return; - } - curwin = wp; - curbuf = curwin->w_buffer; - } - if (curwin == old_curwin) { - undisplay_dollar(); - } - - // Don't scroll the window in which completion is being done. - if (!pum_visible() || curwin != old_curwin) { - if (dir == MSCR_DOWN || dir == MSCR_UP) { - if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) { - scroll_redraw(dir, (long)(curwin->w_botline - curwin->w_topline)); - } else if (p_mousescroll_vert > 0) { - scroll_redraw(dir, p_mousescroll_vert); - } - } else { - mouse_scroll_horiz(dir); - } - } - - curwin->w_redr_status = true; - - curwin = old_curwin; - curbuf = curwin->w_buffer; - - if (!equalpos(curwin->w_cursor, tpos)) { - start_arrow(&tpos); - can_cindent = true; - } -} - static void ins_left(void) { - pos_T tpos; const bool end_change = dont_sync_undo == kFalse; // end undoable change if ((fdo_flags & FDO_HOR) && KeyTyped) { foldOpenCursor(); } undisplay_dollar(); - tpos = curwin->w_cursor; + pos_T tpos = curwin->w_cursor; if (oneleft() == OK) { start_arrow_with_change(&tpos, end_change); if (!end_change) { @@ -4210,13 +4019,11 @@ static void ins_left(void) static void ins_home(int c) { - pos_T tpos; - if ((fdo_flags & FDO_HOR) && KeyTyped) { foldOpenCursor(); } undisplay_dollar(); - tpos = curwin->w_cursor; + pos_T tpos = curwin->w_cursor; if (c == K_C_HOME) { curwin->w_cursor.lnum = 1; } @@ -4228,13 +4035,11 @@ static void ins_home(int c) static void ins_end(int c) { - pos_T tpos; - if ((fdo_flags & FDO_HOR) && KeyTyped) { foldOpenCursor(); } undisplay_dollar(); - tpos = curwin->w_cursor; + pos_T tpos = curwin->w_cursor; if (c == K_C_END) { curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; } @@ -4256,7 +4061,7 @@ static void ins_s_left(void) if (!end_change) { AppendCharToRedobuff(K_S_LEFT); } - (void)bck_word(1L, false, false); + (void)bck_word(1, false, false); curwin->w_set_curswant = true; } else { vim_beep(BO_CRSR); @@ -4315,7 +4120,7 @@ static void ins_s_right(void) if (!end_change) { AppendCharToRedobuff(K_S_RIGHT); } - (void)fwd_word(1L, false, 0); + (void)fwd_word(1, false, 0); curwin->w_set_curswant = true; } else { vim_beep(BO_CRSR); @@ -4326,13 +4131,12 @@ static void ins_s_right(void) /// @param startcol when true move to Insstart.col static void ins_up(bool startcol) { - pos_T tpos; linenr_T old_topline = curwin->w_topline; int old_topfill = curwin->w_topfill; undisplay_dollar(); - tpos = curwin->w_cursor; - if (cursor_up(1L, true) == OK) { + pos_T tpos = curwin->w_cursor; + if (cursor_up(1, true) == OK) { if (startcol) { coladvance(getvcol_nolist(&Insstart)); } @@ -4349,8 +4153,6 @@ static void ins_up(bool startcol) static void ins_pageup(void) { - pos_T tpos; - undisplay_dollar(); if (mod_mask & MOD_MASK_CTRL) { @@ -4362,8 +4164,8 @@ static void ins_pageup(void) return; } - tpos = curwin->w_cursor; - if (onepage(BACKWARD, 1L) == OK) { + pos_T tpos = curwin->w_cursor; + if (onepage(BACKWARD, 1) == OK) { start_arrow(&tpos); can_cindent = true; } else { @@ -4374,13 +4176,12 @@ static void ins_pageup(void) /// @param startcol when true move to Insstart.col static void ins_down(bool startcol) { - pos_T tpos; linenr_T old_topline = curwin->w_topline; int old_topfill = curwin->w_topfill; undisplay_dollar(); - tpos = curwin->w_cursor; - if (cursor_down(1L, true) == OK) { + pos_T tpos = curwin->w_cursor; + if (cursor_down(1, true) == OK) { if (startcol) { coladvance(getvcol_nolist(&Insstart)); } @@ -4397,8 +4198,6 @@ static void ins_down(bool startcol) static void ins_pagedown(void) { - pos_T tpos; - undisplay_dollar(); if (mod_mask & MOD_MASK_CTRL) { @@ -4410,8 +4209,8 @@ static void ins_pagedown(void) return; } - tpos = curwin->w_cursor; - if (onepage(FORWARD, 1L) == OK) { + pos_T tpos = curwin->w_cursor; + if (onepage(FORWARD, 1) == OK) { start_arrow(&tpos); can_cindent = true; } else { @@ -4425,7 +4224,6 @@ static void ins_pagedown(void) static bool ins_tab(void) FUNC_ATTR_WARN_UNUSED_RESULT { - int i; int temp; if (Insstart_blank_vcol == MAXCOL && curwin->w_cursor.lnum == Insstart.lnum) { @@ -4504,7 +4302,6 @@ static bool ins_tab(void) char *ptr; char *saved_line = NULL; // init for GCC pos_T pos; - pos_T fpos; pos_T *cursor; colnr_T want_vcol, vcol; int change_col = -1; @@ -4528,7 +4325,7 @@ static bool ins_tab(void) } // Find first white before the cursor - fpos = curwin->w_cursor; + pos_T fpos = curwin->w_cursor; while (fpos.col > 0 && ascii_iswhite(ptr[-1])) { fpos.col--; ptr--; @@ -4553,7 +4350,7 @@ static bool ins_tab(void) // Use as many TABs as possible. Beware of 'breakindent', 'showbreak' // and 'linebreak' adding extra virtual columns. while (ascii_iswhite(*ptr)) { - i = lbr_chartabsize(&cts); + int i = lbr_chartabsize(&cts); if (cts.cts_vcol + i > want_vcol) { break; } @@ -4595,9 +4392,9 @@ static bool ins_tab(void) fpos.col += repl_off; // Delete following spaces. - i = cursor->col - fpos.col; + int i = cursor->col - fpos.col; if (i > 0) { - STRMOVE(ptr, (char *)ptr + i); + STRMOVE(ptr, ptr + i); // correct replace stack. if ((State & REPLACE_FLAG) && !(State & VREPLACE_FLAG)) { @@ -4606,9 +4403,8 @@ static bool ins_tab(void) } } if (!(State & VREPLACE_FLAG)) { - extmark_splice_cols(curbuf, (int)fpos.lnum - 1, change_col, - cursor->col - change_col, fpos.col - change_col, - kExtmarkUndo); + inserted_bytes(fpos.lnum, change_col, + cursor->col - change_col, fpos.col - change_col); } } cursor->col -= i; @@ -4689,8 +4485,6 @@ bool ins_eol(int c) // done. static int ins_digraph(void) { - int c; - int cc; bool did_putchar = false; pc_status = PC_STATUS_UNSET; @@ -4707,7 +4501,7 @@ static int ins_digraph(void) // mode message to be deleted when ESC is hit no_mapping++; allow_keys++; - c = plain_vgetc(); + int c = plain_vgetc(); no_mapping--; allow_keys--; if (did_putchar) { @@ -4736,7 +4530,7 @@ static int ins_digraph(void) } no_mapping++; allow_keys++; - cc = plain_vgetc(); + int cc = plain_vgetc(); no_mapping--; allow_keys--; if (did_putchar) { @@ -4759,9 +4553,7 @@ static int ins_digraph(void) // Returns the char to be inserted, or NUL if none found. int ins_copychar(linenr_T lnum) { - int c; - char *ptr, *prev_ptr; - char *line; + char *ptr; if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) { vim_beep(BO_COPY); @@ -4769,9 +4561,9 @@ int ins_copychar(linenr_T lnum) } // try to advance to the cursor column - line = ml_get(lnum); - prev_ptr = line; validate_virtcol(); + char *line = ml_get(lnum); + char *prev_ptr = line; chartabsize_T cts; init_chartabsize_arg(&cts, curwin, lnum, 0, line, line); @@ -4787,7 +4579,7 @@ int ins_copychar(linenr_T lnum) } clear_chartabsize_arg(&cts); - c = utf_ptr2char(ptr); + int c = utf_ptr2char(ptr); if (c == NUL) { vim_beep(BO_COPY); } @@ -4809,8 +4601,6 @@ static int ins_ctrl_ey(int tc) } else { c = ins_copychar(curwin->w_cursor.lnum + (c == Ctrl_Y ? -1 : 1)); if (c != NUL) { - long tw_save; - // The character must be taken literally, insert like it // was typed after a CTRL-V, and pretend 'textwidth' // wasn't set. Digits, 'o' and 'x' are special after a @@ -4818,7 +4608,7 @@ static int ins_ctrl_ey(int tc) if (c < 256 && !isalnum(c)) { AppendToRedobuff(CTRL_V_STR); } - tw_save = curbuf->b_p_tw; + OptInt tw_save = curbuf->b_p_tw; curbuf->b_p_tw = -1; insert_special(c, true, false); curbuf->b_p_tw = tw_save; @@ -4835,13 +4625,14 @@ static int ins_ctrl_ey(int tc) // Used when inserting a "normal" character. static void ins_try_si(int c) { - pos_T *pos, old_pos; - char *ptr; - int i; - bool temp; + pos_T *pos; // do some very smart indenting when entering '{' or '}' if (((did_si || can_si_back) && c == '{') || (can_si && c == '}' && inindent(0))) { + pos_T old_pos; + char *ptr; + int i; + bool temp; // for '}' set indent equal to indent of line containing matching '{' if (c == '}' && (pos = findmatch(NULL, '{')) != NULL) { old_pos = curwin->w_cursor; @@ -4974,9 +4765,8 @@ void set_can_cindent(bool val) int ins_apply_autocmds(event_T event) { varnumber_T tick = buf_get_changedtick(curbuf); - int r; - r = apply_autocmds(event, NULL, NULL, false, curbuf); + int r = apply_autocmds(event, NULL, NULL, false, curbuf); // If u_savesub() was called then we are not prepared to start // a new line. Call u_save() with no contents to fix that. |