From 029f72b1a93430b24b88eb3a72c6114d9f149737 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 10 Apr 2024 22:09:20 +0200 Subject: Adding upstream version 2:9.1.0016. Signed-off-by: Daniel Baumann --- src/testdir/test_listchars.vim | 675 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 675 insertions(+) create mode 100644 src/testdir/test_listchars.vim (limited to 'src/testdir/test_listchars.vim') diff --git a/src/testdir/test_listchars.vim b/src/testdir/test_listchars.vim new file mode 100644 index 0000000..57ddcda --- /dev/null +++ b/src/testdir/test_listchars.vim @@ -0,0 +1,675 @@ +" Tests for 'listchars' display with 'list' and :list + +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 + set list + + set listchars+=tab:>-,space:.,trail:< + call append(0, [ + \ ' aa ', + \ ' bb ', + \ ' cccc ', + \ 'dd ee ', + \ ' ' + \ ]) + let expected = [ + \ '>-------aa>-----$', + \ '..bb>---<<$', + \ '...cccc><$', + \ 'dd........ee<<>-$', + \ '<$' + \ ] + call Check_listchars(expected, 5) + call Check_listchars(expected, 4, -1, 5) + + set listchars-=trail:< + let expected = [ + \ '>-------aa>-----$', + \ '..bb>---..$', + \ '...cccc>.$', + \ 'dd........ee..>-$', + \ '.$' + \ ] + call Check_listchars(expected, 5) + call Check_listchars(expected, 4, -1, 5) + + " tab with 3rd character. + set listchars-=tab:>- + set listchars+=tab:<=>,trail:- + let expected = [ + \ '<======>aa<====>$', + \ '..bb<==>--$', + \ '...cccc>-$', + \ 'dd........ee--<>$', + \ '-$' + \ ] + call Check_listchars(expected, 5) + call Check_listchars(expected, 4, -1, 5) + + " tab with 3rd character and linebreak set + set listchars-=tab:<=> + set listchars+=tab:<·> + set linebreak + let expected = [ + \ '<······>aa<····>$', + \ '..bb<··>--$', + \ '...cccc>-$', + \ 'dd........ee--<>$', + \ '-$' + \ ] + call Check_listchars(expected, 5) + set nolinebreak + set listchars-=tab:<·> + set listchars+=tab:<=> + + set listchars-=trail:- + let expected = [ + \ '<======>aa<====>$', + \ '..bb<==>..$', + \ '...cccc>.$', + \ 'dd........ee..<>$', + \ '.$' + \ ] + call Check_listchars(expected, 5) + call Check_listchars(expected, 4, -1, 5) + + 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<<<<$', + \ '$' + \ ] + call Check_listchars(expected, 6) + call Check_listchars(expected, 5, -1, 6) + call assert_equal(expected, split(execute("%list"), "\n")) + + " Test multispace + normal ggdG + set listchars& + set listchars+=multispace:yYzZ + set list + + call append(0, [ + \ ' ffff ', + \ ' i i gg', + \ ' h ', + \ ' j ', + \ ' 0 0 ', + \ ]) + + let expected = [ + \ 'yYzZffffyYzZ$', + \ 'yYi iyYzZygg$', + \ ' hyYzZyYzZyY$', + \ 'yYzZyYzZyYj $', + \ 'yYzZ0yY0yYzZ$', + \ '$' + \ ] + call Check_listchars(expected, 6) + call Check_listchars(expected, 5, -1, 6) + call assert_equal(expected, split(execute("%list"), "\n")) + + " Test leadmultispace + multispace + normal ggdG + set listchars=eol:$,multispace:yYzZ,nbsp:S + set listchars+=leadmultispace:.-+* + set list + + call append(0, [ + \ ' ffff ', + \ ' i i  gg', + \ ' h ', + \ ' j ', + \ ' 0 0 ', + \ ]) + + let expected = [ + \ '.-+*ffffyYzZ$', + \ '.-i iSyYzZgg$', + \ ' hyYzZyYzZyY$', + \ '.-+*.-+*.-j $', + \ '.-+*0yY0yYzZ$', + \ '$' + \ ] + call assert_equal('eol:$,multispace:yYzZ,nbsp:S,leadmultispace:.-+*', &listchars) + 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 + normal ggdG + set listchars-=multispace:yYzZ + set listchars+=space:+,trail:>,eol:$ + set list + + call append(0, [ + \ ' ffff ', + \ ' i i gg', + \ ' h ', + \ ' j ', + \ ' 0 0 ', + \ ]) + + let expected = [ + \ '.-+*ffff>>>>$', + \ '.-i+i+++++gg$', + \ '+h>>>>>>>>>>$', + \ '.-+*.-+*.-j>$', + \ '.-+*0++0>>>>$', + \ '$' + \ ] + call assert_equal('eol:$,nbsp:S,leadmultispace:.-+*,space:+,trail:>,eol:$', &listchars) + 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 + normal ggdG + set listchars& + set listchars=leadmultispace:.-+* + set list + + call append(0, [ + \ ' ffff ', + \ ' i i gg', + \ ' h ', + \ ' j ', + \ ' 0 0 ', + \ ]) + + let expected = [ + \ '.-+*ffff ', + \ '.-i i gg', + \ ' h ', + \ '.-+*.-+*.-j ', + \ '.-+*0 0 ', + \ ' ' + \ ] + call assert_equal('leadmultispace:.-+*', &listchars) + call Check_listchars(expected, 5, 12) + call assert_equal(expected, split(execute("%list"), "\n")) + + " Changing the value of 'ambiwidth' twice shouldn't cause double-free when + " "leadmultispace" is specified. + set ambiwidth=double + set ambiwidth& + + " Test leadmultispace and lead and space + normal ggdG + set listchars& + set listchars+=lead:<,space:- + set listchars+=leadmultispace:.-+* + set list + + call append(0, [ + \ ' ffff ', + \ ' i i gg', + \ ' h ', + \ ' j ', + \ ' 0 0 ', + \ ]) + + let expected = [ + \ '.-+*ffff----$', + \ '.-i-i-----gg$', + \ ',trail:< + + let expected = [ + \ '>>>>ffff<<<<$', + \ '>>ixiXyYXygg$', + \ '>h<<<<<<<<<<$', + \ '>>>>>>>>>>j<$', + \ '>>>>0Xy0<<<<$', + \ '$' + \ ] + call Check_listchars(expected, 6) + call Check_listchars(expected, 5, -1, 6) + call assert_equal(expected, split(execute("%list"), "\n")) + + " removing 'multispace:' + set listchars-=multispace:XyY + set listchars-=multispace:yYzZ + + let expected = [ + \ '>>>>ffff<<<<$', + \ '>>ixixxxxxgg$', + \ '>h<<<<<<<<<<$', + \ '>>>>>>>>>>j<$', + \ '>>>>0xx0<<<<$', + \ '$' + \ ] + call Check_listchars(expected, 6) + call Check_listchars(expected, 5, -1, 6) + 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< ' + call Check_listchars([expected], 1) + + set listchars=nbsp:X + call Check_listchars([expected], 1) + + " test extends + normal ggdG + set listchars=extends:Z + set nowrap + set nolist + call append(0, [ repeat('A', &columns + 1) ]) + + let expected = repeat('A', &columns) + call Check_listchars([expected], 1, &columns) + + set list + let expected = expected[:-2] . 'Z' + call Check_listchars([expected], 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:␣,multispace:≡≢≣,nbsp:≠,tab:←↔→ + set list + + let nbsp = nr2char(0xa0) + call append(0, [" a\tb c" .. nbsp .. "d "]) + let expected = ['≡≢≣≡≢≣≡≢a←↔↔↔↔↔→b␣c≠d≡≢⇔'] + 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 + 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⇦⇦⇔'] + call Check_listchars(expected, 1) + call Check_listchars(expected, 1, -1, 3) + call Check_listchars(expected, 1, -1, 13) + + let &encoding=oldencoding + enew! + set listchars& ff& +endfunction + +func Test_listchars_invalid() + enew! + set ff=unix + + set listchars& + set list + set ambiwidth=double + + " No colon + call assert_fails('set listchars=x', 'E474:') + call assert_fails('set listchars=x', 'E474:') + call assert_fails('set listchars=multispace', 'E474:') + call assert_fails('set listchars=leadmultispace', 'E474:') + + " Too short + call assert_fails('set listchars=space:', 'E474:') + call assert_fails('set listchars=tab:x', 'E474:') + call assert_fails('set listchars=multispace:', 'E474:') + call assert_fails('set listchars=leadmultispace:', 'E474:') + + " One occurrence too short + call assert_fails('set listchars=space:,space:x', 'E474:') + call assert_fails('set listchars=space:x,space:', 'E474:') + call assert_fails('set listchars=tab:x,tab:xx', 'E474:') + call assert_fails('set listchars=tab:xx,tab:x', 'E474:') + call assert_fails('set listchars=multispace:,multispace:x', 'E474:') + call assert_fails('set listchars=multispace:x,multispace:', 'E474:') + call assert_fails('set listchars=leadmultispace:,leadmultispace:x', 'E474:') + call assert_fails('set listchars=leadmultispace:x,leadmultispace:', 'E474:') + + " Too long + call assert_fails('set listchars=space:xx', 'E474:') + call assert_fails('set listchars=tab:xxxx', 'E474:') + + " Has double-width character + call assert_fails('set listchars=space:·', 'E474:') + call assert_fails('set listchars=tab:·x', 'E474:') + call assert_fails('set listchars=tab:x·', 'E474:') + call assert_fails('set listchars=tab:xx·', 'E474:') + call assert_fails('set listchars=multispace:·', 'E474:') + call assert_fails('set listchars=multispace:xxx·', 'E474:') + call assert_fails('set listchars=leadmultispace:·', 'E474:') + call assert_fails('set listchars=leadmultispace:xxx·', 'E474:') + + " Has control character + call assert_fails("set listchars=space:\x01", 'E474:') + call assert_fails("set listchars=tab:\x01x", 'E474:') + call assert_fails("set listchars=tab:x\x01", 'E474:') + call assert_fails("set listchars=tab:xx\x01", 'E474:') + call assert_fails("set listchars=multispace:\x01", 'E474:') + call assert_fails("set listchars=multispace:xxx\x01", 'E474:') + call assert_fails('set listchars=space:\\x01', 'E474:') + call assert_fails('set listchars=tab:\\x01x', 'E474:') + call assert_fails('set listchars=tab:x\\x01', 'E474:') + call assert_fails('set listchars=tab:xx\\x01', 'E474:') + call assert_fails('set listchars=multispace:\\x01', 'E474:') + call assert_fails('set listchars=multispace:xxx\\x01', 'E474:') + call assert_fails("set listchars=leadmultispace:\x01", 'E474:') + call assert_fails('set listchars=leadmultispace:\\x01', 'E474:') + call assert_fails("set listchars=leadmultispace:xxx\x01", 'E474:') + call assert_fails('set listchars=leadmultispace:xxx\\x01', 'E474:') + + enew! + set ambiwidth& 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$" + \ ] + call Check_listchars(expected, 1) + 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('$'))) + + " Closing window with local lcs-multispace should not cause a memory leak. + setlocal listchars=multispace:---+ + split + call s:CheckListCharsValue('multispace:---+') + close + + %bw! + set list& listchars& +endfunc + +func Test_listchars_foldcolumn() + CheckScreendump + + let lines =<< trim END + call setline(1, ['aaa', '', 'a', 'aaaaaa']) + vsplit + vsplit + windo set signcolumn=yes foldcolumn=1 winminwidth=0 nowrap list listchars=extends:>,precedes:< + END + call writefile(lines, 'XTest_listchars', 'D') + + let buf = RunVimInTerminal('-S XTest_listchars', {'rows': 10, 'cols': 60}) + + call term_sendkeys(buf, "13\>") + call VerifyScreenDump(buf, 'Test_listchars_01', {}) + call term_sendkeys(buf, "\>") + call VerifyScreenDump(buf, 'Test_listchars_02', {}) + call term_sendkeys(buf, "\>") + call VerifyScreenDump(buf, 'Test_listchars_03', {}) + call term_sendkeys(buf, "\>") + call VerifyScreenDump(buf, 'Test_listchars_04', {}) + call term_sendkeys(buf, "\>") + call VerifyScreenDump(buf, 'Test_listchars_05', {}) + call term_sendkeys(buf, "\h") + call term_sendkeys(buf, ":set nowrap foldcolumn=4\") + call term_sendkeys(buf, "15\<") + call VerifyScreenDump(buf, 'Test_listchars_06', {}) + call term_sendkeys(buf, "4\<") + call VerifyScreenDump(buf, 'Test_listchars_07', {}) + + " clean up + call StopVimInTerminal(buf) +endfunc + + +" vim: shiftwidth=2 sts=2 expandtab -- cgit v1.2.3