xref: /vim-8.2.3635/src/testdir/test_syntax.vim (revision b1c9198a)
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