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