diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-11-30 20:35:25 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-11-30 20:35:25 +0000 |
commit | 1b7b916b7631ddf73c38e3a0070d64e4636cb2f3 (patch) | |
tree | cd08258054db80bb9a11b1061bb091c70b76926a /src/nvim/ops.c | |
parent | eaa89c11d0f8aefbb512de769c6c82f61a8baca3 (diff) | |
parent | 4a8bf24ac690004aedf5540fa440e788459e5e34 (diff) | |
download | rneovim-1b7b916b7631ddf73c38e3a0070d64e4636cb2f3.tar.gz rneovim-1b7b916b7631ddf73c38e3a0070d64e4636cb2f3.tar.bz2 rneovim-1b7b916b7631ddf73c38e3a0070d64e4636cb2f3.zip |
Merge remote-tracking branch 'upstream/master' into aucmd_textputpostaucmd_textputpost
Diffstat (limited to 'src/nvim/ops.c')
-rw-r--r-- | src/nvim/ops.c | 750 |
1 files changed, 352 insertions, 398 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 17a0d6e543..9d0b8e01cd 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.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 - // ops.c: implementation of various operators: op_shift, op_delete, op_tilde, // op_change, op_yank, do_put, do_join @@ -12,10 +9,11 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/types.h> #include "nvim/api/private/defs.h" -#include "nvim/ascii.h" -#include "nvim/assert.h" +#include "nvim/ascii_defs.h" +#include "nvim/assert_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" #include "nvim/change.h" @@ -34,11 +32,11 @@ #include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" -#include "nvim/highlight_defs.h" +#include "nvim/highlight.h" #include "nvim/indent.h" #include "nvim/indent_c.h" #include "nvim/keycodes.h" -#include "nvim/macros.h" +#include "nvim/macros_defs.h" #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" @@ -49,19 +47,20 @@ #include "nvim/normal.h" #include "nvim/ops.h" #include "nvim/option.h" +#include "nvim/option_defs.h" +#include "nvim/option_vars.h" #include "nvim/os/input.h" #include "nvim/os/time.h" #include "nvim/plines.h" -#include "nvim/screen.h" #include "nvim/search.h" #include "nvim/state.h" #include "nvim/strings.h" #include "nvim/terminal.h" #include "nvim/textformat.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" static yankreg_T y_regs[NUM_REGISTERS] = { 0 }; @@ -97,13 +96,16 @@ struct block_def { # include "ops.c.generated.h" #endif +static const char e_search_pattern_and_expression_register_may_not_contain_two_or_more_lines[] + = N_("E883: Search pattern and expression register may not contain two or more lines"); + // Flags for third item in "opchars". #define OPF_LINES 1 // operator always works on lines #define OPF_CHANGE 2 // operator changes text -// The names of operators. -// IMPORTANT: Index must correspond with defines in vim.h!!! -// The third field indicates whether the operator always works on lines. +/// The names of operators. +/// IMPORTANT: Index must correspond with defines in ops.h!!! +/// The third field indicates whether the operator always works on lines. static char opchars[][3] = { { NUL, NUL, 0 }, // OP_NOP { 'd', NUL, OPF_CHANGE }, // OP_DELETE @@ -213,8 +215,7 @@ int get_extra_op_char(int optype) /// handle a shift operation void op_shift(oparg_T *oap, int curs_top, int amount) { - long i; - int first_char; + int i; int block_col = 0; if (u_save((linenr_T)(oap->start.lnum - 1), @@ -227,7 +228,7 @@ void op_shift(oparg_T *oap, int curs_top, int amount) } for (i = oap->line_count - 1; i >= 0; i--) { - first_char = (uint8_t)(*get_cursor_line_ptr()); + int first_char = (uint8_t)(*get_cursor_line_ptr()); if (first_char == NUL) { // empty line curwin->w_cursor.col = 0; } else if (oap->motion_type == kMTBlockWise) { @@ -280,7 +281,7 @@ void op_shift(oparg_T *oap, int curs_top, int amount) } } - changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true); + changed_lines(curbuf, oap->start.lnum, 0, oap->end.lnum + 1, 0, true); } /// Shift the current line one shiftwidth left (if left != 0) or right @@ -289,15 +290,13 @@ void op_shift(oparg_T *oap, int curs_top, int amount) /// @param call_changed_bytes call changed_bytes() void shift_line(int left, int round, int amount, int call_changed_bytes) { - int count; - int i, j; - const int sw_val = (int)get_sw_value_indent(curbuf); + const int sw_val = get_sw_value_indent(curbuf); - count = get_indent(); // get current indent + int count = get_indent(); // get current indent if (round) { // round off indent - i = count / sw_val; // number of 'shiftwidth' rounded down - j = count % sw_val; // extra spaces + int i = count / sw_val; // number of 'shiftwidth' rounded down + int j = count % sw_val; // extra spaces if (j && left) { // first remove extra spaces amount--; } @@ -337,11 +336,10 @@ static void shift_block(oparg_T *oap, int amount) const int oldstate = State; char *newp; const int oldcol = curwin->w_cursor.col; - const int sw_val = (int)get_sw_value_indent(curbuf); + const int sw_val = get_sw_value_indent(curbuf); const int ts_val = (int)curbuf->b_p_ts; struct block_def bd; int incr; - int i = 0, j = 0; const int old_p_ri = p_ri; p_ri = 0; // don't want revins in indent @@ -392,40 +390,36 @@ static void shift_block(oparg_T *oap, int amount) bd.start_vcol = cts.cts_vcol; clear_chartabsize_arg(&cts); + int tabs = 0, spaces = 0; // OK, now total=all the VWS reqd, and textstart points at the 1st // non-ws char in the block. if (!curbuf->b_p_et) { - tabstop_fromto(ws_vcol, ws_vcol + total, ts_val, curbuf->b_p_vts_array, &i, &j); + tabstop_fromto(ws_vcol, ws_vcol + total, + ts_val, curbuf->b_p_vts_array, &tabs, &spaces); } else { - j = total; + spaces = total; } // if we're splitting a TAB, allow for it - int col_pre = bd.pre_whitesp_c - (bd.startspaces != 0); + const int col_pre = bd.pre_whitesp_c - (bd.startspaces != 0); bd.textcol -= col_pre; - const int len = (int)strlen(bd.textstart) + 1; - int col = bd.textcol + i + j + len; - assert(col >= 0); - newp = xmalloc((size_t)col); - memset(newp, NUL, (size_t)col); + + const size_t new_line_len // the length of the line after the block shift + = (size_t)bd.textcol + (size_t)tabs + (size_t)spaces + strlen(bd.textstart); + newp = xmalloc(new_line_len + 1); memmove(newp, oldp, (size_t)bd.textcol); startcol = bd.textcol; oldlen = (int)(bd.textstart - old_textstart) + col_pre; - newlen = i + j; - memset(newp + bd.textcol, TAB, (size_t)i); - memset(newp + bd.textcol + i, ' ', (size_t)j); - // the end - memmove(newp + bd.textcol + i + j, bd.textstart, (size_t)len); + newlen = tabs + spaces; + memset(newp + bd.textcol, TAB, (size_t)tabs); + memset(newp + bd.textcol + tabs, ' ', (size_t)spaces); + // Note that STRMOVE() copies the trailing NUL. + STRMOVE(newp + bd.textcol + tabs + spaces, bd.textstart); } else { // left - colnr_T destination_col; // column to which text in block will - // be shifted char *verbatim_copy_end; // end of the part of the line which is // copied verbatim colnr_T verbatim_copy_width; // the (displayed) width of this part // of line - size_t fill; // nr of spaces that replace a TAB - size_t new_line_len; // the length of the line after the - // block shift char *non_white = bd.textstart; // Firstly, let's find the first non-whitespace character that is @@ -458,10 +452,10 @@ static void shift_block(oparg_T *oap, int amount) const colnr_T block_space_width = non_white_col - oap->start_vcol; // We will shift by "total" or "block_space_width", whichever is less. const colnr_T shift_amount = block_space_width < total - ? block_space_width - : total; + ? block_space_width + : total; // The column to which we will shift the text. - destination_col = non_white_col - shift_amount; + const colnr_T destination_col = non_white_col - shift_amount; // Now let's find out how much of the beginning of the line we can // reuse without modification. @@ -492,7 +486,8 @@ static void shift_block(oparg_T *oap, int amount) // part of the line that will be copied, it means we encountered a tab // character, which we will have to partly replace with spaces. assert(destination_col - verbatim_copy_width >= 0); - fill = (size_t)(destination_col - verbatim_copy_width); + const size_t fill // nr of spaces that replace a TAB + = (size_t)(destination_col - verbatim_copy_width); assert(verbatim_copy_end - oldp >= 0); const size_t verbatim_diff = (size_t)(verbatim_copy_end - oldp); @@ -500,14 +495,16 @@ static void shift_block(oparg_T *oap, int amount) // - the beginning of the original line up to "verbatim_copy_end", // - "fill" number of spaces, // - the rest of the line, pointed to by non_white. - new_line_len = verbatim_diff + fill + strlen(non_white) + 1; + const size_t new_line_len // the length of the line after the block shift + = verbatim_diff + fill + strlen(non_white); - newp = xmalloc(new_line_len); + newp = xmalloc(new_line_len + 1); startcol = (int)verbatim_diff; oldlen = bd.textcol + (int)(non_white - bd.textstart) - (int)verbatim_diff; newlen = (int)fill; memmove(newp, oldp, verbatim_diff); memset(newp + verbatim_diff, ' ', fill); + // Note that STRMOVE() copies the trailing NUL. STRMOVE(newp + verbatim_diff + fill, non_white); } // replace the line @@ -531,11 +528,10 @@ static void block_insert(oparg_T *oap, char *s, int b_insert, struct block_def * colnr_T offset; // pointer along new line size_t s_len = strlen(s); char *newp, *oldp; // new, old lines - linenr_T lnum; // loop var int oldstate = State; State = MODE_INSERT; // don't want MODE_REPLACE for State - for (lnum = oap->start.lnum + 1; lnum <= oap->end.lnum; lnum++) { + for (linenr_T lnum = oap->start.lnum + 1; lnum <= oap->end.lnum; lnum++) { block_prep(oap, bdp, lnum, true); if (bdp->is_short && b_insert) { continue; // OP_INSERT, line ends before block start @@ -627,17 +623,15 @@ static void block_insert(oparg_T *oap, char *s, int b_insert, struct block_def * } } // for all lnum - changed_lines(oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L, true); - State = oldstate; + + changed_lines(curbuf, oap->start.lnum + 1, 0, oap->end.lnum + 1, 0, true); } /// Handle reindenting a block of lines. void op_reindent(oparg_T *oap, Indenter how) { - long i = 0; - char *l; - int amount; + int i = 0; linenr_T first_changed = 0; linenr_T last_changed = 0; linenr_T start_lnum = curwin->w_cursor.lnum; @@ -650,8 +644,9 @@ void op_reindent(oparg_T *oap, Indenter how) // Save for undo. Do this once for all lines, much faster than doing this // for each line separately, especially when undoing. - if (u_savecommon(curbuf, start_lnum - 1, start_lnum + (linenr_T)oap->line_count, - start_lnum + (linenr_T)oap->line_count, false) == OK) { + if (u_savecommon(curbuf, start_lnum - 1, start_lnum + oap->line_count, + start_lnum + oap->line_count, false) == OK) { + int amount; for (i = oap->line_count - 1; i >= 0 && !got_int; i--) { // it's a slow thing to do, so give feedback so there's no worry // that the computer's just hung. @@ -659,14 +654,14 @@ void op_reindent(oparg_T *oap, Indenter how) if (i > 1 && (i % 50 == 0 || i == oap->line_count - 1) && oap->line_count > p_report) { - smsg(_("%" PRId64 " lines to indent... "), (int64_t)i); + smsg(0, _("%" PRId64 " lines to indent... "), (int64_t)i); } // Be vi-compatible: For lisp indenting the first line is not // indented, unless there is only one line. if (i != oap->line_count - 1 || oap->line_count == 1 || how != get_lisp_indent) { - l = skipwhite(get_cursor_line_ptr()); + char *l = skipwhite(get_cursor_line_ptr()); if (*l == NUL) { // empty or blank line amount = 0; } else { @@ -693,18 +688,16 @@ void op_reindent(oparg_T *oap, Indenter how) // highlighting was present, need to continue until the last line. When // there is no change still need to remove the Visual highlighting. if (last_changed != 0) { - changed_lines(first_changed, 0, - oap->is_VIsual ? start_lnum + (linenr_T)oap->line_count : - last_changed + 1, 0L, true); + changed_lines(curbuf, first_changed, 0, + oap->is_VIsual ? start_lnum + oap->line_count + : last_changed + 1, 0, true); } else if (oap->is_VIsual) { redraw_curbuf_later(UPD_INVERTED); } if (oap->line_count > p_report) { i = oap->line_count - (i + 1); - smsg(NGETTEXT("%" PRId64 " line indented ", - "%" PRId64 " lines indented ", i), - (int64_t)i); + smsg(0, NGETTEXT("%" PRId64 " line indented ", "%" PRId64 " lines indented ", i), (int64_t)i); } if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) { // set '[ and '] marks @@ -721,9 +714,7 @@ static char *expr_line = NULL; /// @return '=' when OK, NUL otherwise. int get_expr_register(void) { - char *new_line; - - new_line = getcmdline('=', 0L, 0, true); + char *new_line = getcmdline('=', 0, 0, true); if (new_line == NULL) { return NUL; } @@ -748,8 +739,6 @@ void set_expr_line(char *new_line) /// @return a pointer to allocated memory, or NULL for failure. char *get_expr_line(void) { - char *expr_copy; - char *rv; static int nested = 0; if (expr_line == NULL) { @@ -758,7 +747,7 @@ char *get_expr_line(void) // Make a copy of the expression, because evaluating it may cause it to be // changed. - expr_copy = xstrdup(expr_line); + char *expr_copy = xstrdup(expr_line); // When we are invoked recursively limit the evaluation to 10 levels. // Then return the string as-is. @@ -767,7 +756,7 @@ char *get_expr_line(void) } nested++; - rv = eval_to_string(expr_copy, NULL, true); + char *rv = eval_to_string(expr_copy, true); nested--; xfree(expr_copy); return rv; @@ -855,15 +844,6 @@ static bool is_append_register(int regname) return ASCII_ISUPPER(regname); } -/// @see get_yank_register -/// @returns true when register should be inserted literally -/// (selection or clipboard) -static inline bool is_literal_register(int regname) - FUNC_ATTR_CONST -{ - return regname == '*' || regname == '+'; -} - /// @return a copy of contents in register `name` for use in do_put. Should be /// freed by caller. yankreg_T *copy_register(int name) @@ -902,9 +882,7 @@ bool yank_register_mline(int regname) /// @return FAIL for failure, OK otherwise. int do_record(int c) { - char *p; static int regname; - yankreg_T *old_y_previous; int retval; if (reg_recording == 0) { @@ -927,11 +905,11 @@ int do_record(int c) dict_T *dict = get_v_event(&save_v_event); // The recorded text contents. - p = (char *)get_recorded(); + char *p = get_recorded(); if (p != NULL) { // Remove escaping for K_SPECIAL in multi-byte chars. - vim_unescape_ks((char_u *)p); - (void)tv_dict_add_str(dict, S_LEN("regcontents"), (const char *)p); + vim_unescape_ks(p); + (void)tv_dict_add_str(dict, S_LEN("regcontents"), p); } // Name of requested register, or empty string for unnamed operation. @@ -951,14 +929,14 @@ int do_record(int c) if (p_ch == 0 || ui_has(kUIMessages)) { showmode(); } else { - msg(""); + msg("", 0); } if (p == NULL) { retval = FAIL; } else { // We don't want to change the default register here, so save and // restore the current register name. - old_y_previous = y_previous; + yankreg_T *old_y_previous = y_previous; retval = stuff_yank(regname, p); @@ -996,10 +974,12 @@ static int stuff_yank(int regname, char *p) yankreg_T *reg = get_yank_register(regname, YREG_YANK); if (is_append_register(regname) && reg->y_array != NULL) { char **pp = &(reg->y_array[reg->y_size - 1]); - char *lp = xmalloc(strlen(*pp) + strlen(p) + 1); - STRCPY(lp, *pp); - // TODO(philix): use xstpcpy() in stuff_yank() - STRCAT(lp, p); + const size_t ppl = strlen(*pp); + const size_t pl = strlen(p); + char *lp = xmalloc(ppl + pl + 1); + memcpy(lp, *pp, ppl); + memcpy(lp + ppl, p, pl); + *(lp + ppl + pl) = NUL; xfree(p); xfree(*pp); *pp = lp; @@ -1037,13 +1017,11 @@ static char *execreg_line_continuation(char **lines, size_t *idx) garray_T ga; ga_init(&ga, (int)sizeof(char), 400); - char *p; - // search backwards to find the first line of this command. // Any line not starting with \ or "\ is the start of the // command. while (--i > 0) { - p = skipwhite(lines[i]); + char *p = skipwhite(lines[i]); if (*p != '\\' && (p[0] != '"' || p[1] != '\\' || p[2] != ' ')) { break; } @@ -1053,7 +1031,7 @@ static char *execreg_line_continuation(char **lines, size_t *idx) // join all the lines ga_concat(&ga, lines[cmd_start]); for (size_t j = cmd_start + 1; j <= cmd_end; j++) { - p = skipwhite(lines[j]); + char *p = skipwhite(lines[j]); if (*p == '\\') { // Adjust the growsize to the current length to // speed up concatenating many lines. @@ -1080,7 +1058,6 @@ static char *execreg_line_continuation(char **lines, size_t *idx) /// @return FAIL for failure, OK otherwise int do_execreg(int regname, int colon, int addcr, int silent) { - char *p; int retval = OK; if (regname == '@') { // repeat previous one @@ -1109,12 +1086,12 @@ int do_execreg(int regname, int colon, int addcr, int silent) // don't keep the cmdline containing @: XFREE_CLEAR(new_last_cmdline); // Escape all control characters with a CTRL-V - p = vim_strsave_escaped_ext(last_cmdline, - "\001\002\003\004\005\006\007" - "\010\011\012\013\014\015\016\017" - "\020\021\022\023\024\025\026\027" - "\030\031\032\033\034\035\036\037", - Ctrl_V, false); + char *p = vim_strsave_escaped_ext(last_cmdline, + "\001\002\003\004\005\006\007" + "\010\011\012\013\014\015\016\017" + "\020\021\022\023\024\025\026\027" + "\030\031\032\033\034\035\036\037", + Ctrl_V, false); // When in Visual mode "'<,'>" will be prepended to the command. // Remove it when it's already there. if (VIsual_active && strncmp(p, "'<,'>", 5) == 0) { @@ -1124,14 +1101,14 @@ int do_execreg(int regname, int colon, int addcr, int silent) } xfree(p); } else if (regname == '=') { - p = get_expr_line(); + char *p = get_expr_line(); if (p == NULL) { return FAIL; } retval = put_in_typebuf(p, true, colon, silent); xfree(p); } else if (regname == '.') { // use last inserted text - p = get_last_insert_save(); + char *p = get_last_insert_save(); if (p == NULL) { emsg(_(e_noinstext)); return FAIL; @@ -1149,7 +1126,6 @@ int do_execreg(int regname, int colon, int addcr, int silent) // Insert lines into typeahead buffer, from last one to first one. put_reedit_in_typebuf(silent); - char *escaped; for (size_t i = reg->y_size; i-- > 0;) { // from y_size - 1 to 0 included // insert NL between lines and after last line if type is kMTLineWise if (reg->y_type == kMTLineWise || i < reg->y_size - 1 || addcr) { @@ -1162,13 +1138,13 @@ int do_execreg(int regname, int colon, int addcr, int silent) char *str = reg->y_array[i]; bool free_str = false; if (colon && i > 0) { - p = skipwhite(str); + char *p = skipwhite(str); if (*p == '\\' || (p[0] == '"' && p[1] == '\\' && p[2] == ' ')) { str = execreg_line_continuation(reg->y_array, &i); free_str = true; } } - escaped = vim_strsave_escape_ks(str); + char *escaped = vim_strsave_escape_ks(str); if (free_str) { xfree(str); } @@ -1191,7 +1167,7 @@ int do_execreg(int regname, int colon, int addcr, int silent) /// used only after other typeahead has been processed. static void put_reedit_in_typebuf(int silent) { - char_u buf[3]; + uint8_t buf[3]; if (restart_edit == NUL) { return; @@ -1202,7 +1178,7 @@ static void put_reedit_in_typebuf(int silent) buf[1] = 'R'; buf[2] = NUL; } else { - buf[0] = (char_u)(restart_edit == 'I' ? 'i' : restart_edit); + buf[0] = (uint8_t)(restart_edit == 'I' ? 'i' : restart_edit); buf[1] = NUL; } if (ins_typebuf((char *)buf, REMAP_NONE, 0, true, silent) == OK) { @@ -1274,12 +1250,12 @@ int insert_reg(int regname, bool literally_arg) char *arg; if (regname == '.') { // Insert last inserted text. - retval = stuff_inserted(NUL, 1L, true); + retval = stuff_inserted(NUL, 1, true); } else if (get_spec_reg(regname, &arg, &allocated, true)) { if (arg == NULL) { return FAIL; } - stuffescaped((const char *)arg, literally); + stuffescaped(arg, literally); if (allocated) { xfree(arg); } @@ -1292,9 +1268,9 @@ int insert_reg(int regname, bool literally_arg) if (regname == '-') { AppendCharToRedobuff(Ctrl_R); AppendCharToRedobuff(regname); - do_put(regname, NULL, BACKWARD, 1L, PUT_CURSEND); + do_put(regname, NULL, BACKWARD, 1, PUT_CURSEND); } else { - stuffescaped((const char *)reg->y_array[i], literally); + stuffescaped(reg->y_array[i], literally); } // Insert a newline between lines and after last line if // y_type is kMTLineWise. @@ -1317,8 +1293,6 @@ int insert_reg(int regname, bool literally_arg) /// @return true if "regname" is a special register, bool get_spec_reg(int regname, char **argp, bool *allocated, bool errmsg) { - size_t cnt; - *argp = NULL; *allocated = false; switch (regname) { @@ -1366,7 +1340,7 @@ bool get_spec_reg(int regname, char **argp, bool *allocated, bool errmsg) return false; } *argp = file_name_at_cursor(FNAME_MESS | FNAME_HYP | (regname == Ctrl_P ? FNAME_EXP : 0), - 1L, NULL); + 1, NULL); *allocated = true; return true; @@ -1375,10 +1349,10 @@ bool get_spec_reg(int regname, char **argp, bool *allocated, bool errmsg) if (!errmsg) { return false; } - cnt = find_ident_under_cursor(argp, (regname == Ctrl_W - ? (FIND_IDENT|FIND_STRING) - : FIND_STRING)); - *argp = cnt ? xstrnsave(*argp, cnt) : NULL; + size_t cnt = find_ident_under_cursor(argp, (regname == Ctrl_W + ? (FIND_IDENT|FIND_STRING) + : FIND_STRING)); + *argp = cnt ? xmemdupz(*argp, cnt) : NULL; *allocated = true; return true; @@ -1387,7 +1361,7 @@ bool get_spec_reg(int regname, char **argp, bool *allocated, bool errmsg) return false; } - *argp = ml_get_buf(curwin->w_buffer, curwin->w_cursor.lnum, false); + *argp = ml_get_buf(curwin->w_buffer, curwin->w_cursor.lnum); return true; case '_': // black hole: always empty @@ -1454,10 +1428,7 @@ static void shift_delete_registers(bool y_append) /// @return FAIL if undo failed, OK otherwise. int op_delete(oparg_T *oap) { - int n; linenr_T lnum; - char *ptr; - char *newp, *oldp; struct block_def bd = { 0 }; linenr_T old_lcount = curbuf->b_ml.ml_line_count; @@ -1490,7 +1461,7 @@ int op_delete(oparg_T *oap) && oap->line_count > 1 && oap->motion_force == NUL && oap->op_type == OP_DELETE) { - ptr = ml_get(oap->end.lnum) + oap->end.col; + char *ptr = ml_get(oap->end.lnum) + oap->end.col; if (*ptr != NUL) { ptr += oap->inclusive; } @@ -1584,12 +1555,12 @@ int op_delete(oparg_T *oap) curwin->w_cursor.coladd = 0; } - // n == number of chars deleted + // "n" == number of chars deleted // If we delete a TAB, it may be replaced by several characters. // Thus the number of characters may increase! - n = bd.textlen - bd.startspaces - bd.endspaces; - oldp = ml_get(lnum); - newp = xmalloc(strlen(oldp) - (size_t)n + 1); + int n = bd.textlen - bd.startspaces - bd.endspaces; + char *oldp = ml_get(lnum); + char *newp = xmalloc(strlen(oldp) - (size_t)n + 1); // copy up to deleted part memmove(newp, oldp, (size_t)bd.textcol); // insert spaces @@ -1607,8 +1578,8 @@ int op_delete(oparg_T *oap) } check_cursor_col(); - changed_lines(curwin->w_cursor.lnum, curwin->w_cursor.col, - oap->end.lnum + 1, 0L, true); + changed_lines(curbuf, curwin->w_cursor.lnum, curwin->w_cursor.col, + oap->end.lnum + 1, 0, true); oap->line_count = 0; // no lines deleted } else if (oap->motion_type == kMTLineWise) { if (oap->op_type == OP_CHANGE) { @@ -1642,19 +1613,18 @@ int op_delete(oparg_T *oap) // leave cursor past last char in line if (oap->line_count > 1) { - u_clearline(); // "U" command not possible after "2cc" + u_clearline(curbuf); // "U" command not possible after "2cc" } } else { del_lines(oap->line_count, true); beginline(BL_WHITE | BL_FIX); - u_clearline(); // "U" command not possible after "dd" + u_clearline(curbuf); // "U" command not possible after "dd" } } else { if (virtual_op) { - int endcol = 0; - // For virtualedit: break the tabs that are partly included. if (gchar_pos(&oap->start) == '\t') { + int endcol = 0; if (u_save_cursor() == FAIL) { // save first line for undo return FAIL; } @@ -1701,7 +1671,7 @@ int op_delete(oparg_T *oap) display_dollar(oap->end.col - !oap->inclusive); } - n = oap->end.col - oap->start.col + 1 - !oap->inclusive; + int n = oap->end.col - oap->start.col + 1 - !oap->inclusive; if (virtual_op) { // fix up things for virtualedit-delete: @@ -1732,8 +1702,8 @@ int op_delete(oparg_T *oap) pos_T curpos; // save deleted and changed lines for undo - if (u_save((linenr_T)(curwin->w_cursor.lnum - 1), - (linenr_T)(curwin->w_cursor.lnum + oap->line_count)) == FAIL) { + if (u_save(curwin->w_cursor.lnum - 1, + curwin->w_cursor.lnum + oap->line_count) == FAIL) { return FAIL; } @@ -1750,7 +1720,7 @@ int op_delete(oparg_T *oap) del_lines(oap->line_count - 2, false); // delete from start of line until op_end - n = (oap->end.col + 1 - !oap->inclusive); + int n = (oap->end.col + 1 - !oap->inclusive); curwin->w_cursor.col = 0; (void)del_bytes((colnr_T)n, !virtual_op, oap->op_type == OP_DELETE && !oap->is_VIsual); @@ -1798,7 +1768,7 @@ static void mb_adjust_opend(oparg_T *oap) static inline void pbyte(pos_T lp, int c) { assert(c <= UCHAR_MAX); - *(ml_get_buf(curbuf, lp.lnum, true) + lp.col) = (char)c; + *(ml_get_buf_mut(curbuf, lp.lnum) + lp.col) = (char)c; if (!curbuf_splice_pending) { extmark_splice_cols(curbuf, (int)lp.lnum - 1, lp.col, 1, 1, kExtmarkUndo); } @@ -1820,10 +1790,7 @@ static void replace_character(int c) /// Replace a whole area with one character. static int op_replace(oparg_T *oap, int c) { - int n, numc; - int num_chars; - char *newp, *oldp; - colnr_T oldlen; + int n; struct block_def bd; char *after_p = NULL; int had_ctrl_v_cr = false; @@ -1848,6 +1815,11 @@ static int op_replace(oparg_T *oap, int c) // block mode replace if (oap->motion_type == kMTBlockWise) { + int numc; + int num_chars; + char *newp; + char *oldp; + colnr_T oldlen; bd.is_MAX = (curwin->w_curswant == MAXCOL); for (; curwin->w_cursor.lnum <= oap->end.lnum; curwin->w_cursor.lnum++) { curwin->w_cursor.col = 0; // make sure cursor position is valid @@ -1947,7 +1919,7 @@ static int op_replace(oparg_T *oap, int c) linenr_T baselnum = curwin->w_cursor.lnum; if (after_p != NULL) { ml_append(curwin->w_cursor.lnum++, after_p, (int)after_p_len, false); - appended_lines_mark(curwin->w_cursor.lnum, 1L); + appended_lines_mark(curwin->w_cursor.lnum, 1); oap->end.lnum++; xfree(after_p); } @@ -2043,7 +2015,7 @@ static int op_replace(oparg_T *oap, int c) curwin->w_cursor = oap->start; check_cursor(); - changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1, 0L, true); + changed_lines(curbuf, oap->start.lnum, oap->start.col, oap->end.lnum + 1, 0, true); if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) { // Set "'[" and "']" marks. @@ -2057,7 +2029,6 @@ static int op_replace(oparg_T *oap, int c) /// Handle the (non-standard vi) tilde operator. Also for "gu", "gU" and "g?". void op_tilde(oparg_T *oap) { - pos_T pos; struct block_def bd; int did_change = false; @@ -2066,7 +2037,7 @@ void op_tilde(oparg_T *oap) return; } - pos = oap->start; + pos_T pos = oap->start; if (oap->motion_type == kMTBlockWise) { // Visual block mode for (; pos.lnum <= oap->end.lnum; pos.lnum++) { int one_change; @@ -2077,7 +2048,7 @@ void op_tilde(oparg_T *oap) did_change |= one_change; } if (did_change) { - changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true); + changed_lines(curbuf, oap->start.lnum, 0, oap->end.lnum + 1, 0, true); } } else { // not block mode if (oap->motion_type == kMTLineWise) { @@ -2095,18 +2066,18 @@ void op_tilde(oparg_T *oap) did_change = swapchars(oap->op_type, &pos, oap->end.col - pos.col + 1); } else { - for (;;) { + while (true) { did_change |= swapchars(oap->op_type, &pos, - pos.lnum == oap->end.lnum ? oap->end.col + 1 : - (int)strlen(ml_get_pos(&pos))); + pos.lnum == oap->end.lnum ? oap->end.col + 1 + : (int)strlen(ml_get_pos(&pos))); if (ltoreq(oap->end, pos) || inc(&pos) == -1) { break; } } } if (did_change) { - changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1, - 0L, true); + changed_lines(curbuf, oap->start.lnum, oap->start.col, oap->end.lnum + 1, + 0, true); } } @@ -2122,8 +2093,7 @@ void op_tilde(oparg_T *oap) } if (oap->line_count > p_report) { - smsg(NGETTEXT("%" PRId64 " line changed", - "%" PRId64 " lines changed", oap->line_count), + smsg(0, NGETTEXT("%" PRId64 " line changed", "%" PRId64 " lines changed", oap->line_count), (int64_t)oap->line_count); } } @@ -2216,15 +2186,12 @@ bool swapchar(int op_type, pos_T *pos) } /// Insert and append operators for Visual mode. -void op_insert(oparg_T *oap, long count1) +void op_insert(oparg_T *oap, int count1) { - long ins_len, pre_textlen = 0; - char *firstline, *ins_text; - colnr_T ind_pre_col = 0, ind_post_col; - int ind_pre_vcol = 0, ind_post_vcol = 0; + int pre_textlen = 0; + colnr_T ind_pre_col = 0; + int ind_pre_vcol = 0; struct block_def bd; - int i; - pos_T t1; // edit() changes this - record it for OP_APPEND bd.is_MAX = (curwin->w_curswant == MAXCOL); @@ -2261,12 +2228,12 @@ void op_insert(oparg_T *oap, long count1) // Get indent information ind_pre_col = (colnr_T)getwhitecols_curline(); ind_pre_vcol = get_indent(); - firstline = ml_get(oap->start.lnum) + bd.textcol; + char *firstline = ml_get(oap->start.lnum) + bd.textcol; if (oap->op_type == OP_APPEND) { firstline += bd.textlen; } - pre_textlen = (long)strlen(firstline); + pre_textlen = (int)strlen(firstline); } if (oap->op_type == OP_APPEND) { @@ -2284,7 +2251,7 @@ void op_insert(oparg_T *oap, long count1) if (u_save_cursor() == FAIL) { return; } - for (i = 0; i < bd.endspaces; i++) { + for (int i = 0; i < bd.endspaces; i++) { ins_char(' '); } bd.textlen += bd.endspaces; @@ -2301,7 +2268,7 @@ void op_insert(oparg_T *oap, long count1) } } - t1 = oap->start; + pos_T t1 = oap->start; const pos_T start_insert = curwin->w_cursor; (void)edit(NUL, false, (linenr_T)count1); @@ -2321,12 +2288,13 @@ void op_insert(oparg_T *oap, long count1) } if (oap->motion_type == kMTBlockWise) { + int ind_post_vcol = 0; struct block_def bd2; bool did_indent = false; // if indent kicked in, the firstline might have changed // but only do that, if the indent actually increased - ind_post_col = (colnr_T)getwhitecols_curline(); + colnr_T ind_post_col = (colnr_T)getwhitecols_curline(); if (curbuf->b_op_start.col > ind_pre_col && ind_post_col > ind_pre_col) { bd.textcol += ind_post_col - ind_pre_col; ind_post_vcol = get_indent(); @@ -2391,7 +2359,7 @@ void op_insert(oparg_T *oap, long count1) // Subsequent calls to ml_get() flush the firstline data - take a // copy of the required string. - firstline = ml_get(oap->start.lnum); + char *firstline = ml_get(oap->start.lnum); const size_t len = strlen(firstline); colnr_T add = bd.textcol; colnr_T offset = 0; // offset when cursor was moved in insert mode @@ -2414,9 +2382,9 @@ void op_insert(oparg_T *oap, long count1) } else { firstline += add; } - ins_len = (long)strlen(firstline) - pre_textlen - offset; + int ins_len = (int)strlen(firstline) - pre_textlen - offset; if (pre_textlen >= 0 && ins_len > 0) { - ins_text = xstrnsave(firstline, (size_t)ins_len); + char *ins_text = xmemdupz(firstline, (size_t)ins_len); // block handled here if (u_save(oap->start.lnum, (linenr_T)(oap->end.lnum + 1)) == OK) { block_insert(oap, ins_text, (oap->op_type == OP_INSERT), &bd); @@ -2434,20 +2402,12 @@ void op_insert(oparg_T *oap, long count1) /// @return true if edit() returns because of a CTRL-O command int op_change(oparg_T *oap) { - colnr_T l; - int retval; - long offset; - linenr_T linenr; - long ins_len; - long pre_textlen = 0; - long pre_indent = 0; - char *newp; + int pre_textlen = 0; + int pre_indent = 0; char *firstline; - char *ins_text; - char *oldp; struct block_def bd; - l = oap->start.col; + 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 @@ -2477,8 +2437,8 @@ int op_change(oparg_T *oap) coladvance_force(getviscol()); } firstline = ml_get(oap->start.lnum); - pre_textlen = (long)strlen(firstline); - pre_indent = (long)getwhitecols(firstline); + pre_textlen = (int)strlen(firstline); + pre_indent = (int)getwhitecols(firstline); bd.textcol = curwin->w_cursor.col; } @@ -2490,7 +2450,7 @@ int op_change(oparg_T *oap) const bool save_finish_op = finish_op; finish_op = false; - retval = edit(NUL, false, (linenr_T)1); + int retval = edit(NUL, false, 1); finish_op = save_finish_op; @@ -2499,23 +2459,27 @@ int op_change(oparg_T *oap) // Don't repeat the insert when Insert mode ended with CTRL-C. if (oap->motion_type == kMTBlockWise && oap->start.lnum != oap->end.lnum && !got_int) { + int ins_len; // Auto-indenting may have changed the indent. If the cursor was past // the indent, exclude that indent change from the inserted text. firstline = ml_get(oap->start.lnum); if (bd.textcol > (colnr_T)pre_indent) { - long new_indent = (long)getwhitecols(firstline); + int new_indent = (int)getwhitecols(firstline); pre_textlen += new_indent - pre_indent; bd.textcol += (colnr_T)(new_indent - pre_indent); } - ins_len = (long)strlen(firstline) - pre_textlen; + ins_len = (int)strlen(firstline) - pre_textlen; if (ins_len > 0) { + int offset; + char *newp; + char *oldp; // Subsequent calls to ml_get() flush the firstline data - take a // copy of the inserted text. - ins_text = xmalloc((size_t)(ins_len + 1)); + char *ins_text = xmalloc((size_t)ins_len + 1); xstrlcpy(ins_text, firstline + bd.textcol, (size_t)ins_len + 1); - for (linenr = oap->start.lnum + 1; linenr <= oap->end.lnum; + for (linenr_T linenr = oap->start.lnum + 1; linenr <= oap->end.lnum; linenr++) { block_prep(oap, &bd, linenr, true); if (!bd.is_short || virtual_op) { @@ -2543,11 +2507,11 @@ int op_change(oparg_T *oap) STRMOVE(newp + offset, oldp); ml_replace(linenr, newp, false); extmark_splice_cols(curbuf, (int)linenr - 1, bd.textcol, - 0, vpos.coladd + (int)ins_len, kExtmarkUndo); + 0, vpos.coladd + ins_len, kExtmarkUndo); } } check_cursor(); - changed_lines(oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L, true); + changed_lines(curbuf, oap->start.lnum + 1, 0, oap->end.lnum + 1, 0, true); xfree(ins_text); } } @@ -2559,9 +2523,7 @@ int op_change(oparg_T *oap) #if defined(EXITFREE) void clear_registers(void) { - int i; - - for (i = 0; i < NUM_REGISTERS; i++) { + for (int i = 0; i < NUM_REGISTERS; i++) { free_register(&y_regs[i]); } } @@ -2617,14 +2579,9 @@ bool op_yank(oparg_T *oap, bool message) static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) { yankreg_T newreg; // new yank register when appending - char **new_ptr; - linenr_T lnum; // current line number - size_t j; MotionType yank_type = oap->motion_type; size_t yanklines = (size_t)oap->line_count; linenr_T yankendlnum = oap->end.lnum; - char *p; - char *pnew; struct block_def bd; yankreg_T *curr = reg; // copy of current register @@ -2656,7 +2613,7 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) reg->timestamp = os_time(); size_t y_idx = 0; // index in y_array[] - lnum = oap->start.lnum; + linenr_T lnum = oap->start.lnum; // current line number if (yank_type == kMTBlockWise) { // Visual block mode @@ -2682,7 +2639,7 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) colnr_T startcol = 0, endcol = MAXCOL; int is_oneChar = false; colnr_T cs, ce; - p = ml_get(lnum); + char *p = ml_get(lnum); bd.startspaces = 0; bd.endspaces = 0; @@ -2692,8 +2649,10 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) getvcol(curwin, &oap->start, &cs, NULL, &ce); if (ce != cs && oap->start.coladd > 0) { // Part of a tab selected -- but don't double-count it. - bd.startspaces = (ce - cs + 1) - - oap->start.coladd; + bd.startspaces = (ce - cs + 1) - oap->start.coladd; + if (bd.startspaces < 0) { + bd.startspaces = 0; + } startcol++; } } @@ -2743,7 +2702,8 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) } if (curr != reg) { // append the new block to the old block - new_ptr = xmalloc(sizeof(char *) * (curr->y_size + reg->y_size)); + size_t j; + char **new_ptr = xmalloc(sizeof(char *) * (curr->y_size + reg->y_size)); for (j = 0; j < curr->y_size; j++) { new_ptr[j] = curr->y_array[j]; } @@ -2759,8 +2719,8 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) // the new block, unless being Vi compatible. if (curr->y_type == kMTCharWise && vim_strchr(p_cpo, CPO_REGAPPEND) == NULL) { - pnew = xmalloc(strlen(curr->y_array[curr->y_size - 1]) - + strlen(reg->y_array[0]) + 1); + char *pnew = xmalloc(strlen(curr->y_array[curr->y_size - 1]) + + strlen(reg->y_array[0]) + 1); STRCPY(pnew, curr->y_array[--j]); STRCAT(pnew, reg->y_array[0]); xfree(curr->y_array[j]); @@ -2797,12 +2757,12 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) update_screen(); } if (yank_type == kMTBlockWise) { - smsg(NGETTEXT("block of %" PRId64 " line yanked%s", - "block of %" PRId64 " lines yanked%s", yanklines), + smsg(0, NGETTEXT("block of %" PRId64 " line yanked%s", + "block of %" PRId64 " lines yanked%s", yanklines), (int64_t)yanklines, namebuf); } else { - smsg(NGETTEXT("%" PRId64 " line yanked%s", - "%" PRId64 " lines yanked%s", yanklines), + smsg(0, NGETTEXT("%" PRId64 " line yanked%s", + "%" PRId64 " lines yanked%s", yanklines), (int64_t)yanklines, namebuf); } } @@ -2873,7 +2833,7 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) // The yanked text contents. list_T *const list = tv_list_alloc((ptrdiff_t)reg->y_size); for (size_t i = 0; i < reg->y_size; i++) { - tv_list_append_string(list, (const char *)reg->y_array[i], -1); + tv_list_append_string(list, reg->y_array[i], -1); } tv_list_set_lock(list, VAR_FIXED); (void)tv_dict_add_list(dict, S_LEN("regcontents"), list); @@ -2968,39 +2928,28 @@ static void do_autocmd_textputpost(int regname, yankreg_T *reg) /// PUT_LINE force linewise put (":put") /// PUT_BLOCK_INNER in block mode, do not add trailing spaces /// @param dir BACKWARD for 'P', FORWARD for 'p' -void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) +void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) { - char *ptr; - char *newp; - char *oldp; - int yanklen; size_t totlen = 0; // init for gcc linenr_T lnum = 0; - colnr_T col = 0; - size_t i; // index in y_array[] MotionType y_type; size_t y_size; - size_t oldlen; int y_width = 0; colnr_T vcol = 0; - int delcount; int incr = 0; struct block_def bd; char **y_array = NULL; linenr_T nr_lines = 0; - pos_T new_cursor; int indent; int orig_indent = 0; // init for gcc int indent_diff = 0; // init for gcc bool first_indent = true; int lendiff = 0; - pos_T old_pos; char *insert_string = NULL; bool allocated = false; - long cnt; const pos_T orig_start = curbuf->b_op_start; const pos_T orig_end = curbuf->b_op_end; - unsigned int cur_ve_flags = get_ve_flags(); + unsigned cur_ve_flags = get_ve_flags(); if (flags & PUT_FIXINDENT) { orig_indent = get_indent(); @@ -3015,8 +2964,9 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) bool non_linewise_vis = (VIsual_active && VIsual_mode != 'V'); // PUT_LINE has special handling below which means we use 'i' to start. - char command_start_char = non_linewise_vis ? 'c' : - (flags & PUT_LINE ? 'i' : (dir == FORWARD ? 'a' : 'i')); + char command_start_char = non_linewise_vis + ? 'c' + : (flags & PUT_LINE ? 'i' : (dir == FORWARD ? 'a' : 'i')); // To avoid 'autoindent' on linewise puts, create a new line with `:put _`. if (flags & PUT_LINE) { @@ -3112,9 +3062,9 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) // For the = register we need to split the string at NL // characters. // Loop twice: count the number of lines and save them. - for (;;) { + while (true) { y_size = 0; - ptr = insert_string; + char *ptr = insert_string; while (ptr != NULL) { if (y_array != NULL) { y_array[y_size] = ptr; @@ -3172,16 +3122,16 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) if (dir == FORWARD && *p != NUL) { MB_PTR_ADV(p); } - ptr = xstrdup(p); - ml_append(curwin->w_cursor.lnum, ptr, (colnr_T)0, false); + char *ptr = xstrdup(p); + ml_append(curwin->w_cursor.lnum, ptr, 0, false); xfree(ptr); - oldp = get_cursor_line_ptr(); + char *oldp = get_cursor_line_ptr(); p = oldp + curwin->w_cursor.col; if (dir == FORWARD && *p != NUL) { MB_PTR_ADV(p); } - ptr = xstrnsave(oldp, (size_t)(p - oldp)); + ptr = xmemdupz(oldp, (size_t)(p - oldp)); ml_replace(curwin->w_cursor.lnum, ptr, false); nr_lines++; dir = FORWARD; @@ -3227,8 +3177,8 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) } // In an empty buffer the empty line is going to be replaced, include // it in the saved lines. - if ((buf_is_empty(curbuf) ? - u_save(0, 2) : u_save(lnum - 1, lnum)) == FAIL) { + if ((buf_is_empty(curbuf) + ? u_save(0, 2) : u_save(lnum - 1, lnum)) == FAIL) { goto end; } if (dir == FORWARD) { @@ -3241,12 +3191,12 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) goto end; } - yanklen = (int)strlen(y_array[0]); + int yanklen = (int)strlen(y_array[0]); if (cur_ve_flags == VE_ALL && y_type == kMTCharWise) { if (gchar_cursor() == TAB) { int viscol = getviscol(); - long ts = curbuf->b_p_ts; + OptInt ts = curbuf->b_p_ts; // Don't need to insert spaces when "p" on the last position of a // tab or "P" on the first position. if (dir == FORWARD @@ -3262,7 +3212,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) } lnum = curwin->w_cursor.lnum; - col = curwin->w_cursor.col; + colnr_T col = curwin->w_cursor.col; // Block mode if (y_type == kMTBlockWise) { @@ -3303,7 +3253,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) } curwin->w_cursor.coladd = 0; bd.textcol = 0; - for (i = 0; i < y_size; i++) { + for (size_t i = 0; i < y_size; i++) { int spaces = 0; char shortline; // can just be 0 or 1, needed for blockwise paste beyond the current @@ -3313,20 +3263,19 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) bd.startspaces = 0; bd.endspaces = 0; vcol = 0; - delcount = 0; + int delcount = 0; // add a new line if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) { - if (ml_append(curbuf->b_ml.ml_line_count, "", - (colnr_T)1, false) == FAIL) { + if (ml_append(curbuf->b_ml.ml_line_count, "", 1, false) == FAIL) { break; } nr_lines++; lines_appended = 1; } // get the old line and advance to the position to insert at - oldp = get_cursor_line_ptr(); - oldlen = strlen(oldp); + char *oldp = get_cursor_line_ptr(); + size_t oldlen = strlen(oldp); chartabsize_T cts; init_chartabsize_arg(&cts, curwin, curwin->w_cursor.lnum, 0, oldp, oldp); @@ -3336,7 +3285,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) cts.cts_vcol += incr; } vcol = cts.cts_vcol; - ptr = cts.cts_ptr; + char *ptr = cts.cts_ptr; bd.textcol = (colnr_T)(ptr - oldp); clear_chartabsize_arg(&cts); @@ -3385,8 +3334,9 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) break; } - totlen = (size_t)(count * (yanklen + spaces) + bd.startspaces + bd.endspaces); - newp = xmalloc(totlen + oldlen + 1); + totlen = (size_t)count * (size_t)(yanklen + spaces) + (size_t)bd.startspaces + + (size_t)bd.endspaces; + char *newp = xmalloc(totlen + oldlen + 1); // copy part up to cursor to new line ptr = newp; @@ -3398,12 +3348,12 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) ptr += bd.startspaces; // insert the new text - for (long j = 0; j < count; j++) { + for (int j = 0; j < count; j++) { memmove(ptr, y_array[i], (size_t)yanklen); ptr += yanklen; // insert block's trailing spaces only if there's text behind - if ((j < count - 1 || !shortline) && spaces) { + if ((j < count - 1 || !shortline) && spaces > 0) { memset(ptr, ' ', (size_t)spaces); ptr += spaces; } else { @@ -3429,7 +3379,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) } } - changed_lines(lnum, 0, curbuf->b_op_start.lnum + (linenr_T)y_size + changed_lines(curbuf, lnum, 0, curbuf->b_op_start.lnum + (linenr_T)y_size - nr_lines, nr_lines, true); // Set '[ mark. @@ -3477,7 +3427,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) // Line mode: BACKWARD is the same as FORWARD on the previous line lnum--; } - new_cursor = curwin->w_cursor; + pos_T new_cursor = curwin->w_cursor; // simple case: insert into one line at a time if (y_type == kMTCharWise && y_size == 1) { @@ -3511,10 +3461,10 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) // multiplication overflow emsg(_(e_resulting_text_too_long)); } else { - totlen = (size_t)(count * yanklen); + totlen = (size_t)count * (size_t)yanklen; do { - oldp = ml_get(lnum); - oldlen = strlen(oldp); + char *oldp = ml_get(lnum); + size_t oldlen = strlen(oldp); if (lnum > start_lnum) { pos_T pos = { .lnum = lnum, @@ -3529,10 +3479,10 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) lnum++; continue; } - newp = xmalloc(totlen + oldlen + 1); + char *newp = xmalloc(totlen + oldlen + 1); memmove(newp, oldp, (size_t)col); - ptr = newp + col; - for (i = 0; i < (size_t)count; i++) { + char *ptr = newp + col; + for (size_t i = 0; i < (size_t)count; i++) { memmove(ptr, y_array[0], (size_t)yanklen); ptr += yanklen; } @@ -3545,7 +3495,8 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) // Place cursor on last putted char. if (lnum == curwin->w_cursor.lnum) { // make sure curwin->w_virtcol is updated - changed_cline_bef_curs(); + changed_cline_bef_curs(curwin); + invalidate_botline(curwin); curwin->w_cursor.col += (colnr_T)(totlen - 1); } changed_bytes(lnum, col); @@ -3573,28 +3524,27 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) } } else { linenr_T new_lnum = new_cursor.lnum; - size_t len; // Insert at least one line. When y_type is kMTCharWise, break the first // line in two. - for (cnt = 1; cnt <= count; cnt++) { - i = 0; + for (int cnt = 1; cnt <= count; cnt++) { + size_t i = 0; if (y_type == kMTCharWise) { // Split the current line in two at the insert position. // First insert y_array[size - 1] in front of second line. // Then append y_array[0] to first line. lnum = new_cursor.lnum; - ptr = ml_get(lnum) + col; + char *ptr = ml_get(lnum) + col; totlen = strlen(y_array[y_size - 1]); - newp = xmalloc((size_t)(strlen(ptr) + totlen + 1)); + char *newp = xmalloc((size_t)(strlen(ptr) + totlen + 1)); STRCPY(newp, y_array[y_size - 1]); STRCAT(newp, ptr); // insert second line - ml_append(lnum, newp, (colnr_T)0, false); + ml_append(lnum, newp, 0, false); new_lnum++; xfree(newp); - oldp = ml_get(lnum); + char *oldp = ml_get(lnum); newp = xmalloc((size_t)col + (size_t)yanklen + 1); // copy first part of line memmove(newp, oldp, (size_t)col); @@ -3608,7 +3558,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) for (; i < y_size; i++) { if ((y_type != kMTCharWise || i < y_size - 1)) { - if (ml_append(lnum, y_array[i], (colnr_T)0, false) == FAIL) { + if (ml_append(lnum, y_array[i], 0, false) == FAIL) { goto error; } new_lnum++; @@ -3616,9 +3566,9 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) lnum++; nr_lines++; if (flags & PUT_FIXINDENT) { - old_pos = curwin->w_cursor; + pos_T old_pos = curwin->w_cursor; curwin->w_cursor.lnum = lnum; - ptr = ml_get(lnum); + char *ptr = ml_get(lnum); if (cnt == count && i == y_size - 1) { lendiff = (int)strlen(ptr); } @@ -3679,21 +3629,21 @@ error: ExtmarkOp kind = (y_type == kMTLineWise && !(flags & PUT_LINE_SPLIT)) ? kExtmarkUndo : kExtmarkNOOP; mark_adjust(curbuf->b_op_start.lnum + (y_type == kMTCharWise), - (linenr_T)MAXLNUM, nr_lines, 0L, kind); + (linenr_T)MAXLNUM, nr_lines, 0, kind); // note changed text for displaying and folding if (y_type == kMTCharWise) { - changed_lines(curwin->w_cursor.lnum, col, + changed_lines(curbuf, curwin->w_cursor.lnum, col, curwin->w_cursor.lnum + 1, nr_lines, true); } else { - changed_lines(curbuf->b_op_start.lnum, 0, + changed_lines(curbuf, curbuf->b_op_start.lnum, 0, curbuf->b_op_start.lnum, nr_lines, true); } // Put the '] mark on the first byte of the last inserted character. // Correct the length for change in indent. curbuf->b_op_end.lnum = new_lnum; - len = strlen(y_array[y_size - 1]); + size_t len = strlen(y_array[y_size - 1]); col = (colnr_T)len - lendiff; if (col > 1) { curbuf->b_op_end.col = col - 1; @@ -3742,6 +3692,15 @@ error: msgmore(nr_lines); curwin->w_set_curswant = true; + // Make sure the cursor is not after the NUL. + int len = (int)strlen(get_cursor_line_ptr()); + if (curwin->w_cursor.col > len) { + if (cur_ve_flags == VE_ALL) { + curwin->w_cursor.coladd = curwin->w_cursor.col - len; + } + curwin->w_cursor.col = len; + } + end: if (reg) { do_autocmd_textputpost(regname, reg); @@ -3768,7 +3727,7 @@ end: /// there move it left. void adjust_cursor_eol(void) { - unsigned int cur_ve_flags = get_ve_flags(); + unsigned cur_ve_flags = get_ve_flags(); const bool adj_cursor = (curwin->w_cursor.col > 0 && gchar_cursor() == NUL @@ -3827,9 +3786,7 @@ void ex_display(exarg_T *eap) { char *p; yankreg_T *yb; - int name; char *arg = eap->arg; - int clen; int type; if (arg != NULL && *arg == NUL) { @@ -3840,7 +3797,7 @@ void ex_display(exarg_T *eap) // Highlight title msg_puts_title(_("\nType Name Content")); for (int i = -1; i < NUM_REGISTERS && !got_int; i++) { - name = get_register_name(i); + int name = get_register_name(i); switch (get_reg_type(name, NULL)) { case kMTLineWise: type = 'l'; break; @@ -3895,9 +3852,9 @@ void ex_display(exarg_T *eap) n -= 2; } for (p = yb->y_array[j]; - *p != NUL && (n -= ptr2cells(p)) >= 0; p++) { // -V1019 - clen = utfc_ptr2len(p); - msg_outtrans_len(p, clen); + *p != NUL && (n -= ptr2cells(p)) >= 0; p++) { + int clen = utfc_ptr2len(p); + msg_outtrans_len(p, clen, 0); p += clen - 1; } } @@ -3910,7 +3867,7 @@ void ex_display(exarg_T *eap) } // display last inserted text - if ((p = (char *)get_last_insert()) != NULL + if ((p = get_last_insert()) != NULL && (arg == NULL || vim_strchr(arg, '.') != NULL) && !got_int && !message_filtered(p)) { msg_puts("\n c \". "); @@ -3966,18 +3923,16 @@ void ex_display(exarg_T *eap) static void dis_msg(const char *p, bool skip_esc) FUNC_ATTR_NONNULL_ALL { - int n; - int l; - - n = Columns - 6; + int n = Columns - 6; while (*p != NUL && !(*p == ESC && skip_esc && *(p + 1) == NUL) && (n -= ptr2cells(p)) >= 0) { + int l; if ((l = utfc_ptr2len(p)) > 1) { - msg_outtrans_len(p, l); + msg_outtrans_len(p, l, 0); p += l; } else { - msg_outtrans_len(p++, 1); + msg_outtrans_len(p++, 1, 0); } } os_breakcheck(); @@ -3997,7 +3952,6 @@ static void dis_msg(const char *p, bool skip_esc) char *skip_comment(char *line, bool process, bool include_space, bool *is_comment) { char *comment_flags = NULL; - int lead_len; int leader_offset = get_last_leader_offset(line, &comment_flags); *is_comment = false; @@ -4020,7 +3974,7 @@ char *skip_comment(char *line, bool process, bool include_space, bool *is_commen return line; } - lead_len = get_leader_len(line, &comment_flags, false, include_space); + int lead_len = get_leader_len(line, &comment_flags, false, include_space); if (lead_len == 0) { return line; @@ -4061,14 +4015,10 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions char *curr = NULL; char *curr_start = NULL; char *cend; - char *newp; - char *spaces; // number of spaces inserted before a line int endcurr1 = NUL; int endcurr2 = NUL; int currsize = 0; // size of the current line int sumsize = 0; // size of the long new line - linenr_T t; - colnr_T col = 0; int ret = OK; int *comments = NULL; int remove_comments = (use_formatoptions == true) @@ -4083,15 +4033,16 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions // Allocate an array to store the number of spaces inserted before each // line. We will use it to pre-compute the length of the new line and the // proper placement of each original line in the new one. - spaces = xcalloc(count, 1); + char *spaces = xcalloc(count, 1); // number of spaces inserted before a line if (remove_comments) { comments = xcalloc(count, sizeof(*comments)); } - // Don't move anything, just compute the final line length + // Don't move anything yet, just compute the final line length // and setup the array of space strings lengths - for (t = 0; t < (linenr_T)count; t++) { - curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t)); + // This loops forward over joined lines. + for (linenr_T t = 0; t < (linenr_T)count; t++) { + curr_start = ml_get(curwin->w_cursor.lnum + t); curr = curr_start; if (t == 0 && setmark && (cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) { // Set the '[ mark. @@ -4162,14 +4113,15 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions } // store the column position before last line - col = sumsize - currsize - spaces[count - 1]; + colnr_T col = sumsize - currsize - spaces[count - 1]; // allocate the space for the new line - newp = xmalloc((size_t)sumsize + 1); + char *newp = xmalloc((size_t)sumsize + 1); cend = newp + sumsize; *cend = 0; // Move affected lines to the new long one. + // This loops backwards over the joined lines, including the original line. // // Move marks from each deleted line to the joined line, adjusting the // column. This is not Vi compatible, but Vi deletes the marks, thus that @@ -4177,7 +4129,7 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions curbuf_splice_pending++; - for (t = (linenr_T)count - 1;; t--) { + for (linenr_T t = (linenr_T)count - 1;; t--) { cend -= currsize; memmove(cend, curr, (size_t)currsize); if (spaces[t] > 0) { @@ -4189,9 +4141,9 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions // what is added if it is inside these spaces. const int spaces_removed = (int)((curr - curr_start) - spaces[t]); linenr_T lnum = curwin->w_cursor.lnum + t; - colnr_T mincol = (colnr_T)0; + colnr_T mincol = 0; linenr_T lnum_amount = -t; - long col_amount = (cend - newp - spaces_removed); + colnr_T col_amount = (colnr_T)(cend - newp - spaces_removed); mark_col_adjust(lnum, mincol, lnum_amount, col_amount, spaces_removed); @@ -4220,15 +4172,15 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions // Only report the change in the first line here, del_lines() will report // the deleted line. - changed_lines(curwin->w_cursor.lnum, currsize, - curwin->w_cursor.lnum + 1, 0L, true); + changed_lines(curbuf, curwin->w_cursor.lnum, currsize, + curwin->w_cursor.lnum + 1, 0, true); // Delete following lines. To do this we move the cursor there // briefly, and then move it back. After del_lines() the cursor may // have moved up (last line deleted), so the current lnum is kept in t. - t = curwin->w_cursor.lnum; + linenr_T t = curwin->w_cursor.lnum; curwin->w_cursor.lnum++; - del_lines((long)count - 1, false); + del_lines((int)count - 1, false); curwin->w_cursor.lnum = t; curbuf_splice_pending--; curbuf->deleted_bytes2 = 0; @@ -4290,11 +4242,6 @@ static void restore_lbr(bool lbr_saved) static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool is_del) { int incr = 0; - char *pend; - char *pstart; - char *line; - char *prev_pstart; - char *prev_pend; // Avoid a problem with unwanted linebreaks in block mode. const bool lbr_saved = reset_lbr(); @@ -4310,8 +4257,8 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool bdp->end_char_vcols = 0; bdp->start_char_vcols = 0; - line = ml_get(lnum); - prev_pstart = line; + char *line = ml_get(lnum); + char *prev_pstart = line; chartabsize_T cts; init_chartabsize_arg(&cts, curwin, lnum, bdp->start_vcol, line, line); @@ -4330,7 +4277,7 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool MB_PTR_ADV(cts.cts_ptr); } bdp->start_vcol = cts.cts_vcol; - pstart = cts.cts_ptr; + char *pstart = cts.cts_ptr; clear_chartabsize_arg(&cts); bdp->start_char_vcols = incr; @@ -4347,7 +4294,7 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool if (is_del && bdp->startspaces) { bdp->startspaces = bdp->start_char_vcols - bdp->startspaces; } - pend = pstart; + char *pend = pstart; bdp->end_vcol = bdp->start_vcol; if (bdp->end_vcol > oap->end_vcol) { // it's all in one character bdp->is_oneChar = true; @@ -4369,7 +4316,7 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool } } else { init_chartabsize_arg(&cts, curwin, lnum, bdp->end_vcol, line, pend); - prev_pend = pend; + char *prev_pend = pend; while (cts.cts_vcol <= oap->end_vcol && *cts.cts_ptr != NUL) { // Count a tab for what it's worth (if list mode not on) prev_pend = cts.cts_ptr; @@ -4421,7 +4368,6 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool /// @param[in] g_cmd Prefixed with `g`. void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) { - pos_T pos; struct block_def bd; ssize_t change_cnt = 0; linenr_T amount = Prenum1; @@ -4432,7 +4378,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) disable_fold_update++; if (!VIsual_active) { - pos = curwin->w_cursor; + pos_T pos = curwin->w_cursor; if (u_save_cursor() == FAIL) { disable_fold_update--; return; @@ -4440,10 +4386,9 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) change_cnt = do_addsub(oap->op_type, &pos, 0, amount); disable_fold_update--; if (change_cnt) { - changed_lines(pos.lnum, 0, pos.lnum + 1, 0L, true); + changed_lines(curbuf, pos.lnum, 0, pos.lnum + 1, 0, true); } } else { - int one_change; int length; pos_T startpos; @@ -4453,7 +4398,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) return; } - pos = oap->start; + pos_T pos = oap->start; for (; pos.lnum <= oap->end.lnum; pos.lnum++) { if (oap->motion_type == kMTBlockWise) { // Visual block mode @@ -4483,7 +4428,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) length = oap->end.col - pos.col + 1; } } - one_change = do_addsub(oap->op_type, &pos, length, amount); + int one_change = do_addsub(oap->op_type, &pos, length, amount); if (one_change) { // Remember the start position of the first change. if (change_cnt == 0) { @@ -4499,7 +4444,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) disable_fold_update--; if (change_cnt) { - changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true); + changed_lines(curbuf, oap->start.lnum, 0, oap->end.lnum + 1, 0, true); } if (!change_cnt && oap->is_VIsual) { @@ -4514,8 +4459,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) } if (change_cnt > p_report) { - smsg(NGETTEXT("%" PRId64 " lines changed", - "%" PRId64 " lines changed", change_cnt), + smsg(0, NGETTEXT("%" PRId64 " lines changed", "%" PRId64 " lines changed", change_cnt), (int64_t)change_cnt); } } @@ -4531,17 +4475,11 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) /// @return true if some character was changed. int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) { - int col; char *buf1 = NULL; char buf2[NUMBUFLEN]; int pre; // 'X' or 'x': hex; '0': octal; 'B' or 'b': bin static bool hexupper = false; // 0xABC uvarnumber_T n; - uvarnumber_T oldn; - char *ptr; - int c; - int todel; - int firstdigit; bool negative = false; bool was_positive = true; bool visual = VIsual_active; @@ -4565,8 +4503,8 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) } curwin->w_cursor = *pos; - ptr = ml_get(pos->lnum); - col = pos->col; + char *ptr = ml_get(pos->lnum); + int col = pos->col; if (*ptr == NUL || col + !!save_coladd >= (int)strlen(ptr)) { goto theend; @@ -4659,7 +4597,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) } // If a number was found, and saving for undo works, replace the number. - firstdigit = (uint8_t)ptr[col]; + int firstdigit = (uint8_t)ptr[col]; if (!ascii_isdigit(firstdigit) && !(do_alpha && ASCII_ISALPHA(firstdigit))) { beep_flush(); goto theend; @@ -4712,11 +4650,12 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) : length); } + bool overflow = false; vim_str2nr(ptr + col, &pre, &length, 0 + (do_bin ? STR2NR_BIN : 0) + (do_oct ? STR2NR_OCT : 0) + (do_hex ? STR2NR_HEX : 0), - NULL, &n, maxlen, false); + NULL, &n, maxlen, false, &overflow); // ignore leading '-' for hex, octal and bin numbers if (pre && negative) { @@ -4734,10 +4673,12 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) subtract ^= true; } - oldn = n; + uvarnumber_T oldn = n; - n = subtract ? n - (uvarnumber_T)Prenum1 - : n + (uvarnumber_T)Prenum1; + if (!overflow) { // if number is too big don't add/subtract + n = subtract ? n - (uvarnumber_T)Prenum1 + : n + (uvarnumber_T)Prenum1; + } // handle wraparound for decimal numbers if (!pre) { @@ -4761,7 +4702,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) if (do_unsigned && negative) { if (subtract) { // sticking at zero. - n = (uvarnumber_T)0; + n = 0; } else { // sticking at 2^64 - 1. n = (uvarnumber_T)(-1); @@ -4779,8 +4720,8 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) curwin->w_cursor.col = col; startpos = curwin->w_cursor; did_change = true; - todel = length; - c = gchar_cursor(); + int todel = length; + int c = gchar_cursor(); // Don't include the '-' in the length, only the length of the part // after it is kept the same. @@ -4829,7 +4770,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) } } - while (bits > 0) { + while (bits > 0 && i < NUMBUFLEN - 1) { buf2[i++] = ((n >> --bits) & 0x1) ? '1' : '0'; } @@ -5015,7 +4956,7 @@ void *get_reg_contents(int regname, int flags) if (flags & kGRegList) { list_T *const list = tv_list_alloc((ptrdiff_t)reg->y_size); for (size_t i = 0; i < reg->y_size; i++) { - tv_list_append_string(list, (const char *)reg->y_array[i], -1); + tv_list_append_string(list, reg->y_array[i], -1); } return list; @@ -5084,7 +5025,7 @@ static void finish_write_reg(int name, yankreg_T *reg, yankreg_T *old_y_previous /// @see write_reg_contents_ex void write_reg_contents(int name, const char *str, ssize_t len, int must_append) { - write_reg_contents_ex(name, str, len, must_append, kMTUnknown, 0L); + write_reg_contents_ex(name, str, len, must_append, kMTUnknown, 0); } void write_reg_contents_lst(int name, char **strings, bool must_append, MotionType yank_type, @@ -5095,8 +5036,7 @@ void write_reg_contents_lst(int name, char **strings, bool must_append, MotionTy if (strings[0] == NULL) { s = ""; } else if (strings[1] != NULL) { - emsg(_("E883: search pattern and expression register may not " - "contain two or more lines")); + emsg(_(e_search_pattern_and_expression_register_may_not_contain_two_or_more_lines)); return; } write_reg_contents_ex(name, s, -1, must_append, yank_type, block_len); @@ -5214,7 +5154,7 @@ void write_reg_contents_ex(int name, const char *str, ssize_t len, bool must_app /// @param str string or list of strings to put in register /// @param len length of the string (Ignored when str_list=true.) /// @param blocklen width of visual block, or -1 for "I don't know." -/// @param str_list True if str is `char_u **`. +/// @param str_list True if str is `char **`. static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char *str, size_t len, colnr_T blocklen, bool str_list) FUNC_ATTR_NONNULL_ALL @@ -5374,10 +5314,8 @@ static varnumber_T line_count_info(char *line, varnumber_T *wc, varnumber_T *cc, /// @param dict when not NULL, store the info there instead of showing it. void cursor_pos_info(dict_T *dict) { - char *p; char buf1[50]; char buf2[40]; - linenr_T lnum; varnumber_T byte_count = 0; varnumber_T bom_count = 0; varnumber_T byte_count_cursor = 0; @@ -5385,9 +5323,6 @@ void cursor_pos_info(dict_T *dict) varnumber_T char_count_cursor = 0; varnumber_T word_count = 0; varnumber_T word_count_cursor = 0; - int eol_size; - varnumber_T last_check = 100000L; - long line_count_selected = 0; pos_T min_pos, max_pos; oparg_T oparg; struct block_def bd; @@ -5397,10 +5332,13 @@ void cursor_pos_info(dict_T *dict) // Compute the length of the file in characters. if (curbuf->b_ml.ml_flags & ML_EMPTY) { if (dict == NULL) { - msg(_(no_lines_msg)); + msg(_(no_lines_msg), 0); return; } } else { + int eol_size; + varnumber_T last_check = 100000; + int line_count_selected = 0; if (get_fileformat(curbuf) == EOL_DOS) { eol_size = 2; } else { @@ -5424,8 +5362,8 @@ void cursor_pos_info(dict_T *dict) char *const saved_w_sbr = curwin->w_p_sbr; // Make 'sbr' empty for a moment to get the correct size. - p_sbr = empty_option; - curwin->w_p_sbr = empty_option; + p_sbr = empty_string_option; + curwin->w_p_sbr = empty_string_option; oparg.is_VIsual = true; oparg.motion_type = kMTBlockWise; oparg.op_type = OP_NOP; @@ -5445,21 +5383,21 @@ void cursor_pos_info(dict_T *dict) line_count_selected = max_pos.lnum - min_pos.lnum + 1; } - for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; lnum++) { + for (linenr_T lnum = 1; lnum <= curbuf->b_ml.ml_line_count; lnum++) { // Check for a CTRL-C every 100000 characters. if (byte_count > last_check) { os_breakcheck(); if (got_int) { return; } - last_check = byte_count + 100000L; + last_check = byte_count + 100000; } // Do extra processing for VIsual mode. if (l_VIsual_active && lnum >= min_pos.lnum && lnum <= max_pos.lnum) { char *s = NULL; - long len = 0L; + int len = 0; switch (l_VIsual_mode) { case Ctrl_V: @@ -5467,7 +5405,7 @@ void cursor_pos_info(dict_T *dict) block_prep(&oparg, &bd, lnum, false); virtual_op = kNone; s = bd.textstart; - len = (long)bd.textlen; + len = bd.textlen; break; case 'V': s = ml_get(lnum); @@ -5490,7 +5428,7 @@ void cursor_pos_info(dict_T *dict) if (lnum == curbuf->b_ml.ml_line_count && !curbuf->b_p_eol && (curbuf->b_p_bin || !curbuf->b_p_fixeol) - && (long)strlen(s) < len) { + && (int)strlen(s) < len) { byte_count_cursor -= eol_size; } } @@ -5551,11 +5489,11 @@ void cursor_pos_info(dict_T *dict) (int64_t)byte_count_cursor, (int64_t)byte_count); } } else { - p = get_cursor_line_ptr(); + char *p = get_cursor_line_ptr(); validate_virtcol(); col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1, (int)curwin->w_virtcol + 1); - col_print((char *)buf2, sizeof(buf2), (int)strlen(p), linetabsize(p)); + col_print(buf2, sizeof(buf2), (int)strlen(p), linetabsize_str(p)); if (char_count_cursor == byte_count_cursor && char_count == byte_count) { @@ -5592,13 +5530,13 @@ void cursor_pos_info(dict_T *dict) } if (dict == NULL) { // Don't shorten this message, the user asked for it. - p = p_shm; + char *p = p_shm; p_shm = ""; if (p_ch < 1) { msg_start(); msg_scroll = true; } - msg(IObuff); + msg(IObuff, 0); p_shm = p; } } @@ -5607,7 +5545,7 @@ void cursor_pos_info(dict_T *dict) // Don't shorten this message, the user asked for it. tv_dict_add_nr(dict, S_LEN("words"), word_count); tv_dict_add_nr(dict, S_LEN("chars"), char_count); - tv_dict_add_nr(dict, S_LEN("bytes"), (varnumber_T)(byte_count + bom_count)); + tv_dict_add_nr(dict, S_LEN("bytes"), byte_count + bom_count); STATIC_ASSERT(sizeof("visual") == sizeof("cursor"), "key_len argument in tv_dict_add_nr is wrong"); @@ -5631,7 +5569,7 @@ static void op_colon(oparg_T *oap) if (oap->start.lnum == curwin->w_cursor.lnum) { stuffcharReadbuff('.'); } else { - stuffnumReadbuff((long)oap->start.lnum); + stuffnumReadbuff(oap->start.lnum); } // When using !! on a closed fold the range ".!" works best to operate @@ -5652,7 +5590,7 @@ static void op_colon(oparg_T *oap) stuffReadbuff(".+"); stuffnumReadbuff(oap->line_count - 1); } else { - stuffnumReadbuff((long)oap->end.lnum); + stuffnumReadbuff(oap->end.lnum); } } } @@ -5660,13 +5598,13 @@ static void op_colon(oparg_T *oap) stuffReadbuff("!"); } if (oap->op_type == OP_INDENT) { - stuffReadbuff((const char *)get_equalprg()); + stuffReadbuff(get_equalprg()); stuffReadbuff("\n"); } else if (oap->op_type == OP_FORMAT) { if (*curbuf->b_p_fp != NUL) { - stuffReadbuff((const char *)curbuf->b_p_fp); + stuffReadbuff(curbuf->b_p_fp); } else if (*p_fp != NUL) { - stuffReadbuff((const char *)p_fp); + stuffReadbuff(p_fp); } else { stuffReadbuff("fmt"); } @@ -5680,11 +5618,12 @@ static void op_colon(oparg_T *oap) static Callback opfunc_cb; /// Process the 'operatorfunc' option value. -void set_operatorfunc_option(char **errmsg) +const char *did_set_operatorfunc(optset_T *args FUNC_ATTR_UNUSED) { if (option_set_callback_func(p_opfunc, &opfunc_cb) == FAIL) { - *errmsg = e_invarg; + return e_invarg; } + return NULL; } #if defined(EXITFREE) @@ -5822,31 +5761,34 @@ typedef struct { int rv_mode; ///< 'v', 'V', or Ctrl-V linenr_T rv_line_count; ///< number of lines colnr_T rv_vcol; ///< number of cols or end column - long rv_count; ///< count for Visual operator + int rv_count; ///< count for Visual operator int rv_arg; ///< extra argument } redo_VIsual_T; +static bool is_ex_cmdchar(cmdarg_T *cap) +{ + return cap->cmdchar == ':' || cap->cmdchar == K_COMMAND; +} + /// Handle an operator after Visual mode or when the movement is finished. /// "gui_yank" is true when yanking text for the clipboard. void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) { oparg_T *oap = cap->oap; - pos_T old_cursor; - bool empty_region_error; - int restart_edit_save; int lbr_saved = curwin->w_p_lbr; // The visual area is remembered for redo static redo_VIsual_T redo_VIsual = { NUL, 0, 0, 0, 0 }; - bool include_line_break = false; - - old_cursor = curwin->w_cursor; + pos_T old_cursor = curwin->w_cursor; // If an operation is pending, handle it... if ((finish_op || VIsual_active) && oap->op_type != OP_NOP) { + bool empty_region_error; + int restart_edit_save; + bool include_line_break = false; // Yank can be redone when 'y' is in 'cpoptions', but not when yanking // for the clipboard. const bool redo_yank = vim_strchr(p_cpo, CPO_YANK) != NULL && !gui_yank; @@ -5882,7 +5824,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) if ((redo_yank || oap->op_type != OP_YANK) && ((!VIsual_active || oap->motion_force) // Also redo Operator-pending Visual mode mappings. - || ((cap->cmdchar == ':' || cap->cmdchar == K_COMMAND) + || ((is_ex_cmdchar(cap) || cap->cmdchar == K_LUA) && oap->op_type != OP_COLON)) && cap->cmdchar != 'D' && oap->op_type != OP_FOLD @@ -5902,17 +5844,24 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) AppendToRedobuffLit(cap->searchbuf, -1); } AppendToRedobuff(NL_STR); - } else if (cap->cmdchar == ':' || cap->cmdchar == K_COMMAND) { + } else if (is_ex_cmdchar(cap)) { // do_cmdline() has stored the first typed line in // "repeat_cmdline". When several lines are typed repeating // won't be possible. if (repeat_cmdline == NULL) { ResetRedobuff(); } else { - AppendToRedobuffLit(repeat_cmdline, -1); + if (cap->cmdchar == ':') { + AppendToRedobuffLit(repeat_cmdline, -1); + } else { + AppendToRedobuffSpec(repeat_cmdline); + } AppendToRedobuff(NL_STR); XFREE_CLEAR(repeat_cmdline); } + } else if (cap->cmdchar == K_LUA) { + AppendNumberToRedobuff(repeat_luaref); + AppendToRedobuff(NL_STR); } } @@ -5968,8 +5917,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) } else if (VIsual_mode == 'v') { // If 'selection' is "exclusive", backup one character for // charwise selections. - include_line_break = - unadjust_for_sel(); + include_line_break = unadjust_for_sel(); } oap->start = VIsual; @@ -6048,7 +5996,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) resel_VIsual_vcol = oap->end_vcol; } } - resel_VIsual_line_count = (linenr_T)oap->line_count; + resel_VIsual_line_count = oap->line_count; } // can't redo yank (unless 'y' is in 'cpoptions') and ":" @@ -6069,7 +6017,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) prep_redo(oap->regname, cap->count0, get_op_char(oap->op_type), get_extra_op_char(oap->op_type), oap->motion_force, cap->cmdchar, cap->nchar); - } else if (cap->cmdchar != ':' && cap->cmdchar != K_COMMAND) { + } else if (!is_ex_cmdchar(cap) && cap->cmdchar != K_LUA) { int opchar = get_op_char(oap->op_type); int extra_opchar = get_extra_op_char(oap->op_type); int nchar = oap->op_type == OP_REPLACE ? cap->nchar : NUL; @@ -6083,9 +6031,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) if (opchar == 'g' && extra_opchar == '@') { // also repeat the count for 'operatorfunc' - prep_redo_num2(oap->regname, 0L, NUL, 'v', cap->count0, opchar, extra_opchar, nchar); + prep_redo_num2(oap->regname, 0, NUL, 'v', cap->count0, opchar, extra_opchar, nchar); } else { - prep_redo(oap->regname, 0L, NUL, 'v', opchar, extra_opchar, nchar); + prep_redo(oap->regname, 0, NUL, 'v', opchar, extra_opchar, nchar); } } if (!redo_VIsual_busy) { @@ -6207,7 +6155,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) switch (oap->op_type) { case OP_LSHIFT: case OP_RSHIFT: - op_shift(oap, true, oap->is_VIsual ? (int)cap->count1 : 1); + op_shift(oap, true, oap->is_VIsual ? cap->count1 : 1); auto_format(false, true); break; @@ -6275,6 +6223,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) // Restore linebreak, so that when the user edits it looks as before. restore_lbr(lbr_saved); + // trigger TextChangedI + curbuf->b_last_changedtick_i = buf_get_changedtick(curbuf); + if (op_change(oap)) { // will call edit() cap->retval |= CA_COMMAND_BUSY; } @@ -6306,8 +6257,8 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) break; } op_reindent(oap, - *curbuf->b_p_inde != NUL ? get_expr_indent : - get_c_indent); + *curbuf->b_p_inde != NUL ? get_expr_indent + : get_c_indent); break; } @@ -6373,6 +6324,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) // Restore linebreak, so that when the user edits it looks as before. restore_lbr(lbr_saved); + // trigger TextChangedI + curbuf->b_last_changedtick_i = buf_get_changedtick(curbuf); + op_insert(oap, cap->count1); // Reset linebreak, so that formatting works correctly. @@ -6502,7 +6456,7 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing) clipboard_didwarn = true; // Do NOT error (emsg()) here--if it interrupts :redir we get into // a weird state, stuck in "redirect mode". - msg(MSG_NO_CLIP); + msg(MSG_NO_CLIP, 0); } // ... else, be silent (don't flood during :while, :redir, etc.). goto end; @@ -6525,7 +6479,7 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing) } if (cb_flags & CB_UNNAMEDPLUS) { - *name = (cb_flags & CB_UNNAMED && writing) ? '"': '+'; + *name = (cb_flags & CB_UNNAMED && writing) ? '"' : '+'; target = &y_regs[PLUS_REGISTER]; } else { *name = '*'; @@ -6694,7 +6648,7 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet) if (TV_LIST_ITEM_TV(li)->v_type != VAR_STRING) { goto err; } - reg->y_array[tv_idx++] = xstrdupnul((const char *)TV_LIST_ITEM_TV(li)->vval.v_string); + reg->y_array[tv_idx++] = xstrdupnul(TV_LIST_ITEM_TV(li)->vval.v_string); }); if (reg->y_size > 0 && strlen(reg->y_array[reg->y_size - 1]) == 0) { @@ -6755,7 +6709,7 @@ static void set_clipboard(int name, yankreg_T *reg) list_T *const lines = tv_list_alloc((ptrdiff_t)reg->y_size + (reg->y_type != kMTCharWise)); for (size_t i = 0; i < reg->y_size; i++) { - tv_list_append_string(lines, (const char *)reg->y_array[i], -1); + tv_list_append_string(lines, reg->y_array[i], -1); } char regtype; @@ -6777,7 +6731,7 @@ static void set_clipboard(int name, yankreg_T *reg) list_T *args = tv_list_alloc(3); tv_list_append_list(args, lines); - tv_list_append_string(args, ®type, 1); // -V614 + tv_list_append_string(args, ®type, 1); tv_list_append_string(args, ((char[]) { (char)name }), 1); (void)eval_call_provider("clipboard", "set", args, true); @@ -6965,14 +6919,14 @@ bcount_t get_region_bytecount(buf_T *buf, linenr_T start_lnum, linenr_T end_lnum if (start_lnum == end_lnum) { return end_col - start_col; } - const char *first = (const char *)ml_get_buf(buf, start_lnum, false); + const char *first = ml_get_buf(buf, start_lnum); bcount_t deleted_bytes = (bcount_t)strlen(first) - start_col + 1; for (linenr_T i = 1; i <= end_lnum - start_lnum - 1; i++) { if (start_lnum + i > max_lnum) { return deleted_bytes; } - deleted_bytes += (bcount_t)strlen(ml_get_buf(buf, start_lnum + i, false)) + 1; + deleted_bytes += (bcount_t)strlen(ml_get_buf(buf, start_lnum + i)) + 1; } if (end_lnum > max_lnum) { return deleted_bytes; |