diff options
Diffstat (limited to 'src/nvim/ex_cmds.c')
-rw-r--r-- | src/nvim/ex_cmds.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 2bac6cba58..9be6adcd61 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -851,6 +851,11 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest) return OK; } + bcount_t start_byte = ml_find_line_or_offset(curbuf, line1, NULL, true); + bcount_t end_byte = ml_find_line_or_offset(curbuf, line2+1, NULL, true); + bcount_t extent_byte = end_byte-start_byte; + bcount_t dest_byte = ml_find_line_or_offset(curbuf, dest+1, NULL, true); + num_lines = line2 - line1 + 1; /* @@ -885,6 +890,8 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest) last_line = curbuf->b_ml.ml_line_count; mark_adjust_nofold(line1, line2, last_line - line2, 0L, kExtmarkNOOP); changed_lines(last_line - num_lines + 1, 0, last_line + 1, num_lines, false); + int line_off = 0; + bcount_t byte_off = 0; if (dest >= line2) { mark_adjust_nofold(line2 + 1, dest, -num_lines, 0L, kExtmarkNOOP); FOR_ALL_TAB_WINDOWS(tab, win) { @@ -894,6 +901,8 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest) } curbuf->b_op_start.lnum = dest - num_lines + 1; curbuf->b_op_end.lnum = dest; + line_off = -num_lines; + byte_off = -extent_byte; } else { mark_adjust_nofold(dest + 1, line1 - 1, num_lines, 0L, kExtmarkNOOP); FOR_ALL_TAB_WINDOWS(tab, win) { @@ -909,11 +918,10 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest) -(last_line - dest - extra), 0L, kExtmarkNOOP); // extmarks are handled separately - int size = line2-line1+1; - int off = dest >= line2 ? -size : 0; - extmark_move_region(curbuf, line1-1, 0, - line2-line1+1, 0, - dest+off, 0, kExtmarkUndo); + extmark_move_region(curbuf, line1-1, 0, start_byte, + line2-line1+1, 0, extent_byte, + dest+line_off, 0, dest_byte+byte_off, + kExtmarkUndo); changed_lines(last_line - num_lines + 1, 0, last_line + 1, -extra, false); @@ -3913,6 +3921,18 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, ADJUST_SUB_FIRSTLNUM(); + // TODO(bfredl): adjust also in preview, because decorations? + // this has some robustness issues, will look into later. + bool do_splice = !preview; + bcount_t replaced_bytes = 0; + lpos_T start = regmatch.startpos[0], end = regmatch.endpos[0]; + if (do_splice) { + for (i = 0; i < nmatch-1; i++) { + replaced_bytes += STRLEN(ml_get(lnum_start+i)) + 1; + } + replaced_bytes += end.col - start.col; + } + // Now the trick is to replace CTRL-M chars with a real line // break. This would make it impossible to insert a CTRL-M in @@ -3956,17 +3976,14 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, current_match.end.col = new_endcol; current_match.end.lnum = lnum; - // TODO(bfredl): adjust in preview, because decorations? - // this has some robustness issues, will look into later. - if (!preview) { - lpos_T start = regmatch.startpos[0], end = regmatch.endpos[0]; + if (do_splice) { int matchcols = end.col - ((end.lnum == start.lnum) ? start.col : 0); int subcols = new_endcol - ((lnum == lnum_start) ? start_col : 0); extmark_splice(curbuf, lnum_start-1, start_col, - end.lnum-start.lnum, matchcols, - lnum-lnum_start, subcols, kExtmarkUndo); - } + end.lnum-start.lnum, matchcols, replaced_bytes, + lnum-lnum_start, subcols, sublen-1, kExtmarkUndo); + } } |