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_syntax_list() 123 syntax on 124 let a = execute('syntax list') 125 call assert_equal("\nNo Syntax items defined for this buffer", a) 126 127 view ../memfile_test.c 128 setfiletype c 129 130 let a = execute('syntax list') 131 call assert_match('cInclude*', a) 132 call assert_match('cDefine', a) 133 134 let a = execute('syntax list cDefine') 135 call assert_notmatch('cInclude*', a) 136 call assert_match('cDefine', a) 137 call assert_match(' links to Macro$', a) 138 139 call assert_fails('syntax list ABCD', 'E28:') 140 call assert_fails('syntax list @ABCD', 'E392:') 141 142 syntax clear 143 let a = execute('syntax list') 144 call assert_equal("\nNo Syntax items defined for this buffer", a) 145 146 bd 147endfunc 148 149func Test_syntax_completion() 150 call feedkeys(":syn \<C-A>\<C-B>\"\<CR>", 'tx') 151 call assert_equal('"syn case clear cluster conceal enable include iskeyword keyword list manual match off on region reset spell sync', @:) 152 153 call feedkeys(":syn case \<C-A>\<C-B>\"\<CR>", 'tx') 154 call assert_equal('"syn case ignore match', @:) 155 156 call feedkeys(":syn spell \<C-A>\<C-B>\"\<CR>", 'tx') 157 call assert_equal('"syn spell default notoplevel toplevel', @:) 158 159 call feedkeys(":syn sync \<C-A>\<C-B>\"\<CR>", 'tx') 160 call assert_equal('"syn sync ccomment clear fromstart linebreaks= linecont lines= match maxlines= minlines= region', @:) 161 162 " Check that clearing "Aap" avoids it showing up before Boolean. 163 hi Aap ctermfg=blue 164 call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx') 165 call assert_match('^"syn list Aap Boolean Character ', @:) 166 hi clear Aap 167 168 call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx') 169 call assert_match('^"syn list Boolean Character ', @:) 170 171 call feedkeys(":syn match \<C-A>\<C-B>\"\<CR>", 'tx') 172 call assert_match('^"syn match Boolean Character ', @:) 173endfunc 174 175func Test_syntax_arg_skipped() 176 syn clear 177 syntax case ignore 178 if 0 179 syntax case match 180 endif 181 call assert_match('case ignore', execute('syntax case')) 182 183 syn keyword Foo foo 184 call assert_match('Foo', execute('syntax')) 185 syn clear 186 call assert_match('case match', execute('syntax case')) 187 call assert_notmatch('Foo', execute('syntax')) 188 189 if has('conceal') 190 syn clear 191 syntax conceal on 192 if 0 193 syntax conceal off 194 endif 195 call assert_match('conceal on', execute('syntax conceal')) 196 syn clear 197 call assert_match('conceal off', execute('syntax conceal')) 198 199 syntax conceal on 200 syntax conceal off 201 call assert_match('conceal off', execute('syntax conceal')) 202 endif 203 204 syntax region Bar start=/</ end=/>/ 205 if 0 206 syntax region NotTest start=/</ end=/>/ contains=@Spell 207 endif 208 call assert_match('Bar', execute('syntax')) 209 call assert_notmatch('NotTest', execute('syntax')) 210 call assert_notmatch('Spell', execute('syntax')) 211 212 hi Foo ctermfg=blue 213 let a = execute('hi Foo') 214 if 0 215 syntax rest 216 endif 217 call assert_equal(a, execute('hi Foo')) 218 hi clear Bar 219 hi clear Foo 220 221 set ft=tags 222 syn off 223 if 0 224 syntax enable 225 endif 226 call assert_match('No Syntax items defined', execute('syntax')) 227 syntax enable 228 call assert_match('tagComment', execute('syntax')) 229 set ft= 230 231 syn clear 232 if 0 233 syntax include @Spell nothing 234 endif 235 call assert_notmatch('Spell', execute('syntax')) 236 237 syn clear 238 syn iskeyword 48-57,$,_ 239 call assert_match('48-57,$,_', execute('syntax iskeyword')) 240 if 0 241 syn clear 242 syn iskeyword clear 243 endif 244 call assert_match('48-57,$,_', execute('syntax iskeyword')) 245 syn iskeyword clear 246 call assert_match('not set', execute('syntax iskeyword')) 247 syn iskeyword 48-57,$,_ 248 syn clear 249 call assert_match('not set', execute('syntax iskeyword')) 250 251 syn clear 252 syn keyword Foo foo 253 if 0 254 syn keyword NotAdded bar 255 endif 256 call assert_match('Foo', execute('syntax')) 257 call assert_notmatch('NotAdded', execute('highlight')) 258 259 syn clear 260 syn keyword Foo foo 261 call assert_match('Foo', execute('syntax')) 262 call assert_match('Foo', execute('syntax list')) 263 call assert_notmatch('Foo', execute('if 0 | syntax | endif')) 264 call assert_notmatch('Foo', execute('if 0 | syntax list | endif')) 265 266 syn clear 267 syn match Fopi /asdf/ 268 if 0 269 syn match Fopx /asdf/ 270 endif 271 call assert_match('Fopi', execute('syntax')) 272 call assert_notmatch('Fopx', execute('syntax')) 273 274 syn clear 275 syn spell toplevel 276 call assert_match('spell toplevel', execute('syntax spell')) 277 if 0 278 syn spell notoplevel 279 endif 280 call assert_match('spell toplevel', execute('syntax spell')) 281 syn spell notoplevel 282 call assert_match('spell notoplevel', execute('syntax spell')) 283 syn spell default 284 call assert_match('spell default', execute('syntax spell')) 285 286 syn clear 287 if 0 288 syntax cluster Spell 289 endif 290 call assert_notmatch('Spell', execute('syntax')) 291 292 syn clear 293 syn keyword Foo foo 294 syn sync ccomment 295 syn sync maxlines=5 296 if 0 297 syn sync maxlines=11 298 endif 299 call assert_match('on C-style comments', execute('syntax sync')) 300 call assert_match('maximal 5 lines', execute('syntax sync')) 301 syn sync clear 302 if 0 303 syn sync ccomment 304 endif 305 call assert_notmatch('on C-style comments', execute('syntax sync')) 306 307 syn clear 308endfunc 309 310func Test_syntax_invalid_arg() 311 call assert_fails('syntax case asdf', 'E390:') 312 if has('conceal') 313 call assert_fails('syntax conceal asdf', 'E390:') 314 endif 315 call assert_fails('syntax spell asdf', 'E390:') 316 call assert_fails('syntax clear @ABCD', 'E391:') 317 call assert_fails('syntax include @Xxx', 'E397:') 318 call assert_fails('syntax region X start="{"', 'E399:') 319 call assert_fails('syntax sync x', 'E404:') 320 call assert_fails('syntax keyword Abc a[', 'E789:') 321 call assert_fails('syntax keyword Abc a[bc]d', 'E890:') 322endfunc 323 324func Test_syn_sync() 325 syntax region HereGroup start=/this/ end=/that/ 326 syntax sync match SyncHere grouphere HereGroup "pattern" 327 call assert_match('SyncHere', execute('syntax sync')) 328 syn sync clear 329 call assert_notmatch('SyncHere', execute('syntax sync')) 330 syn clear 331endfunc 332 333func Test_syn_clear() 334 syntax keyword Foo foo 335 syntax keyword Bar tar 336 call assert_match('Foo', execute('syntax')) 337 call assert_match('Bar', execute('syntax')) 338 call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) 339 syn clear Foo 340 call assert_notmatch('Foo', execute('syntax')) 341 call assert_match('Bar', execute('syntax')) 342 call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) 343 syn clear Foo Bar 344 call assert_notmatch('Foo', execute('syntax')) 345 call assert_notmatch('Bar', execute('syntax')) 346 hi clear Foo 347 call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) 348 hi clear Bar 349endfunc 350 351func Test_invalid_name() 352 syn clear 353 syn keyword Nop yes 354 call assert_fails("syntax keyword Wr\x17ong bar", 'E669:') 355 syntax keyword @Wrong bar 356 call assert_match('W18:', execute('1messages')) 357 syn clear 358 hi clear Nop 359 hi clear @Wrong 360endfunc 361 362func Test_ownsyntax() 363 new Xfoo 364 call setline(1, '#define FOO') 365 syntax on 366 set filetype=c 367 ownsyntax perl 368 call assert_equal('perlComment', synIDattr(synID(line('.'), col('.'), 1), 'name')) 369 call assert_equal('c', b:current_syntax) 370 call assert_equal('perl', w:current_syntax) 371 372 " A new split window should have the original syntax. 373 split 374 call assert_equal('cDefine', synIDattr(synID(line('.'), col('.'), 1), 'name')) 375 call assert_equal('c', b:current_syntax) 376 call assert_equal(0, exists('w:current_syntax')) 377 378 wincmd x 379 call assert_equal('perlComment', synIDattr(synID(line("."), col("."), 1), "name")) 380 381 syntax off 382 set filetype& 383 %bw! 384endfunc 385 386func Test_ownsyntax_completion() 387 call feedkeys(":ownsyntax java\<C-A>\<C-B>\"\<CR>", 'tx') 388 call assert_equal('"ownsyntax java javacc javascript', @:) 389endfunc 390 391func Test_highlight_invalid_arg() 392 if has('gui_running') 393 call assert_fails('hi XXX guifg=xxx', 'E254:') 394 endif 395 call assert_fails('hi DoesNotExist', 'E411:') 396 call assert_fails('hi link', 'E412:') 397 call assert_fails('hi link a', 'E412:') 398 call assert_fails('hi link a b c', 'E413:') 399 call assert_fails('hi XXX =', 'E415:') 400 call assert_fails('hi XXX cterm', 'E416:') 401 call assert_fails('hi XXX cterm=', 'E417:') 402 call assert_fails('hi XXX cterm=DoesNotExist', 'E418:') 403 call assert_fails('hi XXX ctermfg=DoesNotExist', 'E421:') 404 call assert_fails('hi XXX xxx=White', 'E423:') 405endfunc 406 407func Test_bg_detection() 408 if has('gui_running') 409 return 410 endif 411 " auto-detection of &bg, make sure sure it isn't set anywhere before 412 " this test 413 hi Normal ctermbg=0 414 call assert_equal('dark', &bg) 415 hi Normal ctermbg=4 416 call assert_equal('dark', &bg) 417 hi Normal ctermbg=12 418 call assert_equal('light', &bg) 419 hi Normal ctermbg=15 420 call assert_equal('light', &bg) 421 422 " manually-set &bg takes precedence over auto-detection 423 set bg=light 424 hi Normal ctermbg=4 425 call assert_equal('light', &bg) 426 set bg=dark 427 hi Normal ctermbg=12 428 call assert_equal('dark', &bg) 429 430 hi Normal ctermbg=NONE 431endfunc 432 433func Test_syntax_hangs() 434 if !has('reltime') || !has('float') || !has('syntax') 435 return 436 endif 437 438 " This pattern takes a long time to match, it should timeout. 439 new 440 call setline(1, ['aaa', repeat('abc ', 1000), 'ccc']) 441 let start = reltime() 442 set nolazyredraw redrawtime=101 443 syn match Error /\%#=1a*.*X\@<=b*/ 444 redraw 445 let elapsed = reltimefloat(reltime(start)) 446 call assert_true(elapsed > 0.1) 447 call assert_true(elapsed < 1.0) 448 449 " second time syntax HL is disabled 450 let start = reltime() 451 redraw 452 let elapsed = reltimefloat(reltime(start)) 453 call assert_true(elapsed < 0.1) 454 455 " after CTRL-L the timeout flag is reset 456 let start = reltime() 457 exe "normal \<C-L>" 458 redraw 459 let elapsed = reltimefloat(reltime(start)) 460 call assert_true(elapsed > 0.1) 461 call assert_true(elapsed < 1.0) 462 463 set redrawtime& 464 bwipe! 465endfunc 466 467func Test_conceal() 468 if !has('conceal') 469 return 470 endif 471 472 new 473 call setline(1, ['', '123456']) 474 syn match test23 "23" conceal cchar=X 475 syn match test45 "45" conceal 476 477 set conceallevel=0 478 call assert_equal('123456 ', ScreenLines(2, 7)[0]) 479 call assert_equal([[0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)')) 480 481 set conceallevel=1 482 call assert_equal('1X 6 ', ScreenLines(2, 7)[0]) 483 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)')) 484 485 set conceallevel=1 486 set listchars=conceal:Y 487 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)')) 488 call assert_equal('1XY6 ', ScreenLines(2, 7)[0]) 489 490 set conceallevel=2 491 call assert_match('1X6 ', 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=3 495 call assert_match('16 ', ScreenLines(2, 7)[0]) 496 call assert_equal([[0, '', 0], [1, '', 1], [1, '', 1], [1, '', 2], [1, '', 2], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)')) 497 498 syn clear 499 set conceallevel& 500 bw! 501endfunc 502 503func Test_synstack_synIDtrans() 504 new 505 setfiletype c 506 syntax on 507 call setline(1, ' /* A comment with a TODO */') 508 509 call assert_equal([], synstack(1, 1)) 510 511 norm f/ 512 call assert_equal(['cComment', 'cCommentStart'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) 513 call assert_equal(['Comment', 'Comment'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")')) 514 515 norm fA 516 call assert_equal(['cComment'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) 517 call assert_equal(['Comment'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")')) 518 519 norm fT 520 call assert_equal(['cComment', 'cTodo'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) 521 call assert_equal(['Comment', 'Todo'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")')) 522 523 syn clear 524 bw! 525endfunc 526 527" Check highlighting for a small piece of C code with a screen dump. 528func Test_syntax_c() 529 if !CanRunVimInTerminal() 530 return 531 endif 532 call writefile([ 533 \ '/* comment line at the top */', 534 \ ' int', 535 \ 'main(int argc, char **argv)// another comment', 536 \ '{', 537 \ '#if 0', 538 \ ' int not_used;', 539 \ '#else', 540 \ ' int used;', 541 \ '#endif', 542 \ ' printf("Just an example piece of C code\n");', 543 \ ' return 0x0ff;', 544 \ '}', 545 \ ' static void', 546 \ 'myFunction(const double count, struct nothing, long there) {', 547 \ ' // 123: nothing to read here', 548 \ ' for (int i = 0; i < count; ++i) {', 549 \ ' break;', 550 \ ' }', 551 \ '}', 552 \ ], 'Xtest.c') 553 554 " This makes the default for 'background' use "dark", check that the 555 " response to t_RB corrects it to "light". 556 let $COLORFGBG = '15;0' 557 558 let buf = RunVimInTerminal('Xtest.c', {}) 559 call VerifyScreenDump(buf, 'Test_syntax_c_01', {}) 560 call StopVimInTerminal(buf) 561 562 let $COLORFGBG = '' 563 call delete('Xtest.c') 564endfun 565