diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-09-25 06:31:52 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-25 06:31:52 +0800 |
commit | 7d4967547b2793a29f9bd602ec6819458be1bd49 (patch) | |
tree | cd405ae99d784613e2222bdf14c24a9b794b9915 | |
parent | 9154fc76b740c4b61ad78a1cb7620c7e1b6d0494 (diff) | |
download | rneovim-7d4967547b2793a29f9bd602ec6819458be1bd49.tar.gz rneovim-7d4967547b2793a29f9bd602ec6819458be1bd49.tar.bz2 rneovim-7d4967547b2793a29f9bd602ec6819458be1bd49.zip |
vim-patch:9.0.1938: multispace wrong when scrolling horizontally (#25348)
Problem: multispace wrong when scrolling horizontally
Solution: Update position in "multispace" or "leadmultispace" also in
skipped chars. Reorder conditions to be more consistent.
closes: vim/vim#13145
closes: vim/vim#13147
https://github.com/vim/vim/commit/abc808112ee5df58a9f612f2bb5a65389c2c14e1
-rw-r--r-- | src/nvim/drawline.c | 28 | ||||
-rw-r--r-- | src/nvim/message.c | 15 | ||||
-rw-r--r-- | test/old/testdir/test_listchars.vim | 203 |
3 files changed, 124 insertions, 122 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 7d64d9fa3c..1e5798db32 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -1539,6 +1539,25 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl cts.cts_vcol += charsize; prev_ptr = cts.cts_ptr; MB_PTR_ADV(cts.cts_ptr); + if (wp->w_p_list) { + in_multispace = *prev_ptr == ' ' && (*cts.cts_ptr == ' ' + || (prev_ptr > line && prev_ptr[-1] == ' ')); + if (!in_multispace) { + multispace_pos = 0; + } else if (cts.cts_ptr >= line + leadcol + && wp->w_p_lcs_chars.multispace != NULL) { + multispace_pos++; + if (wp->w_p_lcs_chars.multispace[multispace_pos] == NUL) { + multispace_pos = 0; + } + } else if (cts.cts_ptr < line + leadcol + && wp->w_p_lcs_chars.leadmultispace != NULL) { + multispace_pos++; + if (wp->w_p_lcs_chars.leadmultispace[multispace_pos] == NUL) { + multispace_pos = 0; + } + } + } } wlv.vcol = cts.cts_vcol; ptr = cts.cts_ptr; @@ -2367,9 +2386,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl } } - in_multispace = c == ' ' && ((ptr > line + 1 && ptr[-2] == ' ') || *ptr == ' '); - if (!in_multispace) { - multispace_pos = 0; + if (wp->w_p_list) { + in_multispace = c == ' ' && (*ptr == ' ' + || (prev_ptr > line && prev_ptr[-1] == ' ')); + if (!in_multispace) { + multispace_pos = 0; + } } // 'list': Change char 160 to 'nbsp' and space to 'space'. diff --git a/src/nvim/message.c b/src/nvim/message.c index 98e5a231b8..ad78092cac 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1907,10 +1907,13 @@ void msg_prt_line(const char *s, int list) continue; } else { attr = 0; - c = (unsigned char)(*s++); - in_multispace = c == ' ' && ((col > 0 && s[-2] == ' ') || *s == ' '); - if (!in_multispace) { - multispace_pos = 0; + c = (uint8_t)(*s++); + if (list) { + in_multispace = c == ' ' && (*s == ' ' + || (col > 0 && s[-2] == ' ')); + if (!in_multispace) { + multispace_pos = 0; + } } if (c == TAB && (!list || curwin->w_p_lcs_chars.tab1)) { // tab amount depends on current column @@ -1950,7 +1953,7 @@ void msg_prt_line(const char *s, int list) // the same in plain text. attr = HL_ATTR(HLF_0); } else if (c == ' ') { - if (list && lead != NULL && s <= lead && in_multispace + if (lead != NULL && s <= lead && in_multispace && curwin->w_p_lcs_chars.leadmultispace != NULL) { c = curwin->w_p_lcs_chars.leadmultispace[multispace_pos++]; if (curwin->w_p_lcs_chars.leadmultispace[multispace_pos] == NUL) { @@ -1963,7 +1966,7 @@ void msg_prt_line(const char *s, int list) } else if (trail != NULL && s > trail) { c = curwin->w_p_lcs_chars.trail; attr = HL_ATTR(HLF_0); - } else if (list && in_multispace + } else if (in_multispace && curwin->w_p_lcs_chars.multispace != NULL) { c = curwin->w_p_lcs_chars.multispace[multispace_pos++]; if (curwin->w_p_lcs_chars.multispace[multispace_pos] == NUL) { diff --git a/test/old/testdir/test_listchars.vim b/test/old/testdir/test_listchars.vim index 69f1df3098..5366f503fc 100644 --- a/test/old/testdir/test_listchars.vim +++ b/test/old/testdir/test_listchars.vim @@ -4,6 +4,36 @@ source check.vim source view_util.vim source screendump.vim +func Check_listchars(expected, end_lnum, end_scol = -1, leftcol = 0) + if a:leftcol > 0 + let save_wrap = &wrap + set nowrap + call cursor(1, 1) + exe 'normal! ' .. a:leftcol .. 'zl' + endif + + redraw! + for i in range(1, a:end_lnum) + if a:leftcol > 0 + let col = virtcol2col(0, i, a:leftcol) + let col += getline(i)->strpart(col - 1, 1, v:true)->len() + call cursor(i, col) + redraw + call assert_equal(a:leftcol, winsaveview().leftcol) + else + call cursor(i, 1) + end + + let end_scol = a:end_scol < 0 ? '$'->virtcol() - a:leftcol : a:end_scol + call assert_equal([a:expected[i - 1]->strcharpart(a:leftcol)], + \ ScreenLines(i, end_scol)) + endfor + + if a:leftcol > 0 + let &wrap = save_wrap + endif +endfunc + func Test_listchars() enew! set ff=unix @@ -24,11 +54,8 @@ func Test_listchars() \ 'dd........ee<<>-$', \ '<$' \ ] - redraw! - for i in range(1, 5) - call cursor(i, 1) - call assert_equal([expected[i - 1]], ScreenLines(i, '$'->virtcol())) - endfor + call Check_listchars(expected, 5) + call Check_listchars(expected, 4, -1, 5) set listchars-=trail:< let expected = [ @@ -38,11 +65,8 @@ func Test_listchars() \ 'dd........ee..>-$', \ '.$' \ ] - redraw! - for i in range(1, 5) - call cursor(i, 1) - call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) - endfor + call Check_listchars(expected, 5) + call Check_listchars(expected, 4, -1, 5) " tab with 3rd character. set listchars-=tab:>- @@ -54,11 +78,8 @@ func Test_listchars() \ 'dd........ee--<>$', \ '-$' \ ] - redraw! - for i in range(1, 5) - call cursor(i, 1) - call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) - endfor + call Check_listchars(expected, 5) + call Check_listchars(expected, 4, -1, 5) " tab with 3rd character and linebreak set set listchars-=tab:<=> @@ -71,11 +92,7 @@ func Test_listchars() \ 'dd........ee--<>$', \ '-$' \ ] - redraw! - for i in range(1, 5) - call cursor(i, 1) - call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) - endfor + call Check_listchars(expected, 5) set nolinebreak set listchars-=tab:<·> set listchars+=tab:<=> @@ -88,11 +105,8 @@ func Test_listchars() \ 'dd........ee..<>$', \ '.$' \ ] - redraw! - for i in range(1, 5) - call cursor(i, 1) - call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) - endfor + call Check_listchars(expected, 5) + call Check_listchars(expected, 4, -1, 5) set listchars-=tab:<=> set listchars+=tab:>- @@ -110,7 +124,8 @@ func Test_listchars() \ '..fff>--<<$', \ '>-------gg>-----$', \ '.....h>-$', - \ 'iii<<<<><<$', '$'], l) + \ 'iii<<<<><<$', + \ '$'], l) " Test lead and trail normal ggdG @@ -132,14 +147,10 @@ func Test_listchars() \ 'h<<<<<<<<<<<$', \ '<<<<<<<<<<<<$', \ '>>>>0xx0<<<<$', - \ '$' + \ '$' \ ] - redraw! - for i in range(1, 5) - call cursor(i, 1) - call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) - endfor - + call Check_listchars(expected, 6) + call Check_listchars(expected, 5, -1, 6) call assert_equal(expected, split(execute("%list"), "\n")) " Test multispace @@ -162,14 +173,10 @@ func Test_listchars() \ ' hyYzZyYzZyY$', \ 'yYzZyYzZyYj $', \ 'yYzZ0yY0yYzZ$', - \ '$' + \ '$' \ ] - redraw! - for i in range(1, 5) - call cursor(i, 1) - call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) - endfor - + call Check_listchars(expected, 6) + call Check_listchars(expected, 5, -1, 6) call assert_equal(expected, split(execute("%list"), "\n")) " Test leadmultispace + multispace @@ -192,15 +199,14 @@ func Test_listchars() \ ' hyYzZyYzZyY$', \ '.-+*.-+*.-j $', \ '.-+*0yY0yYzZ$', - \ '$' + \ '$' \ ] - redraw! call assert_equal('eol:$,multispace:yYzZ,nbsp:S,leadmultispace:.-+*', &listchars) - for i in range(1, 5) - call cursor(i, 1) - call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) - endfor - + call Check_listchars(expected, 6) + call Check_listchars(expected, 5, -1, 1) + call Check_listchars(expected, 5, -1, 2) + call Check_listchars(expected, 5, -1, 3) + call Check_listchars(expected, 5, -1, 6) call assert_equal(expected, split(execute("%list"), "\n")) " Test leadmultispace without multispace @@ -223,16 +229,14 @@ func Test_listchars() \ '+h>>>>>>>>>>$', \ '.-+*.-+*.-j>$', \ '.-+*0++0>>>>$', - \ '$', + \ '$' \ ] - - redraw! call assert_equal('eol:$,nbsp:S,leadmultispace:.-+*,space:+,trail:>,eol:$', &listchars) - for i in range(1, 5) - call cursor(i, 1) - call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) - endfor - + call Check_listchars(expected, 6) + call Check_listchars(expected, 5, -1, 1) + call Check_listchars(expected, 5, -1, 2) + call Check_listchars(expected, 5, -1, 3) + call Check_listchars(expected, 5, -1, 6) call assert_equal(expected, split(execute("%list"), "\n")) " Test leadmultispace only @@ -255,14 +259,10 @@ func Test_listchars() \ ' h ', \ '.-+*.-+*.-j ', \ '.-+*0 0 ', - \ ' ', + \ ' ' \ ] - redraw! call assert_equal('leadmultispace:.-+*', &listchars) - for i in range(1, 5) - call cursor(i, 1) - call assert_equal([expected[i - 1]], ScreenLines(i, 12)) - endfor + call Check_listchars(expected, 5, 12) call assert_equal(expected, split(execute("%list"), "\n")) " Test leadmultispace and lead and space @@ -286,14 +286,14 @@ func Test_listchars() \ '<h----------$', \ '.-+*.-+*.-j-$', \ '.-+*0--0----$', - \ '$', + \ '$' \ ] - redraw! call assert_equal('eol:$,lead:<,space:-,leadmultispace:.-+*', &listchars) - for i in range(1, 5) - call cursor(i, 1) - call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) - endfor + call Check_listchars(expected, 6) + call Check_listchars(expected, 5, -1, 1) + call Check_listchars(expected, 5, -1, 2) + call Check_listchars(expected, 5, -1, 3) + call Check_listchars(expected, 5, -1, 6) call assert_equal(expected, split(execute("%list"), "\n")) " the last occurrence of 'multispace:' is used @@ -307,15 +307,11 @@ func Test_listchars() \ 'xhXyYXyYXyYX$', \ 'XyYXyYXyYXjx$', \ 'XyYX0Xy0XyYX$', - \ '$' + \ '$' \ ] - redraw! call assert_equal('eol:$,multispace:yYzZ,space:x,multispace:XyY', &listchars) - for i in range(1, 5) - call cursor(i, 1) - call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) - endfor - + call Check_listchars(expected, 6) + call Check_listchars(expected, 5, -1, 6) call assert_equal(expected, split(execute("%list"), "\n")) set listchars+=lead:>,trail:< @@ -326,14 +322,10 @@ func Test_listchars() \ '>h<<<<<<<<<<$', \ '>>>>>>>>>>j<$', \ '>>>>0Xy0<<<<$', - \ '$' + \ '$' \ ] - redraw! - for i in range(1, 5) - call cursor(i, 1) - call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) - endfor - + call Check_listchars(expected, 6) + call Check_listchars(expected, 5, -1, 6) call assert_equal(expected, split(execute("%list"), "\n")) " removing 'multispace:' @@ -346,14 +338,10 @@ func Test_listchars() \ '>h<<<<<<<<<<$', \ '>>>>>>>>>>j<$', \ '>>>>0xx0<<<<$', - \ '$' + \ '$' \ ] - redraw! - for i in range(1, 5) - call cursor(i, 1) - call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) - endfor - + call Check_listchars(expected, 6) + call Check_listchars(expected, 5, -1, 6) call assert_equal(expected, split(execute("%list"), "\n")) " test nbsp @@ -365,15 +353,10 @@ func Test_listchars() call append(0, [ ">" .. nbsp .. "<" ]) let expected = '>X< ' - - redraw! - call cursor(1, 1) - call assert_equal([expected], ScreenLines(1, virtcol('$'))) + call Check_listchars([expected], 1) set listchars=nbsp:X - redraw! - call cursor(1, 1) - call assert_equal([expected], ScreenLines(1, virtcol('$'))) + call Check_listchars([expected], 1) " test extends normal ggdG @@ -383,16 +366,11 @@ func Test_listchars() call append(0, [ repeat('A', &columns + 1) ]) let expected = repeat('A', &columns) - - redraw! - call cursor(1, 1) - call assert_equal([expected], ScreenLines(1, &columns)) + call Check_listchars([expected], 1, &columns) set list let expected = expected[:-2] . 'Z' - redraw! - call cursor(1, 1) - call assert_equal([expected], ScreenLines(1, &columns)) + call Check_listchars([expected], 1, &columns) enew! set listchars& ff& @@ -411,19 +389,20 @@ func Test_listchars_unicode() let nbsp = nr2char(0xa0) call append(0, [" a\tb c" .. nbsp .. "d "]) let expected = ['≡≢≣≡≢≣≡≢a←↔↔↔↔↔→b␣c≠d≡≢⇔'] - redraw! - call cursor(1, 1) - call assert_equal(expected, ScreenLines(1, virtcol('$'))) + call Check_listchars(expected, 1) + call Check_listchars(expected, 1, -1, 3) + call Check_listchars(expected, 1, -1, 13) set listchars=eol:\\u21d4,space:\\u2423,multispace:≡\\u2262\\U00002263,nbsp:\\U00002260,tab:←↔\\u2192 - redraw! - call assert_equal(expected, ScreenLines(1, virtcol('$'))) + call Check_listchars(expected, 1) + call Check_listchars(expected, 1, -1, 3) + call Check_listchars(expected, 1, -1, 13) set listchars+=lead:⇨,trail:⇦ let expected = ['⇨⇨⇨⇨⇨⇨⇨⇨a←↔↔↔↔↔→b␣c≠d⇦⇦⇔'] - redraw! - call cursor(1, 1) - call assert_equal(expected, ScreenLines(1, virtcol('$'))) + call Check_listchars(expected, 1) + call Check_listchars(expected, 1, -1, 3) + call Check_listchars(expected, 1, -1, 13) let &encoding=oldencoding enew! @@ -515,9 +494,7 @@ func Test_listchars_composing() let expected = [ \ "_ \u3099^I \u309A=" .. nbsp1 .. "\u0302=" .. nbsp2 .. "\u0302$" \ ] - redraw! - call cursor(1, 1) - call assert_equal(expected, ScreenLines(1, virtcol('$'))) + call Check_listchars(expected, 1) let &encoding=oldencoding enew! set listchars& ff& |