Mercurial > vim
view src/testdir/test_syntax.vim @ 32962:7771cb060685 v9.0.1781
patch 9.0.1781: Problems when setting bin/paste option
Commit: https://github.com/vim/vim/commit/757593c07a4f4ac43eb6c6e52fc299abc9bc08bc
Author: Christian Brabandt <cb@256bit.org>
Date: Tue Aug 22 21:44:10 2023 +0200
patch 9.0.1781: Problems when setting bin/paste option
Problem: Problems when setting bin/paste option
Solution: When setting binary/paste, remember that this also affects
depending options, so that :verbose set returns the right
location.
Mention if depending options for 'binary' or 'paste' have been reset
indirectly. Add a test to verify it works.
Also noticed as small bug, that the global option value for expandtab
was not reset when paste option is set, so fix that while at it.
closes: #12837
closes: #12879
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Tue, 22 Aug 2023 22:00:03 +0200 |
parents | 97bb0811cfd4 |
children | d6b9d567433f |
line wrap: on
line source
" Test for syntax and syntax iskeyword option source check.vim CheckFeature syntax source view_util.vim source screendump.vim func GetSyntaxItem(pat) let c = '' let a = ['a', getreg('a'), getregtype('a')] 0 redraw! call search(a:pat, 'W') let synid = synID(line('.'), col('.'), 1) while synid == synID(line('.'), col('.'), 1) norm! v"ay " stop at whitespace if @a =~# '\s' break endif let c .= @a norm! l endw call call('setreg', a) 0 return c endfunc func AssertHighlightGroups(lnum, startcol, expected, trans = 1, msg = "") " Assert that the characters starting at a given (line, col) " sequentially match the expected highlight groups. " If groups are provided as a string, each character is assumed to be a " group and spaces represent no group, useful for visually describing tests. let l:expectedGroups = type(a:expected) == v:t_string \ ? a:expected->split('\zs')->map({_, v -> trim(v)}) \ : a:expected let l:errors = 0 let l:msg = (a:msg->empty() ? "" : a:msg .. ": ") \ .. "Wrong highlight group at " .. a:lnum .. "," for l:i in range(a:startcol, a:startcol + l:expectedGroups->len() - 1) let l:errors += synID(a:lnum, l:i, a:trans) \ ->synIDattr("name") \ ->assert_equal(l:expectedGroups[l:i - 1], \ l:msg .. l:i) endfor endfunc func Test_syn_iskeyword() new call setline(1, [ \ 'CREATE TABLE FOOBAR(', \ ' DLTD_BY VARCHAR2(100)', \ ');', \ '']) syntax on set ft=sql syn match SYN /C\k\+\>/ hi link SYN ErrorMsg call assert_equal('DLTD_BY', GetSyntaxItem('DLTD')) /\<D\k\+\>/:norm! ygn call assert_equal('DLTD_BY', @0) redir @c syn iskeyword redir END call assert_equal("\nsyntax iskeyword not set", @c) syn iskeyword @,48-57,_,192-255 redir @c syn iskeyword redir END call assert_equal("\nsyntax iskeyword @,48-57,_,192-255", @c) setlocal isk-=_ call assert_equal('DLTD_BY', GetSyntaxItem('DLTD')) /\<D\k\+\>/:norm! ygn let b2 = @0 call assert_equal('DLTD', @0) syn iskeyword clear redir @c syn iskeyword redir END call assert_equal("\nsyntax iskeyword not set", @c) quit! endfunc func Test_syntax_after_reload() split Xsomefile call setline(1, ['hello', 'there']) w! only! setl filetype=hello au FileType hello let g:gotit = 1 call assert_false(exists('g:gotit')) edit other buf Xsomefile call assert_equal('hello', &filetype) call assert_true(exists('g:gotit')) call delete('Xsomefile') endfunc func Test_syntime() CheckFeature profile syntax on syntime on let a = execute('syntime report') call assert_equal("\nNo Syntax items defined for this buffer", a) let a = execute('syntime clear') call assert_equal("\nNo Syntax items defined for this buffer", a) view ../memfile_test.c setfiletype cpp redraw let a = execute('syntime report') call assert_match('^ TOTAL *COUNT *MATCH *SLOWEST *AVERAGE *NAME *PATTERN', a) call assert_match(' \d*\.\d* \+[^0]\d* .* cppRawString ', a) call assert_match(' \d*\.\d* \+[^0]\d* .* cppNumber ', a) syntime off syntime clear let a = execute('syntime report') call assert_match('^ TOTAL *COUNT *MATCH *SLOWEST *AVERAGE *NAME *PATTERN', a) call assert_notmatch('.* cppRawString *', a) call assert_notmatch('.* cppNumber*', a) call assert_notmatch('[1-9]', a) call assert_fails('syntime abc', 'E475:') syntax clear let a = execute('syntime report') call assert_equal("\nNo Syntax items defined for this buffer", a) bd endfunc func Test_syntime_completion() CheckFeature profile call feedkeys(":syntime \<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"syntime clear off on report', @:) endfunc func Test_syntax_list() syntax on let a = execute('syntax list') call assert_equal("\nNo Syntax items defined for this buffer", a) view ../memfile_test.c setfiletype c let a = execute('syntax list') call assert_match('cInclude*', a) call assert_match('cDefine', a) let a = execute('syntax list cDefine') call assert_notmatch('cInclude*', a) call assert_match('cDefine', a) call assert_match(' links to Macro$', a) call assert_fails('syntax list ABCD', 'E28:') call assert_fails('syntax list @ABCD', 'E392:') syntax clear let a = execute('syntax list') call assert_equal("\nNo Syntax items defined for this buffer", a) syntax keyword Type int containedin=g1 skipwhite skipempty skipnl nextgroup=Abc let exp = "Type xxx containedin=g1 nextgroup=Abc skipnl skipwhite skipempty int" call assert_equal(exp, split(execute("syntax list"), "\n")[1]) bd endfunc func Test_syntax_completion() call feedkeys(":syn \<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"syn case clear cluster conceal enable foldlevel include iskeyword keyword list manual match off on region reset spell sync', @:) call feedkeys(":syn case \<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"syn case ignore match', @:) call feedkeys(":syn spell \<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"syn spell default notoplevel toplevel', @:) call feedkeys(":syn sync \<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"syn sync ccomment clear fromstart linebreaks= linecont lines= match maxlines= minlines= region', @:) " Check that clearing "Aap" avoids it showing up before Boolean. hi Aap ctermfg=blue call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx') call assert_match('^"syn list Aap Boolean Character ', @:) hi clear Aap call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx') call assert_match('^"syn list Boolean Character ', @:) call feedkeys(":syn match \<C-A>\<C-B>\"\<CR>", 'tx') call assert_match('^"syn match Boolean Character ', @:) syn cluster Aax contains=Aap call feedkeys(":syn list @A\<C-A>\<C-B>\"\<CR>", 'tx') call assert_match('^"syn list @Aax', @:) endfunc func Test_echohl_completion() call feedkeys(":echohl no\<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"echohl NonText Normal none', @:) endfunc func Test_syntax_arg_skipped() syn clear syntax case ignore if 0 syntax case match endif call assert_match('case ignore', execute('syntax case')) syn keyword Foo foo call assert_match('Foo', execute('syntax')) syn clear call assert_match('case match', execute('syntax case')) call assert_notmatch('Foo', execute('syntax')) if has('conceal') syn clear syntax conceal on if 0 syntax conceal off endif call assert_match('conceal on', execute('syntax conceal')) syn clear call assert_match('conceal off', execute('syntax conceal')) syntax conceal on syntax conceal off call assert_match('conceal off', execute('syntax conceal')) endif syntax region Bar start=/</ end=/>/ if 0 syntax region NotTest start=/</ end=/>/ contains=@Spell endif call assert_match('Bar', execute('syntax')) call assert_notmatch('NotTest', execute('syntax')) call assert_notmatch('Spell', execute('syntax')) hi Foo ctermfg=blue let a = execute('hi Foo') if 0 syntax rest endif call assert_equal(a, execute('hi Foo')) hi clear Bar hi clear Foo set ft=tags syn off if 0 syntax enable endif call assert_match('No Syntax items defined', execute('syntax')) syntax enable call assert_match('tagComment', execute('syntax')) set ft= syn clear if 0 syntax include @Spell nothing endif call assert_notmatch('Spell', execute('syntax')) syn clear syn iskeyword 48-57,$,_ call assert_match('48-57,$,_', execute('syntax iskeyword')) if 0 syn clear syn iskeyword clear endif call assert_match('48-57,$,_', execute('syntax iskeyword')) syn iskeyword clear call assert_match('not set', execute('syntax iskeyword')) syn iskeyword 48-57,$,_ syn clear call assert_match('not set', execute('syntax iskeyword')) syn clear syn keyword Foo foo if 0 syn keyword NotAdded bar endif call assert_match('Foo', execute('syntax')) call assert_notmatch('NotAdded', execute('highlight')) syn clear syn keyword Foo foo call assert_match('Foo', execute('syntax')) call assert_match('Foo', execute('syntax list')) call assert_notmatch('Foo', execute('if 0 | syntax | endif')) call assert_notmatch('Foo', execute('if 0 | syntax list | endif')) syn clear syn match Fopi /asdf/ if 0 syn match Fopx /asdf/ endif call assert_match('Fopi', execute('syntax')) call assert_notmatch('Fopx', execute('syntax')) syn clear syn spell toplevel call assert_match('spell toplevel', execute('syntax spell')) if 0 syn spell notoplevel endif call assert_match('spell toplevel', execute('syntax spell')) syn spell notoplevel call assert_match('spell notoplevel', execute('syntax spell')) syn spell default call assert_match('spell default', execute('syntax spell')) syn clear if 0 syntax cluster Spell endif call assert_notmatch('Spell', execute('syntax')) syn clear syn keyword Foo foo syn sync ccomment syn sync maxlines=5 if 0 syn sync maxlines=11 endif call assert_match('on C-style comments', execute('syntax sync')) call assert_match('maximal 5 lines', execute('syntax sync')) syn sync clear if 0 syn sync ccomment endif call assert_notmatch('on C-style comments', execute('syntax sync')) syn sync fromstart call assert_match('syncing starts at the first line', execute('syntax sync')) syn clear endfunc " Check for an error. Used when multiple errors are thrown and we are checking " for an earliest error. func AssertFails(cmd, errcode) let save_exception = '' try exe a:cmd catch let save_exception = v:exception endtry call assert_match(a:errcode, save_exception) endfunc func Test_syntax_invalid_arg() call assert_fails('syntax case asdf', 'E390:') if has('conceal') call assert_fails('syntax conceal asdf', 'E390:') endif call assert_fails('syntax spell asdf', 'E390:') call assert_fails('syntax clear @ABCD', 'E391:') call assert_fails('syntax include random_file', 'E484:') call assert_fails('syntax include <afile>', 'E495:') call assert_fails('syntax sync x', 'E404:') call assert_fails('syntax keyword Abc a[', 'E789:') call assert_fails('syntax keyword Abc a[bc]d', 'E890:') call assert_fails('syntax cluster Abc add=A add=', 'E406:') " Test for too many \z\( and unmatched \z\( " Not able to use assert_fails() here because both E50:/E879: and E475: " messages are emitted. set regexpengine=1 call AssertFails("syntax region MyRegion start='\\z\\(' end='\\*/'", 'E52:') let cmd = "syntax region MyRegion start='" let cmd ..= repeat("\\z\\(.\\)", 10) .. "' end='\*/'" call AssertFails(cmd, 'E50:') set regexpengine=2 call AssertFails("syntax region MyRegion start='\\z\\(' end='\\*/'", 'E54:') let cmd = "syntax region MyRegion start='" let cmd ..= repeat("\\z\\(.\\)", 10) .. "' end='\*/'" call AssertFails(cmd, 'E879:') set regexpengine& call AssertFails('syntax keyword cMyItem grouphere G1', 'E393:') call AssertFails('syntax sync match Abc grouphere MyItem "abc"', 'E394:') call AssertFails('syn keyword Type contains int', 'E395:') call assert_fails('syntax include @Xxx', 'E397:') call AssertFails('syntax region X start', 'E398:') call assert_fails('syntax region X start="{"', 'E399:') call AssertFails('syntax cluster contains=Abc', 'E400:') call AssertFails("syntax match Character /'.'", 'E401:') call AssertFails("syntax match Character /'.'/a", 'E402:') call assert_fails('syntax sync linecont /\%(/', 'E53:') call assert_fails('syntax sync linecont /pat', 'E404:') call assert_fails('syntax sync linecont', 'E404:') call assert_fails('syntax sync linecont /pat1/ linecont /pat2/', 'E403:') call assert_fails('syntax sync minlines=a', 'E404:') call AssertFails('syntax match ABC /x/ contains=', 'E406:') call AssertFails("syntax match Character contains /'.'/", 'E405:') call AssertFails('syntax match ccFoo "Foo" nextgroup=ALLBUT,F', 'E407:') call AssertFails('syntax region Block start="{" contains=F,ALLBUT', 'E408:') call AssertFails("syntax match Characters contains=a.*x /'.'/", 'E409:') call assert_fails('syntax match Search /abc/ contains=ALLBUT,/\%(/', 'E53:') endfunc func Test_syn_sync() syntax region HereGroup start=/this/ end=/that/ syntax sync match SyncHere grouphere HereGroup "pattern" call assert_match('SyncHere', execute('syntax sync')) syn sync clear call assert_notmatch('SyncHere', execute('syntax sync')) syn clear endfunc func Test_syn_clear() syntax keyword Foo foo syntax keyword Bar tar call assert_match('Foo', execute('syntax')) call assert_match('Bar', execute('syntax')) call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) syn clear Foo call assert_notmatch('Foo', execute('syntax')) call assert_match('Bar', execute('syntax')) call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) syn clear Foo Bar call assert_notmatch('Foo', execute('syntax')) call assert_notmatch('Bar', execute('syntax')) hi clear Foo call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) hi clear Bar call assert_fails('syntax clear invalid_syngroup', 'E28:') endfunc func Test_invalid_name() syn clear syn keyword Nop yes call assert_fails("syntax keyword Wr\x17ong bar", 'E669:') syntax keyword @Wrong bar call assert_match('W18:', execute('1messages')) syn clear hi clear Nop hi clear @Wrong endfunc func Test_ownsyntax() new XfooOwnSyntax call setline(1, '#define FOO') syntax on set filetype=c ownsyntax perl " this should not crash set call assert_equal('perlComment', synIDattr(synID(line('.'), col('.'), 1), 'name')) call assert_equal('c', b:current_syntax) call assert_equal('perl', w:current_syntax) " A new split window should have the original syntax. split call assert_equal('cDefine', synIDattr(synID(line('.'), col('.'), 1), 'name')) call assert_equal('c', b:current_syntax) call assert_equal(0, exists('w:current_syntax')) wincmd x call assert_equal('perlComment', synIDattr(synID(line("."), col("."), 1), "name")) syntax off set filetype& %bw! endfunc func Test_ownsyntax_completion() call feedkeys(":ownsyntax java\<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"ownsyntax java javacc javascript javascriptreact', @:) endfunc func Test_highlight_invalid_arg() if has('gui_running') call assert_fails('hi XXX guifg=xxx', 'E254:') endif call assert_fails('hi DoesNotExist', 'E411:') call assert_fails('hi link', 'E412:') call assert_fails('hi link a', 'E412:') call assert_fails('hi link a b c', 'E413:') call assert_fails('hi XXX =', 'E415:') call assert_fails('hi XXX cterm', 'E416:') call assert_fails('hi XXX cterm=', 'E417:') call assert_fails('hi XXX cterm=DoesNotExist', 'E418:') call assert_fails('hi XXX ctermfg=DoesNotExist', 'E421:') call assert_fails('hi XXX xxx=White', 'E423:') endfunc func Test_bg_detection() CheckNotGui " auto-detection of &bg, make sure it isn't set anywhere before this test hi Normal ctermbg=0 call assert_equal('dark', &bg) hi Normal ctermbg=4 call assert_equal('dark', &bg) hi Normal ctermbg=12 call assert_equal('light', &bg) hi Normal ctermbg=15 call assert_equal('light', &bg) " manually-set &bg takes precedence over auto-detection set bg=light hi Normal ctermbg=4 call assert_equal('light', &bg) set bg=dark hi Normal ctermbg=12 call assert_equal('dark', &bg) hi Normal ctermbg=NONE endfunc func Test_syntax_hangs() CheckFunction reltimefloat CheckFeature syntax " So, it turns out the Windows 7 implements TimerQueue timers differently " and they can expire *before* the requested time has elapsed. So allow for " the timeout occurring after 80 ms (5 * 16 (the typical clock tick)). if has("win32") let min_timeout = 0.08 else let min_timeout = 0.1 endif " This pattern takes a long time to match, it should timeout. new call setline(1, ['aaa', repeat('abc ', 1000), 'ccc']) let start = reltime() set nolazyredraw redrawtime=101 syn match Error /\%#=1a*.*X\@<=b*/ redraw let elapsed = reltimefloat(reltime(start)) call assert_inrange(min_timeout, 1.0, elapsed) " second time syntax HL is disabled let start = reltime() redraw let elapsed = reltimefloat(reltime(start)) call assert_inrange(0, 0.1, elapsed) " after CTRL-L the timeout flag is reset let start = reltime() exe "normal \<C-L>" redraw let elapsed = reltimefloat(reltime(start)) call assert_inrange(min_timeout, 1.0, elapsed) set redrawtime& bwipe! endfunc func Test_conceal() CheckFeature conceal new call setline(1, ['', '123456']) syn match test23 "23" conceal cchar=X syn match test45 "45" conceal set conceallevel=0 call assert_equal('123456 ', ScreenLines(2, 7)[0]) call assert_equal([[0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)')) set conceallevel=1 call assert_equal('1X 6 ', ScreenLines(2, 7)[0]) call assert_equal([[0, '', 0], [1, 'X', 1], [1, 'X', 1], [1, ' ', 2], [1, ' ', 2], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)')) set conceallevel=1 set listchars=conceal:Y call assert_equal([[0, '', 0], [1, 'X', 1], [1, 'X', 1], [1, 'Y', 2], [1, 'Y', 2], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)')) call assert_equal('1XY6 ', ScreenLines(2, 7)[0]) set conceallevel=2 call assert_match('1X6 ', ScreenLines(2, 7)[0]) call assert_equal([[0, '', 0], [1, 'X', 1], [1, 'X', 1], [1, '', 2], [1, '', 2], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)')) set conceallevel=3 call assert_match('16 ', ScreenLines(2, 7)[0]) call assert_equal([[0, '', 0], [1, '', 1], [1, '', 1], [1, '', 2], [1, '', 2], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)')) call AssertFails("syntax match Entity '&' conceal cchar=\<Tab>", 'E844:') syn clear set conceallevel& bw! endfunc func Test_synstack_synIDtrans() new setfiletype c syntax on call setline(1, ' /* A comment with a TODO */') call assert_equal([], synstack(1, 1)) norm f/ eval synstack(line("."), col("."))->map('synIDattr(v:val, "name")')->assert_equal(['cComment', 'cCommentStart']) eval synstack(line("."), col("."))->map('synIDattr(synIDtrans(v:val), "name")')->assert_equal(['Comment', 'Comment']) norm fA call assert_equal(['cComment'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) call assert_equal(['Comment'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")')) norm fT call assert_equal(['cComment', 'cTodo'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) call assert_equal(['Comment', 'Todo'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")')) call assert_fails("let n=synIDtrans([])", 'E745:') syn clear bw! endfunc " Check highlighting for a small piece of C code with a screen dump. func Test_syntax_c() CheckRunVimInTerminal call writefile([ \ '/* comment line at the top */', \ 'int main(int argc, char **argv) { // another comment', \ '#if 0', \ ' int not_used;', \ '#else', \ ' int used;', \ '#endif', \ ' printf("Just an example piece of C code\n");', \ ' return 0x0ff;', \ '}', \ "\t\t ", \ ' static void', \ 'myFunction(const double count, struct nothing, long there) {', \ "\t// 123: nothing to endif here", \ "\tfor (int i = 0; i < count; ++i) {", \ "\t break;", \ "\t}", \ "\tNote: asdf", \ '}', \ ], 'Xtest.c', 'D') " This makes the default for 'background' use "dark", check that the " response to t_RB corrects it to "light". let $COLORFGBG = '15;0' let buf = RunVimInTerminal('Xtest.c', {}) call term_sendkeys(buf, ":syn keyword Search Note\r") call term_sendkeys(buf, ":syn match Error /^\\s\\+$/\r") call term_sendkeys(buf, ":set hlsearch\r") call term_sendkeys(buf, "/endif\r") call term_sendkeys(buf, "vjfC") call VerifyScreenDump(buf, 'Test_syntax_c_01', {}) call term_sendkeys(buf, "\<Esc>") call StopVimInTerminal(buf) let $COLORFGBG = '' endfun " Test \z(...) along with \z1 func Test_syn_zsub() new syntax on call setline(1, 'xxx start foo xxx not end foo xxx end foo xxx') let l:expected = ' ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ ' for l:re in [0, 1, 2] " Example taken from :help :syn-ext-match syntax region Z start="start \z(\I\i*\)" skip="not end \z1" end="end \z1" eval AssertHighlightGroups(1, 1, l:expected, 1, 'regexp=' .. l:re) syntax clear Z endfor set re& bw! endfunc " Using \z() in a region with NFA failing should not crash. func Test_syn_wrong_z_one() new call setline(1, ['just some text', 'with foo and bar to match with']) syn region FooBar start="foo\z(.*\)bar" end="\z1" call test_override("nfa_fail", 1) redraw! redraw! call test_override("ALL", 0) bwipe! endfunc func Test_syntax_after_bufdo() call writefile(['/* aaa comment */'], 'Xaaa.c', 'D') call writefile(['/* bbb comment */'], 'Xbbb.c', 'D') call writefile(['/* ccc comment */'], 'Xccc.c', 'D') call writefile(['/* ddd comment */'], 'Xddd.c', 'D') let bnr = bufnr('%') new Xaaa.c badd Xbbb.c badd Xccc.c badd Xddd.c exe "bwipe " . bnr let l = [] bufdo call add(l, bufnr('%')) call assert_equal(4, len(l)) syntax on " This used to only enable syntax HL in the last buffer. bufdo tab split tabrewind for tab in range(1, 4) norm fm call assert_equal(['cComment'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) tabnext endfor bwipe! Xaaa.c bwipe! Xbbb.c bwipe! Xccc.c bwipe! Xddd.c syntax off endfunc func Test_syntax_foldlevel() new call setline(1, [ \ 'void f(int a)', \ '{', \ ' if (a == 1) {', \ ' a = 0;', \ ' } else if (a == 2) {', \ ' a = 1;', \ ' } else {', \ ' a = 2;', \ ' }', \ ' if (a > 0) {', \ ' if (a == 1) {', \ ' a = 0;', \ ' } /* missing newline */ } /* end of outer if */ else {', \ ' a = 1;', \ ' }', \ ' if (a == 1)', \ ' {', \ ' a = 0;', \ ' }', \ ' else if (a == 2)', \ ' {', \ ' a = 1;', \ ' }', \ ' else', \ ' {', \ ' a = 2;', \ ' }', \ '}', \ ]) setfiletype c syntax on set foldmethod=syntax call assert_fails('syn foldlevel start start', 'E390:') call assert_fails('syn foldlevel not_an_option', 'E390:') set foldlevel=1 syn foldlevel start redir @c syn foldlevel redir END call assert_equal("\nsyntax foldlevel start", @c) syn sync fromstart call assert_match('from the first line$', execute('syn sync')) let a = map(range(3,9), 'foldclosed(v:val)') call assert_equal([3,3,3,3,3,3,3], a) " attached cascade folds together let a = map(range(10,15), 'foldclosed(v:val)') call assert_equal([10,10,10,10,10,10], a) " over-attached 'else' hidden let a = map(range(16,27), 'foldclosed(v:val)') let unattached_results = [-1,17,17,17,-1,21,21,21,-1,25,25,25] call assert_equal(unattached_results, a) " unattached cascade folds separately syn foldlevel minimum redir @c syn foldlevel redir END call assert_equal("\nsyntax foldlevel minimum", @c) syn sync fromstart let a = map(range(3,9), 'foldclosed(v:val)') call assert_equal([3,3,5,5,7,7,7], a) " attached cascade folds separately let a = map(range(10,15), 'foldclosed(v:val)') call assert_equal([10,10,10,13,13,13], a) " over-attached 'else' visible let a = map(range(16,27), 'foldclosed(v:val)') call assert_equal(unattached_results, a) " unattached cascade folds separately set foldlevel=2 syn foldlevel start syn sync fromstart let a = map(range(11,14), 'foldclosed(v:val)') call assert_equal([11,11,11,-1], a) " over-attached 'else' hidden syn foldlevel minimum syn sync fromstart let a = map(range(11,14), 'foldclosed(v:val)') call assert_equal([11,11,-1,-1], a) " over-attached 'else' visible quit! endfunc func Test_search_syntax_skip() new let lines =<< trim END /* This is VIM */ Another Text for VIM let a = "VIM" END call setline(1, lines) syntax on syntax match Comment "^/\*.*\*/" syntax match String '".*"' " Skip argument using string evaluation. 1 call search('VIM', 'w', '', 0, 'synIDattr(synID(line("."), col("."), 1), "name") =~? "comment"') call assert_equal('Another Text for VIM', getline('.')) 1 call search('VIM', 'cw', '', 0, 'synIDattr(synID(line("."), col("."), 1), "name") !~? "string"') call assert_equal(' let a = "VIM"', getline('.')) " Skip argument using Lambda. 1 call search('VIM', 'w', '', 0, { -> synIDattr(synID(line("."), col("."), 1), "name") =~? "comment"}) call assert_equal('Another Text for VIM', getline('.')) 1 call search('VIM', 'cw', '', 0, { -> synIDattr(synID(line("."), col("."), 1), "name") !~? "string"}) call assert_equal(' let a = "VIM"', getline('.')) " Skip argument using funcref. func InComment() return synIDattr(synID(line("."), col("."), 1), "name") =~? "comment" endfunc func NotInString() return synIDattr(synID(line("."), col("."), 1), "name") !~? "string" endfunc 1 call search('VIM', 'w', '', 0, function('InComment')) call assert_equal('Another Text for VIM', getline('.')) 1 call search('VIM', 'cw', '', 0, function('NotInString')) call assert_equal(' let a = "VIM"', getline('.')) delfunc InComment delfunc NotInString bwipe! endfunc func Test_syn_contained_transparent() " Comments starting with "Regression:" show the result when the highlighting " span of the containing item is assigned to the contained region. syntax on let l:case = "Transparent region contained in region" new syntax region X start=/\[/ end=/\]/ contained transparent syntax region Y start=/(/ end=/)/ contains=X call setline(1, "==(--[~~]--)==") let l:expected = " YYYYYYYYYY " eval AssertHighlightGroups(1, 1, l:expected, 1, l:case) syntax clear Y X bw! let l:case = "Transparent region extends region" new syntax region X start=/\[/ end=/\]/ contained transparent syntax region Y start=/(/ end=/)/ end=/e/ contains=X call setline(1, "==(--[~~e~~]--)==") let l:expected = " YYYYYYYYYYYYY " " Regression: " YYYYYYY YYY " eval AssertHighlightGroups(1, 1, l:expected, 1, l:case) syntax clear Y X bw! let l:case = "Nested transparent regions extend region" new syntax region X start=/\[/ end=/\]/ contained transparent syntax region Y start=/(/ end=/)/ end=/e/ contains=X call setline(1, "==(--[~~e~~[~~e~~]~~e~~]--)==") let l:expected = " YYYYYYYYYYYYYYYYYYYYYYYYY " " Regression: " YYYYYYY YYYYYYYYY " eval AssertHighlightGroups(1, 1, l:expected, 1, l:case) syntax clear Y X bw! let l:case = "Transparent region contained in match" new syntax region X start=/\[/ end=/\]/ contained transparent syntax match Y /(.\{-})/ contains=X call setline(1, "==(--[~~]--)==") let l:expected = " YYYYYYYYYY " eval AssertHighlightGroups(1, 1, l:expected, 1, l:case) syntax clear Y X bw! let l:case = "Transparent region extends match" new syntax region X start=/\[/ end=/\]/ contained transparent syntax match Y /(.\{-}[e)]/ contains=X call setline(1, "==(--[~~e~~]--)==") let l:expected = " YYYYYYYYYY " " Regression: " YYYYYYY " eval AssertHighlightGroups(1, 1, l:expected, 1, l:case) syntax clear Y X bw! let l:case = "Nested transparent regions extend match" new syntax region X start=/\[/ end=/\]/ contained transparent syntax match Y /(.\{-}[e)]/ contains=X call setline(1, "==(--[~~e~~[~~e~~]~~e~~]--)==") let l:expected = " YYYYYYYYYYYYYYYYYYYYYY " " Regression: " YYYYYYY YYYYYY " eval AssertHighlightGroups(1, 1, l:expected, 1, l:case) syntax clear Y X bw! endfunc func Test_syn_include_contains_TOP() let l:case = "TOP in included syntax means its group list name" new syntax include @INCLUDED syntax/c.vim syntax region FencedCodeBlockC start=/```c/ end=/```/ contains=@INCLUDED call setline(1, ['```c', '#if 0', 'int', '#else', 'int', '#endif', '```' ]) let l:expected = ["cCppOutIf2"] eval AssertHighlightGroups(3, 1, l:expected, 1) " cCppOutElse has contains=TOP let l:expected = ["cType"] eval AssertHighlightGroups(5, 1, l:expected, 1, l:case) syntax clear bw! endfunc " This was using freed memory func Test_WinEnter_synstack_synID() autocmd WinEnter * call synstack(line("."), col(".")) autocmd WinEnter * call synID(line('.'), col('.') - 1, 1) call setline(1, 'aaaaa') normal! $ new close au! WinEnter bw! endfunc " vim: shiftwidth=2 sts=2 expandtab