From 09232958ff9c7d4737701160549c8d64a0f92856 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sun, 6 Oct 2019 20:52:30 -0400 Subject: vim-patch:8.1.2120: some MB_ macros are more complicated than necessary Problem: Some MB_ macros are more complicated than necessary. (Dominique Pelle) Solution: Simplify the macros. Expand inline. https://github.com/vim/vim/commit/1614a14901558ca091329315d14a7d5e1b53aa47 --- 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 4f0c1b5cb9..6f515151d6 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -4641,7 +4641,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) if (visual) { while (ptr[col] != NUL && length > 0 && !ascii_isdigit(ptr[col]) && !(doalp && ASCII_ISALPHA(ptr[col]))) { - int mb_len = MB_PTR2LEN(ptr + col); + int mb_len = utfc_ptr2len(ptr + col); col += mb_len; length -= mb_len; -- cgit From 0586a4b512b2495d32f20c46946d35a0d403bd52 Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Mon, 23 Sep 2019 21:19:26 +0200 Subject: vim-patch:8.1.1588: in :let-heredoc line continuation is recognized Problem: In :let-heredoc line continuation is recognized. Solution: Do not consume line continuation. (Ozaki Kiichi, closes vim/vim#4580) https://github.com/vim/vim/commit/e96a2498f9a2d3e93ac07431f6d4afd77f30afdf --- src/nvim/ops.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 6f515151d6..0d27365d2b 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -671,13 +671,15 @@ int get_expr_register(void) { char_u *new_line; - new_line = getcmdline('=', 0L, 0); - if (new_line == NULL) + new_line = getcmdline('=', 0L, 0, true); + if (new_line == NULL) { return NUL; - if (*new_line == NUL) /* use previous line */ + } + if (*new_line == NUL) { // use previous line xfree(new_line); - else + } else { set_expr_line(new_line); + } return '='; } -- cgit From 913d01bb03616f3bb7468490573a1579d62debbe Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Thu, 17 Oct 2019 09:44:10 +0200 Subject: vim-patch:8.1.2096: too many #ifdefs #11229 Problem: Too many #ifdefs. Solution: Graduate FEAT_COMMENTS. https://github.com/vim/vim/commit/8c96af9c05bfcac2d5ae081e098d4863db561511 Fixes https://github.com/vim/vim/issues/4972. --- src/nvim/ops.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 0d27365d2b..030782cbcc 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -270,20 +270,21 @@ void shift_line( int left, int round, int amount, - int call_changed_bytes /* call changed_bytes() */ + int call_changed_bytes // call changed_bytes() ) { int count; int i, j; int p_sw = get_sw_value(curbuf); - count = get_indent(); /* get current indent */ + count = get_indent(); // get current indent - if (round) { /* round off indent */ - i = count / p_sw; /* number of p_sw rounded down */ - j = count % p_sw; /* extra spaces */ - if (j && left) /* first remove extra spaces */ - --amount; + if (round) { // round off indent + i = count / p_sw; // number of p_sw rounded down + j = count % p_sw; // extra spaces + if (j && left) { // first remove extra spaces + amount--; + } if (left) { i -= amount; if (i < 0) @@ -291,7 +292,7 @@ void shift_line( } else i += amount; count = i * p_sw; - } else { /* original vi indent */ + } else { // original vi indent if (left) { count -= p_sw * amount; if (count < 0) @@ -300,11 +301,12 @@ void shift_line( count += p_sw * amount; } - /* Set new indent */ - if (State & VREPLACE_FLAG) - change_indent(INDENT_SET, count, FALSE, NUL, call_changed_bytes); - else + // Set new indent + 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); + } } /* @@ -4281,15 +4283,13 @@ int paragraph_start(linenr_T lnum) return TRUE; /* after empty line */ do_comments = has_format_option(FO_Q_COMS); - if (fmt_check_par(lnum - 1 - , &leader_len, &leader_flags, do_comments - )) - return TRUE; /* after non-paragraph line */ + if (fmt_check_par(lnum - 1, &leader_len, &leader_flags, do_comments)) { + return true; // after non-paragraph line + } - if (fmt_check_par(lnum - , &next_leader_len, &next_leader_flags, do_comments - )) - return TRUE; /* "lnum" is not a paragraph line */ + if (fmt_check_par(lnum, &next_leader_len, &next_leader_flags, do_comments)) { + return true; // "lnum" is not a paragraph line + } if (has_format_option(FO_WHITE_PAR) && !ends_in_white(lnum - 1)) return TRUE; /* missing trailing space in previous line. */ -- cgit From 63ab994fba2f2e0878be734d20bf8d106ddab67c Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Fri, 1 Nov 2019 22:26:06 -0400 Subject: vim-patch:8.1.2235: "C" with 'virtualedit' set does not include multi-byte char Problem: "C" with 'virtualedit' set does not include multi-byte char. Solution: Include the whole multi-byte char. (Nobuhiro Takasaki, closes vim/vim#5152) https://github.com/vim/vim/commit/77ccc00340ed2598f7aa09716217e878665964fa --- 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 030782cbcc..fbbdfdcd82 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1562,6 +1562,7 @@ int op_delete(oparg_T *oap) oap->end = curwin->w_cursor; curwin->w_cursor = oap->start; } + mb_adjust_opend(oap); } if (oap->line_count == 1) { /* delete characters within one line */ -- cgit From a9065a50518ef59351f9d0d32041a991a751653f Mon Sep 17 00:00:00 2001 From: timeyyy Date: Wed, 18 Jan 2017 13:20:07 +0100 Subject: nsmarks: initial commit --- src/nvim/ops.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 169 insertions(+), 16 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index fbbdfdcd82..1631204840 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -49,6 +49,7 @@ #include "nvim/undo.h" #include "nvim/macros.h" #include "nvim/window.h" +#include "nvim/lib/kvec.h" #include "nvim/os/input.h" #include "nvim/os/time.h" @@ -126,6 +127,30 @@ static char opchars[][3] = { Ctrl_X, NUL, false }, // OP_NR_SUB }; +char *nvim_lltoa(int64_t val, int base) +{ + static char buf[64] = { 0 }; + + int i = 62; + int sign = (val < 0); + if (sign) { + val = -val; + } + + if (val == 0) { + return "0"; + } + + for (; val && i ; i--, val /= base) { + buf[i] = "0123456789abcdef"[val % base]; + } + + if (sign) { + buf[i--] = '-'; + } + return &buf[i+1]; +} + /* * Translate a command name into an operator type. * Must only be called with a valid operator name! @@ -306,6 +331,20 @@ void shift_line( change_indent(INDENT_SET, count, false, NUL, call_changed_bytes); } else { (void)set_indent(count, call_changed_bytes ? SIN_CHANGED : 0); + + colnr_T col_amount; + colnr_T mincol = (curwin->w_cursor.col + 1) -p_sw; + if (left) { + col_amount = -p_sw; + } else { + col_amount = p_sw; + } + extmark_col_adjust(curbuf, + curwin->w_cursor.lnum, + mincol, + 0, + col_amount, + kExtmarkUndo); } } @@ -479,6 +518,13 @@ static void shift_block(oparg_T *oap, int amount) State = oldstate; curwin->w_cursor.col = oldcol; p_ri = old_p_ri; + + colnr_T col_amount = p_sw; + if (left) { + col_amount = -col_amount; + } + extmark_col_adjust(curbuf, curwin->w_cursor.lnum, + curwin->w_cursor.col, 0, col_amount, kExtmarkUndo); } /* @@ -623,10 +669,19 @@ void op_reindent(oparg_T *oap, Indenter how) amount = how(); /* get the indent for this line */ if (amount >= 0 && set_indent(amount, SIN_UNDO)) { - /* did change the indent, call changed_lines() later */ - if (first_changed == 0) + // did change the indent, call changed_lines() later + if (first_changed == 0) { first_changed = curwin->w_cursor.lnum; + } last_changed = curwin->w_cursor.lnum; + + // Adjust extmarks + extmark_col_adjust(curbuf, + curwin->w_cursor.lnum, + 0, // mincol + 0, // lnum_amount + amount, // col_amount + kExtmarkUndo); } } ++curwin->w_cursor.lnum; @@ -1614,13 +1669,15 @@ int op_delete(oparg_T *oap) curpos = curwin->w_cursor; // remember curwin->w_cursor curwin->w_cursor.lnum++; - del_lines(oap->line_count - 2, false); + del_lines(oap->line_count - 2, true); // delete from start of line until op_end 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); + extmark_col_adjust(curbuf, curwin->w_cursor.lnum, + (colnr_T)0, 0L, (long)-n, kExtmarkUndo); curwin->w_cursor = curpos; // restore curwin->w_cursor (void)do_join(2, false, false, false, false); } @@ -1632,10 +1689,41 @@ setmarks: if (oap->motion_type == kMTBlockWise) { curbuf->b_op_end.lnum = oap->end.lnum; curbuf->b_op_end.col = oap->start.col; - } else + } else { curbuf->b_op_end = oap->start; + } curbuf->b_op_start = oap->start; + // TODO(timeyyy): refactor: Move extended marks + // + 1 to change to buf mode, + // and + 1 because we only move marks after the deleted col + colnr_T mincol = oap->start.col + 1 + 1; + colnr_T endcol; + if (oap->motion_type == kMTBlockWise) { + // TODO(timeyyy): refactor extmark_col_adjust to take lnumstart, lnum_end ? + endcol = bd.end_vcol + 1; + for (lnum = curwin->w_cursor.lnum; lnum <= oap->end.lnum; lnum++) { + extmark_col_adjust_delete(curbuf, lnum, mincol, endcol, + kExtmarkUndo, 0); + } + + // Delete characters within one line, + // The case with multiple lines is handled by do_join + } else if (oap->motion_type == kMTCharWise && oap->line_count == 1) { + // + 1 to change to buf mode, then plus 1 to fit function requirements + endcol = oap->end.col + 1 + 1; + + lnum = curwin->w_cursor.lnum; + if (oap->is_VIsual == false) { + // for some reason we required this :/ + endcol = endcol - 1; + // for some reason we required this :/ + if (endcol < mincol) { + endcol = mincol; + } + } + extmark_col_adjust_delete(curbuf, lnum, mincol, endcol, kExtmarkUndo, 0); + } return OK; } @@ -2031,8 +2119,8 @@ bool swapchar(int op_type, pos_T *pos) pos_T sp = curwin->w_cursor; curwin->w_cursor = *pos; - /* don't use del_char(), it also removes composing chars */ - del_bytes(utf_ptr2len(get_cursor_pos_ptr()), FALSE, FALSE); + // don't use del_char(), it also removes composing chars + del_bytes(utf_ptr2len(get_cursor_pos_ptr()), false, false); ins_char(nc); curwin->w_cursor = sp; } else { @@ -2105,8 +2193,9 @@ void op_insert(oparg_T *oap, long count1) * values in "bd". */ if (u_save_cursor() == FAIL) return; - for (i = 0; i < bd.endspaces; i++) + for (i = 0; i < bd.endspaces; i++) { ins_char(' '); + } bd.textlen += bd.endspaces; } } else { @@ -2224,6 +2313,10 @@ void op_insert(oparg_T *oap, long count1) xfree(ins_text); } } + colnr_T col = oap->start.col; + for (linenr_T lnum = oap->start.lnum; lnum <= oap->end.lnum; lnum++) { + extmark_col_adjust(curbuf, lnum, col, 0, 1, kExtmarkUndo); + } } /* @@ -2694,6 +2787,34 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) } + +// Function length couldn't be over 500 lines.. +static void extmarks_do_put(int dir, + size_t totlen, + MotionType y_type, + linenr_T lnum, + colnr_T col) +{ + // adjust extmarks + colnr_T col_amount; + if (dir == FORWARD) { + col_amount = (colnr_T)(totlen-1); + } else { + col_amount = (colnr_T)totlen; + } + // Move extmark with char put + if (y_type == kMTCharWise) { + extmark_col_adjust(curbuf, lnum, col, 0, col_amount, kExtmarkUndo); + // Move extmark with blockwise put + } else if (y_type == kMTBlockWise) { + for (lnum = curbuf->b_op_start.lnum; + lnum <= curbuf->b_op_end.lnum; + lnum++) { + extmark_col_adjust(curbuf, lnum, col, 0, col_amount, kExtmarkUndo); + } + } +} + /* * Put contents of register "regname" into the text. * Caller must check "regname" to be valid! @@ -2708,8 +2829,8 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) char_u *oldp; int yanklen; size_t totlen = 0; // init for gcc - linenr_T lnum; - colnr_T col; + linenr_T lnum = 0; + colnr_T col = 0; size_t i; // index in y_array[] MotionType y_type; size_t y_size; @@ -3286,11 +3407,11 @@ error: curbuf->b_op_start.lnum++; } // Skip mark_adjust when adding lines after the last one, there - // can't be marks there. But still needed in diff mode. + // can't be marks there. if (curbuf->b_op_start.lnum + (y_type == kMTCharWise) - 1 + nr_lines - < curbuf->b_ml.ml_line_count || curwin->w_p_diff) { + < curbuf->b_ml.ml_line_count) { mark_adjust(curbuf->b_op_start.lnum + (y_type == kMTCharWise), - (linenr_T)MAXLNUM, nr_lines, 0L, false); + (linenr_T)MAXLNUM, nr_lines, 0L, false, kExtmarkUndo); } // note changed text for displaying and folding @@ -3352,6 +3473,8 @@ end: /* If the cursor is past the end of the line put it at the end. */ adjust_cursor_eol(); + + extmarks_do_put(dir, totlen, y_type, lnum, col); } /* @@ -3745,6 +3868,12 @@ int do_join(size_t count, * column. This is not Vi compatible, but Vi deletes the marks, thus that * should not really be a problem. */ + + linenr_T lnum; + colnr_T mincol; + long lnum_amount; + long col_amount; + for (t = (linenr_T)count - 1;; t--) { cend -= currsize; memmove(cend, curr, (size_t)currsize); @@ -3756,12 +3885,18 @@ int do_join(size_t count, // If deleting more spaces than adding, the cursor moves no more than // what is added if it is inside these spaces. const int spaces_removed = (int)((curr - curr_start) - spaces[t]); + lnum = curwin->w_cursor.lnum + t; + mincol = (colnr_T)0; + lnum_amount = (linenr_T)-t; + col_amount = (long)(cend - newp - spaces_removed); + + mark_col_adjust(lnum, mincol, lnum_amount, col_amount, spaces_removed, + kExtmarkUndo); - mark_col_adjust(curwin->w_cursor.lnum + t, (colnr_T)0, (linenr_T)-t, - (long)(cend - newp - spaces_removed), spaces_removed); if (t == 0) { break; } + curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t - 1)); if (remove_comments) curr += comments[t - 1]; @@ -3769,6 +3904,7 @@ int do_join(size_t count, curr = skipwhite(curr); currsize = (int)STRLEN(curr); } + ml_replace(curwin->w_cursor.lnum, newp, false); if (setmark) { @@ -4189,14 +4325,14 @@ format_lines( if (next_leader_len > 0) { (void)del_bytes(next_leader_len, false, false); mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L, - (long)-next_leader_len, 0); + (long)-next_leader_len, 0, kExtmarkUndo); } else if (second_indent > 0) { // the "leader" for FO_Q_SECOND int indent = (int)getwhitecols_curline(); if (indent > 0) { (void)del_bytes(indent, FALSE, FALSE); mark_col_adjust(curwin->w_cursor.lnum, - (colnr_T)0, 0L, (long)-indent, 0); + (colnr_T)0, 0L, (long)-indent, 0, kExtmarkUndo); } } curwin->w_cursor.lnum--; @@ -4862,6 +4998,23 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) curbuf->b_op_end.col--; } + if (did_change) { + extmark_col_adjust_delete(curbuf, + pos->lnum, + startpos.col + 2, + endpos.col + 1 + length, + kExtmarkUndo, + 0); + long col_amount = (long)strlen(nvim_lltoa((int64_t)n, 10)); + col_amount = negative ? col_amount + 1 : col_amount; + extmark_col_adjust(curbuf, + pos->lnum, + startpos.col + 1, + 0, + col_amount, + kExtmarkUndo); + } + theend: if (visual) { curwin->w_cursor = save_cursor; -- cgit From 18a8b702c0ce7a8bacd84f6c95e440ae23a3299e Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 9 Nov 2019 12:41:50 +0100 Subject: extmark: review changes --- src/nvim/ops.c | 77 +++++++++++----------------------------------------------- 1 file changed, 14 insertions(+), 63 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 1631204840..95674f8b40 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -127,30 +127,6 @@ static char opchars[][3] = { Ctrl_X, NUL, false }, // OP_NR_SUB }; -char *nvim_lltoa(int64_t val, int base) -{ - static char buf[64] = { 0 }; - - int i = 62; - int sign = (val < 0); - if (sign) { - val = -val; - } - - if (val == 0) { - return "0"; - } - - for (; val && i ; i--, val /= base) { - buf[i] = "0123456789abcdef"[val % base]; - } - - if (sign) { - buf[i--] = '-'; - } - return &buf[i+1]; -} - /* * Translate a command name into an operator type. * Must only be called with a valid operator name! @@ -332,13 +308,8 @@ void shift_line( } else { (void)set_indent(count, call_changed_bytes ? SIN_CHANGED : 0); - colnr_T col_amount; colnr_T mincol = (curwin->w_cursor.col + 1) -p_sw; - if (left) { - col_amount = -p_sw; - } else { - col_amount = p_sw; - } + colnr_T col_amount = left ? -p_sw : p_sw; extmark_col_adjust(curbuf, curwin->w_cursor.lnum, mincol, @@ -519,10 +490,7 @@ static void shift_block(oparg_T *oap, int amount) curwin->w_cursor.col = oldcol; p_ri = old_p_ri; - colnr_T col_amount = p_sw; - if (left) { - col_amount = -col_amount; - } + colnr_T col_amount = left ? -p_sw : p_sw; extmark_col_adjust(curbuf, curwin->w_cursor.lnum, curwin->w_cursor.col, 0, col_amount, kExtmarkUndo); } @@ -1669,7 +1637,7 @@ int op_delete(oparg_T *oap) curpos = curwin->w_cursor; // remember curwin->w_cursor curwin->w_cursor.lnum++; - del_lines(oap->line_count - 2, true); + del_lines(oap->line_count - 2, false); // delete from start of line until op_end n = (oap->end.col + 1 - !oap->inclusive); @@ -1715,12 +1683,7 @@ setmarks: lnum = curwin->w_cursor.lnum; if (oap->is_VIsual == false) { - // for some reason we required this :/ - endcol = endcol - 1; - // for some reason we required this :/ - if (endcol < mincol) { - endcol = mincol; - } + endcol = MAX(endcol - 1, mincol); } extmark_col_adjust_delete(curbuf, lnum, mincol, endcol, kExtmarkUndo, 0); } @@ -2787,8 +2750,6 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) } - -// Function length couldn't be over 500 lines.. static void extmarks_do_put(int dir, size_t totlen, MotionType y_type, @@ -2796,12 +2757,7 @@ static void extmarks_do_put(int dir, colnr_T col) { // adjust extmarks - colnr_T col_amount; - if (dir == FORWARD) { - col_amount = (colnr_T)(totlen-1); - } else { - col_amount = (colnr_T)totlen; - } + colnr_T col_amount = (colnr_T)(dir == FORWARD ? totlen-1 : totlen); // Move extmark with char put if (y_type == kMTCharWise) { extmark_col_adjust(curbuf, lnum, col, 0, col_amount, kExtmarkUndo); @@ -3869,11 +3825,6 @@ int do_join(size_t count, * should not really be a problem. */ - linenr_T lnum; - colnr_T mincol; - long lnum_amount; - long col_amount; - for (t = (linenr_T)count - 1;; t--) { cend -= currsize; memmove(cend, curr, (size_t)currsize); @@ -3885,10 +3836,10 @@ int do_join(size_t count, // If deleting more spaces than adding, the cursor moves no more than // what is added if it is inside these spaces. const int spaces_removed = (int)((curr - curr_start) - spaces[t]); - lnum = curwin->w_cursor.lnum + t; - mincol = (colnr_T)0; - lnum_amount = (linenr_T)-t; - col_amount = (long)(cend - newp - spaces_removed); + linenr_T lnum = curwin->w_cursor.lnum + t; + colnr_T mincol = (colnr_T)0; + long lnum_amount = (linenr_T)-t; + long col_amount = (long)(cend - newp - spaces_removed); mark_col_adjust(lnum, mincol, lnum_amount, col_amount, spaces_removed, kExtmarkUndo); @@ -4675,7 +4626,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) { int col; - char_u *buf1; + char_u *buf1 = NULL; char_u buf2[NUMBUFLEN]; int pre; // 'X' or 'x': hex; '0': octal; 'B' or 'b': bin static bool hexupper = false; // 0xABC @@ -4984,7 +4935,6 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) *ptr = NUL; STRCAT(buf1, buf2); ins_str(buf1); // insert the new number - xfree(buf1); endpos = curwin->w_cursor; if (curwin->w_cursor.col) { curwin->w_cursor.col--; @@ -4998,15 +4948,15 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) curbuf->b_op_end.col--; } - if (did_change) { + // if buf1 wasn't allocated, only a singe ASCII char was changed in-place. + if (did_change && buf1 != NULL) { extmark_col_adjust_delete(curbuf, pos->lnum, startpos.col + 2, endpos.col + 1 + length, kExtmarkUndo, 0); - long col_amount = (long)strlen(nvim_lltoa((int64_t)n, 10)); - col_amount = negative ? col_amount + 1 : col_amount; + long col_amount = (long)STRLEN(buf1); extmark_col_adjust(curbuf, pos->lnum, startpos.col + 1, @@ -5016,6 +4966,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) } theend: + xfree(buf1); if (visual) { curwin->w_cursor = save_cursor; } else if (did_change) { -- cgit From 0cb6fc804dbf7b46772ea14e8c7b40909b97202c Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Tue, 12 Nov 2019 20:04:15 -0500 Subject: vim-patch:8.1.2293: join adds trailing space when second line is empty Problem: Join adds trailing space when second line is empty. (Brennan Vincent) Solution: Do not add a trailing space. https://github.com/vim/vim/commit/cc184cfb09161b3bbc7d5d8859a18e812367d19c --- 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 95674f8b40..2301b2159f 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -3773,7 +3773,10 @@ int do_join(size_t count, if (insert_space && t > 0) { curr = skipwhite(curr); - if (*curr != ')' && currsize != 0 && endcurr1 != TAB + if (*curr != NUL + && *curr != ')' + && currsize != 0 + && endcurr1 != TAB && (!has_format_option(FO_MBYTE_JOIN) || (utf_ptr2char(curr) < 0x100 && endcurr1 < 0x100)) && (!has_format_option(FO_MBYTE_JOIN2) -- cgit From 2cc83c961c0533222890adec51ac56041fb2a6b4 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Thu, 14 Nov 2019 20:06:13 +0100 Subject: refactor: use inserted_bytes pattern from vim This covers all "small" inserts and deletes in insert mode, as well as a few more cases like small normal mode deletes vim-patch:8.1.0678: text properties as not adjusted for inserted text --- src/nvim/ops.c | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 2301b2159f..f2d35d5e43 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1644,8 +1644,6 @@ int op_delete(oparg_T *oap) curwin->w_cursor.col = 0; (void)del_bytes((colnr_T)n, !virtual_op, oap->op_type == OP_DELETE && !oap->is_VIsual); - extmark_col_adjust(curbuf, curwin->w_cursor.lnum, - (colnr_T)0, 0L, (long)-n, kExtmarkUndo); curwin->w_cursor = curpos; // restore curwin->w_cursor (void)do_join(2, false, false, false, false); } @@ -1685,7 +1683,6 @@ setmarks: if (oap->is_VIsual == false) { endcol = MAX(endcol - 1, mincol); } - extmark_col_adjust_delete(curbuf, lnum, mincol, endcol, kExtmarkUndo, 0); } return OK; } @@ -2279,7 +2276,7 @@ void op_insert(oparg_T *oap, long count1) colnr_T col = oap->start.col; for (linenr_T lnum = oap->start.lnum; lnum <= oap->end.lnum; lnum++) { extmark_col_adjust(curbuf, lnum, col, 0, 1, kExtmarkUndo); - } + } } /* @@ -4279,14 +4276,14 @@ format_lines( if (next_leader_len > 0) { (void)del_bytes(next_leader_len, false, false); mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L, - (long)-next_leader_len, 0, kExtmarkUndo); + (long)-next_leader_len, 0, kExtmarkNOOP); } else if (second_indent > 0) { // the "leader" for FO_Q_SECOND int indent = (int)getwhitecols_curline(); if (indent > 0) { - (void)del_bytes(indent, FALSE, FALSE); + (void)del_bytes(indent, false, false); mark_col_adjust(curwin->w_cursor.lnum, - (colnr_T)0, 0L, (long)-indent, 0, kExtmarkUndo); + (colnr_T)0, 0L, (long)-indent, 0, kExtmarkNOOP); } } curwin->w_cursor.lnum--; @@ -4951,23 +4948,6 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) curbuf->b_op_end.col--; } - // if buf1 wasn't allocated, only a singe ASCII char was changed in-place. - if (did_change && buf1 != NULL) { - extmark_col_adjust_delete(curbuf, - pos->lnum, - startpos.col + 2, - endpos.col + 1 + length, - kExtmarkUndo, - 0); - long col_amount = (long)STRLEN(buf1); - extmark_col_adjust(curbuf, - pos->lnum, - startpos.col + 1, - 0, - col_amount, - kExtmarkUndo); - } - theend: xfree(buf1); if (visual) { -- cgit From fd5710ae9a3bcbc0f9cbb71de9e39253350ff09c Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 25 Nov 2019 01:08:02 -0800 Subject: doc + extmarks tweaks #11421 - nvim_buf_get_extmarks: rename "amount" => "limit" - rename `set_extmark_index_from_obj` --- 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 f2d35d5e43..294c65ca03 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -5204,8 +5204,7 @@ void write_reg_contents_lst(int name, char_u **strings, /// write_reg_contents_ex - store `str` in register `name` /// -/// If `str` ends in '\n' or '\r', use linewise, otherwise use -/// characterwise. +/// If `str` ends in '\n' or '\r', use linewise, otherwise use charwise. /// /// @warning when `name` is '/', `len` and `must_append` are ignored. This /// means that `str` MUST be NUL-terminated. -- cgit From 04ebfeb8818b7f5b3d0b174c18257f1afa0bc8fd Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Wed, 18 Dec 2019 05:22:58 -0500 Subject: vim-patch:8.2.0018: :join does not add white space where it should Problem: :join does not add white space where it should. (Zdenek Dohnal) Solution: Handle joining multiple lines propely. https://github.com/vim/vim/commit/91b65e49440e77222a65b6f868507453239f409b --- 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 294c65ca03..0ca16e2c25 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -3772,7 +3772,7 @@ int do_join(size_t count, curr = skipwhite(curr); if (*curr != NUL && *curr != ')' - && currsize != 0 + && sumsize != 0 && endcurr1 != TAB && (!has_format_option(FO_MBYTE_JOIN) || (utf_ptr2char(curr) < 0x100 && endcurr1 < 0x100)) -- cgit From 35c3985da617ffa7ff7f6d7aee4b08267e03e898 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Wed, 25 Dec 2019 06:36:48 -0500 Subject: clang/'Dead store': remove dead code --- src/nvim/ops.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 0ca16e2c25..b597c5b214 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1672,17 +1672,6 @@ setmarks: extmark_col_adjust_delete(curbuf, lnum, mincol, endcol, kExtmarkUndo, 0); } - - // Delete characters within one line, - // The case with multiple lines is handled by do_join - } else if (oap->motion_type == kMTCharWise && oap->line_count == 1) { - // + 1 to change to buf mode, then plus 1 to fit function requirements - endcol = oap->end.col + 1 + 1; - - lnum = curwin->w_cursor.lnum; - if (oap->is_VIsual == false) { - endcol = MAX(endcol - 1, mincol); - } } return OK; } -- cgit From eeabd3a8c6e904bf3e01017b60336c0063356943 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Mon, 30 Dec 2019 16:55:46 -0500 Subject: vim-patch:8.2.0063: wrong size argument to vim_snprintf() Problem: Wrong size argument to vim_snprintf(). (Dominique Pelle) Solution: Reduce the size by the length. (related to vim/vim#5410) https://github.com/vim/vim/commit/08b28b7ad52d5ee3cb5fa5982b647e325a410484 --- src/nvim/ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index b597c5b214..6a621cdaa6 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -5654,7 +5654,8 @@ void cursor_pos_info(dict_T *dict) bom_count = bomb_size(); if (dict == NULL && bom_count > 0) { - vim_snprintf((char *)IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff), + const size_t len = STRLEN(IObuff); + vim_snprintf((char *)IObuff + len, IOSIZE - len, _("(+%" PRId64 " for BOM)"), (int64_t)bom_count); } if (dict == NULL) { -- cgit From ca1a00edd6d6345b848a28d077d6a192528f811e Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Tue, 14 Jan 2020 12:45:09 +0100 Subject: extmarks/bufhl: reimplement using new marktree data structure Add new "splice" interface for tracking buffer changes at the byte level. This will later be reused for byte-resolution buffer updates. (Implementation has been started, but using undocumented "_on_bytes" option now as interface hasn't been finalized). Use this interface to improve many edge cases of extmark adjustment. Changed tests indicate previously incorrect behavior. Adding tests for more edge cases will be follow-up work (overlaps on_bytes tests) Don't consider creation/deletion of marks an undoable event by itself. This behavior was never documented, and imposes complexity for little gain. Add nvim__buf_add_decoration temporary API for direct access to the new implementation. This should be refactored into a proper API for decorations, probably involving a huge dict. fixes #11598 --- src/nvim/ops.c | 161 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 86 insertions(+), 75 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 6a621cdaa6..5da81dbff6 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -31,6 +31,7 @@ #include "nvim/indent.h" #include "nvim/log.h" #include "nvim/mark.h" +#include "nvim/mark_extended.h" #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/memory.h" @@ -307,15 +308,6 @@ void shift_line( change_indent(INDENT_SET, count, false, NUL, call_changed_bytes); } else { (void)set_indent(count, call_changed_bytes ? SIN_CHANGED : 0); - - colnr_T mincol = (curwin->w_cursor.col + 1) -p_sw; - colnr_T col_amount = left ? -p_sw : p_sw; - extmark_col_adjust(curbuf, - curwin->w_cursor.lnum, - mincol, - 0, - col_amount, - kExtmarkUndo); } } @@ -352,6 +344,8 @@ static void shift_block(oparg_T *oap, int amount) char_u *const oldp = get_cursor_line_ptr(); + int startcol, oldlen, newlen; + if (!left) { /* * 1. Get start vcol @@ -361,6 +355,7 @@ static void shift_block(oparg_T *oap, int amount) */ total += bd.pre_whitesp; // all virtual WS up to & incl a split TAB colnr_T ws_vcol = bd.start_vcol - bd.pre_whitesp; + char_u * old_textstart = bd.textstart; if (bd.startspaces) { if (has_mbyte) { if ((*mb_ptr2len)(bd.textstart) == 1) { @@ -387,14 +382,19 @@ static void shift_block(oparg_T *oap, int amount) j = ((ws_vcol % p_ts) + total) % p_ts; /* number of spp */ else j = total; - /* if we're splitting a TAB, allow for it */ - bd.textcol -= bd.pre_whitesp_c - (bd.startspaces != 0); + + // if we're splitting a TAB, allow for it + 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 = (char_u *)xmalloc((size_t)col); memset(newp, NUL, (size_t)col); 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 */ @@ -478,7 +478,10 @@ static void shift_block(oparg_T *oap, int amount) // - the rest of the line, pointed to by non_white. new_line_len = verbatim_diff + fill + STRLEN(non_white) + 1; - newp = (char_u *) xmalloc(new_line_len); + newp = (char_u *)xmalloc(new_line_len); + 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); STRMOVE(newp + verbatim_diff + fill, non_white); @@ -486,13 +489,12 @@ static void shift_block(oparg_T *oap, int amount) // replace the line ml_replace(curwin->w_cursor.lnum, newp, false); changed_bytes(curwin->w_cursor.lnum, (colnr_T)bd.textcol); + extmark_splice(curbuf, (int)curwin->w_cursor.lnum-1, startcol, + 0, oldlen, 0, newlen, + kExtmarkUndo); State = oldstate; curwin->w_cursor.col = oldcol; p_ri = old_p_ri; - - colnr_T col_amount = left ? -p_sw : p_sw; - extmark_col_adjust(curbuf, curwin->w_cursor.lnum, - curwin->w_cursor.col, 0, col_amount, kExtmarkUndo); } /* @@ -561,6 +563,7 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def // copy up to shifted part memmove(newp, oldp, (size_t)offset); oldp += offset; + int startcol = offset; // insert pre-padding memset(newp + offset, ' ', (size_t)spaces); @@ -569,6 +572,7 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def memmove(newp + offset + spaces, s, s_len); offset += (int)s_len; + int skipped = 0; if (spaces && !bdp->is_short) { // insert post-padding memset(newp + offset + spaces, ' ', (size_t)(p_ts - spaces)); @@ -576,6 +580,7 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def oldp++; // We allowed for that TAB, remember this now count++; + skipped = 1; } if (spaces > 0) @@ -583,6 +588,9 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def STRMOVE(newp + offset, oldp); ml_replace(lnum, newp, false); + extmark_splice(curbuf, (int)lnum-1, startcol, + 0, skipped, + 0, offset-startcol, kExtmarkUndo); if (lnum == oap->end.lnum) { /* Set "']" mark to the end of the block instead of the end of @@ -642,14 +650,6 @@ void op_reindent(oparg_T *oap, Indenter how) first_changed = curwin->w_cursor.lnum; } last_changed = curwin->w_cursor.lnum; - - // Adjust extmarks - extmark_col_adjust(curbuf, - curwin->w_cursor.lnum, - 0, // mincol - 0, // lnum_amount - amount, // col_amount - kExtmarkUndo); } } ++curwin->w_cursor.lnum; @@ -1517,6 +1517,11 @@ int op_delete(oparg_T *oap) STRMOVE(newp + bd.textcol + bd.startspaces + bd.endspaces, oldp); // replace the line ml_replace(lnum, newp, false); + + extmark_splice(curbuf, (int)lnum-1, bd.textcol, + 0, bd.textlen, + 0, bd.startspaces+bd.endspaces, + kExtmarkUndo); } check_cursor_col(); @@ -1633,6 +1638,8 @@ int op_delete(oparg_T *oap) (linenr_T)(curwin->w_cursor.lnum + oap->line_count)) == FAIL) return FAIL; + curbuf_splice_pending++; + pos_T startpos = curwin->w_cursor; // start position for delete truncate_line(true); // delete from cursor to end of line curpos = curwin->w_cursor; // remember curwin->w_cursor @@ -1646,6 +1653,9 @@ int op_delete(oparg_T *oap) oap->op_type == OP_DELETE && !oap->is_VIsual); curwin->w_cursor = curpos; // restore curwin->w_cursor (void)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, 0, 0, kExtmarkUndo); } } @@ -1660,19 +1670,6 @@ setmarks: } curbuf->b_op_start = oap->start; - // TODO(timeyyy): refactor: Move extended marks - // + 1 to change to buf mode, - // and + 1 because we only move marks after the deleted col - colnr_T mincol = oap->start.col + 1 + 1; - colnr_T endcol; - if (oap->motion_type == kMTBlockWise) { - // TODO(timeyyy): refactor extmark_col_adjust to take lnumstart, lnum_end ? - endcol = bd.end_vcol + 1; - for (lnum = curwin->w_cursor.lnum; lnum <= oap->end.lnum; lnum++) { - extmark_col_adjust_delete(curbuf, lnum, mincol, endcol, - kExtmarkUndo, 0); - } - } return OK; } @@ -1695,8 +1692,11 @@ 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_u)c; + assert(c <= UCHAR_MAX); + *(ml_get_buf(curbuf, lp.lnum, true) + lp.col) = (char_u)c; + if (!curbuf_splice_pending) { + extmark_splice(curbuf, (int)lp.lnum-1, lp.col, 0, 1, 0, 1, kExtmarkUndo); + } } // Replace the character under the cursor with "c". @@ -1817,6 +1817,7 @@ 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; if (had_ctrl_v_cr || (c != '\r' && c != '\n')) { // strlen(newp) at this point int newp_len = bd.textcol + bd.startspaces; @@ -1829,21 +1830,27 @@ int op_replace(oparg_T *oap, int c) newp_len += bd.endspaces; // copy the part after the changed part memmove(newp + newp_len, oldp, (size_t)col); - } + } + newcols = newp_len - bd.textcol; } else { // Replacing with \r or \n means splitting the line. after_p_len = (size_t)col; after_p = (char_u *)xmalloc(after_p_len); memmove(after_p, oldp, after_p_len); + newrows = 1; } // replace the line ml_replace(curwin->w_cursor.lnum, newp, false); + 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); oap->end.lnum++; xfree(after_p); } + extmark_splice(curbuf, (int)baselnum-1, bd.textcol, + 0, bd.textlen, + newrows, newcols, kExtmarkUndo); } } else { // Characterwise or linewise motion replace. @@ -1856,6 +1863,8 @@ int op_replace(oparg_T *oap, int c) } else if (!oap->inclusive) dec(&(oap->end)); + // TODO(bfredl): we could batch all the splicing + // done on the same line, at least while (ltoreq(curwin->w_cursor, oap->end)) { n = gchar_cursor(); if (n != NUL) { @@ -2262,10 +2271,6 @@ void op_insert(oparg_T *oap, long count1) xfree(ins_text); } } - colnr_T col = oap->start.col; - for (linenr_T lnum = oap->start.lnum; lnum <= oap->end.lnum; lnum++) { - extmark_col_adjust(curbuf, lnum, col, 0, 1, kExtmarkUndo); - } } /* @@ -2380,6 +2385,9 @@ int op_change(oparg_T *oap) oldp += bd.textcol; STRMOVE(newp + offset, oldp); ml_replace(linenr, newp, false); + extmark_splice(curbuf, (int)linenr-1, bd.textcol, + 0, 0, + 0, vpos.coladd+(int)ins_len, kExtmarkUndo); } } check_cursor(); @@ -2735,28 +2743,6 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) recursive = false; } - -static void extmarks_do_put(int dir, - size_t totlen, - MotionType y_type, - linenr_T lnum, - colnr_T col) -{ - // adjust extmarks - colnr_T col_amount = (colnr_T)(dir == FORWARD ? totlen-1 : totlen); - // Move extmark with char put - if (y_type == kMTCharWise) { - extmark_col_adjust(curbuf, lnum, col, 0, col_amount, kExtmarkUndo); - // Move extmark with blockwise put - } else if (y_type == kMTBlockWise) { - for (lnum = curbuf->b_op_start.lnum; - lnum <= curbuf->b_op_end.lnum; - lnum++) { - extmark_col_adjust(curbuf, lnum, col, 0, col_amount, kExtmarkUndo); - } - } -} - /* * Put contents of register "regname" into the text. * Caller must check "regname" to be valid! @@ -3176,6 +3162,10 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) assert(columns >= 0); memmove(ptr, oldp + bd.textcol + delcount, (size_t)columns); ml_replace(curwin->w_cursor.lnum, newp, false); + extmark_splice(curbuf, (int)curwin->w_cursor.lnum-1, bd.textcol, + 0, delcount, + 0, (int)totlen, + kExtmarkUndo); ++curwin->w_cursor.lnum; if (i == 0) @@ -3277,6 +3267,9 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) if (totlen && (restart_edit != 0 || (flags & PUT_CURSEND))) ++curwin->w_cursor.col; changed_bytes(lnum, col); + extmark_splice(curbuf, (int)lnum-1, col, + 0, 0, + 0, (int)totlen, kExtmarkUndo); } else { // Insert at least one line. When y_type is kMTCharWise, break the first // line in two. @@ -3332,13 +3325,22 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) first_indent = FALSE; } else if ((indent = get_indent() + indent_diff) < 0) indent = 0; - (void)set_indent(indent, 0); + (void)set_indent(indent, SIN_NOMARK); curwin->w_cursor = old_pos; /* remember how many chars were removed */ if (cnt == count && i == y_size - 1) lendiff -= (int)STRLEN(ml_get(lnum)); } } + + if (y_type == kMTCharWise) { + extmark_splice(curbuf, (int)new_cursor.lnum-1, col, 0, 0, + (int)y_size-1, (int)STRLEN(y_array[y_size-1]), + kExtmarkUndo); + } else if (y_type == kMTLineWise && flags & PUT_LINE_SPLIT) { + extmark_splice(curbuf, (int)new_cursor.lnum-1, col, 0, 0, + (int)y_size+1, 0, kExtmarkUndo); + } } error: @@ -3352,8 +3354,10 @@ error: // can't be marks there. if (curbuf->b_op_start.lnum + (y_type == kMTCharWise) - 1 + nr_lines < curbuf->b_ml.ml_line_count) { + 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, false, kExtmarkUndo); + (linenr_T)MAXLNUM, nr_lines, 0L, kind); } // note changed text for displaying and folding @@ -3415,9 +3419,7 @@ end: /* If the cursor is past the end of the line put it at the end. */ adjust_cursor_eol(); - - extmarks_do_put(dir, totlen, y_type, lnum, col); -} +} // NOLINT(readability/fn_size) /* * When the cursor is on the NUL past the end of the line and it should not be @@ -3779,6 +3781,13 @@ int do_join(size_t count, } } } + + if (t > 0 && curbuf_splice_pending == 0) { + extmark_splice(curbuf, (int)curwin->w_cursor.lnum-1, sumsize, + 1, (int)(curr- curr_start), + 0, spaces[t], + kExtmarkUndo); + } currsize = (int)STRLEN(curr); sumsize += currsize + spaces[t]; endcurr1 = endcurr2 = NUL; @@ -3814,6 +3823,8 @@ int do_join(size_t count, * should not really be a problem. */ + curbuf_splice_pending++; + for (t = (linenr_T)count - 1;; t--) { cend -= currsize; memmove(cend, curr, (size_t)currsize); @@ -3830,8 +3841,7 @@ int do_join(size_t count, long lnum_amount = (linenr_T)-t; long col_amount = (long)(cend - newp - spaces_removed); - mark_col_adjust(lnum, mincol, lnum_amount, col_amount, spaces_removed, - kExtmarkUndo); + mark_col_adjust(lnum, mincol, lnum_amount, col_amount, spaces_removed); if (t == 0) { break; @@ -3867,6 +3877,7 @@ int do_join(size_t count, curwin->w_cursor.lnum++; del_lines((long)count - 1, false); curwin->w_cursor.lnum = t; + curbuf_splice_pending--; /* * Set the cursor column: @@ -4265,14 +4276,14 @@ format_lines( if (next_leader_len > 0) { (void)del_bytes(next_leader_len, false, false); mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L, - (long)-next_leader_len, 0, kExtmarkNOOP); + (long)-next_leader_len, 0); } else if (second_indent > 0) { // the "leader" for FO_Q_SECOND int indent = (int)getwhitecols_curline(); if (indent > 0) { (void)del_bytes(indent, false, false); mark_col_adjust(curwin->w_cursor.lnum, - (colnr_T)0, 0L, (long)-indent, 0, kExtmarkNOOP); + (colnr_T)0, 0L, (long)-indent, 0); } } curwin->w_cursor.lnum--; -- cgit From 1042338c0062ea091ea1e52b161fd25adcdc927f Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 16 Jan 2020 00:10:16 -0500 Subject: clang/'Logic error': zero-init struct --- 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 5da81dbff6..da2b81fd0a 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1372,7 +1372,7 @@ int op_delete(oparg_T *oap) linenr_T lnum; char_u *ptr; char_u *newp, *oldp; - struct block_def bd; + struct block_def bd = { 0 }; linenr_T old_lcount = curbuf->b_ml.ml_line_count; if (curbuf->b_ml.ml_flags & ML_EMPTY) { // nothing to do -- cgit From 48a869dc6d29514e943070da9f22f702f5179826 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Mon, 20 Jan 2020 19:29:12 +0100 Subject: shed biking: it's always extmarks, never marks extended --- 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 da2b81fd0a..641323ae5e 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -31,7 +31,7 @@ #include "nvim/indent.h" #include "nvim/log.h" #include "nvim/mark.h" -#include "nvim/mark_extended.h" +#include "nvim/extmark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/memory.h" -- cgit From e22d0cf12c985e670fcc562a6ce75e82a0b3a741 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 23 Jan 2020 19:36:39 -0500 Subject: vim-patch:8.2.0147: block Visual mode operators not correct when 'linebreak' set Problem: Block Visual mode operators not correct when 'linebreak' set. Solution: Set w_p_lbr to lbr_saved more often. (Ken Takata, closes vim/vim#5524) https://github.com/vim/vim/commit/03c3bd9fd094c1aede2e8fe3ad8fd25b9f033053 --- src/nvim/ops.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 641323ae5e..bcf54087f5 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -4414,7 +4414,10 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, char_u *line; char_u *prev_pstart; char_u *prev_pend; + const int lbr_saved = curwin->w_p_lbr; + // Avoid a problem with unwanted linebreaks in block mode. + curwin->w_p_lbr = false; bdp->startspaces = 0; bdp->endspaces = 0; bdp->textlen = 0; @@ -4514,6 +4517,7 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, } bdp->textcol = (colnr_T) (pstart - line); bdp->textstart = pstart; + curwin->w_p_lbr = lbr_saved; } /// Handle the add/subtract operator. -- cgit From 94ad6652f11e1d6791292d0a2bf2d777ddeefbcc Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Fri, 24 Jan 2020 23:40:47 -0500 Subject: Remove enc_utf8,has_mbyte dead code --- src/nvim/ops.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index bcf54087f5..db5c98ed78 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -357,15 +357,11 @@ static void shift_block(oparg_T *oap, int amount) colnr_T ws_vcol = bd.start_vcol - bd.pre_whitesp; char_u * old_textstart = bd.textstart; if (bd.startspaces) { - if (has_mbyte) { - if ((*mb_ptr2len)(bd.textstart) == 1) { - bd.textstart++; - } else { - ws_vcol = 0; - bd.startspaces = 0; - } - } else { + if (utfc_ptr2len(bd.textstart) == 1) { bd.textstart++; + } else { + ws_vcol = 0; + bd.startspaces = 0; } } for (; ascii_iswhite(*bd.textstart); ) { @@ -1215,9 +1211,7 @@ static void stuffescaped(const char *arg, int literally) /* stuff a single special character */ if (*arg != NUL) { - const int c = (has_mbyte - ? mb_cptr2char_adv((const char_u **)&arg) - : (uint8_t)(*arg++)); + const int c = mb_cptr2char_adv((const char_u **)&arg); if (literally && ((c < ' ' && c != TAB) || c == DEL)) { stuffcharReadbuff(Ctrl_V); } @@ -1389,8 +1383,7 @@ int op_delete(oparg_T *oap) return FAIL; } - if (has_mbyte) - mb_adjust_opend(oap); + mb_adjust_opend(oap); /* * Imitate the strange Vi behaviour: If the delete spans more than one @@ -1736,8 +1729,7 @@ int op_replace(oparg_T *oap, int c) c = NL; } - if (has_mbyte) - mb_adjust_opend(oap); + mb_adjust_opend(oap); if (u_save((linenr_T)(oap->start.lnum - 1), (linenr_T)(oap->end.lnum + 1)) == FAIL) @@ -2012,17 +2004,16 @@ void op_tilde(oparg_T *oap) * Returns TRUE if some character was changed. */ static int swapchars(int op_type, pos_T *pos, int length) + FUNC_ATTR_NONNULL_ALL { - int todo; int did_change = 0; - for (todo = length; todo > 0; --todo) { - if (has_mbyte) { - int len = (*mb_ptr2len)(ml_get_pos(pos)); + for (int todo = length; todo > 0; todo--) { + const int len = utfc_ptr2len(ml_get_pos(pos)); - /* we're counting bytes, not characters */ - if (len > 0) - todo -= len - 1; + // we're counting bytes, not characters + if (len > 0) { + todo -= len - 1; } did_change |= swapchar(op_type, pos); if (inc(pos) == -1) /* at end of file */ @@ -3052,7 +3043,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col); // move to start of next multi-byte character - curwin->w_cursor.col += (*mb_ptr2len)(get_cursor_pos_ptr()); + curwin->w_cursor.col += utfc_ptr2len(get_cursor_pos_ptr()); col++; } else { getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2); @@ -3615,7 +3606,7 @@ dis_msg( while (*p != NUL && !(*p == ESC && skip_esc && *(p + 1) == NUL) && (n -= ptr2cells(p)) >= 0) { - if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) { + if ((l = utfc_ptr2len(p)) > 1) { msg_outtrans_len(p, l); p += l; } else -- cgit From 2538e615130c7f4baa1029d0be2bc2d7f66cdd7e Mon Sep 17 00:00:00 2001 From: Axel Forsman Date: Thu, 30 Jan 2020 07:34:34 +0100 Subject: Fix shift change callbacks reading bad cursor (#11782) Sloppy code inherited from Vim caused user scripts to be able to observe the cursor line in an invalid intermediary state, due to Neovim change callbacks being unbuffered unlike Vim listeners. Manifested in Vimscript executed from the callback possibly erroring when `:call`:ing any function, due to the implicit range `curwin->w_cursor.lnum,curwin->w_cursor.lnum` failing validation. Fixed by deferring the call to `changed_lines()` until after `curwin->w_cursor.lnum` gets its correct value. --- src/nvim/ops.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index db5c98ed78..6d327c0814 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -221,8 +221,6 @@ void op_shift(oparg_T *oap, int curs_top, int amount) ++curwin->w_cursor.lnum; } - changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true); - if (oap->motion_type == kMTBlockWise) { curwin->w_cursor.lnum = oap->start.lnum; curwin->w_cursor.col = block_col; @@ -262,8 +260,11 @@ void op_shift(oparg_T *oap, int curs_top, int amount) curbuf->b_op_start = oap->start; curbuf->b_op_end.lnum = oap->end.lnum; curbuf->b_op_end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum)); - if (curbuf->b_op_end.col > 0) - --curbuf->b_op_end.col; + if (curbuf->b_op_end.col > 0) { + curbuf->b_op_end.col--; + } + + changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true); } // Shift the current line one shiftwidth left (if left != 0) or right -- cgit From 4813ad48cd12a03ca50c01ac1b20518bf4df57f2 Mon Sep 17 00:00:00 2001 From: erw7 Date: Mon, 20 May 2019 11:57:45 +0900 Subject: vim-patch:8.1.0027: difficult to make a plugin that feeds a line to a job Problem: Difficult to make a plugin that feeds a line to a job. Solution: Add the nitial code for the "prompt" buftype. https://github.com/vim/vim/commit/f273245f6433d5d43a5671306b520a3230c35787 --- src/nvim/ops.c | 72 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 31 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 6d327c0814..735a33ca97 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -89,6 +89,10 @@ struct block_def { # include "ops.c.generated.h" #endif +// 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!!! @@ -96,36 +100,36 @@ struct block_def { */ static char opchars[][3] = { - { NUL, NUL, false }, // OP_NOP - { 'd', NUL, false }, // OP_DELETE - { 'y', NUL, false }, // OP_YANK - { 'c', NUL, false }, // OP_CHANGE - { '<', NUL, true }, // OP_LSHIFT - { '>', NUL, true }, // OP_RSHIFT - { '!', NUL, true }, // OP_FILTER - { 'g', '~', false }, // OP_TILDE - { '=', NUL, true }, // OP_INDENT - { 'g', 'q', true }, // OP_FORMAT - { ':', NUL, true }, // OP_COLON - { 'g', 'U', false }, // OP_UPPER - { 'g', 'u', false }, // OP_LOWER - { 'J', NUL, true }, // DO_JOIN - { 'g', 'J', true }, // DO_JOIN_NS - { 'g', '?', false }, // OP_ROT13 - { 'r', NUL, false }, // OP_REPLACE - { 'I', NUL, false }, // OP_INSERT - { 'A', NUL, false }, // OP_APPEND - { 'z', 'f', true }, // OP_FOLD - { 'z', 'o', true }, // OP_FOLDOPEN - { 'z', 'O', true }, // OP_FOLDOPENREC - { 'z', 'c', true }, // OP_FOLDCLOSE - { 'z', 'C', true }, // OP_FOLDCLOSEREC - { 'z', 'd', true }, // OP_FOLDDEL - { 'z', 'D', true }, // OP_FOLDDELREC - { 'g', 'w', true }, // OP_FORMAT2 - { 'g', '@', false }, // OP_FUNCTION - { Ctrl_A, NUL, false }, // OP_NR_ADD - { Ctrl_X, NUL, false }, // OP_NR_SUB + { NUL, NUL, 0 }, // OP_NOP + { 'd', NUL, OPF_CHANGE }, // OP_DELETE + { 'y', NUL, 0 }, // OP_YANK + { 'c', NUL, OPF_CHANGE }, // OP_CHANGE + { '<', NUL, OPF_LINES | OPF_CHANGE }, // OP_LSHIFT + { '>', NUL, OPF_LINES | OPF_CHANGE }, // OP_RSHIFT + { '!', NUL, OPF_LINES | OPF_CHANGE }, // OP_FILTER + { 'g', '~', OPF_CHANGE }, // OP_TILDE + { '=', NUL, OPF_LINES | OPF_CHANGE }, // OP_INDENT + { 'g', 'q', OPF_LINES | OPF_CHANGE }, // OP_FORMAT + { ':', NUL, OPF_LINES }, // OP_COLON + { 'g', 'U', OPF_CHANGE }, // OP_UPPER + { 'g', 'u', OPF_CHANGE }, // OP_LOWER + { 'J', NUL, OPF_LINES | OPF_CHANGE }, // DO_JOIN + { 'g', 'J', OPF_LINES | OPF_CHANGE }, // DO_JOIN_NS + { 'g', '?', OPF_CHANGE }, // OP_ROT13 + { 'r', NUL, OPF_CHANGE }, // OP_REPLACE + { 'I', NUL, OPF_CHANGE }, // OP_INSERT + { 'A', NUL, OPF_CHANGE }, // OP_APPEND + { 'z', 'f', OPF_LINES }, // OP_FOLD + { 'z', 'o', OPF_LINES }, // OP_FOLDOPEN + { 'z', 'O', OPF_LINES }, // OP_FOLDOPENREC + { 'z', 'c', OPF_LINES }, // OP_FOLDCLOSE + { 'z', 'C', OPF_LINES }, // OP_FOLDCLOSEREC + { 'z', 'd', OPF_LINES }, // OP_FOLDDEL + { 'z', 'D', OPF_LINES }, // OP_FOLDDELREC + { 'g', 'w', OPF_LINES | OPF_CHANGE }, // OP_FORMAT2 + { 'g', '@', OPF_CHANGE }, // OP_FUNCTION + { Ctrl_A, NUL, OPF_CHANGE }, // OP_NR_ADD + { Ctrl_X, NUL, OPF_CHANGE }, // OP_NR_SUB }; /* @@ -169,7 +173,13 @@ int get_op_type(int char1, int char2) */ int op_on_lines(int op) { - return opchars[op][2]; + return opchars[op][2] & OPF_LINES; +} + +// Return TRUE if operator "op" changes text. +int op_is_change(int op) +{ + return opchars[op][2] & OPF_CHANGE; } /* -- cgit From 607240a8bac80f02d812084d3146b4372ddae6dd Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 22 Feb 2020 12:09:21 -0500 Subject: pvs/v1048: variable was assigned same value --- src/nvim/ops.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 735a33ca97..4ac12e868f 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -2534,7 +2534,7 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) case kMTCharWise: { colnr_T startcol = 0, endcol = MAXCOL; - int is_oneChar = FALSE; + int is_oneChar = false; colnr_T cs, ce; p = ml_get(lnum); bd.startspaces = 0; @@ -2565,8 +2565,8 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) && 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; + // Special case: inside a single char + is_oneChar = true; bd.startspaces = oap->end.coladd - oap->start.coladd + oap->inclusive; endcol = startcol; @@ -4425,8 +4425,8 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bdp->textlen = 0; bdp->start_vcol = 0; bdp->end_vcol = 0; - bdp->is_short = FALSE; - bdp->is_oneChar = FALSE; + bdp->is_short = false; + bdp->is_oneChar = false; bdp->pre_whitesp = 0; bdp->pre_whitesp_c = 0; bdp->end_char_vcols = 0; @@ -4452,9 +4452,10 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bdp->start_char_vcols = incr; if (bdp->start_vcol < oap->start_vcol) { /* line too short */ bdp->end_vcol = bdp->start_vcol; - bdp->is_short = TRUE; - if (!is_del || oap->op_type == OP_APPEND) + bdp->is_short = true; + if (!is_del || oap->op_type == OP_APPEND) { bdp->endspaces = oap->end_vcol - oap->start_vcol + 1; + } } else { /* notice: this converts partly selected Multibyte characters to * spaces, too. */ @@ -4463,11 +4464,11 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bdp->startspaces = bdp->start_char_vcols - bdp->startspaces; 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; - if (oap->op_type == OP_INSERT) + if (bdp->end_vcol > oap->end_vcol) { // it's all in one character + bdp->is_oneChar = true; + if (oap->op_type == OP_INSERT) { bdp->endspaces = bdp->start_char_vcols - bdp->startspaces; - else if (oap->op_type == OP_APPEND) { + } else if (oap->op_type == OP_APPEND) { bdp->startspaces += oap->end_vcol - oap->start_vcol + 1; bdp->endspaces = bdp->start_char_vcols - bdp->startspaces; } else { @@ -4492,17 +4493,16 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, if (bdp->end_vcol <= oap->end_vcol && (!is_del || oap->op_type == OP_APPEND - || oap->op_type == OP_REPLACE)) { /* line too short */ - bdp->is_short = TRUE; - /* Alternative: include spaces to fill up the block. - * Disadvantage: can lead to trailing spaces when the line is - * short where the text is put */ - /* if (!is_del || oap->op_type == OP_APPEND) */ - if (oap->op_type == OP_APPEND || virtual_op) + || oap->op_type == OP_REPLACE)) { // line too short + bdp->is_short = true; + // Alternative: include spaces to fill up the block. + // Disadvantage: can lead to trailing spaces when the line is + // short where the text is put + // if (!is_del || oap->op_type == OP_APPEND) + if (oap->op_type == OP_APPEND || virtual_op) { bdp->endspaces = oap->end_vcol - bdp->end_vcol + oap->inclusive; - else - bdp->endspaces = 0; /* replace doesn't add characters */ + } } else if (bdp->end_vcol > oap->end_vcol) { bdp->endspaces = bdp->end_vcol - oap->end_vcol - 1; if (!is_del && bdp->endspaces) { -- cgit From 4de2957a997bc54a968e40cebc51a42f29afb39c Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 22 Feb 2020 14:54:41 -0500 Subject: vim-patch:8.0.1587: inserting from the clipboard doesn't work literally Problem: inserting from the clipboard doesn't work literally Solution: When pasting from the * or + register always assume literally. https://github.com/vim/vim/commit/3324d0a86421a634572758dcfde917547f4d4c67 --- src/nvim/ops.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 4ac12e868f..5457400b76 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -842,6 +842,15 @@ 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 == '+'; +} + /// Returns a copy of contents in register `name` /// for use in do_put. Should be freed by caller. yankreg_T *copy_register(int name) @@ -1152,11 +1161,12 @@ static int put_in_typebuf( */ int insert_reg( int regname, - int literally /* insert literally, not as if typed */ + bool literally_arg // insert literally, not as if typed ) { int retval = OK; bool allocated; + const bool literally = literally_arg || is_literal_register(regname); /* * It is possible to get into an endless loop by having CTRL-R a in @@ -1326,12 +1336,14 @@ bool get_spec_reg( /// register contents will be interpreted as commands. /// /// @param regname Register name. -/// @param literally Insert text literally instead of "as typed". +/// @param literally_arg Insert text literally instead of "as typed". /// @param remcr When true, don't add CR characters. /// /// @returns FAIL for failure, OK otherwise -bool cmdline_paste_reg(int regname, bool literally, bool remcr) +bool cmdline_paste_reg(int regname, bool literally_arg, bool remcr) { + const bool literally = literally_arg || is_literal_register(regname); + yankreg_T *reg = get_yank_register(regname, YREG_PASTE); if (reg->y_array == NULL) return FAIL; -- cgit From 63fc0e1d1cedcb8e39524e785648d3f98d682f66 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sun, 15 Mar 2020 14:58:57 -0400 Subject: vim-patch:8.2.0389: delayed redraw when shifting text from Insert mode Problem: Delayed redraw when shifting text from Insert mode. Solution: Use msg_attr_keep() instead of msg(). (closes vim/vim#5782) https://github.com/vim/vim/commit/e4fc746d13f5b6a0b5c3a8efdff7de1454c3297d --- 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 5457400b76..a70224f98b 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -261,7 +261,7 @@ void op_shift(oparg_T *oap, int curs_top, int amount) sprintf((char *)IObuff, _("%" PRId64 " lines %sed %d times"), (int64_t)oap->line_count, s, amount); } - msg(IObuff); + msg_attr_keep(IObuff, 0, true, false); } /* -- cgit From 8a1276005a1099187710bdcc19284de51a0aa89a Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Wed, 3 Jun 2020 16:51:25 +0200 Subject: Add v:event.visual during `TextYankPost` (#12382) * propagate visual selection to textyankpost event * adapt tests * add docs * also adapt oldtest --- src/nvim/ops.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index a70224f98b..755c1519fd 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -2748,6 +2748,10 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) buf[1] = NUL; tv_dict_add_str(dict, S_LEN("operator"), buf); + // Selection type: visual or not. + tv_dict_add_special(dict, S_LEN("visual"), + oap->is_VIsual ? kSpecialVarTrue : kSpecialVarFalse); + tv_dict_set_keys_readonly(dict); textlock++; apply_autocmds(EVENT_TEXTYANKPOST, NULL, NULL, false, curbuf); -- cgit From 1805fb469a39d998f9bef0415999aa835d051044 Mon Sep 17 00:00:00 2001 From: Billy Su Date: Tue, 28 Apr 2020 23:21:50 +0800 Subject: vim-patch:8.2.0111: VAR_SPECIAL is also used for booleans Problem: VAR_SPECIAL is also used for booleans. Solution: Add VAR_BOOL for better type checking. https://github.com/vim/vim/commit/9b4a15d5dba354d2e1e02871470bad103f34769a --- src/nvim/ops.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 755c1519fd..eb32a1dd9b 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -2740,8 +2740,8 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) tv_dict_add_str(dict, S_LEN("regname"), buf); // Motion type: inclusive or exclusive. - tv_dict_add_special(dict, S_LEN("inclusive"), - oap->inclusive ? kSpecialVarTrue : kSpecialVarFalse); + tv_dict_add_bool(dict, S_LEN("inclusive"), + oap->inclusive ? kBoolVarTrue : kBoolVarFalse); // Kind of operation: yank, delete, change). buf[0] = (char)get_op_char(oap->op_type); @@ -2749,8 +2749,8 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) tv_dict_add_str(dict, S_LEN("operator"), buf); // Selection type: visual or not. - tv_dict_add_special(dict, S_LEN("visual"), - oap->is_VIsual ? kSpecialVarTrue : kSpecialVarFalse); + tv_dict_add_bool(dict, S_LEN("visual"), + oap->is_VIsual ? kBoolVarTrue : kBoolVarFalse); tv_dict_set_keys_readonly(dict); textlock++; -- cgit From 833a5d16a21aac58367c2cedbc7a34f321183e76 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Fri, 12 Jun 2020 23:38:33 -0400 Subject: vim-patch:8.2.0963: number increment/decrement does not work with 'virtualedit' Problem: Number increment/decrement does not work with 'virtualedit'. Solution: Handle coladd changing. (Christian Brabandt, closes vim/vim#6240, closes vim/vim#923) https://github.com/vim/vim/commit/6c6be9e88d72a60ee279ccad73d018c534b71d66 --- src/nvim/ops.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index eb32a1dd9b..e905029dae 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -4671,17 +4671,23 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) int maxlen = 0; pos_T startpos; pos_T endpos; + colnr_T save_coladd = 0; dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL); // "heX" dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL); // "Octal" dobin = (vim_strchr(curbuf->b_p_nf, 'b') != NULL); // "Bin" doalp = (vim_strchr(curbuf->b_p_nf, 'p') != NULL); // "alPha" + if (virtual_active()) { + save_coladd = pos->coladd; + pos->coladd = 0; + } + curwin->w_cursor = *pos; ptr = ml_get(pos->lnum); col = pos->col; - if (*ptr == NUL) { + if (*ptr == NUL || col + !!save_coladd >= (int)STRLEN(ptr)) { goto theend; } @@ -4976,6 +4982,8 @@ theend: curwin->w_cursor = save_cursor; } else if (did_change) { curwin->w_set_curswant = true; + } else if (virtual_active()) { + curwin->w_cursor.coladd = save_coladd; } return did_change; -- cgit From be9de61012047b82e0f57742205e25a9a11ecf1c Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Fri, 10 Jul 2020 19:29:31 -0400 Subject: vim-patch:8.2.1170: cursor off by one with block paste while 'virtualedit' "all" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: Cursor off by one with block paste while 'virtualedit' is "all". Solution: Adjust condition. (Hugo Gualandi, closes vim/vim#6430) https://github.com/vim/vim/commit/ef85a9b2d9e992ab594e089af3883e381cfad426 N/A patches for version.c: vim-patch:8.2.1114: terminal test sometimes times out Problem: Terminal test sometimes times out. Solution: Split the test in two parts. https://github.com/vim/vim/commit/1112c0febb509d0cb219f3a2479fd36833507167 vim-patch:8.2.1171: possible crash when out of memory Problem: Possible crash when out of memory. Solution: Check for NULL pointer. (Dominique Pellé, closes vim/vim#6432) https://github.com/vim/vim/commit/58bb61cf5ee008254eb331bc3574eac87d2dcc4a vim-patch:8.2.1172: error messages when doing "make clean" in doc or tee Problem: Error messages when doing "make clean" in the runtime/doc or src/tee directories. Solution: Use "rm -f". https://github.com/vim/vim/commit/08fc48492acc07259d91293df12bf66447819443 vim-patch:8.2.1173: tee doesn't build on some systems Problem: Tee doesn't build on some systems. Solution: Include header files. (Dominique Pelle, closes vim/vim#6431) https://github.com/vim/vim/commit/40043152924827fa8c4064951065ff507c610164 vim-patch:8.2.1177: terminal2 test sometimes hangs in the GUI Problem: Terminal2 test sometimes hangs in the GUI. Solution: Move some tests to other files to further locate the problem. Set the GUI to a fixed screen size. https://github.com/vim/vim/commit/18aa13d13b69c090dbe186cd4939896488c433e3 vim-patch:8.2.1179: Test_termwinscroll() sometimes hangs in the GUI Problem: Test_termwinscroll() sometimes hangs in the GUI. Solution: Skip the test in the GUI. https://github.com/vim/vim/commit/f65927fc8d0102ef2d0fea776381caedf4c51e32 vim-patch:8.2.1180: build failure in small version Problem: Build failure in small version. Solution: Add #ifdef. https://github.com/vim/vim/commit/1e624c912dff19e889c9398b56fe537952c02fef vim-patch:8.2.1181: json code not fully tested Problem: Json code not fully tested. Solution: Add more test coverage. (Dominique Pellé, closes vim/vim#6433) https://github.com/vim/vim/commit/21e5bdd271fa4d0ff4511cf74b160315e1d17cff --- src/nvim/ops.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/nvim/ops.c') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index e905029dae..595a699563 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -3080,10 +3080,12 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) if (ve_flags == VE_ALL && (curwin->w_cursor.coladd > 0 || endcol2 == curwin->w_cursor.col)) { - if (dir == FORWARD && c == NUL) - ++col; - if (dir != FORWARD && c != NUL) - ++curwin->w_cursor.col; + if (dir == FORWARD && c == NUL) { + col++; + } + if (dir != FORWARD && c != NUL && curwin->w_cursor.coladd > 0) { + curwin->w_cursor.col++; + } if (c == TAB) { if (dir == BACKWARD && curwin->w_cursor.col) curwin->w_cursor.col--; -- cgit