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