1" Test for syntax and syntax iskeyword option 2 3if !has("syntax") 4 finish 5endif 6 7source view_util.vim 8source screendump.vim 9 10func GetSyntaxItem(pat) 11 let c = '' 12 let a = ['a', getreg('a'), getregtype('a')] 13 0 14 redraw! 15 call search(a:pat, 'W') 16 let synid = synID(line('.'), col('.'), 1) 17 while synid == synID(line('.'), col('.'), 1) 18 norm! v"ay 19 " stop at whitespace 20 if @a =~# '\s' 21 break 22 endif 23 let c .= @a 24 norm! l 25 endw 26 call call('setreg', a) 27 0 28 return c 29endfunc 30 31func Test_syn_iskeyword() 32 new 33 call setline(1, [ 34 \ 'CREATE TABLE FOOBAR(', 35 \ ' DLTD_BY VARCHAR2(100)', 36 \ ');', 37 \ '']) 38 39 syntax on 40 set ft=sql 41 syn match SYN /C\k\+\>/ 42 hi link SYN ErrorMsg 43 call assert_equal('DLTD_BY', GetSyntaxItem('DLTD')) 44 /\<D\k\+\>/:norm! ygn 45 call assert_equal('DLTD_BY', @0) 46 redir @c 47 syn iskeyword 48 redir END 49 call assert_equal("\nsyntax iskeyword not set", @c) 50 51 syn iskeyword @,48-57,_,192-255 52 redir @c 53 syn iskeyword 54 redir END 55 call assert_equal("\nsyntax iskeyword @,48-57,_,192-255", @c) 56 57 setlocal isk-=_ 58 call assert_equal('DLTD_BY', GetSyntaxItem('DLTD')) 59 /\<D\k\+\>/:norm! ygn 60 let b2 = @0 61 call assert_equal('DLTD', @0) 62 63 syn iskeyword clear 64 redir @c 65 syn iskeyword 66 redir END 67 call assert_equal("\nsyntax iskeyword not set", @c) 68 69 quit! 70endfunc 71 72func Test_syntax_after_reload() 73 split Xsomefile 74 call setline(1, ['hello', 'there']) 75 w! 76 only! 77 setl filetype=hello 78 au FileType hello let g:gotit = 1 79 call assert_false(exists('g:gotit')) 80 edit other 81 buf Xsomefile 82 call assert_equal('hello', &filetype) 83 call assert_true(exists('g:gotit')) 84 call delete('Xsomefile') 85endfunc 86 87func Test_syntime() 88 if !has('profile') 89 return 90 endif 91 92 syntax on 93 syntime on 94 let a = execute('syntime report') 95 call assert_equal("\nNo Syntax items defined for this buffer", a) 96 97 view ../memfile_test.c 98 setfiletype cpp 99 redraw 100 let a = execute('syntime report') 101 call assert_match('^ TOTAL *COUNT *MATCH *SLOWEST *AVERAGE *NAME *PATTERN', a) 102 call assert_match(' \d*\.\d* \+[^0]\d* .* cppRawString ', a) 103 call assert_match(' \d*\.\d* \+[^0]\d* .* cppNumber ', a) 104 105 syntime off 106 syntime clear 107 let a = execute('syntime report') 108 call assert_match('^ TOTAL *COUNT *MATCH *SLOWEST *AVERAGE *NAME *PATTERN', a) 109 call assert_notmatch('.* cppRawString *', a) 110 call assert_notmatch('.* cppNumber*', a) 111 call assert_notmatch('[1-9]', a) 112 113 call assert_fails('syntime abc', 'E475') 114 115 syntax clear 116 let a = execute('syntime report') 117 call assert_equal("\nNo Syntax items defined for this buffer", a) 118 119 bd 120endfunc 121 122func Test_syntime_completion() 123 if !has('profile') 124 return 125 endif 126 127 call feedkeys(":syntime \<C-A>\<C-B>\"\<CR>", 'tx') 128 call assert_equal('"syntime clear off on report', @:) 129endfunc 130 131func Test_syntax_list() 132 syntax on 133 let a = execute('syntax list') 134 call assert_equal("\nNo Syntax items defined for this buffer", a) 135 136 view ../memfile_test.c 137 setfiletype c 138 139 let a = execute('syntax list') 140 call assert_match('cInclude*', a) 141 call assert_match('cDefine', a) 142 143 let a = execute('syntax list cDefine') 144 call assert_notmatch('cInclude*', a) 145 call assert_match('cDefine', a) 146 call assert_match(' links to Macro$', a) 147 148 call assert_fails('syntax list ABCD', 'E28:') 149 call assert_fails('syntax list @ABCD', 'E392:') 150 151 syntax clear 152 let a = execute('syntax list') 153 call assert_equal("\nNo Syntax items defined for this buffer", a) 154 155 bd 156endfunc 157 158func Test_syntax_completion() 159 call feedkeys(":syn \<C-A>\<C-B>\"\<CR>", 'tx') 160 call assert_equal('"syn case clear cluster conceal enable include iskeyword keyword list manual match off on region reset spell sync', @:) 161 162 call feedkeys(":syn case \<C-A>\<C-B>\"\<CR>", 'tx') 163 call assert_equal('"syn case ignore match', @:) 164 165 call feedkeys(":syn spell \<C-A>\<C-B>\"\<CR>", 'tx') 166 call assert_equal('"syn spell default notoplevel toplevel', @:) 167 168 call feedkeys(":syn sync \<C-A>\<C-B>\"\<CR>", 'tx') 169 call assert_equal('"syn sync ccomment clear fromstart linebreaks= linecont lines= match maxlines= minlines= region', @:) 170 171 " Check that clearing "Aap" avoids it showing up before Boolean. 172 hi Aap ctermfg=blue 173 call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx') 174 call assert_match('^"syn list Aap Boolean Character ', @:) 175 hi clear Aap 176 177 call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx') 178 call assert_match('^"syn list Boolean Character ', @:) 179 180 call feedkeys(":syn match \<C-A>\<C-B>\"\<CR>", 'tx') 181 call assert_match('^"syn match Boolean Character ', @:) 182endfunc 183 184func Test_syntax_arg_skipped() 185 syn clear 186 syntax case ignore 187 if 0 188 syntax case match 189 endif 190 call assert_match('case ignore', execute('syntax case')) 191 192 syn keyword Foo foo 193 call assert_match('Foo', execute('syntax')) 194 syn clear 195 call assert_match('case match', execute('syntax case')) 196 call assert_notmatch('Foo', execute('syntax')) 197 198 if has('conceal') 199 syn clear 200 syntax conceal on 201 if 0 202 syntax conceal off 203 endif 204 call assert_match('conceal on', execute('syntax conceal')) 205 syn clear 206 call assert_match('conceal off', execute('syntax conceal')) 207 208 syntax conceal on 209 syntax conceal off 210 call assert_match('conceal off', execute('syntax conceal')) 211 endif 212 213 syntax region Bar start=/</ end=/>/ 214 if 0 215 syntax region NotTest start=/</ end=/>/ contains=@Spell 216 endif 217 call assert_match('Bar', execute('syntax')) 218 call assert_notmatch('NotTest', execute('syntax')) 219 call assert_notmatch('Spell', execute('syntax')) 220 221 hi Foo ctermfg=blue 222 let a = execute('hi Foo') 223 if 0 224 syntax rest 225 endif 226 call assert_equal(a, execute('hi Foo')) 227 hi clear Bar 228 hi clear Foo 229 230 set ft=tags 231 syn off 232 if 0 233 syntax enable 234 endif 235 call assert_match('No Syntax items defined', execute('syntax')) 236 syntax enable 237 call assert_match('tagComment', execute('syntax')) 238 set ft= 239 240 syn clear 241 if 0 242 syntax include @Spell nothing 243 endif 244 call assert_notmatch('Spell', execute('syntax')) 245 246 syn clear 247 syn iskeyword 48-57,$,_ 248 call assert_match('48-57,$,_', execute('syntax iskeyword')) 249 if 0 250 syn clear 251 syn iskeyword clear 252 endif 253 call assert_match('48-57,$,_', execute('syntax iskeyword')) 254 syn iskeyword clear 255 call assert_match('not set', execute('syntax iskeyword')) 256 syn iskeyword 48-57,$,_ 257 syn clear 258 call assert_match('not set', execute('syntax iskeyword')) 259 260 syn clear 261 syn keyword Foo foo 262 if 0 263 syn keyword NotAdded bar 264 endif 265 call assert_match('Foo', execute('syntax')) 266 call assert_notmatch('NotAdded', execute('highlight')) 267 268 syn clear 269 syn keyword Foo foo 270 call assert_match('Foo', execute('syntax')) 271 call assert_match('Foo', execute('syntax list')) 272 call assert_notmatch('Foo', execute('if 0 | syntax | endif')) 273 call assert_notmatch('Foo', execute('if 0 | syntax list | endif')) 274 275 syn clear 276 syn match Fopi /asdf/ 277 if 0 278 syn match Fopx /asdf/ 279 endif 280 call assert_match('Fopi', execute('syntax')) 281 call assert_notmatch('Fopx', execute('syntax')) 282 283 syn clear 284 syn spell toplevel 285 call assert_match('spell toplevel', execute('syntax spell')) 286 if 0 287 syn spell notoplevel 288 endif 289 call assert_match('spell toplevel', execute('syntax spell')) 290 syn spell notoplevel 291 call assert_match('spell notoplevel', execute('syntax spell')) 292 syn spell default 293 call assert_match('spell default', execute('syntax spell')) 294 295 syn clear 296 if 0 297 syntax cluster Spell 298 endif 299 call assert_notmatch('Spell', execute('syntax')) 300 301 syn clear 302 syn keyword Foo foo 303 syn sync ccomment 304 syn sync maxlines=5 305 if 0 306 syn sync maxlines=11 307 endif 308 call assert_match('on C-style comments', execute('syntax sync')) 309 call assert_match('maximal 5 lines', execute('syntax sync')) 310 syn sync clear 311 if 0 312 syn sync ccomment 313 endif 314 call assert_notmatch('on C-style comments', execute('syntax sync')) 315 316 syn clear 317endfunc 318 319func Test_syntax_invalid_arg() 320 call assert_fails('syntax case asdf', 'E390:') 321 if has('conceal') 322 call assert_fails('syntax conceal asdf', 'E390:') 323 endif 324 call assert_fails('syntax spell asdf', 'E390:') 325 call assert_fails('syntax clear @ABCD', 'E391:') 326 call assert_fails('syntax include @Xxx', 'E397:') 327 call assert_fails('syntax region X start="{"', 'E399:') 328 call assert_fails('syntax sync x', 'E404:') 329 call assert_fails('syntax keyword Abc a[', 'E789:') 330 call assert_fails('syntax keyword Abc a[bc]d', 'E890:') 331endfunc 332 333func Test_syn_sync() 334 syntax region HereGroup start=/this/ end=/that/ 335 syntax sync match SyncHere grouphere HereGroup "pattern" 336 call assert_match('SyncHere', execute('syntax sync')) 337 syn sync clear 338 call assert_notmatch('SyncHere', execute('syntax sync')) 339 syn clear 340endfunc 341 342func Test_syn_clear() 343 syntax keyword Foo foo 344 syntax keyword Bar tar 345 call assert_match('Foo', execute('syntax')) 346 call assert_match('Bar', execute('syntax')) 347 call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) 348 syn clear Foo 349 call assert_notmatch('Foo', execute('syntax')) 350 call assert_match('Bar', execute('syntax')) 351 call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) 352 syn clear Foo Bar 353 call assert_notmatch('Foo', execute('syntax')) 354 call assert_notmatch('Bar', execute('syntax')) 355 hi clear Foo 356 call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) 357 hi clear Bar 358endfunc 359 360func Test_invalid_name() 361 syn clear 362 syn keyword Nop yes 363 call assert_fails("syntax keyword Wr\x17ong bar", 'E669:') 364 syntax keyword @Wrong bar 365 call assert_match('W18:', execute('1messages')) 366 syn clear 367 hi clear Nop 368 hi clear @Wrong 369endfunc 370 371func Test_ownsyntax() 372 new Xfoo 373 call setline(1, '#define FOO') 374 syntax on 375 set filetype=c 376 ownsyntax perl 377 call assert_equal('perlComment', synIDattr(synID(line('.'), col('.'), 1), 'name')) 378 call assert_equal('c', b:current_syntax) 379 call assert_equal('perl', w:current_syntax) 380 381 " A new split window should have the original syntax. 382 split 383 call assert_equal('cDefine', synIDattr(synID(line('.'), col('.'), 1), 'name')) 384 call assert_equal('c', b:current_syntax) 385 call assert_equal(0, exists('w:current_syntax')) 386 387 wincmd x 388 call assert_equal('perlComment', synIDattr(synID(line("."), col("."), 1), "name")) 389 390 syntax off 391 set filetype& 392 %bw! 393endfunc 394 395func Test_ownsyntax_completion() 396 call feedkeys(":ownsyntax java\<C-A>\<C-B>\"\<CR>", 'tx') 397 call assert_equal('"ownsyntax java javacc javascript', @:) 398endfunc 399 400func Test_highlight_invalid_arg() 401 if has('gui_running') 402 call assert_fails('hi XXX guifg=xxx', 'E254:') 403 endif 404 call assert_fails('hi DoesNotExist', 'E411:') 405 call assert_fails('hi link', 'E412:') 406 call assert_fails('hi link a', 'E412:') 407 call assert_fails('hi link a b c', 'E413:') 408 call assert_fails('hi XXX =', 'E415:') 409 call assert_fails('hi XXX cterm', 'E416:') 410 call assert_fails('hi XXX cterm=', 'E417:') 411 call assert_fails('hi XXX cterm=DoesNotExist', 'E418:') 412 call assert_fails('hi XXX ctermfg=DoesNotExist', 'E421:') 413 call assert_fails('hi XXX xxx=White', 'E423:') 414endfunc 415 416func Test_bg_detection() 417 if has('gui_running') 418 return 419 endif 420 " auto-detection of &bg, make sure sure it isn't set anywhere before 421 " this test 422 hi Normal ctermbg=0 423 call assert_equal('dark', &bg) 424 hi Normal ctermbg=4 425 call assert_equal('dark', &bg) 426 hi Normal ctermbg=12 427 call assert_equal('light', &bg) 428 hi Normal ctermbg=15 429 call assert_equal('light', &bg) 430 431 " manually-set &bg takes precedence over auto-detection 432 set bg=light 433 hi Normal ctermbg=4 434 call assert_equal('light', &bg) 435 set bg=dark 436 hi Normal ctermbg=12 437 call assert_equal('dark', &bg) 438 439 hi Normal ctermbg=NONE 440endfunc 441 442func Test_syntax_hangs() 443 if !has('reltime') || !has('float') || !has('syntax') 444 return 445 endif 446 447 " This pattern takes a long time to match, it should timeout. 448 new 449 call setline(1, ['aaa', repeat('abc ', 1000), 'ccc']) 450 let start = reltime() 451 set nolazyredraw redrawtime=101 452 syn match Error /\%#=1a*.*X\@<=b*/ 453 redraw 454 let elapsed = reltimefloat(reltime(start)) 455 call assert_true(elapsed > 0.1) 456 call assert_true(elapsed < 1.0) 457 458 " second time syntax HL is disabled 459 let start = reltime() 460 redraw 461 let elapsed = reltimefloat(reltime(start)) 462 call assert_true(elapsed < 0.1) 463 464 " after CTRL-L the timeout flag is reset 465 let start = reltime() 466 exe "normal \<C-L>" 467 redraw 468 let elapsed = reltimefloat(reltime(start)) 469 call assert_true(elapsed > 0.1) 470 call assert_true(elapsed < 1.0) 471 472 set redrawtime& 473 bwipe! 474endfunc 475 476func Test_conceal() 477 if !has('conceal') 478 return 479 endif 480 481 new 482 call setline(1, ['', '123456']) 483 syn match test23 "23" conceal cchar=X 484 syn match test45 "45" conceal 485 486 set conceallevel=0 487 call assert_equal('123456 ', ScreenLines(2, 7)[0]) 488 call assert_equal([[0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)')) 489 490 set conceallevel=1 491 call assert_equal('1X 6 ', ScreenLines(2, 7)[0]) 492 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)')) 493 494 set conceallevel=1 495 set listchars=conceal:Y 496 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)')) 497 call assert_equal('1XY6 ', ScreenLines(2, 7)[0]) 498 499 set conceallevel=2 500 call assert_match('1X6 ', ScreenLines(2, 7)[0]) 501 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)')) 502 503 set conceallevel=3 504 call assert_match('16 ', ScreenLines(2, 7)[0]) 505 call assert_equal([[0, '', 0], [1, '', 1], [1, '', 1], [1, '', 2], [1, '', 2], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)')) 506 507 syn clear 508 set conceallevel& 509 bw! 510endfunc 511 512func Test_synstack_synIDtrans() 513 new 514 setfiletype c 515 syntax on 516 call setline(1, ' /* A comment with a TODO */') 517 518 call assert_equal([], synstack(1, 1)) 519 520 norm f/ 521 call assert_equal(['cComment', 'cCommentStart'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) 522 call assert_equal(['Comment', 'Comment'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")')) 523 524 norm fA 525 call assert_equal(['cComment'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) 526 call assert_equal(['Comment'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")')) 527 528 norm fT 529 call assert_equal(['cComment', 'cTodo'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) 530 call assert_equal(['Comment', 'Todo'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")')) 531 532 syn clear 533 bw! 534endfunc 535 536" Check highlighting for a small piece of C code with a screen dump. 537func Test_syntax_c() 538 if !CanRunVimInTerminal() 539 throw 'Skipped: cannot make screendumps' 540 endif 541 call writefile([ 542 \ '/* comment line at the top */', 543 \ ' int', 544 \ 'main(int argc, char **argv)// another comment', 545 \ '{', 546 \ '#if 0', 547 \ ' int not_used;', 548 \ '#else', 549 \ ' int used;', 550 \ '#endif', 551 \ ' printf("Just an example piece of C code\n");', 552 \ ' return 0x0ff;', 553 \ '}', 554 \ ' static void', 555 \ 'myFunction(const double count, struct nothing, long there) {', 556 \ ' // 123: nothing to read here', 557 \ ' for (int i = 0; i < count; ++i) {', 558 \ ' break;', 559 \ ' }', 560 \ '}', 561 \ ], 'Xtest.c') 562 563 " This makes the default for 'background' use "dark", check that the 564 " response to t_RB corrects it to "light". 565 let $COLORFGBG = '15;0' 566 567 let buf = RunVimInTerminal('Xtest.c', {}) 568 call VerifyScreenDump(buf, 'Test_syntax_c_01', {}) 569 call StopVimInTerminal(buf) 570 571 let $COLORFGBG = '' 572 call delete('Xtest.c') 573endfun 574 575" Using \z() in a region with NFA failing should not crash. 576func Test_syn_wrong_z_one() 577 new 578 call setline(1, ['just some text', 'with foo and bar to match with']) 579 syn region FooBar start="foo\z(.*\)bar" end="\z1" 580 call test_override("nfa_fail", 1) 581 redraw! 582 redraw! 583 call test_override("ALL", 0) 584 bwipe! 585endfunc 586