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