summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-09-24 23:32:18 +0200
committerChristian Brabandt <cb@256bit.org>2023-09-24 23:32:18 +0200
commitabc808112ee5df58a9f612f2bb5a65389c2c14e1 (patch)
tree2af294f535b972a9da4430e3b56a82fbc1714878
parent46a0582ffa4ea79b112ac01e25adccf93b49cd9d (diff)
patch 9.0.1938: multispace wrong when scrolling horizontallyv9.0.1938
Problem: multispace wrong when scrolling horizontally Solution: Update position in "multispace" or "leadmultispace" also in skipped chars. Reorder conditions to be more consistent. closes: #13145 closes: #13147 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: zeertzjq <zeertzjq@outlook.com>
-rw-r--r--src/drawline.c34
-rw-r--r--src/message.c15
-rw-r--r--src/testdir/test_listchars.vim203
-rw-r--r--src/version.c2
4 files changed, 129 insertions, 125 deletions
diff --git a/src/drawline.c b/src/drawline.c
index 95ea3f025a..4d63fae34d 100644
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -1684,6 +1684,27 @@ win_line(
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_lcs_chars.multispace != NULL)
+ {
+ ++multispace_pos;
+ if (wp->w_lcs_chars.multispace[multispace_pos] == NUL)
+ multispace_pos = 0;
+ }
+ else if (cts.cts_ptr < line + leadcol
+ && wp->w_lcs_chars.leadmultispace != NULL)
+ {
+ ++multispace_pos;
+ if (wp->w_lcs_chars.leadmultispace[multispace_pos] == NUL)
+ multispace_pos = 0;
+ }
+ }
}
wlv.vcol = cts.cts_vcol;
ptr = cts.cts_ptr;
@@ -2589,9 +2610,7 @@ win_line(
#ifdef FEAT_LINEBREAK
int c0;
#endif
-#ifdef FEAT_SPELL
char_u *prev_ptr = ptr;
-#endif
// Get a character from the line itself.
c = *ptr;
@@ -2941,10 +2960,13 @@ win_line(
}
}
#endif
- 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'
// setting in 'listchars'. But not when the character is
diff --git a/src/message.c b/src/message.c
index 98a362411e..2fc6cefa9d 100644
--- a/src/message.c
+++ b/src/message.c
@@ -2005,10 +2005,13 @@ msg_prt_line(char_u *s, int list)
{
attr = 0;
c = *s++;
- in_multispace = c == ' '
- && ((col > 0 && s[-2] == ' ') || *s == ' ');
- if (!in_multispace)
- multispace_pos = 0;
+ if (list)
+ {
+ in_multispace = c == ' ' && (*s == ' '
+ || (col > 0 && s[-2] == ' '));
+ if (!in_multispace)
+ multispace_pos = 0;
+ }
if (c == TAB && (!list || curwin->w_lcs_chars.tab1))
{
// tab amount depends on current column
@@ -2062,7 +2065,7 @@ msg_prt_line(char_u *s, int list)
}
else if (c == ' ')
{
- if (list && lead != NULL && s <= lead && in_multispace
+ if (lead != NULL && s <= lead && in_multispace
&& curwin->w_lcs_chars.leadmultispace != NULL)
{
c = curwin->w_lcs_chars.leadmultispace[multispace_pos++];
@@ -2082,7 +2085,7 @@ msg_prt_line(char_u *s, int list)
c = curwin->w_lcs_chars.trail;
attr = HL_ATTR(HLF_8);
}
- else if (list && in_multispace
+ else if (in_multispace
&& curwin->w_lcs_chars.multispace != NULL)
{
c = curwin->w_lcs_chars.multispace[multispace_pos++];
diff --git a/src/testdir/test_listchars.vim b/src/testdir/test_listchars.vim
index 2f495c3ab1..8628fb20e0 100644
--- a/src/testdir/test_listchars.vim
+++ b/src/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&
diff --git a/src/version.c b/src/version.c
index 7978aa0bf0..16e3e8a359 100644
--- a/src/version.c
+++ b/src/version.c
@@ -700,6 +700,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1938,
+/**/
1937,
/**/
1936,