From 2ebd328a798778825be61015acd975d8a929dfec Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 9 Dec 2023 11:36:11 +0800 Subject: refactor: format casting of negative number better (#26482) --- src/nvim/ops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 3a4e87edf7..16aa46e97d 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -4630,13 +4630,13 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) if (!pre) { if (subtract) { if (n > oldn) { - n = 1 + (n ^ (uvarnumber_T) - 1); + n = 1 + (n ^ (uvarnumber_T)(-1)); negative ^= true; } } else { // add if (n < oldn) { - n = (n ^ (uvarnumber_T) - 1); + n = (n ^ (uvarnumber_T)(-1)); negative ^= true; } } -- cgit From 6cb78e2d1c4c6c63c628c965076a07ce5f7adbb6 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 16 Dec 2023 22:14:28 +0100 Subject: docs: add style rule regarding initialization Specifically, specify that each initialization should be done on a separate line. --- src/nvim/ops.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 16aa46e97d..71c2c7930e 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -390,7 +390,8 @@ static void shift_block(oparg_T *oap, int amount) bd.start_vcol = cts.cts_vcol; clear_chartabsize_arg(&cts); - int tabs = 0, spaces = 0; + int tabs = 0; + int 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) { @@ -1891,7 +1892,8 @@ static int op_replace(oparg_T *oap, int c) size_t after_p_len = 0; int col = oldlen - bd.textcol - bd.textlen + 1; assert(col >= 0); - int newrows = 0, newcols = 0; + int newrows = 0; + int newcols = 0; if (had_ctrl_v_cr || (c != '\r' && c != '\n')) { // strlen(newp) at this point int newp_len = bd.textcol + bd.startspaces; @@ -2040,11 +2042,9 @@ void op_tilde(oparg_T *oap) pos_T pos = oap->start; if (oap->motion_type == kMTBlockWise) { // Visual block mode for (; pos.lnum <= oap->end.lnum; pos.lnum++) { - int one_change; - block_prep(oap, &bd, pos.lnum, false); pos.col = bd.textcol; - one_change = swapchars(oap->op_type, &pos, bd.textlen); + int one_change = swapchars(oap->op_type, &pos, bd.textlen); did_change |= one_change; } if (did_change) { @@ -2636,7 +2636,8 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) break; case kMTCharWise: { - colnr_T startcol = 0, endcol = MAXCOL; + colnr_T startcol = 0; + colnr_T endcol = MAXCOL; int is_oneChar = false; colnr_T cs, ce; char *p = ml_get(lnum); @@ -2685,8 +2686,7 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) if (endcol == MAXCOL) { endcol = (colnr_T)strlen(p); } - if (startcol > endcol - || is_oneChar) { + if (startcol > endcol || is_oneChar) { bd.textlen = 0; } else { bd.textlen = endcol - startcol + oap->inclusive; -- cgit From 7f6b775b45de5011ff1c44e63e57551566d80704 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 16 Dec 2023 22:14:28 +0100 Subject: refactor: use `bool` to represent boolean values --- src/nvim/ops.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 71c2c7930e..6f5f209a71 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1496,7 +1496,7 @@ int op_delete(oparg_T *oap) // register. For the black hole register '_' don't yank anything. if (oap->regname != '_') { yankreg_T *reg = NULL; - int did_yank = false; + bool did_yank = false; if (oap->regname != 0) { // check for read-only register if (!valid_yank_reg(oap->regname, true)) { @@ -1794,7 +1794,7 @@ static int op_replace(oparg_T *oap, int c) int n; struct block_def bd; char *after_p = NULL; - int had_ctrl_v_cr = false; + bool had_ctrl_v_cr = false; if ((curbuf->b_ml.ml_flags & ML_EMPTY) || oap->empty) { return OK; // nothing to do @@ -2638,7 +2638,7 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) case kMTCharWise: { colnr_T startcol = 0; colnr_T endcol = MAXCOL; - int is_oneChar = false; + bool is_oneChar = false; colnr_T cs, ce; char *p = ml_get(lnum); bd.startspaces = 0; @@ -3696,7 +3696,7 @@ void adjust_cursor_eol(void) } /// @return true if lines starting with '#' should be left aligned. -int preprocs_left(void) +bool preprocs_left(void) { return ((curbuf->b_p_si && !curbuf->b_p_cin) || (curbuf->b_p_cin && in_cinkeys('#', ' ', true) @@ -3956,7 +3956,7 @@ char *skip_comment(char *line, bool process, bool include_space, bool *is_commen /// to set those marks. /// /// @return FAIL for failure, OK otherwise -int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions, bool setmark) +int do_join(size_t count, bool insert_space, bool save_undo, bool use_formatoptions, bool setmark) { char *curr = NULL; char *curr_start = NULL; @@ -3967,8 +3967,7 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions int sumsize = 0; // size of the long new line int ret = OK; int *comments = NULL; - int remove_comments = (use_formatoptions == true) - && has_format_option(FO_REMOVE_COMS); + bool remove_comments = use_formatoptions && has_format_option(FO_REMOVE_COMS); bool prev_was_comment = false; assert(count >= 1); -- cgit From a61d8b615cf99e317fd78a5c9b39aed90908fc51 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 20 Dec 2023 05:27:18 +0800 Subject: vim-patch:9.0.2178: reg_executing() wrong for :normal with range (#26660) Problem: reg_executing() returns wrong result in :normal with range when 'showcmd' is set (after 8.2.4705). Solution: Reset "pending_end_reg_executing" when executing a register. closes: vim/vim#13707 https://github.com/vim/vim/commit/615202bd0ebc1d8e3532f24b9b7232c2fd86b181 --- src/nvim/ops.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 6f5f209a71..ece7ccc960 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1160,6 +1160,7 @@ int do_execreg(int regname, int colon, int addcr, int silent) } } reg_executing = regname == 0 ? '"' : regname; // disable the 'q' command + pending_end_reg_executing = false; } return retval; } -- cgit From af93a74a0f4afa9a3a4f55ffdf28141eaf776d22 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 18 Dec 2023 10:55:23 +0100 Subject: refactor: run IWYU on entire repo Reference: https://github.com/neovim/neovim/issues/6371. --- src/nvim/ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index ece7ccc960..d0a6b2c074 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include "nvim/api/private/defs.h" #include "nvim/ascii_defs.h" -- cgit From ab2aad509d6e4fc57a6afe056275405ec6451671 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Wed, 20 Dec 2023 17:22:19 +0100 Subject: refactor: follow style guide --- src/nvim/ops.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index d0a6b2c074..8dc267cc45 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -215,7 +215,6 @@ int get_extra_op_char(int optype) /// handle a shift operation void op_shift(oparg_T *oap, int curs_top, int amount) { - int i; int block_col = 0; if (u_save((linenr_T)(oap->start.lnum - 1), @@ -227,7 +226,7 @@ void op_shift(oparg_T *oap, int curs_top, int amount) block_col = curwin->w_cursor.col; } - for (i = oap->line_count - 1; i >= 0; i--) { + for (int i = oap->line_count - 1; i >= 0; i--) { int first_char = (uint8_t)(*get_cursor_line_ptr()); if (first_char == NUL) { // empty line curwin->w_cursor.col = 0; -- cgit From 46ceefb52be6b014dd27b6adfbca3e1c9dff0c0c Mon Sep 17 00:00:00 2001 From: JD <46619169+rudiejd@users.noreply.github.com> Date: Wed, 27 Dec 2023 20:57:13 -0500 Subject: fix(clipboard): make getreg() accurate for clipboard registers (#26740) Problem: getreg("*") / getreg("+") disagree with :registers. Solution: Avoid falling back to unnamed register if provider fails. --- src/nvim/ops.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 8dc267cc45..4cce2e7ba6 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -815,9 +815,15 @@ yankreg_T *get_yank_register(int regname, int mode) { yankreg_T *reg; - if (mode == YREG_PASTE && get_clipboard(regname, ®, false)) { + if ((mode == YREG_PASTE || mode == YREG_PUT) + && get_clipboard(regname, ®, false)) { // reg is set to clipboard contents. return reg; + } else if (mode == YREG_PUT && (regname == '*' || regname == '+')) { + // in case clipboard not available and we aren't actually pasting, + // return an empty register + static yankreg_T empty_reg = { .y_array = NULL }; + return &empty_reg; } else if (mode != YREG_YANK && (regname == 0 || regname == '"' || regname == '*' || regname == '+') && y_previous != NULL) { @@ -4893,7 +4899,7 @@ void *get_reg_contents(int regname, int flags) return get_reg_wrap_one_line(xstrdup(retval), flags); } - yankreg_T *reg = get_yank_register(regname, YREG_PASTE); + yankreg_T *reg = get_yank_register(regname, YREG_PUT); if (reg->y_array == NULL) { return NULL; } -- cgit From c89292fcb7f2ebf06efb7c1d00c28f34c6f68fec Mon Sep 17 00:00:00 2001 From: dundargoc Date: Thu, 28 Dec 2023 13:42:24 +0100 Subject: refactor: follow style guide --- src/nvim/ops.c | 110 ++++++++++++++++++++++++++------------------------------- 1 file changed, 50 insertions(+), 60 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 4cce2e7ba6..5a83d7d247 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -213,7 +213,7 @@ int get_extra_op_char(int optype) } /// handle a shift operation -void op_shift(oparg_T *oap, int curs_top, int amount) +void op_shift(oparg_T *oap, bool curs_top, int amount) { int block_col = 0; @@ -287,7 +287,7 @@ void op_shift(oparg_T *oap, int curs_top, int amount) /// leaves cursor on first blank in the line. /// /// @param call_changed_bytes call changed_bytes() -void shift_line(int left, int round, int amount, int call_changed_bytes) +void shift_line(bool left, bool round, int amount, int call_changed_bytes) { const int sw_val = get_sw_value_indent(curbuf); @@ -323,7 +323,7 @@ void shift_line(int left, int round, int amount, int call_changed_bytes) if (State & VREPLACE_FLAG) { change_indent(INDENT_SET, count, false, NUL, call_changed_bytes); } else { - (void)set_indent(count, call_changed_bytes ? SIN_CHANGED : 0); + set_indent(count, call_changed_bytes ? SIN_CHANGED : 0); } } @@ -520,7 +520,7 @@ static void shift_block(oparg_T *oap, int amount) /// Insert string "s" (b_insert ? before : after) block :AKelly /// Caller must prepare for undo. -static void block_insert(oparg_T *oap, char *s, int b_insert, struct block_def *bdp) +static void block_insert(oparg_T *oap, char *s, bool b_insert, struct block_def *bdp) { int ts_val; int count = 0; // extra spaces to replace a cut TAB @@ -915,14 +915,14 @@ int do_record(int c) if (p != NULL) { // Remove escaping for K_SPECIAL in multi-byte chars. vim_unescape_ks(p); - (void)tv_dict_add_str(dict, S_LEN("regcontents"), p); + tv_dict_add_str(dict, S_LEN("regcontents"), p); } // Name of requested register, or empty string for unnamed operation. char buf[NUMBUFLEN + 2]; buf[0] = (char)regname; buf[1] = NUL; - (void)tv_dict_add_str(dict, S_LEN("regname"), buf); + tv_dict_add_str(dict, S_LEN("regname"), buf); tv_dict_set_keys_readonly(dict); // Get the recorded key hits. K_SPECIAL will be escaped, this @@ -1702,8 +1702,8 @@ int op_delete(oparg_T *oap) } } - (void)del_bytes((colnr_T)n, !virtual_op, - oap->op_type == OP_DELETE && !oap->is_VIsual); + del_bytes((colnr_T)n, !virtual_op, + oap->op_type == OP_DELETE && !oap->is_VIsual); } else { // delete characters between lines pos_T curpos; @@ -1729,10 +1729,10 @@ int op_delete(oparg_T *oap) // delete from start of line until op_end 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); + del_bytes((colnr_T)n, !virtual_op, + oap->op_type == OP_DELETE && !oap->is_VIsual); curwin->w_cursor = curpos; // restore curwin->w_cursor - (void)do_join(2, false, false, false, false); + do_join(2, false, false, false, false); curbuf_splice_pending--; extmark_splice(curbuf, (int)startpos.lnum - 1, startpos.col, (int)oap->line_count - 1, n, deleted_bytes, @@ -1822,11 +1822,6 @@ 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 @@ -1857,7 +1852,7 @@ static int op_replace(oparg_T *oap, int c) && !bd.is_oneChar && bd.end_char_vcols > 0) ? bd.end_char_vcols - 1 : 0; // Figure out how many characters to replace. - numc = oap->end_vcol - oap->start_vcol + 1; + int numc = oap->end_vcol - oap->start_vcol + 1; if (bd.is_short && (!virtual_op || bd.is_MAX)) { numc -= (oap->end_vcol - bd.end_vcol) + 1; } @@ -1873,11 +1868,11 @@ static int op_replace(oparg_T *oap, int c) } // Compute bytes needed, move character count to num_chars. - num_chars = numc; + int num_chars = numc; numc *= utf_char2len(c); - oldp = get_cursor_line_ptr(); - oldlen = (int)strlen(oldp); + char *oldp = get_cursor_line_ptr(); + colnr_T oldlen = (int)strlen(oldp); size_t newp_size = (size_t)bd.textcol + (size_t)bd.startspaces; if (had_ctrl_v_cr || (c != '\r' && c != '\n')) { @@ -1887,7 +1882,7 @@ static int op_replace(oparg_T *oap, int c) - bd.textcol - bd.textlen); } } - newp = xmallocz(newp_size); + char *newp = xmallocz(newp_size); // copy up to deleted part memmove(newp, oldp, (size_t)bd.textcol); oldp += bd.textcol + bd.textlen; @@ -2038,7 +2033,7 @@ static int op_replace(oparg_T *oap, int c) void op_tilde(oparg_T *oap) { struct block_def bd; - int did_change = false; + bool did_change = false; if (u_save((linenr_T)(oap->start.lnum - 1), (linenr_T)(oap->end.lnum + 1)) == FAIL) { @@ -2050,7 +2045,7 @@ void op_tilde(oparg_T *oap) for (; pos.lnum <= oap->end.lnum; pos.lnum++) { block_prep(oap, &bd, pos.lnum, false); pos.col = bd.textcol; - int one_change = swapchars(oap->op_type, &pos, bd.textlen); + bool one_change = swapchars(oap->op_type, &pos, bd.textlen); did_change |= one_change; } if (did_change) { @@ -2276,7 +2271,7 @@ void op_insert(oparg_T *oap, int count1) pos_T t1 = oap->start; const pos_T start_insert = curwin->w_cursor; - (void)edit(NUL, false, (linenr_T)count1); + edit(NUL, false, (linenr_T)count1); // When a tab was inserted, and the characters in front of the tab // have been converted to a tab as well, the column of the cursor @@ -2478,9 +2473,6 @@ int op_change(oparg_T *oap) 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. char *ins_text = xmalloc((size_t)ins_len + 1); @@ -2495,16 +2487,16 @@ int op_change(oparg_T *oap) // initial coladd offset as part of "startspaces" if (bd.is_short) { vpos.lnum = linenr; - (void)getvpos(&vpos, oap->start_vcol); + getvpos(&vpos, oap->start_vcol); } else { vpos.coladd = 0; } - oldp = ml_get(linenr); - newp = xmalloc(strlen(oldp) + (size_t)vpos.coladd - + (size_t)ins_len + 1); + char *oldp = ml_get(linenr); + char *newp = xmalloc(strlen(oldp) + (size_t)vpos.coladd + + (size_t)ins_len + 1); // copy up to block start memmove(newp, oldp, (size_t)bd.textcol); - offset = bd.textcol; + int offset = bd.textcol; memset(newp + offset, ' ', (size_t)vpos.coladd); offset += vpos.coladd; memmove(newp + offset, ins_text, (size_t)ins_len); @@ -2842,17 +2834,17 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) 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); + tv_dict_add_list(dict, S_LEN("regcontents"), list); // Register type. char buf[NUMBUFLEN + 2]; format_reg_type(reg->y_type, reg->y_width, buf, ARRAY_SIZE(buf)); - (void)tv_dict_add_str(dict, S_LEN("regtype"), buf); + tv_dict_add_str(dict, S_LEN("regtype"), buf); // Name of requested register, or empty string for unnamed operation. buf[0] = (char)oap->regname; buf[1] = NUL; - (void)tv_dict_add_str(dict, S_LEN("regname"), buf); + tv_dict_add_str(dict, S_LEN("regname"), buf); // Motion type: inclusive or exclusive. tv_dict_add_bool(dict, S_LEN("inclusive"), @@ -2861,11 +2853,11 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) // Kind of operation: yank, delete, change). buf[0] = (char)get_op_char(oap->op_type); buf[1] = NUL; - (void)tv_dict_add_str(dict, S_LEN("operator"), buf); + tv_dict_add_str(dict, S_LEN("operator"), buf); // Selection type: visual or not. - (void)tv_dict_add_bool(dict, S_LEN("visual"), - oap->is_VIsual ? kBoolVarTrue : kBoolVarFalse); + tv_dict_add_bool(dict, S_LEN("visual"), + oap->is_VIsual ? kBoolVarTrue : kBoolVarFalse); tv_dict_set_keys_readonly(dict); textlock++; @@ -2934,7 +2926,7 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) if (flags & PUT_LINE) { stuffcharReadbuff(command_start_char); for (; count > 0; count--) { - (void)stuff_inserted(NUL, 1, count != 1); + stuff_inserted(NUL, 1, count != 1); if (count != 1) { // To avoid 'autoindent' affecting the text, use Ctrl_U to remove any // whitespace. Can't just insert Ctrl_U into readbuf1, this would go @@ -2946,7 +2938,7 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) } } } else { - (void)stuff_inserted(command_start_char, count, false); + stuff_inserted(command_start_char, count, false); } // Putting the text is done later, so can't move the cursor to the next @@ -3124,9 +3116,9 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) // Correct line number for closed fold. Don't move the cursor yet, // u_save() uses it. if (dir == BACKWARD) { - (void)hasFolding(lnum, &lnum, NULL); + hasFolding(lnum, &lnum, NULL); } else { - (void)hasFolding(lnum, NULL, &lnum); + hasFolding(lnum, NULL, &lnum); } if (dir == FORWARD) { lnum++; @@ -3350,13 +3342,11 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) } curbuf->b_op_end.coladd = 0; if (flags & PUT_CURSEND) { - colnr_T len; - curwin->w_cursor = curbuf->b_op_end; curwin->w_cursor.col++; // in Insert mode we might be after the NUL, correct for that - len = (colnr_T)strlen(get_cursor_line_ptr()); + colnr_T len = (colnr_T)strlen(get_cursor_line_ptr()); if (curwin->w_cursor.col > len) { curwin->w_cursor.col = len; } @@ -3539,7 +3529,7 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) } else if ((indent = get_indent() + indent_diff) < 0) { indent = 0; } - (void)set_indent(indent, SIN_NOMARK); + set_indent(indent, SIN_NOMARK); curwin->w_cursor = old_pos; // remember how many chars were removed if (cnt == count && i == y_size - 1) { @@ -4379,7 +4369,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) length = oap->end.col - pos.col + 1; } } - int one_change = do_addsub(oap->op_type, &pos, length, amount); + bool 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) { @@ -4424,7 +4414,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) /// @param Prenum1 Amount of addition or subtraction. /// /// @return true if some character was changed. -int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) +bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) { char *buf1 = NULL; char buf2[NUMBUFLEN]; @@ -4580,7 +4570,7 @@ 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; - (void)del_char(false); + del_char(false); ins_char(firstdigit); endpos = curwin->w_cursor; curwin->w_cursor.col = col; @@ -4688,7 +4678,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) } } // del_char() will mark line needing displaying - (void)del_char(false); + del_char(false); c = gchar_cursor(); } @@ -5229,16 +5219,16 @@ static varnumber_T line_count_info(char *line, varnumber_T *wc, varnumber_T *cc, varnumber_T i; varnumber_T words = 0; varnumber_T chars = 0; - int is_word = 0; + bool is_word = false; for (i = 0; i < limit && line[i] != NUL;) { if (is_word) { if (ascii_isspace(line[i])) { words++; - is_word = 0; + is_word = false; } } else if (!ascii_isspace(line[i])) { - is_word = 1; + is_word = true; } chars++; i += utfc_ptr2len(line + i); @@ -5526,7 +5516,7 @@ static void op_colon(oparg_T *oap) // When using !! on a closed fold the range ".!" works best to operate // on, it will be made the whole closed fold later. linenr_T endOfStartFold = oap->start.lnum; - (void)hasFolding(oap->start.lnum, NULL, &endOfStartFold); + hasFolding(oap->start.lnum, NULL, &endOfStartFold); if (oap->end.lnum != oap->start.lnum && oap->end.lnum != endOfStartFold) { // Make it a range with the end line. stuffcharReadbuff(','); @@ -5745,7 +5735,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) const bool redo_yank = vim_strchr(p_cpo, CPO_YANK) != NULL && !gui_yank; // Avoid a problem with unwanted linebreaks in block mode - (void)reset_lbr(); + reset_lbr(); oap->is_VIsual = VIsual_active; if (oap->motion_force == 'V') { oap->motion_type = kMTLineWise; @@ -6131,7 +6121,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) vim_beep(BO_OPER); CancelRedo(); } else { - (void)op_delete(oap); + op_delete(oap); // save cursor line for undo if it wasn't saved yet if (oap->motion_type == kMTLineWise && has_format_option(FO_AUTO) @@ -6150,7 +6140,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) } else { restore_lbr(lbr_saved); oap->excl_tr_ws = cap->cmdchar == 'z'; - (void)op_yank(oap, !gui_yank); + op_yank(oap, !gui_yank); } check_cursor_col(); break; @@ -6281,7 +6271,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) op_insert(oap, cap->count1); // Reset linebreak, so that formatting works correctly. - (void)reset_lbr(); + reset_lbr(); // TODO(brammool): when inserting in several lines, should format all // the lines. @@ -6355,7 +6345,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) if (!p_sol && oap->motion_type == kMTLineWise && !oap->end_adjusted && (oap->op_type == OP_LSHIFT || oap->op_type == OP_RSHIFT || oap->op_type == OP_DELETE)) { - (void)reset_lbr(); + reset_lbr(); coladvance(curwin->w_curswant = old_col); } } else { @@ -6685,7 +6675,7 @@ static void set_clipboard(int name, yankreg_T *reg) tv_list_append_string(args, ®type, 1); tv_list_append_string(args, ((char[]) { (char)name }), 1); - (void)eval_call_provider("clipboard", "set", args, true); + eval_call_provider("clipboard", "set", args, true); } /// Avoid slow things (clipboard) during batch operations (while/for-loops). -- cgit From 1813661a6197c76ea6621284570aca1d56597099 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Thu, 4 Jan 2024 15:38:16 +0100 Subject: refactor(IWYU): fix headers Remove `export` pramgas from defs headers as it causes IWYU to believe that the definitions from the defs headers comes from main header, which is not what we really want. --- src/nvim/ops.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 5a83d7d247..8386dcaec6 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -15,7 +15,9 @@ #include "nvim/ascii_defs.h" #include "nvim/assert_defs.h" #include "nvim/autocmd.h" +#include "nvim/autocmd_defs.h" #include "nvim/buffer.h" +#include "nvim/buffer_defs.h" #include "nvim/change.h" #include "nvim/charset.h" #include "nvim/cursor.h" @@ -29,17 +31,22 @@ #include "nvim/extmark.h" #include "nvim/fold.h" #include "nvim/garray.h" +#include "nvim/garray_defs.h" #include "nvim/getchar.h" -#include "nvim/gettext.h" +#include "nvim/getchar_defs.h" +#include "nvim/gettext_defs.h" #include "nvim/globals.h" #include "nvim/highlight.h" +#include "nvim/highlight_defs.h" #include "nvim/indent.h" #include "nvim/indent_c.h" #include "nvim/keycodes.h" #include "nvim/macros_defs.h" #include "nvim/mark.h" +#include "nvim/mark_defs.h" #include "nvim/mbyte.h" #include "nvim/memline.h" +#include "nvim/memline_defs.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/mouse.h" @@ -54,11 +61,13 @@ #include "nvim/plines.h" #include "nvim/search.h" #include "nvim/state.h" +#include "nvim/state_defs.h" #include "nvim/strings.h" #include "nvim/terminal.h" #include "nvim/textformat.h" #include "nvim/types_defs.h" #include "nvim/ui.h" +#include "nvim/ui_defs.h" #include "nvim/undo.h" #include "nvim/vim_defs.h" #include "nvim/window.h" -- cgit From 2783b6b0a48389f5e12109d9894269768c3e9fe5 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 6 Jan 2024 07:01:08 +0800 Subject: vim-patch:9.1.0015: i_CTRL-R- no longer works in replace mode Problem: i_CTRL-R- no longer works in replace mode Solution: delete characters in replace mode before putting, add a test, add a bit warning into the documentation, that i_CTRL-R-P/O is not supported in Replace mode for now fixes: vim/vim#13792 closes: vim/vim#13816 https://github.com/vim/vim/commit/5d5cbb2b9ac526fb6fad2116e24a282affc45efe Co-authored-by: Christian Brabandt --- src/nvim/ops.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 8386dcaec6..32095177be 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1282,9 +1282,22 @@ int insert_reg(int regname, bool literally_arg) } else { for (size_t i = 0; i < reg->y_size; i++) { if (regname == '-') { + Direction dir = BACKWARD; + if ((State & REPLACE_FLAG) != 0) { + pos_T curpos; + u_save_cursor(); + del_bytes((colnr_T)strlen(reg->y_array[0]), true, false); + curpos = curwin->w_cursor; + if (oneright() == FAIL) { + // hit end of line, need to put forward (after the current position) + dir = FORWARD; + } + curwin->w_cursor = curpos; + } + AppendCharToRedobuff(Ctrl_R); AppendCharToRedobuff(regname); - do_put(regname, NULL, BACKWARD, 1, PUT_CURSEND); + do_put(regname, NULL, dir, 1, PUT_CURSEND); } else { stuffescaped(reg->y_array[i], literally); } -- cgit From 64a50d08c4866011be73d6af0e8ae90e06c3f949 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 13 Jan 2024 08:29:54 +0800 Subject: vim-patch:9.1.0021: i_CTRL-R- doesn't work for multibyte chars in Replace mode Problem: i_CTRL-R- doesn't work for multibyte chars in Replace mode, Coverity complains missing return value for u_save_cursor() Solution: Use mb_charlen() and del_chars() instead, handle failure mode for u_save_cursor() correctly (@zeertzjq) closes: vim/vim#13846 https://github.com/vim/vim/commit/424ec1f235a53131042aed94d30f6e2528e551d9 --- src/nvim/ops.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 32095177be..84cba5d05c 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1286,7 +1286,10 @@ int insert_reg(int regname, bool literally_arg) if ((State & REPLACE_FLAG) != 0) { pos_T curpos; u_save_cursor(); - del_bytes((colnr_T)strlen(reg->y_array[0]), true, false); + if (u_save_cursor() == FAIL) { + return FAIL; + } + del_chars(mb_charlen(reg->y_array[0]), true); curpos = curwin->w_cursor; if (oneright() == FAIL) { // hit end of line, need to put forward (after the current position) -- cgit From e5d9b15044d56acd48569b3ca7ac9dabdeaa750e Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 25 Dec 2023 13:06:00 +0100 Subject: fix(buffer_updates): correct buffer updates when splitting empty line fixes #11591 --- src/nvim/ops.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 8386dcaec6..78926807e2 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -18,6 +18,7 @@ #include "nvim/autocmd_defs.h" #include "nvim/buffer.h" #include "nvim/buffer_defs.h" +#include "nvim/buffer_updates.h" #include "nvim/change.h" #include "nvim/charset.h" #include "nvim/cursor.h" @@ -3068,6 +3069,7 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) return; } + colnr_T split_pos = 0; if (y_type == kMTLineWise) { if (flags & PUT_LINE_SPLIT) { // "p" or "P" in Visual mode: split the lines to put the text in @@ -3075,23 +3077,24 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) if (u_save_cursor() == FAIL) { goto end; } - char *p = get_cursor_pos_ptr(); + char *curline = get_cursor_line_ptr(); + char *p = curline + curwin->w_cursor.col; if (dir == FORWARD && *p != NUL) { MB_PTR_ADV(p); } + // we need this later for the correct extmark_splice() event + split_pos = (colnr_T)(p - curline); + char *ptr = xstrdup(p); ml_append(curwin->w_cursor.lnum, ptr, 0, false); xfree(ptr); - char *oldp = get_cursor_line_ptr(); - p = oldp + curwin->w_cursor.col; - if (dir == FORWARD && *p != NUL) { - MB_PTR_ADV(p); - } - ptr = xmemdupz(oldp, (size_t)(p - oldp)); + ptr = xmemdupz(get_cursor_line_ptr(), (size_t)split_pos); ml_replace(curwin->w_cursor.lnum, ptr, false); nr_lines++; dir = FORWARD; + + buf_updates_send_changes(curbuf, curwin->w_cursor.lnum, 1, 1); } if (flags & PUT_LINE_FORWARD) { // Must be "p" for a Visual block, put lines below the block. @@ -3550,7 +3553,7 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) bcount_t totsize = 0; int lastsize = 0; if (y_type == kMTCharWise - || (y_type == kMTLineWise && flags & PUT_LINE_SPLIT)) { + || (y_type == kMTLineWise && (flags & PUT_LINE_SPLIT))) { for (i = 0; i < y_size - 1; i++) { totsize += (bcount_t)strlen(y_array[i]) + 1; } @@ -3561,9 +3564,9 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) extmark_splice(curbuf, (int)new_cursor.lnum - 1, col, 0, 0, 0, (int)y_size - 1, lastsize, totsize, kExtmarkUndo); - } else if (y_type == kMTLineWise && flags & PUT_LINE_SPLIT) { + } else if (y_type == kMTLineWise && (flags & PUT_LINE_SPLIT)) { // Account for last pasted NL + last NL - extmark_splice(curbuf, (int)new_cursor.lnum - 1, col + 1, 0, 0, 0, + extmark_splice(curbuf, (int)new_cursor.lnum - 1, split_pos, 0, 0, 0, (int)y_size + 1, 0, totsize + 2, kExtmarkUndo); } -- cgit From 92c59c39c3d98d313071f9761c448e8acfd00118 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 14 Jan 2024 08:47:57 +0800 Subject: fix(ops.c): remove duplicate u_save_cursor() --- src/nvim/ops.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 7c6e63a2bf..2819d98208 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1286,7 +1286,6 @@ int insert_reg(int regname, bool literally_arg) Direction dir = BACKWARD; if ((State & REPLACE_FLAG) != 0) { pos_T curpos; - u_save_cursor(); if (u_save_cursor() == FAIL) { return FAIL; } -- cgit From cdf848a314bf91a0c87c717f9a44742dea877515 Mon Sep 17 00:00:00 2001 From: VanaIgr Date: Mon, 18 Dec 2023 20:57:04 -0600 Subject: perf: reuse fast character size calculation algorithm from getvcol() --- src/nvim/ops.c | 132 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 64 insertions(+), 68 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 2819d98208..e6527773f9 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -387,17 +387,18 @@ static void shift_block(oparg_T *oap, int amount) } // TODO(vim): is passing bd.textstart for start of the line OK? - chartabsize_T cts; - init_chartabsize_arg(&cts, curwin, curwin->w_cursor.lnum, - bd.start_vcol, bd.textstart, bd.textstart); - while (ascii_iswhite(*cts.cts_ptr)) { - incr = lbr_chartabsize_adv(&cts); + CharsizeArg arg; + CSType cstype = init_charsize_arg(&arg, curwin, curwin->w_cursor.lnum, bd.textstart); + StrCharInfo ci = utf_ptr2StrCharInfo(bd.textstart); + int vcol = bd.start_vcol; + while (ascii_iswhite(ci.chr.value)) { + incr = win_charsize(cstype, vcol, ci.ptr, ci.chr.value, &arg).width; + ci = utfc_next(ci); total += incr; - cts.cts_vcol += incr; + vcol += incr; } - bd.textstart = cts.cts_ptr; - bd.start_vcol = cts.cts_vcol; - clear_chartabsize_arg(&cts); + bd.textstart = ci.ptr; + bd.start_vcol = vcol; int tabs = 0; int spaces = 0; @@ -448,16 +449,13 @@ static void shift_block(oparg_T *oap, int amount) // The character's column is in "bd.start_vcol". colnr_T non_white_col = bd.start_vcol; - chartabsize_T cts; - init_chartabsize_arg(&cts, curwin, curwin->w_cursor.lnum, - non_white_col, bd.textstart, non_white); - while (ascii_iswhite(*cts.cts_ptr)) { - incr = lbr_chartabsize_adv(&cts); - cts.cts_vcol += incr; + CharsizeArg arg; + CSType cstype = init_charsize_arg(&arg, curwin, curwin->w_cursor.lnum, bd.textstart); + while (ascii_iswhite(*non_white)) { + incr = win_charsize(cstype, non_white_col, non_white, (uint8_t)(*non_white), &arg).width; + non_white_col += incr; + non_white++; } - non_white_col = cts.cts_vcol; - non_white = cts.cts_ptr; - clear_chartabsize_arg(&cts); const colnr_T block_space_width = non_white_col - oap->start_vcol; // We will shift by "total" or "block_space_width", whichever is less. @@ -478,19 +476,17 @@ static void shift_block(oparg_T *oap, int amount) if (bd.startspaces) { verbatim_copy_width -= bd.start_char_vcols; } - init_chartabsize_arg(&cts, curwin, 0, verbatim_copy_width, - bd.textstart, verbatim_copy_end); - while (cts.cts_vcol < destination_col) { - incr = lbr_chartabsize(&cts); - if (cts.cts_vcol + incr > destination_col) { + cstype = init_charsize_arg(&arg, curwin, 0, bd.textstart); + StrCharInfo ci = utf_ptr2StrCharInfo(verbatim_copy_end); + while (verbatim_copy_width < destination_col) { + incr = win_charsize(cstype, verbatim_copy_width, ci.ptr, ci.chr.value, &arg).width; + if (verbatim_copy_width + incr > destination_col) { break; } - cts.cts_vcol += incr; - MB_PTR_ADV(cts.cts_ptr); + verbatim_copy_width += incr; + ci = utfc_next(ci); } - verbatim_copy_width = cts.cts_vcol; - verbatim_copy_end = cts.cts_ptr; - clear_chartabsize_arg(&cts); + verbatim_copy_end = ci.ptr; // If "destination_col" is different from the width of the initial // part of the line that will be copied, it means we encountered a tab @@ -3250,19 +3246,19 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) } // get the old line and advance to the position to insert at 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); - while (cts.cts_vcol < col && *cts.cts_ptr != NUL) { - // Count a tab for what it's worth (if list mode not on) - incr = lbr_chartabsize_adv(&cts); - cts.cts_vcol += incr; + CharsizeArg arg; + CSType cstype = init_charsize_arg(&arg, curwin, curwin->w_cursor.lnum, oldp); + StrCharInfo ci = utf_ptr2StrCharInfo(oldp); + vcol = 0; + while (vcol < col && *ci.ptr != NUL) { + incr = win_charsize(cstype, vcol, ci.ptr, ci.chr.value, &arg).width; + vcol += incr; + ci = utfc_next(ci); } - vcol = cts.cts_vcol; - char *ptr = cts.cts_ptr; + size_t oldlen = (size_t)(ci.ptr - oldp) + strlen(ci.ptr); + char *ptr = ci.ptr; bd.textcol = (colnr_T)(ptr - oldp); - clear_chartabsize_arg(&cts); shortline = (vcol < col) || (vcol == col && !*ptr); @@ -3286,16 +3282,15 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) yanklen = (int)strlen(y_array[i]); if ((flags & PUT_BLOCK_INNER) == 0) { - // calculate number of spaces required to fill right side of - // block + // calculate number of spaces required to fill right side of block spaces = y_width + 1; - init_chartabsize_arg(&cts, curwin, 0, 0, y_array[i], y_array[i]); - for (int j = 0; j < yanklen; j++) { - spaces -= lbr_chartabsize(&cts); - cts.cts_ptr++; - cts.cts_vcol = 0; + + cstype = init_charsize_arg(&arg, curwin, 0, y_array[i]); + ci = utf_ptr2StrCharInfo(y_array[i]); + while (*ci.ptr != NUL) { + spaces -= win_charsize(cstype, 0, ci.ptr, ci.chr.value, &arg).width; + ci = utfc_next(ci); } - clear_chartabsize_arg(&cts); if (spaces < 0) { spaces = 0; } @@ -4228,25 +4223,25 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool char *line = ml_get(lnum); char *prev_pstart = line; - chartabsize_T cts; - init_chartabsize_arg(&cts, curwin, lnum, bdp->start_vcol, line, line); - while (cts.cts_vcol < oap->start_vcol && *cts.cts_ptr != NUL) { - // Count a tab for what it's worth (if list mode not on) - incr = lbr_chartabsize(&cts); - cts.cts_vcol += incr; - if (ascii_iswhite(*cts.cts_ptr)) { + CharsizeArg arg; + CSType cstype = init_charsize_arg(&arg, curwin, lnum, line); + StrCharInfo ci = utf_ptr2StrCharInfo(line); + int vcol = bdp->start_vcol; + while (vcol < oap->start_vcol && *ci.ptr != NUL) { + incr = win_charsize(cstype, vcol, ci.ptr, ci.chr.value, &arg).width; + vcol += incr; + if (ascii_iswhite(ci.chr.value)) { bdp->pre_whitesp += incr; bdp->pre_whitesp_c++; } else { bdp->pre_whitesp = 0; bdp->pre_whitesp_c = 0; } - prev_pstart = cts.cts_ptr; - MB_PTR_ADV(cts.cts_ptr); + prev_pstart = ci.ptr; + ci = utfc_next(ci); } - bdp->start_vcol = cts.cts_vcol; - char *pstart = cts.cts_ptr; - clear_chartabsize_arg(&cts); + bdp->start_vcol = vcol; + char *pstart = ci.ptr; bdp->start_char_vcols = incr; if (bdp->start_vcol < oap->start_vcol) { // line too short @@ -4283,17 +4278,18 @@ 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); + cstype = init_charsize_arg(&arg, curwin, lnum, line); + ci = utf_ptr2StrCharInfo(pend); + vcol = bdp->end_vcol; 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; - incr = lbr_chartabsize_adv(&cts); - cts.cts_vcol += incr; - } - bdp->end_vcol = cts.cts_vcol; - pend = cts.cts_ptr; - clear_chartabsize_arg(&cts); + while (vcol <= oap->end_vcol && *ci.ptr != NUL) { + prev_pend = ci.ptr; + incr = win_charsize(cstype, vcol, ci.ptr, ci.chr.value, &arg).width; + vcol += incr; + ci = utfc_next(ci); + } + bdp->end_vcol = vcol; + pend = ci.ptr; if (bdp->end_vcol <= oap->end_vcol && (!is_del -- cgit From e68decab0352d553bd2463842d96379f56073a1c Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 22 Jan 2024 10:39:37 +0800 Subject: refactor: use "csarg" for CharsizeArg variables (#27123) --- src/nvim/ops.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index e6527773f9..7f5be88a88 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -387,12 +387,12 @@ static void shift_block(oparg_T *oap, int amount) } // TODO(vim): is passing bd.textstart for start of the line OK? - CharsizeArg arg; - CSType cstype = init_charsize_arg(&arg, curwin, curwin->w_cursor.lnum, bd.textstart); + CharsizeArg csarg; + CSType cstype = init_charsize_arg(&csarg, curwin, curwin->w_cursor.lnum, bd.textstart); StrCharInfo ci = utf_ptr2StrCharInfo(bd.textstart); int vcol = bd.start_vcol; while (ascii_iswhite(ci.chr.value)) { - incr = win_charsize(cstype, vcol, ci.ptr, ci.chr.value, &arg).width; + incr = win_charsize(cstype, vcol, ci.ptr, ci.chr.value, &csarg).width; ci = utfc_next(ci); total += incr; vcol += incr; @@ -449,10 +449,10 @@ static void shift_block(oparg_T *oap, int amount) // The character's column is in "bd.start_vcol". colnr_T non_white_col = bd.start_vcol; - CharsizeArg arg; - CSType cstype = init_charsize_arg(&arg, curwin, curwin->w_cursor.lnum, bd.textstart); + CharsizeArg csarg; + CSType cstype = init_charsize_arg(&csarg, curwin, curwin->w_cursor.lnum, bd.textstart); while (ascii_iswhite(*non_white)) { - incr = win_charsize(cstype, non_white_col, non_white, (uint8_t)(*non_white), &arg).width; + incr = win_charsize(cstype, non_white_col, non_white, (uint8_t)(*non_white), &csarg).width; non_white_col += incr; non_white++; } @@ -476,10 +476,10 @@ static void shift_block(oparg_T *oap, int amount) if (bd.startspaces) { verbatim_copy_width -= bd.start_char_vcols; } - cstype = init_charsize_arg(&arg, curwin, 0, bd.textstart); + cstype = init_charsize_arg(&csarg, curwin, 0, bd.textstart); StrCharInfo ci = utf_ptr2StrCharInfo(verbatim_copy_end); while (verbatim_copy_width < destination_col) { - incr = win_charsize(cstype, verbatim_copy_width, ci.ptr, ci.chr.value, &arg).width; + incr = win_charsize(cstype, verbatim_copy_width, ci.ptr, ci.chr.value, &csarg).width; if (verbatim_copy_width + incr > destination_col) { break; } @@ -3247,12 +3247,12 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) // get the old line and advance to the position to insert at char *oldp = get_cursor_line_ptr(); - CharsizeArg arg; - CSType cstype = init_charsize_arg(&arg, curwin, curwin->w_cursor.lnum, oldp); + CharsizeArg csarg; + CSType cstype = init_charsize_arg(&csarg, curwin, curwin->w_cursor.lnum, oldp); StrCharInfo ci = utf_ptr2StrCharInfo(oldp); vcol = 0; while (vcol < col && *ci.ptr != NUL) { - incr = win_charsize(cstype, vcol, ci.ptr, ci.chr.value, &arg).width; + incr = win_charsize(cstype, vcol, ci.ptr, ci.chr.value, &csarg).width; vcol += incr; ci = utfc_next(ci); } @@ -3285,10 +3285,10 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) // calculate number of spaces required to fill right side of block spaces = y_width + 1; - cstype = init_charsize_arg(&arg, curwin, 0, y_array[i]); + cstype = init_charsize_arg(&csarg, curwin, 0, y_array[i]); ci = utf_ptr2StrCharInfo(y_array[i]); while (*ci.ptr != NUL) { - spaces -= win_charsize(cstype, 0, ci.ptr, ci.chr.value, &arg).width; + spaces -= win_charsize(cstype, 0, ci.ptr, ci.chr.value, &csarg).width; ci = utfc_next(ci); } if (spaces < 0) { @@ -4223,12 +4223,12 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool char *line = ml_get(lnum); char *prev_pstart = line; - CharsizeArg arg; - CSType cstype = init_charsize_arg(&arg, curwin, lnum, line); + CharsizeArg csarg; + CSType cstype = init_charsize_arg(&csarg, curwin, lnum, line); StrCharInfo ci = utf_ptr2StrCharInfo(line); int vcol = bdp->start_vcol; while (vcol < oap->start_vcol && *ci.ptr != NUL) { - incr = win_charsize(cstype, vcol, ci.ptr, ci.chr.value, &arg).width; + incr = win_charsize(cstype, vcol, ci.ptr, ci.chr.value, &csarg).width; vcol += incr; if (ascii_iswhite(ci.chr.value)) { bdp->pre_whitesp += incr; @@ -4278,13 +4278,13 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool } } } else { - cstype = init_charsize_arg(&arg, curwin, lnum, line); + cstype = init_charsize_arg(&csarg, curwin, lnum, line); ci = utf_ptr2StrCharInfo(pend); vcol = bdp->end_vcol; char *prev_pend = pend; while (vcol <= oap->end_vcol && *ci.ptr != NUL) { prev_pend = ci.ptr; - incr = win_charsize(cstype, vcol, ci.ptr, ci.chr.value, &arg).width; + incr = win_charsize(cstype, vcol, ci.ptr, ci.chr.value, &csarg).width; vcol += incr; ci = utfc_next(ci); } -- cgit From 4e59422e1d4950a3042bad41a7b81c8db4f8b648 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 25 Jan 2024 07:57:21 +0800 Subject: refactor: IWYU (#27186) --- src/nvim/ops.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 7f5be88a88..d785be54e5 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -46,6 +46,7 @@ #include "nvim/mark.h" #include "nvim/mark_defs.h" #include "nvim/mbyte.h" +#include "nvim/mbyte_defs.h" #include "nvim/memline.h" #include "nvim/memline_defs.h" #include "nvim/memory.h" -- cgit From 4860cc5bdcde60994ac331c0c985acdf15115ca8 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 13 Feb 2024 07:38:12 +0800 Subject: vim-patch:9.1.0101: upper-case of German sharp s should be U+1E9E (#27449) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: upper-case of ß should be U+1E9E (CAPITAL LETTER SHARP S) (fenuks) Solution: Make gU, ~ and g~ convert the U+00DF LATIN SMALL LETTER SHARP S (ß) to U+1E9E LATIN CAPITAL LETTER SHARP S (ẞ), update tests (glepnir) This is part of Unicode 5.1.0 from April 2008, so should be fairly safe to use now and since 2017 is part of the German standard orthography, according to Wikipedia: https://en.wikipedia.org/wiki/Capital_%E1%BA%9E#cite_note-auto-12 There is however one exception: UnicodeData.txt for U+00DF LATIN SMALL LETTER SHARP S does NOT define U+1E9E LATIN CAPITAL LETTER SHARP S as its upper case version. Therefore, toupper() won't be able to convert from lower sharp s to upper case sharp s (the other way around however works, since U+00DF is considered the lower case character of U+1E9E and therefore tolower() works correctly for the upper case version). fixes: vim/vim#5573 closes: vim/vim#14018 https://github.com/vim/vim/commit/bd1232a1faf56b614a1e74c4ce51bc6e0650ae00 Co-authored-by: glepnir --- src/nvim/ops.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index d785be54e5..f91df49e4f 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -2165,16 +2165,16 @@ bool swapchar(int op_type, pos_T *pos) return false; } - if (op_type == OP_UPPER && c == 0xdf) { + // ~ is OP_NOP, g~ is OP_TILDE, gU is OP_UPPER + if ((op_type == OP_UPPER || op_type == OP_NOP || op_type == OP_TILDE) && c == 0xdf) { pos_T sp = curwin->w_cursor; - // Special handling of German sharp s: change to "SS". + // Special handling for lowercase German sharp s (ß): convert to uppercase (ẞ). curwin->w_cursor = *pos; del_char(false); - ins_char('S'); - ins_char('S'); + ins_char(0x1E9E); curwin->w_cursor = sp; - inc(pos); + return true; } int nc = c; -- cgit From 404707c7606389ccb6c6062bfe9e2ff30a2552af Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 19 Feb 2024 12:07:16 +0100 Subject: refactor(api): use arena for nvim_put and nvim_paste --- src/nvim/ops.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index f91df49e4f..e7a3aa29aa 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -6499,8 +6499,6 @@ bool prepare_yankreg_from_object(yankreg_T *reg, String regtype, size_t lines) } } - reg->y_array = xcalloc(lines, sizeof(uint8_t *)); - reg->y_size = lines; reg->additional_data = NULL; reg->timestamp = 0; return true; @@ -6513,7 +6511,6 @@ void finish_yankreg_from_object(yankreg_T *reg, bool clipboard_adjust) // but otherwise there is no line after the final newline if (reg->y_type != kMTCharWise) { if (reg->y_type == kMTUnknown || clipboard_adjust) { - xfree(reg->y_array[reg->y_size - 1]); reg->y_size--; } if (reg->y_type == kMTUnknown) { -- cgit From 20e4001eeedc80b1f2857fcaca81f7a211a09b40 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 22 Feb 2024 20:32:52 +0800 Subject: vim-patch:9.1.0120: hard to get visual region using Vim script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: hard to get visual region using Vim script Solution: Add getregion() Vim script function (Shougo Matsushita, Jakub Łuczyński) closes: vim/vim#13998 closes: vim/vim#11579 https://github.com/vim/vim/commit/3f905ab3c4f66562f4a224bf00f49d98a0b0da91 Cherry-pick changes from patch 9.1.0122, with :echom instead of :echow. Co-authored-by: Shougo Matsushita Co-authored-by: Jakub Łuczyński --- src/nvim/ops.c | 141 ++++++++++++++++++++++++++------------------------------- 1 file changed, 63 insertions(+), 78 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index e7a3aa29aa..a4af2a54be 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -84,25 +84,6 @@ static bool clipboard_delay_update = false; // delay clipboard update static bool clipboard_needs_update = false; // clipboard was updated static bool clipboard_didwarn = false; -// structure used by block_prep, op_delete and op_yank for blockwise operators -// also op_change, op_shift, op_insert, op_replace - AKelly -struct block_def { - int startspaces; // 'extra' cols before first char - int endspaces; // 'extra' cols after last char - int textlen; // chars in block - char *textstart; // pointer to 1st char (partially) in block - colnr_T textcol; // index of chars (partially) in block - colnr_T start_vcol; // start col of 1st char wholly inside block - colnr_T end_vcol; // start col of 1st char wholly after block - int is_short; // true if line is too short to fit in block - int is_MAX; // true if curswant==MAXCOL when starting - int is_oneChar; // true if block within one character - int pre_whitesp; // screen cols of ws before block - int pre_whitesp_c; // chars of ws before block - colnr_T end_char_vcols; // number of vcols of post-block char - colnr_T start_char_vcols; // number of vcols of pre-block char -}; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ops.c.generated.h" #endif @@ -2655,66 +2636,11 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) reg->y_array[y_idx] = xstrdup(ml_get(lnum)); break; - case kMTCharWise: { - colnr_T startcol = 0; - colnr_T endcol = MAXCOL; - bool is_oneChar = false; - colnr_T cs, ce; - char *p = ml_get(lnum); - bd.startspaces = 0; - bd.endspaces = 0; - - if (lnum == oap->start.lnum) { - startcol = oap->start.col; - if (virtual_op) { - 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; - if (bd.startspaces < 0) { - bd.startspaces = 0; - } - startcol++; - } - } - } - - if (lnum == oap->end.lnum) { - endcol = oap->end.col; - if (virtual_op) { - getvcol(curwin, &oap->end, &cs, NULL, &ce); - if (p[endcol] == NUL || (cs + oap->end.coladd < ce - // Don't add space for double-wide - // char; endcol will be on last byte - // of multi-byte char. - && utf_head_off(p, p + endcol) == 0)) { - if (oap->start.lnum == oap->end.lnum - && oap->start.col == oap->end.col) { - // Special case: inside a single char - is_oneChar = true; - bd.startspaces = oap->end.coladd - - oap->start.coladd + oap->inclusive; - endcol = startcol; - } else { - bd.endspaces = oap->end.coladd - + oap->inclusive; - endcol -= oap->inclusive; - } - } - } - } - if (endcol == MAXCOL) { - endcol = (colnr_T)strlen(p); - } - if (startcol > endcol || is_oneChar) { - bd.textlen = 0; - } else { - bd.textlen = endcol - startcol + oap->inclusive; - } - bd.textstart = p + startcol; + case kMTCharWise: + charwise_block_prep(oap->start, oap->end, &bd, lnum, oap->inclusive); yank_copy_line(reg, &bd, y_idx, false); break; - } + // NOTREACHED case kMTUnknown: abort(); @@ -4203,7 +4129,7 @@ static void restore_lbr(bool lbr_saved) /// - textlen includes the first/last char to be wholly yanked /// - start/endspaces is the number of columns of the first/last yanked char /// that are to be yanked. -static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool is_del) +void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool is_del) { int incr = 0; // Avoid a problem with unwanted linebreaks in block mode. @@ -4326,6 +4252,65 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool restore_lbr(lbr_saved); } +/// Get block text from "start" to "end" +void charwise_block_prep(pos_T start, pos_T end, struct block_def *bdp, linenr_T lnum, + bool inclusive) +{ + colnr_T startcol = 0; + colnr_T endcol = MAXCOL; + bool is_oneChar = false; + colnr_T cs, ce; + char *p = ml_get(lnum); + bdp->startspaces = 0; + bdp->endspaces = 0; + + if (lnum == start.lnum) { + startcol = start.col; + if (virtual_op) { + getvcol(curwin, &start, &cs, NULL, &ce); + if (ce != cs && start.coladd > 0) { + // Part of a tab selected -- but don't double-count it. + bdp->startspaces = (ce - cs + 1) - start.coladd; + if (bdp->startspaces < 0) { + bdp->startspaces = 0; + } + startcol++; + } + } + } + + if (lnum == end.lnum) { + endcol = end.col; + if (virtual_op) { + getvcol(curwin, &end, &cs, NULL, &ce); + if (p[endcol] == NUL || (cs + end.coladd < ce + // Don't add space for double-wide + // char; endcol will be on last byte + // of multi-byte char. + && utf_head_off(p, p + endcol) == 0)) { + if (start.lnum == end.lnum && start.col == end.col) { + // Special case: inside a single char + is_oneChar = true; + bdp->startspaces = end.coladd - start.coladd + inclusive; + endcol = startcol; + } else { + bdp->endspaces = end.coladd + inclusive; + endcol -= inclusive; + } + } + } + } + if (endcol == MAXCOL) { + endcol = (colnr_T)strlen(p); + } + if (startcol > endcol || is_oneChar) { + bdp->textlen = 0; + } else { + bdp->textlen = endcol - startcol + inclusive; + } + bdp->textstart = p + startcol; +} + /// Handle the add/subtract operator. /// /// @param[in] oap Arguments of operator. -- cgit From febf4810026a1f54f63cedbfef2e30e72cf535bf Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 24 Feb 2024 22:04:52 +0800 Subject: vim-patch:9.1.0132: "C" doesn't include composing chars with 'virtualedit' (#27605) Problem: using "C" and 've=all' set, doesn't include composing chars when changing a line, keeps the composing chars for whatever is typed afterwards. Solution: Use mb_head_off() and mb_ptr2len() instead of mb_tail_off(). (zeertzjq) closes: vim/vim#14083 https://github.com/vim/vim/commit/048761bcd40ec630fd3e039f0066cf4e484ceabd --- src/nvim/ops.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index a4af2a54be..5a0ef66e91 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1770,8 +1770,13 @@ static void mb_adjust_opend(oparg_T *oap) return; } - char *p = ml_get(oap->end.lnum); - oap->end.col += utf_cp_tail_off(p, p + oap->end.col); + const char *line = ml_get(oap->end.lnum); + const char *ptr = line + oap->end.col; + if (*ptr != NUL) { + ptr -= utf_head_off(line, ptr); + ptr += utfc_ptr2len(ptr) - 1; + oap->end.col = (colnr_T)(ptr - line); + } } /// Put character 'c' at position 'lp' -- cgit