From 1eec08d1a24e9fe705c6c11624607f03dbe358f8 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 21 Nov 2025 08:02:20 +0800 Subject: [PATCH] vim-patch:9.1.1922: Wrong virtcol('$') with virtual text at EOL (#36643) Problem: Wrong virtcol('$') with virtual text at EOL (rickhowe). Solution: Also add 1 to end virtcol when there is virtual text. (zeertzjq) fixes: vim/vim#18761 closes: vim/vim#18762 https://github.com/vim/vim/commit/d434f6c2a571e1fda0582986c28a488e1dce8fff --- src/nvim/plines.c | 5 +++-- test/functional/ui/decorations_spec.lua | 11 +++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/nvim/plines.c b/src/nvim/plines.c index 655a0ee002..389af69849 100644 --- a/src/nvim/plines.c +++ b/src/nvim/plines.c @@ -551,9 +551,10 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en } else { while (true) { char_size = charsize_regular(&csarg, ci.ptr, vcol, ci.chr.value); + // make sure we don't go past the end of the line if (*ci.ptr == NUL) { - // if cursor is at NUL, it is treated like 1 cell char unless there is virtual text - char_size.width = MAX(1, csarg.cur_text_width_left + csarg.cur_text_width_right); + // NUL at end of line only takes one column unless there is virtual text + char_size.width = 1 + csarg.cur_text_width_left + csarg.cur_text_width_right; on_NUL = true; break; } diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index 070c21de9d..51cc3ea7b1 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -5872,6 +5872,17 @@ describe('decorations: inline virtual text', function() | ]]) end) + + it("virtcol('$') is correct with inline virt text at EOL", function() + insert(('1234567890\n'):rep(6)) + for _, v in ipairs({ { 2, 'a' }, { 3, 'ab' }, { 4, 'abc' }, { 5, 'abcd' }, { 6, 'αβγ口' } }) do + local ln, tx = unpack(v) + local co = fn.col({ ln, '$' }) + eq(11, fn.virtcol({ ln, '$' })) + api.nvim_buf_set_extmark(0, ns, ln - 1, co - 1, { virt_text = { { tx } }, virt_text_pos = 'inline' }) + eq(11 + fn.strwidth(tx), fn.virtcol({ ln, '$' })) + end + end) end) describe('decorations: virtual lines', function()