summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2018-06-28 19:26:28 +0200
committerBram Moolenaar <Bram@vim.org>2018-06-28 19:26:28 +0200
commit630afe889a2a02b367ea8eaaa48e66ed81e77ff3 (patch)
treeb842a80b4031b81954a44a68d8e7064722b60e26
parentd8b37a53bd29cab78c6997aa75207385213f23e2 (diff)
downloadvim-630afe889a2a02b367ea8eaaa48e66ed81e77ff3.zip
patch 8.1.0125: virtual edit replace with multi-byte fails at end of line
Problem: Virtual edit replace with multi-byte fails at end of line. (Lukas Werling) Solution: use ins_char() to add the character. (Christian Brabandt, closes #3114) Rename PCHAR() to PBYTE() to avoid mistakes like this.
-rw-r--r--src/macros.h4
-rw-r--r--src/ops.c41
-rw-r--r--src/testdir/test_virtualedit.vim16
-rw-r--r--src/version.c2
4 files changed, 50 insertions, 13 deletions
diff --git a/src/macros.h b/src/macros.h
index fcd1a829d..c91b4b620 100644
--- a/src/macros.h
+++ b/src/macros.h
@@ -14,9 +14,9 @@
*/
/*
- * PCHAR(lp, c) - put character 'c' at position 'lp'
+ * PBYTE(lp, c) - put byte 'c' at position 'lp'
*/
-#define PCHAR(lp, c) (*(ml_get_buf(curbuf, (lp).lnum, TRUE) + (lp).col) = (c))
+#define PBYTE(lp, c) (*(ml_get_buf(curbuf, (lp).lnum, TRUE) + (lp).col) = (c))
/*
* Position comparisons
diff --git a/src/ops.c b/src/ops.c
index 73f73d2f9..2e08a5329 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -2146,6 +2146,25 @@ mb_adjust_opend(oparg_T *oap)
#endif
#if defined(FEAT_VISUALEXTRA) || defined(PROTO)
+
+# ifdef FEAT_MBYTE
+/*
+ * Replace the character under the cursor with "c".
+ * This takes care of multi-byte characters.
+ */
+ static void
+replace_character(int c)
+{
+ int n = State;
+
+ State = REPLACE;
+ ins_char(c);
+ State = n;
+ /* Backup to the replaced character. */
+ dec_cursor();
+}
+
+# endif
/*
* Replace a whole area with one character.
*/
@@ -2331,12 +2350,7 @@ op_replace(oparg_T *oap, int c)
* with a multi-byte and the other way around. */
if (curwin->w_cursor.lnum == oap->end.lnum)
oap->end.col += (*mb_char2len)(c) - (*mb_char2len)(n);
- n = State;
- State = REPLACE;
- ins_char(c);
- State = n;
- /* Backup to the replaced character. */
- dec_cursor();
+ replace_character(c);
}
else
#endif
@@ -2358,7 +2372,7 @@ op_replace(oparg_T *oap, int c)
getvpos(&oap->end, end_vcol);
}
#endif
- PCHAR(curwin->w_cursor, c);
+ PBYTE(curwin->w_cursor, c);
}
}
#ifdef FEAT_VIRTUALEDIT
@@ -2377,9 +2391,14 @@ op_replace(oparg_T *oap, int c)
curwin->w_cursor.col -= (virtcols + 1);
for (; virtcols >= 0; virtcols--)
{
- PCHAR(curwin->w_cursor, c);
- if (inc(&curwin->w_cursor) == -1)
- break;
+#ifdef FEAT_MBYTE
+ if ((*mb_char2len)(c) > 1)
+ replace_character(c);
+ else
+ #endif
+ PBYTE(curwin->w_cursor, c);
+ if (inc(&curwin->w_cursor) == -1)
+ break;
}
}
#endif
@@ -2619,7 +2638,7 @@ swapchar(int op_type, pos_T *pos)
}
else
#endif
- PCHAR(*pos, nc);
+ PBYTE(*pos, nc);
return TRUE;
}
return FALSE;
diff --git a/src/testdir/test_virtualedit.vim b/src/testdir/test_virtualedit.vim
index d49025237..abe79f6a4 100644
--- a/src/testdir/test_virtualedit.vim
+++ b/src/testdir/test_virtualedit.vim
@@ -42,6 +42,22 @@ func Test_paste_end_of_line()
set virtualedit=
endfunc
+func Test_replace_end_of_line()
+ new
+ set virtualedit=all
+ call setline(1, range(20))
+ exe "normal! gg2jv10lr-"
+ call assert_equal(["1", "-----------", "3"], getline(2,4))
+ if has('multi_byte')
+ call setline(1, range(20))
+ exe "normal! gg2jv10lr\<c-k>hh"
+ call assert_equal(["1", "───────────", "3"], getline(2,4))
+ endif
+
+ bwipe!
+ set virtualedit=
+endfunc
+
func Test_edit_CTRL_G()
new
set virtualedit=insert
diff --git a/src/version.c b/src/version.c
index 86e24fdc1..31db84053 100644
--- a/src/version.c
+++ b/src/version.c
@@ -790,6 +790,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 125,
+/**/
124,
/**/
123,