vim-patch:9.1.1083: setreg() doesn't correctly handle mbyte chars in blockwise mode

Problem:  setreg() doesn't correctly handle mbyte chars in blockwise
          mode
Solution: use mb_ptr2len_len function pointer (Yee Cheng Chin)

setreg() will automatically calculate the width when a blockwise mode is
specified, but it does not properly calculate the line widths of mbyte
characters when value is passed as newline-terminated string. It does
work when value is passed as a list of lines though.

Fix this by properly using the mbyte function pointer to increment the
loop counter.

closes: vim/vim#16596

a17f8bfb28

Co-authored-by: Yee Cheng Chin <ychin.git@gmail.com>
This commit is contained in:
zeertzjq 2025-02-09 08:30:58 +08:00
parent 00bce2723f
commit 6f0a91579f
2 changed files with 26 additions and 2 deletions

View File

@ -5248,14 +5248,21 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char *str,
start < end + extraline;
start += line_len + 1, lnum++) {
int charlen = 0;
const char *line_end;
for (line_end = start; line_end < end; line_end++) {
const char *line_end = start;
while (line_end < end) { // find the end of the line
if (*line_end == '\n') {
break;
}
if (yank_type == kMTBlockWise) {
charlen += utf_ptr2cells_len(line_end, (int)(end - line_end));
}
if (*line_end == NUL) {
line_end++; // registers can have NUL chars
} else {
line_end += utf_ptr2len_len(line_end, (int)(end - line_end));
}
}
assert(line_end - start >= 0);
line_len = (size_t)(line_end - start);

View File

@ -435,6 +435,23 @@ func Test_set_register()
enew!
endfunc
" Test for blockwise register width calculations
func Test_set_register_blockwise_width()
" Test for regular calculations and overriding the width
call setreg('a', "12\n1234\n123", 'b')
call assert_equal("\<c-v>4", getreginfo('a').regtype)
call setreg('a', "12\n1234\n123", 'b1')
call assert_equal("\<c-v>1", getreginfo('a').regtype)
call setreg('a', "12\n1234\n123", 'b6')
call assert_equal("\<c-v>6", getreginfo('a').regtype)
" Test for Unicode parsing
call setreg('a', "z😅😅z\n12345", 'b')
call assert_equal("\<c-v>6", getreginfo('a').regtype)
call setreg('a', ["z😅😅z", "12345"], 'b')
call assert_equal("\<c-v>6", getreginfo('a').regtype)
endfunc
" Test for clipboard registers (* and +)
func Test_clipboard_regs()
throw 'skipped: needs clipboard=autoselect,autoselectplus'