neovim

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

test_listchars.vim (25472B)


      1 " Tests for 'listchars' display with 'list' and :list
      2 
      3 source check.vim
      4 source view_util.vim
      5 source screendump.vim
      6 
      7 func Check_listchars(expected, end_lnum, end_scol = -1, leftcol = 0)
      8  if a:leftcol > 0
      9    let save_wrap = &wrap
     10    set nowrap
     11    call cursor(1, 1)
     12    exe 'normal! ' .. a:leftcol .. 'zl'
     13  endif
     14 
     15  redraw!
     16  for i in range(1, a:end_lnum)
     17    if a:leftcol > 0
     18      let col = virtcol2col(0, i, a:leftcol)
     19      let col += getline(i)->strpart(col - 1, 1, v:true)->len()
     20      call cursor(i, col)
     21      redraw
     22      call assert_equal(a:leftcol, winsaveview().leftcol)
     23    else
     24      call cursor(i, 1)
     25    end
     26 
     27    let end_scol = a:end_scol < 0 ? '$'->virtcol() - a:leftcol : a:end_scol
     28    call assert_equal([a:expected[i - 1]->strcharpart(a:leftcol)],
     29          \ ScreenLines(i, end_scol))
     30  endfor
     31 
     32  if a:leftcol > 0
     33    let &wrap = save_wrap
     34  endif
     35 endfunc
     36 
     37 func Test_listchars()
     38  enew!
     39  set ff=unix
     40  set list
     41 
     42  set listchars+=tab:>-,space:.,trail:<
     43  call append(0, [
     44       \ '	aa	',
     45       \ '  bb	  ',
     46       \ '   cccc	 ',
     47       \ 'dd        ee  	',
     48       \ ' '
     49       \ ])
     50  let expected = [
     51       \ '>-------aa>-----$',
     52       \ '..bb>---<<$',
     53       \ '...cccc><$',
     54       \ 'dd........ee<<>-$',
     55       \ '<$'
     56       \ ]
     57  call Check_listchars(expected, 5)
     58  call Check_listchars(expected, 4, -1, 5)
     59 
     60  set listchars-=trail:<
     61  let expected = [
     62       \ '>-------aa>-----$',
     63       \ '..bb>---..$',
     64       \ '...cccc>.$',
     65       \ 'dd........ee..>-$',
     66       \ '.$'
     67       \ ]
     68  call Check_listchars(expected, 5)
     69  call Check_listchars(expected, 4, -1, 5)
     70 
     71  " tab with 3rd character.
     72  set listchars-=tab:>-
     73  set listchars+=tab:<=>,trail:-
     74  let expected = [
     75       \ '<======>aa<====>$',
     76       \ '..bb<==>--$',
     77       \ '...cccc>-$',
     78       \ 'dd........ee--<>$',
     79       \ '-$'
     80       \ ]
     81  call Check_listchars(expected, 5)
     82  call Check_listchars(expected, 4, -1, 5)
     83 
     84  " tab with 3rd character and linebreak set
     85  set listchars-=tab:<=>
     86  set listchars+=tab:<·>
     87  set linebreak
     88  let expected = [
     89       \ '<······>aa<····>$',
     90       \ '..bb<··>--$',
     91       \ '...cccc>-$',
     92       \ 'dd........ee--<>$',
     93       \ '-$'
     94       \ ]
     95  call Check_listchars(expected, 5)
     96  set nolinebreak
     97  set listchars-=tab:<·>
     98  set listchars+=tab:<=>
     99 
    100  set listchars-=trail:-
    101  let expected = [
    102       \ '<======>aa<====>$',
    103       \ '..bb<==>..$',
    104       \ '...cccc>.$',
    105       \ 'dd........ee..<>$',
    106       \ '.$'
    107       \ ]
    108  call Check_listchars(expected, 5)
    109  call Check_listchars(expected, 4, -1, 5)
    110 
    111  set listchars-=tab:<=>
    112  set listchars+=tab:>-
    113  set listchars+=trail:<
    114  set nolist
    115  normal ggdG
    116  call append(0, [
    117       \ '  fff	  ',
    118       \ '	gg	',
    119       \ '     h	',
    120       \ 'iii    	  ',
    121       \ ])
    122  let l = split(execute("%list"), "\n")
    123  call assert_equal([
    124       \ '..fff>--<<$',
    125       \ '>-------gg>-----$',
    126       \ '.....h>-$',
    127       \ 'iii<<<<><<$',
    128       \ '$'], l)
    129 
    130  " Test lead and trail
    131  normal ggdG
    132  set listchars=eol:$  " Accommodate Nvim default
    133  set listchars+=lead:>,trail:<,space:x
    134  set list
    135 
    136  call append(0, [
    137       \ '    ffff    ',
    138       \ '          gg',
    139       \ 'h           ',
    140       \ '            ',
    141       \ '    0  0    ',
    142       \ ])
    143 
    144  let expected = [
    145       \ '>>>>ffff<<<<$',
    146       \ '>>>>>>>>>>gg$',
    147       \ 'h<<<<<<<<<<<$',
    148       \ '<<<<<<<<<<<<$',
    149       \ '>>>>0xx0<<<<$',
    150       \ '$'
    151       \ ]
    152  call Check_listchars(expected, 6)
    153  call Check_listchars(expected, 5, -1, 6)
    154  call assert_equal(expected, split(execute("%list"), "\n"))
    155 
    156  " In a line with only spaces, they aren't considered leading even if "trail"
    157  " isn't set.
    158  set listchars-=trail:<
    159  let expected = [
    160       \ '>>>>ffffxxxx$',
    161       \ '>>>>>>>>>>gg$',
    162       \ 'hxxxxxxxxxxx$',
    163       \ 'xxxxxxxxxxxx$',
    164       \ '>>>>0xx0xxxx$',
    165       \ '$'
    166       \ ]
    167  call Check_listchars(expected, 6)
    168  call Check_listchars(expected, 5, -1, 6)
    169  call assert_equal(expected, split(execute("%list"), "\n"))
    170 
    171  " Test multispace
    172  normal ggdG
    173  set listchars=eol:$  " Accommodate Nvim default
    174  set listchars+=multispace:yYzZ
    175  set list
    176 
    177  call append(0, [
    178       \ '    ffff    ',
    179       \ '  i i     gg',
    180       \ ' h          ',
    181       \ '            ',
    182       \ '          j ',
    183       \ '    0  0    ',
    184       \ ])
    185 
    186  let expected = [
    187       \ 'yYzZffffyYzZ$',
    188       \ 'yYi iyYzZygg$',
    189       \ ' hyYzZyYzZyY$',
    190       \ 'yYzZyYzZyYzZ$',
    191       \ 'yYzZyYzZyYj $',
    192       \ 'yYzZ0yY0yYzZ$',
    193       \ '$'
    194       \ ]
    195  call Check_listchars(expected, 7)
    196  call Check_listchars(expected, 6, -1, 6)
    197  call assert_equal(expected, split(execute("%list"), "\n"))
    198 
    199  " Test leadmultispace + multispace
    200  normal ggdG
    201  set listchars=eol:$,multispace:yYzZ,nbsp:S
    202  set listchars+=leadmultispace:.-+*
    203  set list
    204 
    205  call append(0, [
    206       \ '    ffff    ',
    207       \ '  i i     gg',
    208       \ ' h          ',
    209       \ '            ',
    210       \ '          j ',
    211       \ '    0  0    ',
    212       \ ])
    213 
    214  let expected = [
    215       \ '.-+*ffffyYzZ$',
    216       \ '.-i iSyYzZgg$',
    217       \ ' hyYzZyYzZyY$',
    218       \ 'yYzZyYzZyYzZ$',
    219       \ '.-+*.-+*.-j $',
    220       \ '.-+*0yY0yYzZ$',
    221       \ '$'
    222       \ ]
    223  call assert_equal('eol:$,multispace:yYzZ,nbsp:S,leadmultispace:.-+*', &listchars)
    224  call Check_listchars(expected, 7)
    225  call Check_listchars(expected, 6, -1, 1)
    226  call Check_listchars(expected, 6, -1, 2)
    227  call Check_listchars(expected, 6, -1, 3)
    228  call Check_listchars(expected, 6, -1, 6)
    229  call assert_equal(expected, split(execute("%list"), "\n"))
    230 
    231  " Test leadmultispace without multispace
    232  normal ggdG
    233  set listchars-=multispace:yYzZ
    234  set listchars+=space:+,trail:>,eol:$
    235  set list
    236 
    237  call append(0, [
    238       \ '    ffff    ',
    239       \ '  i i     gg',
    240       \ ' h          ',
    241       \ '            ',
    242       \ '          j ',
    243       \ '    0  0    ',
    244       \ ])
    245 
    246  let expected = [
    247       \ '.-+*ffff>>>>$',
    248       \ '.-i+i+++++gg$',
    249       \ '+h>>>>>>>>>>$',
    250       \ '>>>>>>>>>>>>$',
    251       \ '.-+*.-+*.-j>$',
    252       \ '.-+*0++0>>>>$',
    253       \ '$'
    254       \ ]
    255  call assert_equal('eol:$,nbsp:S,leadmultispace:.-+*,space:+,trail:>,eol:$', &listchars)
    256  call Check_listchars(expected, 7)
    257  call Check_listchars(expected, 6, -1, 1)
    258  call Check_listchars(expected, 6, -1, 2)
    259  call Check_listchars(expected, 6, -1, 3)
    260  call Check_listchars(expected, 6, -1, 6)
    261  call assert_equal(expected, split(execute("%list"), "\n"))
    262 
    263  " Test leadmultispace only
    264  normal ggdG
    265  set listchars=eol:$  " Accommodate Nvim default
    266  set listchars=leadmultispace:.-+*
    267  set list
    268 
    269  call append(0, [
    270       \ '    ffff    ',
    271       \ '  i i     gg',
    272       \ ' h          ',
    273       \ '            ',
    274       \ '          j ',
    275       \ '    0  0    ',
    276       \ ])
    277 
    278  let expected = [
    279       \ '.-+*ffff    ',
    280       \ '.-i i     gg',
    281       \ ' h          ',
    282       \ '            ',
    283       \ '.-+*.-+*.-j ',
    284       \ '.-+*0  0    ',
    285       \ ' '
    286       \ ]
    287  call assert_equal('leadmultispace:.-+*', &listchars)
    288  call Check_listchars(expected, 6, 12)
    289  call assert_equal(expected, split(execute("%list"), "\n"))
    290 
    291  " Changing the value of 'ambiwidth' twice shouldn't cause double-free when
    292  " "leadmultispace" is specified.
    293  set ambiwidth=double
    294  set ambiwidth&
    295 
    296  " Test leadmultispace and lead and space
    297  normal ggdG
    298  set listchars=eol:$  " Accommodate Nvim default
    299  set listchars+=lead:<,space:-
    300  set listchars+=leadmultispace:.-+*
    301  set list
    302 
    303  call append(0, [
    304       \ '    ffff    ',
    305       \ '  i i     gg',
    306       \ ' h          ',
    307       \ '            ',
    308       \ '          j ',
    309       \ '    0  0    ',
    310       \ ])
    311 
    312  let expected = [
    313       \ '.-+*ffff----$',
    314       \ '.-i-i-----gg$',
    315       \ '<h----------$',
    316       \ '------------$',
    317       \ '.-+*.-+*.-j-$',
    318       \ '.-+*0--0----$',
    319       \ '$'
    320       \ ]
    321  call assert_equal('eol:$,lead:<,space:-,leadmultispace:.-+*', &listchars)
    322  call Check_listchars(expected, 7)
    323  call Check_listchars(expected, 6, -1, 1)
    324  call Check_listchars(expected, 6, -1, 2)
    325  call Check_listchars(expected, 6, -1, 3)
    326  call Check_listchars(expected, 6, -1, 6)
    327  call assert_equal(expected, split(execute("%list"), "\n"))
    328 
    329  " the last occurrence of 'multispace:' is used
    330  set listchars=eol:$  " Accommodate Nvim default
    331  set listchars+=multispace:yYzZ
    332  set listchars+=space:x,multispace:XyY
    333 
    334  let expected = [
    335       \ 'XyYXffffXyYX$',
    336       \ 'XyixiXyYXygg$',
    337       \ 'xhXyYXyYXyYX$',
    338       \ 'XyYXyYXyYXyY$',
    339       \ 'XyYXyYXyYXjx$',
    340       \ 'XyYX0Xy0XyYX$',
    341       \ '$'
    342       \ ]
    343  call assert_equal('eol:$,multispace:yYzZ,space:x,multispace:XyY', &listchars)
    344  call Check_listchars(expected, 7)
    345  call Check_listchars(expected, 6, -1, 6)
    346  call assert_equal(expected, split(execute("%list"), "\n"))
    347 
    348  set listchars+=lead:>,trail:<
    349 
    350  let expected = [
    351       \ '>>>>ffff<<<<$',
    352       \ '>>ixiXyYXygg$',
    353       \ '>h<<<<<<<<<<$',
    354       \ '<<<<<<<<<<<<$',
    355       \ '>>>>>>>>>>j<$',
    356       \ '>>>>0Xy0<<<<$',
    357       \ '$'
    358       \ ]
    359  call Check_listchars(expected, 7)
    360  call Check_listchars(expected, 6, -1, 6)
    361  call assert_equal(expected, split(execute("%list"), "\n"))
    362 
    363  " removing 'multispace:'
    364  set listchars-=multispace:XyY
    365  set listchars-=multispace:yYzZ
    366 
    367  let expected = [
    368       \ '>>>>ffff<<<<$',
    369       \ '>>ixixxxxxgg$',
    370       \ '>h<<<<<<<<<<$',
    371       \ '<<<<<<<<<<<<$',
    372       \ '>>>>>>>>>>j<$',
    373       \ '>>>>0xx0<<<<$',
    374       \ '$'
    375       \ ]
    376  call Check_listchars(expected, 7)
    377  call Check_listchars(expected, 6, -1, 6)
    378  call assert_equal(expected, split(execute("%list"), "\n"))
    379 
    380  " Test leadtab basic functionality
    381  normal ggdG
    382  set listchars=tab:>-,leadtab:+*
    383  set list
    384  call append(0, [
    385        \ "\ttext",
    386        \ "\t\ttext",
    387        \ "text\ttab"
    388        \ ])
    389  let expected = [
    390        \ '+*******text        ',
    391        \ '+*******+*******text',
    392        \ 'text>---tab         '
    393        \ ]
    394  call Check_listchars(expected, 3, 20)
    395 
    396  " Test leadtab with unicode characters
    397  normal ggdG
    398  set listchars=tab:>-,leadtab:├─┤
    399  call append(0, ["\ttext"])
    400  let expected = ['├──────┤text']
    401  call Check_listchars(expected, 1, 12)
    402 
    403  " Test leadtab with mixed indentation (spaces + tabs)
    404  normal ggdG
    405  set listchars=tab:>-,leadtab:+*,space:.
    406  call append(0, [" \t text"])
    407  let expected = ['.+******.text']
    408  call Check_listchars(expected, 1, 13)
    409 
    410  " Test leadtab with pipe character
    411  normal ggdG
    412  set listchars=tab:>-,leadtab:\|\ 
    413  call append(0, ["\ttext"])
    414  let expected = ['|       text']
    415  call Check_listchars(expected, 1, 12)
    416 
    417  " Test leadtab with unicode bar
    418  normal ggdG
    419  set listchars=tab:>-,leadtab:│\ 
    420  call append(0, ["\ttext"])
    421  let expected = ['│       text']
    422  call Check_listchars(expected, 1, 12)
    423 
    424  " Test leadtab vs tab distinction (leading vs non-leading)
    425  " In a line with only tabs, they aren't considered leading.
    426  normal ggdG
    427  set listchars=tab:>-,leadtab:+*
    428  call append(0, [
    429        \ "\tleading",
    430        \ "text\tnot leading",
    431        \ "\t\tmultiple leading",
    432        \ "\t\t"
    433        \ ])
    434  let expected = [
    435        \ '+*******leading                 ',
    436        \ 'text>---not leading             ',
    437        \ '+*******+*******multiple leading',
    438        \ '>------->-------                '
    439        \ ]
    440  call Check_listchars(expected, 4, 32)
    441 
    442  " Test leadtab with trail and space
    443  normal ggdG
    444  set listchars=tab:>-,leadtab:+*,trail:<,space:.
    445  call append(0, [
    446        \ "\ttext  ",
    447        \ "  \ttext",
    448        \ "\t  text  "
    449        \ ])
    450  let expected = [
    451        \ '+*******text<<  ',
    452        \ '..+*****text    ',
    453        \ '+*******..text<<'
    454        \ ]
    455  call Check_listchars(expected, 3, 16)
    456 
    457  " Test leadtab with eol
    458  normal ggdG
    459  set listchars=tab:>-,leadtab:+*,eol:$
    460  call append(0, ["\ttext", "text\ttab"])
    461  let expected = [
    462        \ '+*******text$',
    463        \ 'text>---tab$ '
    464        \ ]
    465  call Check_listchars(expected, 2, 13)
    466 
    467 
    468  " test nbsp
    469  normal ggdG
    470  set listchars=nbsp:X,trail:Y
    471  set list
    472  " Non-breaking space
    473  let nbsp = nr2char(0xa0)
    474  call append(0, [ ">" .. nbsp .. "<" ])
    475 
    476  let expected = '>X< '
    477  call Check_listchars([expected], 1)
    478 
    479  set listchars=nbsp:X
    480  call Check_listchars([expected], 1)
    481 
    482  " test extends
    483  normal ggdG
    484  set listchars=extends:Z
    485  set nowrap
    486  set nolist
    487  call append(0, [ repeat('A', &columns + 1) ])
    488 
    489  let expected = repeat('A', &columns)
    490  call Check_listchars([expected], 1, &columns)
    491 
    492  set list
    493  let expected = expected[:-2] . 'Z'
    494  call Check_listchars([expected], 1, &columns)
    495 
    496  enew!
    497  set listchars& ff&
    498 endfunc
    499 
    500 " Test that unicode listchars characters get properly inserted
    501 func Test_listchars_unicode()
    502  enew!
    503  let oldencoding=&encoding
    504  set encoding=utf-8
    505  set ff=unix
    506 
    507  set listchars=eol:⇔,space:␣,multispace:≡≢≣,nbsp:≠,tab:←↔→
    508  set list
    509 
    510  let nbsp = nr2char(0xa0)
    511  call append(0, ["        a\tb c" .. nbsp .. "d  "])
    512  let expected = ['≡≢≣≡≢≣≡≢a←↔↔↔↔↔→b␣c≠d≡≢⇔']
    513  call Check_listchars(expected, 1)
    514  call Check_listchars(expected, 1, -1, 3)
    515  call Check_listchars(expected, 1, -1, 13)
    516 
    517  set listchars=eol:\\u21d4,space:\\u2423,multispace:≡\\u2262\\U00002263,nbsp:\\U00002260,tab:←↔\\u2192
    518  call Check_listchars(expected, 1)
    519  call Check_listchars(expected, 1, -1, 3)
    520  call Check_listchars(expected, 1, -1, 13)
    521 
    522  set listchars+=lead:⇨,trail:⇦
    523  let expected = ['⇨⇨⇨⇨⇨⇨⇨⇨a←↔↔↔↔↔→b␣c≠d⇦⇦⇔']
    524  call Check_listchars(expected, 1)
    525  call Check_listchars(expected, 1, -1, 3)
    526  call Check_listchars(expected, 1, -1, 13)
    527 
    528  let &encoding=oldencoding
    529  enew!
    530  set listchars& ff&
    531 endfunction
    532 
    533 func Test_listchars_invalid()
    534  enew!
    535  set ff=unix
    536 
    537  set listchars=eol:$  " Accommodate Nvim default
    538  set list
    539  set ambiwidth=double
    540 
    541  " No colon
    542  call assert_fails('set listchars=x', 'E474:')
    543  call assert_fails('set listchars=x', 'E474:')
    544  call assert_fails('set listchars=multispace', 'E474:')
    545  call assert_fails('set listchars=leadmultispace', 'E474:')
    546 
    547  " Too short
    548  call assert_fails('set listchars=space:', 'E1511:')
    549  call assert_fails('set listchars=tab:x', 'E1511:')
    550  call assert_fails('set listchars=multispace:', 'E1511:')
    551  call assert_fails('set listchars=leadmultispace:', 'E1511:')
    552 
    553  " One occurrence too short
    554  call assert_fails('set listchars=space:x,space:', 'E1511:')
    555  call assert_fails('set listchars=space:,space:x', 'E1511:')
    556  call assert_fails('set listchars=tab:xx,tab:x', 'E1511:')
    557  call assert_fails('set listchars=tab:x,tab:xx', 'E1511:')
    558  call assert_fails('set listchars=multispace:,multispace:x', 'E1511:')
    559  call assert_fails('set listchars=multispace:x,multispace:', 'E1511:')
    560  call assert_fails('set listchars=leadmultispace:,leadmultispace:x', 'E1511:')
    561  call assert_fails('set listchars=leadmultispace:x,leadmultispace:', 'E1511:')
    562 
    563  " Too long
    564  call assert_fails('set listchars=space:xx', 'E1511:')
    565  call assert_fails('set listchars=tab:xxxx', 'E1511:')
    566 
    567  " Has double-width character
    568  call assert_fails('set listchars=space:·', 'E1512:')
    569  call assert_fails('set listchars=tab:·x', 'E1512:')
    570  call assert_fails('set listchars=tab:x·', 'E1512:')
    571  call assert_fails('set listchars=tab:xx·', 'E1512:')
    572  call assert_fails('set listchars=multispace:·', 'E1512:')
    573  call assert_fails('set listchars=multispace:xxx·', 'E1512:')
    574  call assert_fails('set listchars=leadmultispace:·', 'E1512:')
    575  call assert_fails('set listchars=leadmultispace:xxx·', 'E1512:')
    576 
    577  " Has control character
    578  call assert_fails("set listchars=space:\x01", 'E1512:')
    579  call assert_fails("set listchars=tab:\x01x", 'E1512:')
    580  call assert_fails("set listchars=tab:x\x01", 'E1512:')
    581  call assert_fails("set listchars=tab:xx\x01", 'E1512:')
    582  call assert_fails("set listchars=multispace:\x01", 'E1512:')
    583  call assert_fails("set listchars=multispace:xxx\x01", 'E1512:')
    584  call assert_fails('set listchars=space:\\x01', 'E1512:')
    585  call assert_fails('set listchars=tab:\\x01x', 'E1512:')
    586  call assert_fails('set listchars=tab:x\\x01', 'E1512:')
    587  call assert_fails('set listchars=tab:xx\\x01', 'E1512:')
    588  call assert_fails('set listchars=multispace:\\x01', 'E1512:')
    589  call assert_fails('set listchars=multispace:xxx\\x01', 'E1512:')
    590  call assert_fails("set listchars=leadmultispace:\x01", 'E1512:')
    591  call assert_fails('set listchars=leadmultispace:\\x01', 'E1512:')
    592  call assert_fails("set listchars=leadmultispace:xxx\x01", 'E1512:')
    593  call assert_fails('set listchars=leadmultispace:xxx\\x01', 'E1512:')
    594 
    595  enew!
    596  set ambiwidth& listchars& ff&
    597 endfunction
    598 
    599 " Tests that space characters following composing character won't get replaced
    600 " by listchars.
    601 func Test_listchars_composing()
    602  enew!
    603  let oldencoding=&encoding
    604  set encoding=utf-8
    605  set ff=unix
    606  set list
    607 
    608  set listchars=eol:$,space:_,nbsp:=
    609 
    610  let nbsp1 = nr2char(0xa0)
    611  let nbsp2 = nr2char(0x202f)
    612  call append(0, [
    613        \ "  \u3099\t \u309A" .. nbsp1 .. nbsp1 .. "\u0302" .. nbsp2 .. nbsp2 .. "\u0302",
    614        \ ])
    615  let expected = [
    616        \ "_ \u3099^I \u309A=" .. nbsp1 .. "\u0302=" .. nbsp2 .. "\u0302$"
    617        \ ]
    618  call Check_listchars(expected, 1)
    619  let &encoding=oldencoding
    620  enew!
    621  set listchars& ff&
    622 endfunction
    623 
    624 " Check for the value of the 'listchars' option
    625 func s:CheckListCharsValue(expected)
    626  call assert_equal(a:expected, &listchars)
    627  call assert_equal(a:expected, getwinvar(0, '&listchars'))
    628 endfunc
    629 
    630 " Test for using a window local value for 'listchars'
    631 func Test_listchars_window_local()
    632  %bw!
    633  set list listchars&
    634  let nvim_default = &listchars  " Accommodate Nvim default
    635  new
    636  " set a local value for 'listchars'
    637  setlocal listchars=tab:+-,eol:#
    638  call s:CheckListCharsValue('tab:+-,eol:#')
    639  " When local value is reset, global value should be used
    640  setlocal listchars=
    641  call s:CheckListCharsValue(nvim_default)
    642  " Use 'setlocal <' to copy global value
    643  setlocal listchars=space:.,extends:>
    644  setlocal listchars<
    645  call s:CheckListCharsValue(nvim_default)
    646  " Use 'set <' to copy global value
    647  setlocal listchars=space:.,extends:>
    648  set listchars<
    649  call s:CheckListCharsValue(nvim_default)
    650  " Changing global setting should not change the local setting
    651  setlocal listchars=space:.,extends:>
    652  setglobal listchars=tab:+-,eol:#
    653  call s:CheckListCharsValue('space:.,extends:>')
    654  " when split opening a new window, local value should be copied
    655  split
    656  call s:CheckListCharsValue('space:.,extends:>')
    657  " clearing local value in one window should not change the other window
    658  set listchars&
    659  call s:CheckListCharsValue(nvim_default)
    660  close
    661  call s:CheckListCharsValue('space:.,extends:>')
    662 
    663  " use different values for 'listchars' items in two different windows
    664  call setline(1, ["\t  one  two  "])
    665  setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
    666  split
    667  setlocal listchars=tab:[.],lead:#,space:_,trail:.,eol:&
    668  split
    669  set listchars=tab:+-+,lead:^,space:>,trail:<,eol:%
    670  call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
    671  close
    672  call assert_equal(['[......]##one__two..&'], ScreenLines(1, virtcol('$')))
    673  close
    674  call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
    675  " changing the global setting should not change the local value
    676  setglobal listchars=tab:[.],lead:#,space:_,trail:.,eol:&
    677  call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
    678  set listchars<
    679  call assert_equal(['[......]##one__two..&'], ScreenLines(1, virtcol('$')))
    680 
    681  " Using setglobal in a window with local setting should not affect the
    682  " window. But should impact other windows using the global setting.
    683  enew! | only
    684  call setline(1, ["\t  one  two  "])
    685  set listchars=tab:[.],lead:#,space:_,trail:.,eol:&
    686  split
    687  setlocal listchars=tab:+-+,lead:^,space:>,trail:<,eol:%
    688  split
    689  setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
    690  setglobal listchars=tab:{.},lead:-,space:=,trail:#,eol:$
    691  call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
    692  close
    693  call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
    694  close
    695  call assert_equal(['{......}--one==two##$'], ScreenLines(1, virtcol('$')))
    696 
    697  " Setting the global setting to the default value should not impact a window
    698  " using a local setting.
    699  split
    700  setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
    701  setglobal listchars=eol:$  " Accommodate Nvim default
    702  call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
    703  close
    704  call assert_equal(['^I  one  two  $'], ScreenLines(1, virtcol('$')))
    705 
    706  " Setting the local setting to the default value should not impact a window
    707  " using a global setting.
    708  set listchars=tab:{.},lead:-,space:=,trail:#,eol:$
    709  split
    710  setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
    711  call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
    712  setlocal listchars=eol:$  " Accommodate Nvim default
    713  call assert_equal(['^I  one  two  $'], ScreenLines(1, virtcol('$')))
    714  close
    715  call assert_equal(['{......}--one==two##$'], ScreenLines(1, virtcol('$')))
    716 
    717  " Using set in a window with a local setting should change it to use the
    718  " global setting and also impact other windows using the global setting.
    719  split
    720  setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
    721  call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
    722  set listchars=tab:+-+,lead:^,space:>,trail:<,eol:%
    723  call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
    724  close
    725  call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
    726 
    727  " Setting invalid value for a local setting should not impact the local and
    728  " global settings.
    729  split
    730  setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
    731  let cmd = 'setlocal listchars=tab:{.},lead:-,space:=,trail:#,eol:$,x'
    732  call assert_fails(cmd, 'E474:')
    733  call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
    734  close
    735  call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
    736 
    737  " Setting invalid value for a global setting should not impact the local and
    738  " global settings.
    739  split
    740  setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
    741  let cmd = 'setglobal listchars=tab:{.},lead:-,space:=,trail:#,eol:$,x'
    742  call assert_fails(cmd, 'E474:')
    743  call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
    744  close
    745  call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
    746 
    747  " Closing window with local lcs-multispace should not cause a memory leak.
    748  setlocal listchars=multispace:---+
    749  split
    750  call s:CheckListCharsValue('multispace:---+')
    751  close
    752 
    753  %bw!
    754  set list& listchars&
    755 endfunc
    756 
    757 func Test_listchars_foldcolumn()
    758  CheckScreendump
    759 
    760  let lines =<< trim END
    761      call setline(1, ['aaa', '', 'a', 'aaaaaa'])
    762      vsplit
    763      vsplit
    764      windo set signcolumn=yes foldcolumn=1 winminwidth=0 nowrap list listchars=extends:>,precedes:<
    765  END
    766  call writefile(lines, 'XTest_listchars', 'D')
    767 
    768  let buf = RunVimInTerminal('-S XTest_listchars', {'rows': 10, 'cols': 60})
    769 
    770  call term_sendkeys(buf, "13\<C-W>>")
    771  call VerifyScreenDump(buf, 'Test_listchars_01', {})
    772  call term_sendkeys(buf, "\<C-W>>")
    773  call VerifyScreenDump(buf, 'Test_listchars_02', {})
    774  call term_sendkeys(buf, "\<C-W>>")
    775  call VerifyScreenDump(buf, 'Test_listchars_03', {})
    776  call term_sendkeys(buf, "\<C-W>>")
    777  call VerifyScreenDump(buf, 'Test_listchars_04', {})
    778  call term_sendkeys(buf, "\<C-W>>")
    779  call VerifyScreenDump(buf, 'Test_listchars_05', {})
    780  call term_sendkeys(buf, "\<C-W>h")
    781  call term_sendkeys(buf, ":set nowrap foldcolumn=4\<CR>")
    782  call term_sendkeys(buf, "15\<C-W><")
    783  call VerifyScreenDump(buf, 'Test_listchars_06', {})
    784  call term_sendkeys(buf, "4\<C-W><")
    785  call VerifyScreenDump(buf, 'Test_listchars_07', {})
    786 
    787  " clean up
    788  call StopVimInTerminal(buf)
    789 endfunc
    790 
    791 func Test_listchars_precedes_with_wide_char()
    792  new
    793  setlocal nowrap list listchars=eol:$,precedes:!
    794  call setline(1, '123口456')
    795  call assert_equal(['123口456$ '], ScreenLines(1, 10))
    796  let attr = screenattr(1, 9)
    797 
    798  normal! zl
    799  call assert_equal(['!3口456$  '], ScreenLines(1, 10))
    800  call assert_equal(attr, screenattr(1, 1))
    801  normal! zl
    802  call assert_equal(['!口456$   '], ScreenLines(1, 10))
    803  call assert_equal(attr, screenattr(1, 1))
    804  normal! zl
    805  call assert_equal(['!<456$    '], ScreenLines(1, 10))
    806  call assert_equal(attr, screenattr(1, 1))
    807  call assert_equal(attr, screenattr(1, 2))
    808  normal! zl
    809  call assert_equal(['!456$     '], ScreenLines(1, 10))
    810  call assert_equal(attr, screenattr(1, 1))
    811  normal! zl
    812  call assert_equal(['!56$      '], ScreenLines(1, 10))
    813  call assert_equal(attr, screenattr(1, 1))
    814  normal! zl
    815  call assert_equal(['!6$       '], ScreenLines(1, 10))
    816  call assert_equal(attr, screenattr(1, 1))
    817 
    818  bw!
    819 endfunc
    820 
    821 func Test_listchars_precedes_with_tab()
    822  new
    823  setlocal nowrap list listchars=eol:$,precedes:!,tab:<->
    824  call setline(1, "1234\t56")
    825  let expected_line = '1234<-->56$ '
    826  call assert_equal([expected_line], ScreenLines(1, 12))
    827  let expected_attrs = mapnew(range(1, 12), 'screenattr(1, v:val)')
    828  let attr = expected_attrs[-2]
    829 
    830  for i in range(8)
    831    normal! zl
    832    let expected_line = '!' .. expected_line[2:] .. ' '
    833    let expected_attrs = [attr] + expected_attrs[2:] + expected_attrs[-1:]
    834    call assert_equal([expected_line], ScreenLines(1, 12))
    835    let attrs = mapnew(range(1, 12), 'screenattr(1, v:val)')
    836    call assert_equal(expected_attrs, attrs)
    837  endfor
    838 
    839  bw!
    840 endfunc
    841 
    842 " vim: shiftwidth=2 sts=2 expandtab