aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ex_cmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ex_cmds.c')
-rw-r--r--src/nvim/ex_cmds.c72
1 files changed, 48 insertions, 24 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 519978f4fb..3669cbbd2d 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -135,7 +135,7 @@ void do_ascii(const exarg_T *const eap)
char buf1[20];
if (vim_isprintc_strict(c) && (c < ' ' || c > '~')) {
char_u buf3[7];
- transchar_nonprint(buf3, c);
+ transchar_nonprint(curbuf, buf3, c);
vim_snprintf(buf1, sizeof(buf1), " <%s>", (char *)buf3);
} else {
buf1[0] = NUL;
@@ -326,14 +326,19 @@ static int linelen(int *has_tab)
int save;
int len;
- /* find the first non-blank character */
+ // Get the line. If it's empty bail out early (could be the empty string
+ // for an unloaded buffer).
line = get_cursor_line_ptr();
+ if (*line == NUL) {
+ return 0;
+ }
+ // find the first non-blank character
first = skipwhite(line);
- /* find the character after the last non-blank character */
+ // find the character after the last non-blank character
for (last = first + STRLEN(first);
- last > first && ascii_iswhite(last[-1]); --last)
- ;
+ last > first && ascii_iswhite(last[-1]); last--) {
+ }
save = *last;
*last = NUL;
// Get line length.
@@ -846,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;
/*
@@ -880,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) {
@@ -889,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) {
@@ -904,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);
@@ -2227,11 +2240,9 @@ int do_ecmd(
goto theend;
}
- /*
- * if the file was changed we may not be allowed to abandon it
- * - if we are going to re-edit the same file
- * - or if we are the only window on this file and if ECMD_HIDE is FALSE
- */
+ // If the file was changed we may not be allowed to abandon it:
+ // - if we are going to re-edit the same file
+ // - or if we are the only window on this file and if ECMD_HIDE is FALSE
if ( ((!other_file && !(flags & ECMD_OLDBUF))
|| (curbuf->b_nwindows == 1
&& !(flags & (ECMD_HIDE | ECMD_ADDBUF))))
@@ -2484,8 +2495,12 @@ int do_ecmd(
new_name = NULL;
}
set_bufref(&bufref, buf);
- if (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur) {
- // Save all the text, so that the reload can be undone.
+
+ // If the buffer was used before, store the current contents so that
+ // the reload can be undone. Do not do this if the (empty) buffer is
+ // being re-used for another file.
+ if (!(curbuf->b_flags & BF_NEVERLOADED)
+ && (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur)) {
// Sync first so that this is a separate undo-able action.
u_sync(false);
if (u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, true)
@@ -3908,6 +3923,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
@@ -3951,17 +3978,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);
+ }
}