diff options
author | Jan Edmund Lazo <jan.lazo@mail.utoronto.ca> | 2019-06-21 21:29:21 -0400 |
---|---|---|
committer | Jan Edmund Lazo <jan.lazo@mail.utoronto.ca> | 2019-06-23 18:17:09 -0400 |
commit | 3abffe7015701f2468f94af3280871cd34653747 (patch) | |
tree | 3ab6156af0c1a82b6e71c360493a11f1e4e46553 /src | |
parent | f0d6695e7cc13cd5f1ee006575a369faf2546893 (diff) | |
download | rneovim-3abffe7015701f2468f94af3280871cd34653747.tar.gz rneovim-3abffe7015701f2468f94af3280871cd34653747.tar.bz2 rneovim-3abffe7015701f2468f94af3280871cd34653747.zip |
vim-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 vim/vim#3114) Rename PCHAR() to PBYTE() to avoid mistakes like
this.
https://github.com/vim/vim/commit/630afe889a2a02b367ea8eaaa48e66ed81e77ff3
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/ops.c | 35 | ||||
-rw-r--r-- | src/nvim/testdir/test_virtualedit.vim | 16 |
2 files changed, 40 insertions, 11 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 2a3b7beb8e..ef440a27a2 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1638,12 +1638,25 @@ static void mb_adjust_opend(oparg_T *oap) /* * Put character 'c' at position 'lp' */ -static inline void pchar(pos_T lp, int c) +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; } +// Replace the character under the cursor with "c". +// This takes care of multi-byte characters. +static void replace_character(int c) +{ + const int n = State; + + State = REPLACE; + ins_char(c); + State = n; + // Backup to the replaced character. + dec_cursor(); +} + /* * Replace a whole area with one character. */ @@ -1795,12 +1808,7 @@ int 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 { if (n == TAB) { int end_vcol = 0; @@ -1815,7 +1823,7 @@ int op_replace(oparg_T *oap, int c) if (curwin->w_cursor.lnum == oap->end.lnum) getvpos(&oap->end, end_vcol); } - pchar(curwin->w_cursor, c); + pbyte(curwin->w_cursor, c); } } else if (virtual_op && curwin->w_cursor.lnum == oap->end.lnum) { int virtcols = oap->end.coladd; @@ -1830,9 +1838,14 @@ int op_replace(oparg_T *oap, int c) coladvance_force(getviscol2(oap->end.col, oap->end.coladd) + 1); curwin->w_cursor.col -= (virtcols + 1); for (; virtcols >= 0; virtcols--) { - pchar(curwin->w_cursor, c); - if (inc(&curwin->w_cursor) == -1) + if (utf_char2len(c) > 1) { + replace_character(c); + } else { + pbyte(curwin->w_cursor, c); + } + if (inc(&curwin->w_cursor) == -1) { break; + } } } @@ -2007,7 +2020,7 @@ int swapchar(int op_type, pos_T *pos) ins_char(nc); curwin->w_cursor = sp; } else - pchar(*pos, nc); + pbyte(*pos, nc); return TRUE; } return FALSE; diff --git a/src/nvim/testdir/test_virtualedit.vim b/src/nvim/testdir/test_virtualedit.vim index d49025237b..abe79f6a4a 100644 --- a/src/nvim/testdir/test_virtualedit.vim +++ b/src/nvim/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 |