neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit 2aab242a0110b6af80305f6fdf7db50c806113d9
parent 1e498b8f772c9d04fa18bd0251818506043bdf51
Author: zeertzjq <zeertzjq@outlook.com>
Date:   Sat, 27 Sep 2025 21:28:40 +0800

vim-patch:9.1.1798: Wrong display with 'sms' and long wrapped virt text at EOL (#35930)

Problem:  Wrong display with 'smoothscroll' and long wrapped virtual
          text at EOL.
Solution: Handle w_skipcol inside long wrapped virtual text at EOL
          (zeertzjq).

closes: vim/vim#18408

https://github.com/vim/vim/commit/d9318acc0223bafd3ed5e7f8cdde26328bf200e7
Diffstat:
Msrc/nvim/drawline.c | 5++++-
Mtest/functional/ui/decorations_spec.lua | 170+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 163 insertions(+), 12 deletions(-)

diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c @@ -1477,10 +1477,13 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b csarg.max_head_vcol = start_vcol; int vcol = wlv.vcol; StrCharInfo ci = utf_ptr2StrCharInfo(ptr); - while (vcol < start_vcol && *ci.ptr != NUL) { + while (vcol < start_vcol) { cs = win_charsize(cstype, vcol, ci.ptr, ci.chr.value, &csarg); vcol += cs.width; prev_ptr = ci.ptr; + if (*prev_ptr == NUL) { + break; + } ci = utfc_next(ci); if (wp->w_p_list) { in_multispace = *prev_ptr == ' ' && (*ci.ptr == ' ' diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua @@ -5665,53 +5665,201 @@ describe('decorations: inline virtual text', function() it('line size is correct with inline virt text at EOL and showbreak', function() screen:try_resize(50, 8) insert(('0123456789'):rep(5) .. '\nfoo\nbar') - api.nvim_buf_set_extmark(0, ns, 0, 50, { virt_text = { { ('x'):rep(49), 'ErrorMsg' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 50, { virt_text = { { ('x'):rep(145), 'ErrorMsg' } }, virt_text_pos = 'inline' }) - command([[set showbreak=>\ cursorline]]) + command([[set cursorline scrolloff=0 showbreak=>\ smoothscroll]]) screen:expect([[ 01234567890123456789012345678901234567890123456789| - {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}| + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}|*3 + {1:> }{4:x} | + foo | + {22:ba^r }| + | + ]]) + eq(5, api.nvim_win_text_height(0, { start_row = 0, end_row = 0 }).all) + feed('<C-E>') + screen:expect([[ + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}|*3 + {1:> }{4:x} | + foo | + {22:ba^r }| + {1:~ }| + | + ]]) + feed('<C-E>') + screen:expect([[ + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}|*2 {1:> }{4:x} | foo | {22:ba^r }| {1:~ }|*2 | ]]) - eq(3, api.nvim_win_text_height(0, { start_row = 0, end_row = 0 }).all) + feed('<C-E>') + screen:expect([[ + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}| + {1:> }{4:x} | + foo | + {22:ba^r }| + {1:~ }|*3 + | + ]]) + feed('<C-E>') + screen:expect([[ + {1:> }{4:x} | + foo | + {22:ba^r }| + {1:~ }|*4 + | + ]]) + feed('<C-E>') + screen:expect([[ + foo | + {22:ba^r }| + {1:~ }|*5 + | + ]]) - feed('gg$x<C-O>') + feed('gg$xG$') screen:expect([[ 0123456789012345678901234567890123456789012345678{4:x}| - {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}| + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}|*3 + foo | + {22:ba^r }| + {1:~ }| + | + ]]) + eq(4, api.nvim_win_text_height(0, { start_row = 0, end_row = 0 }).all) + feed('<C-E>') + screen:expect([[ + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}|*3 + foo | + {22:ba^r }| + {1:~ }|*2 + | + ]]) + feed('<C-E>') + screen:expect([[ + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}|*2 foo | {22:ba^r }| {1:~ }|*3 | ]]) - eq(2, api.nvim_win_text_height(0, { start_row = 0, end_row = 0 }).all) + feed('<C-E>') + screen:expect([[ + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}| + foo | + {22:ba^r }| + {1:~ }|*4 + | + ]]) + feed('<C-E>') + screen:expect([[ + foo | + {22:ba^r }| + {1:~ }|*5 + | + ]]) + feed('zb') command('set list listchars=eol:$') screen:expect([[ 0123456789012345678901234567890123456789012345678{4:x}| - {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}| + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}|*3 + {1:> $} | + foo{1:$} | + {22:ba^r}{23:$}{22: }| + | + ]]) + eq(5, api.nvim_win_text_height(0, { start_row = 0, end_row = 0 }).all) + feed('<C-E>') + screen:expect([[ + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}|*3 + {1:> $} | + foo{1:$} | + {22:ba^r}{23:$}{22: }| + {1:~ }| + | + ]]) + feed('<C-E>') + screen:expect([[ + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}|*2 {1:> $} | foo{1:$} | {22:ba^r}{23:$}{22: }| {1:~ }|*2 | ]]) - eq(3, api.nvim_win_text_height(0, { start_row = 0, end_row = 0 }).all) + feed('<C-E>') + screen:expect([[ + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}| + {1:> $} | + foo{1:$} | + {22:ba^r}{23:$}{22: }| + {1:~ }|*3 + | + ]]) + feed('<C-E>') + screen:expect([[ + {1:> $} | + foo{1:$} | + {22:ba^r}{23:$}{22: }| + {1:~ }|*4 + | + ]]) + feed('<C-E>') + screen:expect([[ + foo{1:$} | + {22:ba^r}{23:$}{22: }| + {1:~ }|*5 + | + ]]) - feed('gg$x<C-O>') + feed('gg$xG$') screen:expect([[ 012345678901234567890123456789012345678901234567{4:xx}| + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}|*2 + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}{1:$}| + foo{1:$} | + {22:ba^r}{23:$}{22: }| + {1:~ }| + | + ]]) + eq(4, api.nvim_win_text_height(0, { start_row = 0, end_row = 0 }).all) + feed('<C-E>') + screen:expect([[ + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}|*2 + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}{1:$}| + foo{1:$} | + {22:ba^r}{23:$}{22: }| + {1:~ }|*2 + | + ]]) + feed('<C-E>') + screen:expect([[ + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}| {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}{1:$}| foo{1:$} | {22:ba^r}{23:$}{22: }| {1:~ }|*3 | ]]) - eq(2, api.nvim_win_text_height(0, { start_row = 0, end_row = 0 }).all) + feed('<C-E>') + screen:expect([[ + {1:> }{4:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}{1:$}| + foo{1:$} | + {22:ba^r}{23:$}{22: }| + {1:~ }|*4 + | + ]]) + feed('<C-E>') + screen:expect([[ + foo{1:$} | + {22:ba^r}{23:$}{22: }| + {1:~ }|*5 + | + ]]) end) end)