" Tests for 'listchars' display with 'list' and :list source view_util.vim func Test_listchars() enew! set ff=unix set list set listchars+=tab:>-,space:.,trail:< call append(0, [ \ ' aa ', \ ' bb ', \ ' cccc ', \ 'dd ee ', \ ' ' \ ]) let expected = [ \ '>-------aa>-----$', \ '..bb>---<<$', \ '...cccc><$', \ 'dd........ee<<>-$', \ '<$' \ ] redraw! for i in range(1, 5) call cursor(i, 1) call assert_equal([expected[i - 1]], ScreenLines(i, '$'->virtcol())) endfor set listchars-=trail:< let expected = [ \ '>-------aa>-----$', \ '..bb>---..$', \ '...cccc>.$', \ 'dd........ee..>-$', \ '.$' \ ] redraw! for i in range(1, 5) call cursor(i, 1) call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) endfor " tab with 3rd character. set listchars-=tab:>- set listchars+=tab:<=>,trail:- let expected = [ \ '<======>aa<====>$', \ '..bb<==>--$', \ '...cccc>-$', \ 'dd........ee--<>$', \ '-$' \ ] redraw! for i in range(1, 5) call cursor(i, 1) call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) endfor " tab with 3rd character and linebreak set set listchars-=tab:<=> set listchars+=tab:<·> set linebreak let expected = [ \ '<······>aa<····>$', \ '..bb<··>--$', \ '...cccc>-$', \ 'dd........ee--<>$', \ '-$' \ ] redraw! for i in range(1, 5) call cursor(i, 1) call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) endfor set nolinebreak set listchars-=tab:<·> set listchars+=tab:<=> set listchars-=trail:- let expected = [ \ '<======>aa<====>$', \ '..bb<==>..$', \ '...cccc>.$', \ 'dd........ee..<>$', \ '.$' \ ] redraw! for i in range(1, 5) call cursor(i, 1) call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) endfor set listchars-=tab:<=> set listchars+=tab:>- set listchars+=trail:< set nolist normal ggdG call append(0, [ \ ' fff ', \ ' gg ', \ ' h ', \ 'iii ', \ ]) let l = split(execute("%list"), "\n") call assert_equal([ \ '..fff>--<<$', \ '>-------gg>-----$', \ '.....h>-$', \ 'iii<<<<><<$', '$'], l) " Test lead and trail normal ggdG set listchars& set listchars+=lead:>,trail:<,space:x set list call append(0, [ \ ' ffff ', \ ' gg', \ 'h ', \ ' ', \ ' 0 0 ', \ ]) let expected = [ \ '>>>>ffff<<<<$', \ '>>>>>>>>>>gg$', \ 'h<<<<<<<<<<<$', \ '<<<<<<<<<<<<$', \ '>>>>0xx0<<<<$', \ '$' \ ] redraw! for i in range(1, 5) call cursor(i, 1) call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$'))) endfor call assert_equal(expected, split(execute("%list"), "\n")) " test nbsp normal ggdG set listchars=nbsp:X,trail:Y set list " Non-breaking space let nbsp = nr2char(0xa0) call append(0, [ ">" .. nbsp .. "<" ]) let expected = '>X< ' redraw! call cursor(1, 1) call assert_equal([expected], ScreenLines(1, virtcol('$'))) set listchars=nbsp:X redraw! call cursor(1, 1) call assert_equal([expected], ScreenLines(1, virtcol('$'))) " test extends normal ggdG set listchars=extends:Z set nowrap set nolist call append(0, [ repeat('A', &columns + 1) ]) let expected = repeat('A', &columns) redraw! call cursor(1, 1) call assert_equal([expected], ScreenLines(1, &columns)) set list let expected = expected[:-2] . 'Z' redraw! call cursor(1, 1) call assert_equal([expected], ScreenLines(1, &columns)) enew! set listchars& ff& endfunc " Test that unicode listchars characters get properly inserted func Test_listchars_unicode() enew! let oldencoding=&encoding set encoding=utf-8 set ff=unix set listchars=eol:⇔,space:␣,nbsp:≠,tab:←↔→ set list 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('$'))) let &encoding=oldencoding enew! set listchars& ff& endfunction " Tests that space characters following composing character won't get replaced " by listchars. func Test_listchars_composing() enew! let oldencoding=&encoding set encoding=utf-8 set ff=unix set list set listchars=eol:$,space:_,nbsp:= let nbsp1 = nr2char(0xa0) let nbsp2 = nr2char(0x202f) call append(0, [ \ " \u3099\t \u309A" .. nbsp1 .. nbsp1 .. "\u0302" .. nbsp2 .. nbsp2 .. "\u0302", \ ]) let expected = [ \ "_ \u3099^I \u309A=" .. nbsp1 .. "\u0302=" .. nbsp2 .. "\u0302$" \ ] redraw! call cursor(1, 1) call assert_equal(expected, ScreenLines(1, virtcol('$'))) let &encoding=oldencoding enew! set listchars& ff& endfunction " Check for the value of the 'listchars' option func s:CheckListCharsValue(expected) call assert_equal(a:expected, &listchars) call assert_equal(a:expected, getwinvar(0, '&listchars')) endfunc " Test for using a window local value for 'listchars' func Test_listchars_window_local() %bw! set list listchars& new " set a local value for 'listchars' setlocal listchars=tab:+-,eol:# call s:CheckListCharsValue('tab:+-,eol:#') " When local value is reset, global value should be used setlocal listchars= call s:CheckListCharsValue('eol:$') " Use 'setlocal <' to copy global value setlocal listchars=space:.,extends:> setlocal listchars< call s:CheckListCharsValue('eol:$') " Use 'set <' to copy global value setlocal listchars=space:.,extends:> set listchars< call s:CheckListCharsValue('eol:$') " Changing global setting should not change the local setting setlocal listchars=space:.,extends:> setglobal listchars=tab:+-,eol:# call s:CheckListCharsValue('space:.,extends:>') " when split opening a new window, local value should be copied split call s:CheckListCharsValue('space:.,extends:>') " clearing local value in one window should not change the other window set listchars& call s:CheckListCharsValue('eol:$') close call s:CheckListCharsValue('space:.,extends:>') " use different values for 'listchars' items in two different windows call setline(1, ["\t one two "]) setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:# split setlocal listchars=tab:[.],lead:#,space:_,trail:.,eol:& split set listchars=tab:+-+,lead:^,space:>,trail:<,eol:% call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$'))) close call assert_equal(['[......]##one__two..&'], ScreenLines(1, virtcol('$'))) close call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$'))) " changing the global setting should not change the local value setglobal listchars=tab:[.],lead:#,space:_,trail:.,eol:& call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$'))) set listchars< call assert_equal(['[......]##one__two..&'], ScreenLines(1, virtcol('$'))) " Using setglobal in a window with local setting should not affect the " window. But should impact other windows using the global setting. enew! | only call setline(1, ["\t one two "]) set listchars=tab:[.],lead:#,space:_,trail:.,eol:& split setlocal listchars=tab:+-+,lead:^,space:>,trail:<,eol:% split setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:# setglobal listchars=tab:{.},lead:-,space:=,trail:#,eol:$ call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$'))) close call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$'))) close call assert_equal(['{......}--one==two##$'], ScreenLines(1, virtcol('$'))) " Setting the global setting to the default value should not impact a window " using a local setting split setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:# setglobal listchars&vim call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$'))) close call assert_equal(['^I one two $'], ScreenLines(1, virtcol('$'))) " Setting the local setting to the default value should not impact a window " using a global setting set listchars=tab:{.},lead:-,space:=,trail:#,eol:$ split setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:# call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$'))) setlocal listchars&vim call assert_equal(['^I one two $'], ScreenLines(1, virtcol('$'))) close call assert_equal(['{......}--one==two##$'], ScreenLines(1, virtcol('$'))) " Using set in a window with a local setting should change it to use the " global setting and also impact other windows using the global setting split setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:# call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$'))) set listchars=tab:+-+,lead:^,space:>,trail:<,eol:% call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$'))) close call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$'))) " Setting invalid value for a local setting should not impact the local and " global settings split setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:# let cmd = 'setlocal listchars=tab:{.},lead:-,space:=,trail:#,eol:$,x' call assert_fails(cmd, 'E474:') call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$'))) close call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$'))) " Setting invalid value for a global setting should not impact the local and " global settings split setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:# let cmd = 'setglobal listchars=tab:{.},lead:-,space:=,trail:#,eol:$,x' call assert_fails(cmd, 'E474:') call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$'))) close call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$'))) %bw! set list& listchars& endfunc " vim: shiftwidth=2 sts=2 expandtab