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