1" Test for syntax and syntax iskeyword option 2 3source check.vim 4CheckFeature syntax 5 6source view_util.vim 7source screendump.vim 8 9func GetSyntaxItem(pat) 10 let c = '' 11 let a = ['a', getreg('a'), getregtype('a')] 12 0 13 redraw! 14 call search(a:pat, 'W') 15 let synid = synID(line('.'), col('.'), 1) 16 while synid == synID(line('.'), col('.'), 1) 17 norm! v"ay 18 " stop at whitespace 19 if @a =~# '\s' 20 break 21 endif 22 let c .= @a 23 norm! l 24 endw 25 call call('setreg', a) 26 0 27 return c 28endfunc 29 30func Test_syn_iskeyword() 31 new 32 call setline(1, [ 33 \ 'CREATE TABLE FOOBAR(', 34 \ ' DLTD_BY VARCHAR2(100)', 35 \ ');', 36 \ '']) 37 38 syntax on 39 set ft=sql 40 syn match SYN /C\k\+\>/ 41 hi link SYN ErrorMsg 42 call assert_equal('DLTD_BY', GetSyntaxItem('DLTD')) 43 /\<D\k\+\>/:norm! ygn 44 call assert_equal('DLTD_BY', @0) 45 redir @c 46 syn iskeyword 47 redir END 48 call assert_equal("\nsyntax iskeyword not set", @c) 49 50 syn iskeyword @,48-57,_,192-255 51 redir @c 52 syn iskeyword 53 redir END 54 call assert_equal("\nsyntax iskeyword @,48-57,_,192-255", @c) 55 56 setlocal isk-=_ 57 call assert_equal('DLTD_BY', GetSyntaxItem('DLTD')) 58 /\<D\k\+\>/:norm! ygn 59 let b2 = @0 60 call assert_equal('DLTD', @0) 61 62 syn iskeyword clear 63 redir @c 64 syn iskeyword 65 redir END 66 call assert_equal("\nsyntax iskeyword not set", @c) 67 68 quit! 69endfunc 70 71func Test_syntax_after_reload() 72 split Xsomefile 73 call setline(1, ['hello', 'there']) 74 w! 75 only! 76 setl filetype=hello 77 au FileType hello let g:gotit = 1 78 call assert_false(exists('g:gotit')) 79 edit other 80 buf Xsomefile 81 call assert_equal('hello', &filetype) 82 call assert_true(exists('g:gotit')) 83 call delete('Xsomefile') 84endfunc 85 86func Test_syntime() 87 CheckFeature profile 88 89 syntax on 90 syntime on 91 let a = execute('syntime report') 92 call assert_equal("\nNo Syntax items defined for this buffer", a) 93 94 view ../memfile_test.c 95 setfiletype cpp 96 redraw 97 let a = execute('syntime report') 98 call assert_match('^ TOTAL *COUNT *MATCH *SLOWEST *AVERAGE *NAME *PATTERN', a) 99 call assert_match(' \d*\.\d* \+[^0]\d* .* cppRawString ', a) 100 call assert_match(' \d*\.\d* \+[^0]\d* .* cppNumber ', a) 101 102 syntime off 103 syntime clear 104 let a = execute('syntime report') 105 call assert_match('^ TOTAL *COUNT *MATCH *SLOWEST *AVERAGE *NAME *PATTERN', a) 106 call assert_notmatch('.* cppRawString *', a) 107 call assert_notmatch('.* cppNumber*', a) 108 call assert_notmatch('[1-9]', a) 109 110 call assert_fails('syntime abc', 'E475:') 111 112 syntax clear 113 let a = execute('syntime report') 114 call assert_equal("\nNo Syntax items defined for this buffer", a) 115 116 bd 117endfunc 118 119func Test_syntime_completion() 120 CheckFeature profile 121 122 call feedkeys(":syntime \<C-A>\<C-B>\"\<CR>", 'tx') 123 call assert_equal('"syntime clear off on report', @:) 124endfunc 125 126func Test_syntax_list() 127 syntax on 128 let a = execute('syntax list') 129 call assert_equal("\nNo Syntax items defined for this buffer", a) 130 131 view ../memfile_test.c 132 setfiletype c 133 134 let a = execute('syntax list') 135 call assert_match('cInclude*', a) 136 call assert_match('cDefine', a) 137 138 let a = execute('syntax list cDefine') 139 call assert_notmatch('cInclude*', a) 140 call assert_match('cDefine', a) 141 call assert_match(' links to Macro$', a) 142 143 call assert_fails('syntax list ABCD', 'E28:') 144 call assert_fails('syntax list @ABCD', 'E392:') 145 146 syntax clear 147 let a = execute('syntax list') 148 call assert_equal("\nNo Syntax items defined for this buffer", a) 149 150 syntax keyword Type int containedin=g1 skipwhite skipempty skipnl nextgroup=Abc 151 let exp = "Type xxx containedin=g1 nextgroup=Abc skipnl skipwhite skipempty int" 152 call assert_equal(exp, split(execute("syntax list"), "\n")[1]) 153 154 bd 155endfunc 156 157func Test_syntax_completion() 158 call feedkeys(":syn \<C-A>\<C-B>\"\<CR>", 'tx') 159 call assert_equal('"syn case clear cluster conceal enable foldlevel include iskeyword keyword list manual match off on region reset spell sync', @:) 160 161 call feedkeys(":syn case \<C-A>\<C-B>\"\<CR>", 'tx') 162 call assert_equal('"syn case ignore match', @:) 163 164 call feedkeys(":syn spell \<C-A>\<C-B>\"\<CR>", 'tx') 165 call assert_equal('"syn spell default notoplevel toplevel', @:) 166 167 call feedkeys(":syn sync \<C-A>\<C-B>\"\<CR>", 'tx') 168 call assert_equal('"syn sync ccomment clear fromstart linebreaks= linecont lines= match maxlines= minlines= region', @:) 169 170 " Check that clearing "Aap" avoids it showing up before Boolean. 171 hi Aap ctermfg=blue 172 call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx') 173 call assert_match('^"syn list Aap Boolean Character ', @:) 174 hi clear Aap 175 176 call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx') 177 call assert_match('^"syn list Boolean Character ', @:) 178 179 call feedkeys(":syn match \<C-A>\<C-B>\"\<CR>", 'tx') 180 call assert_match('^"syn match Boolean Character ', @:) 181endfunc 182 183func Test_echohl_completion() 184 call feedkeys(":echohl no\<C-A>\<C-B>\"\<CR>", 'tx') 185 call assert_equal('"echohl NonText Normal none', @:) 186endfunc 187 188func Test_syntax_arg_skipped() 189 syn clear 190 syntax case ignore 191 if 0 192 syntax case match 193 endif 194 call assert_match('case ignore', execute('syntax case')) 195 196 syn keyword Foo foo 197 call assert_match('Foo', execute('syntax')) 198 syn clear 199 call assert_match('case match', execute('syntax case')) 200 call assert_notmatch('Foo', execute('syntax')) 201 202 if has('conceal') 203 syn clear 204 syntax conceal on 205 if 0 206 syntax conceal off 207 endif 208 call assert_match('conceal on', execute('syntax conceal')) 209 syn clear 210 call assert_match('conceal off', execute('syntax conceal')) 211 212 syntax conceal on 213 syntax conceal off 214 call assert_match('conceal off', execute('syntax conceal')) 215 endif 216 217 syntax region Bar start=/</ end=/>/ 218 if 0 219 syntax region NotTest start=/</ end=/>/ contains=@Spell 220 endif 221 call assert_match('Bar', execute('syntax')) 222 call assert_notmatch('NotTest', execute('syntax')) 223 call assert_notmatch('Spell', execute('syntax')) 224 225 hi Foo ctermfg=blue 226 let a = execute('hi Foo') 227 if 0 228 syntax rest 229 endif 230 call assert_equal(a, execute('hi Foo')) 231 hi clear Bar 232 hi clear Foo 233 234 set ft=tags 235 syn off 236 if 0 237 syntax enable 238 endif 239 call assert_match('No Syntax items defined', execute('syntax')) 240 syntax enable 241 call assert_match('tagComment', execute('syntax')) 242 set ft= 243 244 syn clear 245 if 0 246 syntax include @Spell nothing 247 endif 248 call assert_notmatch('Spell', execute('syntax')) 249 250 syn clear 251 syn iskeyword 48-57,$,_ 252 call assert_match('48-57,$,_', execute('syntax iskeyword')) 253 if 0 254 syn clear 255 syn iskeyword clear 256 endif 257 call assert_match('48-57,$,_', execute('syntax iskeyword')) 258 syn iskeyword clear 259 call assert_match('not set', execute('syntax iskeyword')) 260 syn iskeyword 48-57,$,_ 261 syn clear 262 call assert_match('not set', execute('syntax iskeyword')) 263 264 syn clear 265 syn keyword Foo foo 266 if 0 267 syn keyword NotAdded bar 268 endif 269 call assert_match('Foo', execute('syntax')) 270 call assert_notmatch('NotAdded', execute('highlight')) 271 272 syn clear 273 syn keyword Foo foo 274 call assert_match('Foo', execute('syntax')) 275 call assert_match('Foo', execute('syntax list')) 276 call assert_notmatch('Foo', execute('if 0 | syntax | endif')) 277 call assert_notmatch('Foo', execute('if 0 | syntax list | endif')) 278 279 syn clear 280 syn match Fopi /asdf/ 281 if 0 282 syn match Fopx /asdf/ 283 endif 284 call assert_match('Fopi', execute('syntax')) 285 call assert_notmatch('Fopx', execute('syntax')) 286 287 syn clear 288 syn spell toplevel 289 call assert_match('spell toplevel', execute('syntax spell')) 290 if 0 291 syn spell notoplevel 292 endif 293 call assert_match('spell toplevel', execute('syntax spell')) 294 syn spell notoplevel 295 call assert_match('spell notoplevel', execute('syntax spell')) 296 syn spell default 297 call assert_match('spell default', execute('syntax spell')) 298 299 syn clear 300 if 0 301 syntax cluster Spell 302 endif 303 call assert_notmatch('Spell', execute('syntax')) 304 305 syn clear 306 syn keyword Foo foo 307 syn sync ccomment 308 syn sync maxlines=5 309 if 0 310 syn sync maxlines=11 311 endif 312 call assert_match('on C-style comments', execute('syntax sync')) 313 call assert_match('maximal 5 lines', execute('syntax sync')) 314 syn sync clear 315 if 0 316 syn sync ccomment 317 endif 318 call assert_notmatch('on C-style comments', execute('syntax sync')) 319 320 syn clear 321endfunc 322 323" Check for an error. Used when multiple errors are thrown and we are checking 324" for an earliest error. 325func AssertFails(cmd, errcode) 326 let save_exception = '' 327 try 328 exe a:cmd 329 catch 330 let save_exception = v:exception 331 endtry 332 call assert_match(a:errcode, save_exception) 333endfunc 334 335func Test_syntax_invalid_arg() 336 call assert_fails('syntax case asdf', 'E390:') 337 if has('conceal') 338 call assert_fails('syntax conceal asdf', 'E390:') 339 endif 340 call assert_fails('syntax spell asdf', 'E390:') 341 call assert_fails('syntax clear @ABCD', 'E391:') 342 call assert_fails('syntax include random_file', 'E484:') 343 call assert_fails('syntax include <afile>', 'E495:') 344 call assert_fails('syntax sync x', 'E404:') 345 call assert_fails('syntax keyword Abc a[', 'E789:') 346 call assert_fails('syntax keyword Abc a[bc]d', 'E890:') 347 call assert_fails('syntax cluster Abc add=A add=', 'E406:') 348 349 " Test for too many \z\( and unmatched \z\( 350 " Not able to use assert_fails() here because both E50:/E879: and E475: 351 " messages are emitted. 352 set regexpengine=1 353 call AssertFails("syntax region MyRegion start='\\z\\(' end='\\*/'", 'E52:') 354 355 let cmd = "syntax region MyRegion start='" 356 let cmd ..= repeat("\\z\\(.\\)", 10) .. "' end='\*/'" 357 call AssertFails(cmd, 'E50:') 358 359 set regexpengine=2 360 call AssertFails("syntax region MyRegion start='\\z\\(' end='\\*/'", 'E54:') 361 362 let cmd = "syntax region MyRegion start='" 363 let cmd ..= repeat("\\z\\(.\\)", 10) .. "' end='\*/'" 364 call AssertFails(cmd, 'E879:') 365 set regexpengine& 366 367 call AssertFails('syntax keyword cMyItem grouphere G1', 'E393:') 368 call AssertFails('syntax sync match Abc grouphere MyItem "abc"', 'E394:') 369 call AssertFails('syn keyword Type contains int', 'E395:') 370 call assert_fails('syntax include @Xxx', 'E397:') 371 call AssertFails('syntax region X start', 'E398:') 372 call assert_fails('syntax region X start="{"', 'E399:') 373 call AssertFails('syntax cluster contains=Abc', 'E400:') 374 call AssertFails("syntax match Character /'.'", 'E401:') 375 call AssertFails("syntax match Character /'.'/a", 'E402:') 376 call assert_fails('syntax sync linecont /\%(/', 'E53:') 377 call assert_fails('syntax sync linecont /pat', 'E404:') 378 call assert_fails('syntax sync linecont', 'E404:') 379 call assert_fails('syntax sync linecont /pat1/ linecont /pat2/', 'E403:') 380 call assert_fails('syntax sync minlines=a', 'E404:') 381 call AssertFails('syntax match ABC /x/ contains=', 'E406:') 382 call AssertFails("syntax match Character contains /'.'/", 'E405:') 383 call AssertFails('syntax match ccFoo "Foo" nextgroup=ALLBUT,F', 'E407:') 384 call AssertFails('syntax region Block start="{" contains=F,ALLBUT', 'E408:') 385 call AssertFails("syntax match Characters contains=a.*x /'.'/", 'E409:') 386 call assert_fails('syntax match Search /abc/ contains=ALLBUT,/\%(/', 'E53:') 387endfunc 388 389func Test_syn_sync() 390 syntax region HereGroup start=/this/ end=/that/ 391 syntax sync match SyncHere grouphere HereGroup "pattern" 392 call assert_match('SyncHere', execute('syntax sync')) 393 syn sync clear 394 call assert_notmatch('SyncHere', execute('syntax sync')) 395 syn clear 396endfunc 397 398func Test_syn_clear() 399 syntax keyword Foo foo 400 syntax keyword Bar tar 401 call assert_match('Foo', execute('syntax')) 402 call assert_match('Bar', execute('syntax')) 403 call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) 404 syn clear Foo 405 call assert_notmatch('Foo', execute('syntax')) 406 call assert_match('Bar', execute('syntax')) 407 call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) 408 syn clear Foo Bar 409 call assert_notmatch('Foo', execute('syntax')) 410 call assert_notmatch('Bar', execute('syntax')) 411 hi clear Foo 412 call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) 413 hi clear Bar 414 call assert_fails('syntax clear invalid_syngroup', 'E28:') 415endfunc 416 417func Test_invalid_name() 418 syn clear 419 syn keyword Nop yes 420 call assert_fails("syntax keyword Wr\x17ong bar", 'E669:') 421 syntax keyword @Wrong bar 422 call assert_match('W18:', execute('1messages')) 423 syn clear 424 hi clear Nop 425 hi clear @Wrong 426endfunc 427 428func Test_ownsyntax() 429 new Xfoo 430 call setline(1, '#define FOO') 431 syntax on 432 set filetype=c 433 434 ownsyntax perl 435 " this should not crash 436 set 437 438 call assert_equal('perlComment', synIDattr(synID(line('.'), col('.'), 1), 'name')) 439 call assert_equal('c', b:current_syntax) 440 call assert_equal('perl', w:current_syntax) 441 442 " A new split window should have the original syntax. 443 split 444 call assert_equal('cDefine', synIDattr(synID(line('.'), col('.'), 1), 'name')) 445 call assert_equal('c', b:current_syntax) 446 call assert_equal(0, exists('w:current_syntax')) 447 448 wincmd x 449 call assert_equal('perlComment', synIDattr(synID(line("."), col("."), 1), "name")) 450 451 syntax off 452 set filetype& 453 %bw! 454endfunc 455 456func Test_ownsyntax_completion() 457 call feedkeys(":ownsyntax java\<C-A>\<C-B>\"\<CR>", 'tx') 458 call assert_equal('"ownsyntax java javacc javascript javascriptreact', @:) 459endfunc 460 461func Test_highlight_invalid_arg() 462 if has('gui_running') 463 call assert_fails('hi XXX guifg=xxx', 'E254:') 464 endif 465 call assert_fails('hi DoesNotExist', 'E411:') 466 call assert_fails('hi link', 'E412:') 467 call assert_fails('hi link a', 'E412:') 468 call assert_fails('hi link a b c', 'E413:') 469 call assert_fails('hi XXX =', 'E415:') 470 call assert_fails('hi XXX cterm', 'E416:') 471 call assert_fails('hi XXX cterm=', 'E417:') 472 call assert_fails('hi XXX cterm=DoesNotExist', 'E418:') 473 call assert_fails('hi XXX ctermfg=DoesNotExist', 'E421:') 474 call assert_fails('hi XXX xxx=White', 'E423:') 475endfunc 476 477func Test_bg_detection() 478 CheckNotGui 479 480 " auto-detection of &bg, make sure sure it isn't set anywhere before 481 " this test 482 hi Normal ctermbg=0 483 call assert_equal('dark', &bg) 484 hi Normal ctermbg=4 485 call assert_equal('dark', &bg) 486 hi Normal ctermbg=12 487 call assert_equal('light', &bg) 488 hi Normal ctermbg=15 489 call assert_equal('light', &bg) 490 491 " manually-set &bg takes precedence over auto-detection 492 set bg=light 493 hi Normal ctermbg=4 494 call assert_equal('light', &bg) 495 set bg=dark 496 hi Normal ctermbg=12 497 call assert_equal('dark', &bg) 498 499 hi Normal ctermbg=NONE 500endfunc 501 502func Test_syntax_hangs() 503 CheckFunction reltimefloat 504 CheckFeature syntax 505 506 " This pattern takes a long time to match, it should timeout. 507 new 508 call setline(1, ['aaa', repeat('abc ', 1000), 'ccc']) 509 let start = reltime() 510 set nolazyredraw redrawtime=101 511 syn match Error /\%#=1a*.*X\@<=b*/ 512 redraw 513 let elapsed = reltimefloat(reltime(start)) 514 call assert_true(elapsed > 0.1) 515 call assert_true(elapsed < 1.0) 516 517 " second time syntax HL is disabled 518 let start = reltime() 519 redraw 520 let elapsed = reltimefloat(reltime(start)) 521 call assert_true(elapsed < 0.1) 522 523 " after CTRL-L the timeout flag is reset 524 let start = reltime() 525 exe "normal \<C-L>" 526 redraw 527 let elapsed = reltimefloat(reltime(start)) 528 call assert_true(elapsed > 0.1) 529 call assert_true(elapsed < 1.0) 530 531 set redrawtime& 532 bwipe! 533endfunc 534 535func Test_conceal() 536 CheckFeature conceal 537 538 new 539 call setline(1, ['', '123456']) 540 syn match test23 "23" conceal cchar=X 541 syn match test45 "45" conceal 542 543 set conceallevel=0 544 call assert_equal('123456 ', ScreenLines(2, 7)[0]) 545 call assert_equal([[0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)')) 546 547 set conceallevel=1 548 call assert_equal('1X 6 ', ScreenLines(2, 7)[0]) 549 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)')) 550 551 set conceallevel=1 552 set listchars=conceal:Y 553 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)')) 554 call assert_equal('1XY6 ', ScreenLines(2, 7)[0]) 555 556 set conceallevel=2 557 call assert_match('1X6 ', ScreenLines(2, 7)[0]) 558 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)')) 559 560 set conceallevel=3 561 call assert_match('16 ', ScreenLines(2, 7)[0]) 562 call assert_equal([[0, '', 0], [1, '', 1], [1, '', 1], [1, '', 2], [1, '', 2], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)')) 563 564 call AssertFails("syntax match Entity '&' conceal cchar=\<Tab>", 'E844:') 565 566 syn clear 567 set conceallevel& 568 bw! 569endfunc 570 571func Test_synstack_synIDtrans() 572 new 573 setfiletype c 574 syntax on 575 call setline(1, ' /* A comment with a TODO */') 576 577 call assert_equal([], synstack(1, 1)) 578 579 norm f/ 580 eval synstack(line("."), col("."))->map('synIDattr(v:val, "name")')->assert_equal(['cComment', 'cCommentStart']) 581 eval synstack(line("."), col("."))->map('synIDattr(synIDtrans(v:val), "name")')->assert_equal(['Comment', 'Comment']) 582 583 norm fA 584 call assert_equal(['cComment'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) 585 call assert_equal(['Comment'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")')) 586 587 norm fT 588 call assert_equal(['cComment', 'cTodo'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) 589 call assert_equal(['Comment', 'Todo'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")')) 590 591 call assert_fails("let n=synIDtrans([])", 'E745:') 592 593 syn clear 594 bw! 595endfunc 596 597" Check highlighting for a small piece of C code with a screen dump. 598func Test_syntax_c() 599 CheckRunVimInTerminal 600 call writefile([ 601 \ '/* comment line at the top */', 602 \ 'int main(int argc, char **argv) { // another comment', 603 \ '#if 0', 604 \ ' int not_used;', 605 \ '#else', 606 \ ' int used;', 607 \ '#endif', 608 \ ' printf("Just an example piece of C code\n");', 609 \ ' return 0x0ff;', 610 \ '}', 611 \ "\t\t ", 612 \ ' static void', 613 \ 'myFunction(const double count, struct nothing, long there) {', 614 \ "\t// 123: nothing to endif here", 615 \ "\tfor (int i = 0; i < count; ++i) {", 616 \ "\t break;", 617 \ "\t}", 618 \ "\tNote: asdf", 619 \ '}', 620 \ ], 'Xtest.c') 621 622 " This makes the default for 'background' use "dark", check that the 623 " response to t_RB corrects it to "light". 624 let $COLORFGBG = '15;0' 625 626 let buf = RunVimInTerminal('Xtest.c', {}) 627 call term_sendkeys(buf, ":syn keyword Search Note\r") 628 call term_sendkeys(buf, ":syn match Error /^\\s\\+$/\r") 629 call term_sendkeys(buf, ":set hlsearch\r") 630 call term_sendkeys(buf, "/endif\r") 631 call term_sendkeys(buf, "vjfC") 632 call VerifyScreenDump(buf, 'Test_syntax_c_01', {}) 633 634 call term_sendkeys(buf, "\<Esc>") 635 call StopVimInTerminal(buf) 636 637 let $COLORFGBG = '' 638 call delete('Xtest.c') 639endfun 640 641" Using \z() in a region with NFA failing should not crash. 642func Test_syn_wrong_z_one() 643 new 644 call setline(1, ['just some text', 'with foo and bar to match with']) 645 syn region FooBar start="foo\z(.*\)bar" end="\z1" 646 call test_override("nfa_fail", 1) 647 redraw! 648 redraw! 649 call test_override("ALL", 0) 650 bwipe! 651endfunc 652 653func Test_syntax_after_bufdo() 654 call writefile(['/* aaa comment */'], 'Xaaa.c') 655 call writefile(['/* bbb comment */'], 'Xbbb.c') 656 call writefile(['/* ccc comment */'], 'Xccc.c') 657 call writefile(['/* ddd comment */'], 'Xddd.c') 658 659 let bnr = bufnr('%') 660 new Xaaa.c 661 badd Xbbb.c 662 badd Xccc.c 663 badd Xddd.c 664 exe "bwipe " . bnr 665 let l = [] 666 bufdo call add(l, bufnr('%')) 667 call assert_equal(4, len(l)) 668 669 syntax on 670 671 " This used to only enable syntax HL in the last buffer. 672 bufdo tab split 673 tabrewind 674 for tab in range(1, 4) 675 norm fm 676 call assert_equal(['cComment'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) 677 tabnext 678 endfor 679 680 bwipe! Xaaa.c 681 bwipe! Xbbb.c 682 bwipe! Xccc.c 683 bwipe! Xddd.c 684 syntax off 685 call delete('Xaaa.c') 686 call delete('Xbbb.c') 687 call delete('Xccc.c') 688 call delete('Xddd.c') 689endfunc 690 691func Test_syntax_foldlevel() 692 new 693 call setline(1, [ 694 \ 'void f(int a)', 695 \ '{', 696 \ ' if (a == 1) {', 697 \ ' a = 0;', 698 \ ' } else if (a == 2) {', 699 \ ' a = 1;', 700 \ ' } else {', 701 \ ' a = 2;', 702 \ ' }', 703 \ ' if (a > 0) {', 704 \ ' if (a == 1) {', 705 \ ' a = 0;', 706 \ ' } /* missing newline */ } /* end of outer if */ else {', 707 \ ' a = 1;', 708 \ ' }', 709 \ ' if (a == 1)', 710 \ ' {', 711 \ ' a = 0;', 712 \ ' }', 713 \ ' else if (a == 2)', 714 \ ' {', 715 \ ' a = 1;', 716 \ ' }', 717 \ ' else', 718 \ ' {', 719 \ ' a = 2;', 720 \ ' }', 721 \ '}', 722 \ ]) 723 setfiletype c 724 syntax on 725 set foldmethod=syntax 726 727 call assert_fails('syn foldlevel start start', 'E390:') 728 call assert_fails('syn foldlevel not_an_option', 'E390:') 729 730 set foldlevel=1 731 732 syn foldlevel start 733 redir @c 734 syn foldlevel 735 redir END 736 call assert_equal("\nsyntax foldlevel start", @c) 737 syn sync fromstart 738 let a = map(range(3,9), 'foldclosed(v:val)') 739 call assert_equal([3,3,3,3,3,3,3], a) " attached cascade folds together 740 let a = map(range(10,15), 'foldclosed(v:val)') 741 call assert_equal([10,10,10,10,10,10], a) " over-attached 'else' hidden 742 let a = map(range(16,27), 'foldclosed(v:val)') 743 let unattached_results = [-1,17,17,17,-1,21,21,21,-1,25,25,25] 744 call assert_equal(unattached_results, a) " unattached cascade folds separately 745 746 syn foldlevel minimum 747 redir @c 748 syn foldlevel 749 redir END 750 call assert_equal("\nsyntax foldlevel minimum", @c) 751 syn sync fromstart 752 let a = map(range(3,9), 'foldclosed(v:val)') 753 call assert_equal([3,3,5,5,7,7,7], a) " attached cascade folds separately 754 let a = map(range(10,15), 'foldclosed(v:val)') 755 call assert_equal([10,10,10,13,13,13], a) " over-attached 'else' visible 756 let a = map(range(16,27), 'foldclosed(v:val)') 757 call assert_equal(unattached_results, a) " unattached cascade folds separately 758 759 set foldlevel=2 760 761 syn foldlevel start 762 syn sync fromstart 763 let a = map(range(11,14), 'foldclosed(v:val)') 764 call assert_equal([11,11,11,-1], a) " over-attached 'else' hidden 765 766 syn foldlevel minimum 767 syn sync fromstart 768 let a = map(range(11,14), 'foldclosed(v:val)') 769 call assert_equal([11,11,-1,-1], a) " over-attached 'else' visible 770 771 quit! 772endfunc 773 774func Test_search_syntax_skip() 775 new 776 let lines =<< trim END 777 778 /* This is VIM */ 779 Another Text for VIM 780 let a = "VIM" 781 END 782 call setline(1, lines) 783 syntax on 784 syntax match Comment "^/\*.*\*/" 785 syntax match String '".*"' 786 787 " Skip argument using string evaluation. 788 1 789 call search('VIM', 'w', '', 0, 'synIDattr(synID(line("."), col("."), 1), "name") =~? "comment"') 790 call assert_equal('Another Text for VIM', getline('.')) 791 1 792 call search('VIM', 'w', '', 0, 'synIDattr(synID(line("."), col("."), 1), "name") !~? "string"') 793 call assert_equal(' let a = "VIM"', getline('.')) 794 795 " Skip argument using Lambda. 796 1 797 call search('VIM', 'w', '', 0, { -> synIDattr(synID(line("."), col("."), 1), "name") =~? "comment"}) 798 call assert_equal('Another Text for VIM', getline('.')) 799 800 1 801 call search('VIM', 'w', '', 0, { -> synIDattr(synID(line("."), col("."), 1), "name") !~? "string"}) 802 call assert_equal(' let a = "VIM"', getline('.')) 803 804 " Skip argument using funcref. 805 func InComment() 806 return synIDattr(synID(line("."), col("."), 1), "name") =~? "comment" 807 endfunc 808 func InString() 809 return synIDattr(synID(line("."), col("."), 1), "name") !~? "string" 810 endfunc 811 1 812 call search('VIM', 'w', '', 0, function('InComment')) 813 call assert_equal('Another Text for VIM', getline('.')) 814 815 1 816 call search('VIM', 'w', '', 0, function('InString')) 817 call assert_equal(' let a = "VIM"', getline('.')) 818 819 delfunc InComment 820 delfunc InString 821 bwipe! 822endfunc 823 824" vim: shiftwidth=2 sts=2 expandtab 825