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.
630afe889a
This commit is contained in:
Jan Edmund Lazo
2019-06-21 21:29:21 -04:00
parent f0d6695e7c
commit 3abffe7015
2 changed files with 40 additions and 11 deletions

View File

@@ -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;

View File

@@ -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