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