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 syn sync fromstart 320 call assert_match('syncing starts at the first line', execute('syntax sync')) 321 322 syn clear 323endfunc 324 325" Check for an error. Used when multiple errors are thrown and we are checking 326" for an earliest error. 327func AssertFails(cmd, errcode) 328 let save_exception = '' 329 try 330 exe a:cmd 331 catch 332 let save_exception = v:exception 333 endtry 334 call assert_match(a:errcode, save_exception) 335endfunc 336 337func Test_syntax_invalid_arg() 338 call assert_fails('syntax case asdf', 'E390:') 339 if has('conceal') 340 call assert_fails('syntax conceal asdf', 'E390:') 341 endif 342 call assert_fails('syntax spell asdf', 'E390:') 343 call assert_fails('syntax clear @ABCD', 'E391:') 344 call assert_fails('syntax include random_file', 'E484:') 345 call assert_fails('syntax include <afile>', 'E495:') 346 call assert_fails('syntax sync x', 'E404:') 347 call assert_fails('syntax keyword Abc a[', 'E789:') 348 call assert_fails('syntax keyword Abc a[bc]d', 'E890:') 349 call assert_fails('syntax cluster Abc add=A add=', 'E406:') 350 351 " Test for too many \z\( and unmatched \z\( 352 " Not able to use assert_fails() here because both E50:/E879: and E475: 353 " messages are emitted. 354 set regexpengine=1 355 call AssertFails("syntax region MyRegion start='\\z\\(' end='\\*/'", 'E52:') 356 357 let cmd = "syntax region MyRegion start='" 358 let cmd ..= repeat("\\z\\(.\\)", 10) .. "' end='\*/'" 359 call AssertFails(cmd, 'E50:') 360 361 set regexpengine=2 362 call AssertFails("syntax region MyRegion start='\\z\\(' end='\\*/'", 'E54:') 363 364 let cmd = "syntax region MyRegion start='" 365 let cmd ..= repeat("\\z\\(.\\)", 10) .. "' end='\*/'" 366 call AssertFails(cmd, 'E879:') 367 set regexpengine& 368 369 call AssertFails('syntax keyword cMyItem grouphere G1', 'E393:') 370 call AssertFails('syntax sync match Abc grouphere MyItem "abc"', 'E394:') 371 call AssertFails('syn keyword Type contains int', 'E395:') 372 call assert_fails('syntax include @Xxx', 'E397:') 373 call AssertFails('syntax region X start', 'E398:') 374 call assert_fails('syntax region X start="{"', 'E399:') 375 call AssertFails('syntax cluster contains=Abc', 'E400:') 376 call AssertFails("syntax match Character /'.'", 'E401:') 377 call AssertFails("syntax match Character /'.'/a", 'E402:') 378 call assert_fails('syntax sync linecont /\%(/', 'E53:') 379 call assert_fails('syntax sync linecont /pat', 'E404:') 380 call assert_fails('syntax sync linecont', 'E404:') 381 call assert_fails('syntax sync linecont /pat1/ linecont /pat2/', 'E403:') 382 call assert_fails('syntax sync minlines=a', 'E404:') 383 call AssertFails('syntax match ABC /x/ contains=', 'E406:') 384 call AssertFails("syntax match Character contains /'.'/", 'E405:') 385 call AssertFails('syntax match ccFoo "Foo" nextgroup=ALLBUT,F', 'E407:') 386 call AssertFails('syntax region Block start="{" contains=F,ALLBUT', 'E408:') 387 call AssertFails("syntax match Characters contains=a.*x /'.'/", 'E409:') 388 call assert_fails('syntax match Search /abc/ contains=ALLBUT,/\%(/', 'E53:') 389endfunc 390 391func Test_syn_sync() 392 syntax region HereGroup start=/this/ end=/that/ 393 syntax sync match SyncHere grouphere HereGroup "pattern" 394 call assert_match('SyncHere', execute('syntax sync')) 395 syn sync clear 396 call assert_notmatch('SyncHere', execute('syntax sync')) 397 syn clear 398endfunc 399 400func Test_syn_clear() 401 syntax keyword Foo foo 402 syntax keyword Bar tar 403 call assert_match('Foo', execute('syntax')) 404 call assert_match('Bar', execute('syntax')) 405 call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) 406 syn clear Foo 407 call assert_notmatch('Foo', execute('syntax')) 408 call assert_match('Bar', execute('syntax')) 409 call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) 410 syn clear Foo Bar 411 call assert_notmatch('Foo', execute('syntax')) 412 call assert_notmatch('Bar', execute('syntax')) 413 hi clear Foo 414 call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) 415 hi clear Bar 416 call assert_fails('syntax clear invalid_syngroup', 'E28:') 417endfunc 418 419func Test_invalid_name() 420 syn clear 421 syn keyword Nop yes 422 call assert_fails("syntax keyword Wr\x17ong bar", 'E669:') 423 syntax keyword @Wrong bar 424 call assert_match('W18:', execute('1messages')) 425 syn clear 426 hi clear Nop 427 hi clear @Wrong 428endfunc 429 430func Test_ownsyntax() 431 new Xfoo 432 call setline(1, '#define FOO') 433 syntax on 434 set filetype=c 435 436 ownsyntax perl 437 " this should not crash 438 set 439 440 call assert_equal('perlComment', synIDattr(synID(line('.'), col('.'), 1), 'name')) 441 call assert_equal('c', b:current_syntax) 442 call assert_equal('perl', w:current_syntax) 443 444 " A new split window should have the original syntax. 445 split 446 call assert_equal('cDefine', synIDattr(synID(line('.'), col('.'), 1), 'name')) 447 call assert_equal('c', b:current_syntax) 448 call assert_equal(0, exists('w:current_syntax')) 449 450 wincmd x 451 call assert_equal('perlComment', synIDattr(synID(line("."), col("."), 1), "name")) 452 453 syntax off 454 set filetype& 455 %bw! 456endfunc 457 458func Test_ownsyntax_completion() 459 call feedkeys(":ownsyntax java\<C-A>\<C-B>\"\<CR>", 'tx') 460 call assert_equal('"ownsyntax java javacc javascript javascriptreact', @:) 461endfunc 462 463func Test_highlight_invalid_arg() 464 if has('gui_running') 465 call assert_fails('hi XXX guifg=xxx', 'E254:') 466 endif 467 call assert_fails('hi DoesNotExist', 'E411:') 468 call assert_fails('hi link', 'E412:') 469 call assert_fails('hi link a', 'E412:') 470 call assert_fails('hi link a b c', 'E413:') 471 call assert_fails('hi XXX =', 'E415:') 472 call assert_fails('hi XXX cterm', 'E416:') 473 call assert_fails('hi XXX cterm=', 'E417:') 474 call assert_fails('hi XXX cterm=DoesNotExist', 'E418:') 475 call assert_fails('hi XXX ctermfg=DoesNotExist', 'E421:') 476 call assert_fails('hi XXX xxx=White', 'E423:') 477endfunc 478 479func Test_bg_detection() 480 CheckNotGui 481 482 " auto-detection of &bg, make sure sure it isn't set anywhere before 483 " this test 484 hi Normal ctermbg=0 485 call assert_equal('dark', &bg) 486 hi Normal ctermbg=4 487 call assert_equal('dark', &bg) 488 hi Normal ctermbg=12 489 call assert_equal('light', &bg) 490 hi Normal ctermbg=15 491 call assert_equal('light', &bg) 492 493 " manually-set &bg takes precedence over auto-detection 494 set bg=light 495 hi Normal ctermbg=4 496 call assert_equal('light', &bg) 497 set bg=dark 498 hi Normal ctermbg=12 499 call assert_equal('dark', &bg) 500 501 hi Normal ctermbg=NONE 502endfunc 503 504func Test_syntax_hangs() 505 CheckFunction reltimefloat 506 CheckFeature syntax 507 508 " This pattern takes a long time to match, it should timeout. 509 new 510 call setline(1, ['aaa', repeat('abc ', 1000), 'ccc']) 511 let start = reltime() 512 set nolazyredraw redrawtime=101 513 syn match Error /\%#=1a*.*X\@<=b*/ 514 redraw 515 let elapsed = reltimefloat(reltime(start)) 516 call assert_true(elapsed > 0.1) 517 call assert_true(elapsed < 1.0) 518 519 " second time syntax HL is disabled 520 let start = reltime() 521 redraw 522 let elapsed = reltimefloat(reltime(start)) 523 call assert_true(elapsed < 0.1) 524 525 " after CTRL-L the timeout flag is reset 526 let start = reltime() 527 exe "normal \<C-L>" 528 redraw 529 let elapsed = reltimefloat(reltime(start)) 530 call assert_true(elapsed > 0.1) 531 call assert_true(elapsed < 1.0) 532 533 set redrawtime& 534 bwipe! 535endfunc 536 537func Test_conceal() 538 CheckFeature conceal 539 540 new 541 call setline(1, ['', '123456']) 542 syn match test23 "23" conceal cchar=X 543 syn match test45 "45" conceal 544 545 set conceallevel=0 546 call assert_equal('123456 ', ScreenLines(2, 7)[0]) 547 call assert_equal([[0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)')) 548 549 set conceallevel=1 550 call assert_equal('1X 6 ', ScreenLines(2, 7)[0]) 551 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)')) 552 553 set conceallevel=1 554 set listchars=conceal:Y 555 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)')) 556 call assert_equal('1XY6 ', ScreenLines(2, 7)[0]) 557 558 set conceallevel=2 559 call assert_match('1X6 ', ScreenLines(2, 7)[0]) 560 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)')) 561 562 set conceallevel=3 563 call assert_match('16 ', ScreenLines(2, 7)[0]) 564 call assert_equal([[0, '', 0], [1, '', 1], [1, '', 1], [1, '', 2], [1, '', 2], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)')) 565 566 call AssertFails("syntax match Entity '&' conceal cchar=\<Tab>", 'E844:') 567 568 syn clear 569 set conceallevel& 570 bw! 571endfunc 572 573func Test_synstack_synIDtrans() 574 new 575 setfiletype c 576 syntax on 577 call setline(1, ' /* A comment with a TODO */') 578 579 call assert_equal([], synstack(1, 1)) 580 581 norm f/ 582 eval synstack(line("."), col("."))->map('synIDattr(v:val, "name")')->assert_equal(['cComment', 'cCommentStart']) 583 eval synstack(line("."), col("."))->map('synIDattr(synIDtrans(v:val), "name")')->assert_equal(['Comment', 'Comment']) 584 585 norm fA 586 call assert_equal(['cComment'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) 587 call assert_equal(['Comment'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")')) 588 589 norm fT 590 call assert_equal(['cComment', 'cTodo'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) 591 call assert_equal(['Comment', 'Todo'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")')) 592 593 call assert_fails("let n=synIDtrans([])", 'E745:') 594 595 syn clear 596 bw! 597endfunc 598 599" Check highlighting for a small piece of C code with a screen dump. 600func Test_syntax_c() 601 CheckRunVimInTerminal 602 call writefile([ 603 \ '/* comment line at the top */', 604 \ 'int main(int argc, char **argv) { // another comment', 605 \ '#if 0', 606 \ ' int not_used;', 607 \ '#else', 608 \ ' int used;', 609 \ '#endif', 610 \ ' printf("Just an example piece of C code\n");', 611 \ ' return 0x0ff;', 612 \ '}', 613 \ "\t\t ", 614 \ ' static void', 615 \ 'myFunction(const double count, struct nothing, long there) {', 616 \ "\t// 123: nothing to endif here", 617 \ "\tfor (int i = 0; i < count; ++i) {", 618 \ "\t break;", 619 \ "\t}", 620 \ "\tNote: asdf", 621 \ '}', 622 \ ], 'Xtest.c') 623 624 " This makes the default for 'background' use "dark", check that the 625 " response to t_RB corrects it to "light". 626 let $COLORFGBG = '15;0' 627 628 let buf = RunVimInTerminal('Xtest.c', {}) 629 call term_sendkeys(buf, ":syn keyword Search Note\r") 630 call term_sendkeys(buf, ":syn match Error /^\\s\\+$/\r") 631 call term_sendkeys(buf, ":set hlsearch\r") 632 call term_sendkeys(buf, "/endif\r") 633 call term_sendkeys(buf, "vjfC") 634 call VerifyScreenDump(buf, 'Test_syntax_c_01', {}) 635 636 call term_sendkeys(buf, "\<Esc>") 637 call StopVimInTerminal(buf) 638 639 let $COLORFGBG = '' 640 call delete('Xtest.c') 641endfun 642 643" Using \z() in a region with NFA failing should not crash. 644func Test_syn_wrong_z_one() 645 new 646 call setline(1, ['just some text', 'with foo and bar to match with']) 647 syn region FooBar start="foo\z(.*\)bar" end="\z1" 648 call test_override("nfa_fail", 1) 649 redraw! 650 redraw! 651 call test_override("ALL", 0) 652 bwipe! 653endfunc 654 655func Test_syntax_after_bufdo() 656 call writefile(['/* aaa comment */'], 'Xaaa.c') 657 call writefile(['/* bbb comment */'], 'Xbbb.c') 658 call writefile(['/* ccc comment */'], 'Xccc.c') 659 call writefile(['/* ddd comment */'], 'Xddd.c') 660 661 let bnr = bufnr('%') 662 new Xaaa.c 663 badd Xbbb.c 664 badd Xccc.c 665 badd Xddd.c 666 exe "bwipe " . bnr 667 let l = [] 668 bufdo call add(l, bufnr('%')) 669 call assert_equal(4, len(l)) 670 671 syntax on 672 673 " This used to only enable syntax HL in the last buffer. 674 bufdo tab split 675 tabrewind 676 for tab in range(1, 4) 677 norm fm 678 call assert_equal(['cComment'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) 679 tabnext 680 endfor 681 682 bwipe! Xaaa.c 683 bwipe! Xbbb.c 684 bwipe! Xccc.c 685 bwipe! Xddd.c 686 syntax off 687 call delete('Xaaa.c') 688 call delete('Xbbb.c') 689 call delete('Xccc.c') 690 call delete('Xddd.c') 691endfunc 692 693func Test_syntax_foldlevel() 694 new 695 call setline(1, [ 696 \ 'void f(int a)', 697 \ '{', 698 \ ' if (a == 1) {', 699 \ ' a = 0;', 700 \ ' } else if (a == 2) {', 701 \ ' a = 1;', 702 \ ' } else {', 703 \ ' a = 2;', 704 \ ' }', 705 \ ' if (a > 0) {', 706 \ ' if (a == 1) {', 707 \ ' a = 0;', 708 \ ' } /* missing newline */ } /* end of outer if */ else {', 709 \ ' a = 1;', 710 \ ' }', 711 \ ' if (a == 1)', 712 \ ' {', 713 \ ' a = 0;', 714 \ ' }', 715 \ ' else if (a == 2)', 716 \ ' {', 717 \ ' a = 1;', 718 \ ' }', 719 \ ' else', 720 \ ' {', 721 \ ' a = 2;', 722 \ ' }', 723 \ '}', 724 \ ]) 725 setfiletype c 726 syntax on 727 set foldmethod=syntax 728 729 call assert_fails('syn foldlevel start start', 'E390:') 730 call assert_fails('syn foldlevel not_an_option', 'E390:') 731 732 set foldlevel=1 733 734 syn foldlevel start 735 redir @c 736 syn foldlevel 737 redir END 738 call assert_equal("\nsyntax foldlevel start", @c) 739 syn sync fromstart 740 call assert_match('from the first line$', execute('syn sync')) 741 let a = map(range(3,9), 'foldclosed(v:val)') 742 call assert_equal([3,3,3,3,3,3,3], a) " attached cascade folds together 743 let a = map(range(10,15), 'foldclosed(v:val)') 744 call assert_equal([10,10,10,10,10,10], a) " over-attached 'else' hidden 745 let a = map(range(16,27), 'foldclosed(v:val)') 746 let unattached_results = [-1,17,17,17,-1,21,21,21,-1,25,25,25] 747 call assert_equal(unattached_results, a) " unattached cascade folds separately 748 749 syn foldlevel minimum 750 redir @c 751 syn foldlevel 752 redir END 753 call assert_equal("\nsyntax foldlevel minimum", @c) 754 syn sync fromstart 755 let a = map(range(3,9), 'foldclosed(v:val)') 756 call assert_equal([3,3,5,5,7,7,7], a) " attached cascade folds separately 757 let a = map(range(10,15), 'foldclosed(v:val)') 758 call assert_equal([10,10,10,13,13,13], a) " over-attached 'else' visible 759 let a = map(range(16,27), 'foldclosed(v:val)') 760 call assert_equal(unattached_results, a) " unattached cascade folds separately 761 762 set foldlevel=2 763 764 syn foldlevel start 765 syn sync fromstart 766 let a = map(range(11,14), 'foldclosed(v:val)') 767 call assert_equal([11,11,11,-1], a) " over-attached 'else' hidden 768 769 syn foldlevel minimum 770 syn sync fromstart 771 let a = map(range(11,14), 'foldclosed(v:val)') 772 call assert_equal([11,11,-1,-1], a) " over-attached 'else' visible 773 774 quit! 775endfunc 776 777func Test_search_syntax_skip() 778 new 779 let lines =<< trim END 780 781 /* This is VIM */ 782 Another Text for VIM 783 let a = "VIM" 784 END 785 call setline(1, lines) 786 syntax on 787 syntax match Comment "^/\*.*\*/" 788 syntax match String '".*"' 789 790 " Skip argument using string evaluation. 791 1 792 call search('VIM', 'w', '', 0, 'synIDattr(synID(line("."), col("."), 1), "name") =~? "comment"') 793 call assert_equal('Another Text for VIM', getline('.')) 794 1 795 call search('VIM', 'w', '', 0, 'synIDattr(synID(line("."), col("."), 1), "name") !~? "string"') 796 call assert_equal(' let a = "VIM"', getline('.')) 797 798 " Skip argument using Lambda. 799 1 800 call search('VIM', 'w', '', 0, { -> synIDattr(synID(line("."), col("."), 1), "name") =~? "comment"}) 801 call assert_equal('Another Text for VIM', getline('.')) 802 803 1 804 call search('VIM', 'w', '', 0, { -> synIDattr(synID(line("."), col("."), 1), "name") !~? "string"}) 805 call assert_equal(' let a = "VIM"', getline('.')) 806 807 " Skip argument using funcref. 808 func InComment() 809 return synIDattr(synID(line("."), col("."), 1), "name") =~? "comment" 810 endfunc 811 func InString() 812 return synIDattr(synID(line("."), col("."), 1), "name") !~? "string" 813 endfunc 814 1 815 call search('VIM', 'w', '', 0, function('InComment')) 816 call assert_equal('Another Text for VIM', getline('.')) 817 818 1 819 call search('VIM', 'w', '', 0, function('InString')) 820 call assert_equal(' let a = "VIM"', getline('.')) 821 822 delfunc InComment 823 delfunc InString 824 bwipe! 825endfunc 826 827" vim: shiftwidth=2 sts=2 expandtab 828