commit 95dfb063daa709d303d0e37e86fbc8067950a830
parent 4fe51dfdae84f139bb92f8517aff914c4adb052c
Author: zeertzjq <zeertzjq@outlook.com>
Date: Wed, 23 Jul 2025 10:46:15 +0800
fix(clipboard): correct blockwise register width computation (#35038)
Diffstat:
3 files changed, 35 insertions(+), 11 deletions(-)
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
@@ -6519,10 +6519,17 @@ void finish_yankreg_from_object(yankreg_T *reg, bool clipboard_adjust)
}
}
+ update_yankreg_width(reg);
+}
+
+/// Updates the "y_width" of a blockwise register based on its contents.
+/// Do nothing on a non-blockwise register.
+static void update_yankreg_width(yankreg_T *reg)
+{
if (reg->y_type == kMTBlockWise) {
size_t maxlen = 0;
for (size_t i = 0; i < reg->y_size; i++) {
- size_t rowlen = reg->y_array[i].size;
+ size_t rowlen = mb_string2cells_len(reg->y_array[i].data, reg->y_array[i].size);
maxlen = MAX(maxlen, rowlen);
}
assert(maxlen <= INT_MAX);
@@ -6624,15 +6631,7 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
}
}
- if (reg->y_type == kMTBlockWise) {
- size_t maxlen = 0;
- for (size_t i = 0; i < reg->y_size; i++) {
- size_t rowlen = reg->y_array[i].size;
- maxlen = MAX(maxlen, rowlen);
- }
- assert(maxlen <= INT_MAX);
- reg->y_width = (int)maxlen - 1;
- }
+ update_yankreg_width(reg);
*target = reg;
return true;
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
@@ -1573,6 +1573,17 @@ describe('API', function()
eq("Invalid 'type': 'bx'", pcall_err(api.nvim_put, { 'xxx', 'yyy' }, 'bx', false, true))
eq("Invalid 'type': 'b3x'", pcall_err(api.nvim_put, { 'xxx', 'yyy' }, 'b3x', false, true))
end)
+
+ it('computes block width correctly when not specified #35034', function()
+ api.nvim_put({ 'line 1', 'line 2', 'line 3' }, 'l', false, false)
+ -- block width should be 4
+ api.nvim_put({ 'あい', 'xxx', 'xx' }, 'b', false, false)
+ expect([[
+ あいline 1
+ xxx line 2
+ xx line 3
+ ]])
+ end)
end)
describe('nvim_strwidth', function()
diff --git a/test/functional/provider/clipboard_spec.lua b/test/functional/provider/clipboard_spec.lua
@@ -537,7 +537,7 @@ describe('clipboard (with fake clipboard.vim)', function()
eq('textstar', api.nvim_get_current_line())
end)
- it('Block paste works correctly', function()
+ it('block paste works correctly', function()
insert([[
aabbcc
ddeeff
@@ -550,6 +550,20 @@ describe('clipboard (with fake clipboard.vim)', function()
ddeeddeeff
]])
end)
+
+ it('block paste computes block width correctly #35034', function()
+ insert('あいうえお')
+ feed('0<C-V>ly')
+ feed('P')
+ expect('あいあいうえお')
+ feed('A\nxxx\nxx<Esc>')
+ feed('0<C-V>kkly')
+ feed('P')
+ expect([[
+ あいあいあいうえお
+ xxx xxx
+ xx xx]])
+ end)
end)
describe('clipboard=unnamedplus', function()