blob: ee9406b3c7688815f05616312e15e7851887aa80 [file] [log] [blame]
Bram Moolenaarb8060fe2016-01-19 22:29:28 +01001" Test for syntax and syntax iskeyword option
2
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02003source check.vim
4CheckFeature syntax
Bram Moolenaarb8060fe2016-01-19 22:29:28 +01005
Bram Moolenaar4d785892017-06-22 22:00:50 +02006source view_util.vim
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +01007source screendump.vim
Bram Moolenaar4d785892017-06-22 22:00:50 +02008
Bram Moolenaarb8060fe2016-01-19 22:29:28 +01009func 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 \ ');',
Bram Moolenaar037c54f2019-04-20 23:47:46 +020036 \ ''])
Bram Moolenaarb8060fe2016-01-19 22:29:28 +010037
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
Bram Moolenaar73b484c2016-12-11 15:11:17 +010059 let b2 = @0
Bram Moolenaarb8060fe2016-01-19 22:29:28 +010060 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
Bram Moolenaarc3691332016-04-20 12:49:49 +020070
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
Bram Moolenaar73b484c2016-12-11 15:11:17 +010085
86func Test_syntime()
87 if !has('profile')
Bram Moolenaar4c8980b2016-12-11 15:24:48 +010088 return
Bram Moolenaar73b484c2016-12-11 15:11:17 +010089 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
Bram Moolenaarb513d302018-12-02 14:55:08 +0100121func 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
Bram Moolenaar73b484c2016-12-11 15:11:17 +0100130func 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
Bram Moolenaar08f41572020-04-20 16:50:00 +0200154 syntax keyword Type int containedin=g1 skipwhite skipempty skipnl nextgroup=Abc
155 let exp = "Type xxx containedin=g1 nextgroup=Abc skipnl skipwhite skipempty int"
156 call assert_equal(exp, split(execute("syntax list"), "\n")[1])
157
Bram Moolenaar73b484c2016-12-11 15:11:17 +0100158 bd
159endfunc
160
161func Test_syntax_completion()
162 call feedkeys(":syn \<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaare35a52a2020-05-31 19:48:53 +0200163 call assert_equal('"syn case clear cluster conceal enable foldlevel include iskeyword keyword list manual match off on region reset spell sync', @:)
Bram Moolenaar73b484c2016-12-11 15:11:17 +0100164
165 call feedkeys(":syn case \<C-A>\<C-B>\"\<CR>", 'tx')
166 call assert_equal('"syn case ignore match', @:)
167
Bram Moolenaar2d028392017-01-08 18:28:22 +0100168 call feedkeys(":syn spell \<C-A>\<C-B>\"\<CR>", 'tx')
169 call assert_equal('"syn spell default notoplevel toplevel', @:)
170
171 call feedkeys(":syn sync \<C-A>\<C-B>\"\<CR>", 'tx')
172 call assert_equal('"syn sync ccomment clear fromstart linebreaks= linecont lines= match maxlines= minlines= region', @:)
173
Bram Moolenaard61e8aa2017-01-17 17:44:46 +0100174 " Check that clearing "Aap" avoids it showing up before Boolean.
175 hi Aap ctermfg=blue
176 call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx')
177 call assert_match('^"syn list Aap Boolean Character ', @:)
178 hi clear Aap
179
Bram Moolenaar73b484c2016-12-11 15:11:17 +0100180 call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx')
181 call assert_match('^"syn list Boolean Character ', @:)
182
183 call feedkeys(":syn match \<C-A>\<C-B>\"\<CR>", 'tx')
184 call assert_match('^"syn match Boolean Character ', @:)
185endfunc
Bram Moolenaarde318c52017-01-17 16:27:10 +0100186
Bram Moolenaar297610b2019-12-27 17:20:55 +0100187func Test_echohl_completion()
188 call feedkeys(":echohl no\<C-A>\<C-B>\"\<CR>", 'tx')
189 call assert_equal('"echohl NonText Normal none', @:)
190endfunc
191
Bram Moolenaarde318c52017-01-17 16:27:10 +0100192func Test_syntax_arg_skipped()
193 syn clear
194 syntax case ignore
195 if 0
196 syntax case match
197 endif
198 call assert_match('case ignore', execute('syntax case'))
199
200 syn keyword Foo foo
201 call assert_match('Foo', execute('syntax'))
202 syn clear
203 call assert_match('case match', execute('syntax case'))
204 call assert_notmatch('Foo', execute('syntax'))
205
206 if has('conceal')
207 syn clear
208 syntax conceal on
209 if 0
210 syntax conceal off
211 endif
212 call assert_match('conceal on', execute('syntax conceal'))
213 syn clear
214 call assert_match('conceal off', execute('syntax conceal'))
Bram Moolenaar58f60ca2017-01-17 17:19:00 +0100215
216 syntax conceal on
217 syntax conceal off
218 call assert_match('conceal off', execute('syntax conceal'))
Bram Moolenaarde318c52017-01-17 16:27:10 +0100219 endif
220
Bram Moolenaard61e8aa2017-01-17 17:44:46 +0100221 syntax region Bar start=/</ end=/>/
Bram Moolenaarde318c52017-01-17 16:27:10 +0100222 if 0
223 syntax region NotTest start=/</ end=/>/ contains=@Spell
224 endif
Bram Moolenaard61e8aa2017-01-17 17:44:46 +0100225 call assert_match('Bar', execute('syntax'))
Bram Moolenaarde318c52017-01-17 16:27:10 +0100226 call assert_notmatch('NotTest', execute('syntax'))
227 call assert_notmatch('Spell', execute('syntax'))
228
229 hi Foo ctermfg=blue
230 let a = execute('hi Foo')
231 if 0
232 syntax rest
233 endif
234 call assert_equal(a, execute('hi Foo'))
Bram Moolenaard61e8aa2017-01-17 17:44:46 +0100235 hi clear Bar
236 hi clear Foo
Bram Moolenaarde318c52017-01-17 16:27:10 +0100237
238 set ft=tags
239 syn off
240 if 0
241 syntax enable
242 endif
243 call assert_match('No Syntax items defined', execute('syntax'))
244 syntax enable
245 call assert_match('tagComment', execute('syntax'))
246 set ft=
247
248 syn clear
249 if 0
250 syntax include @Spell nothing
251 endif
252 call assert_notmatch('Spell', execute('syntax'))
253
254 syn clear
255 syn iskeyword 48-57,$,_
256 call assert_match('48-57,$,_', execute('syntax iskeyword'))
257 if 0
258 syn clear
259 syn iskeyword clear
260 endif
261 call assert_match('48-57,$,_', execute('syntax iskeyword'))
262 syn iskeyword clear
263 call assert_match('not set', execute('syntax iskeyword'))
264 syn iskeyword 48-57,$,_
265 syn clear
266 call assert_match('not set', execute('syntax iskeyword'))
267
268 syn clear
269 syn keyword Foo foo
270 if 0
271 syn keyword NotAdded bar
272 endif
273 call assert_match('Foo', execute('syntax'))
274 call assert_notmatch('NotAdded', execute('highlight'))
275
276 syn clear
277 syn keyword Foo foo
278 call assert_match('Foo', execute('syntax'))
279 call assert_match('Foo', execute('syntax list'))
280 call assert_notmatch('Foo', execute('if 0 | syntax | endif'))
281 call assert_notmatch('Foo', execute('if 0 | syntax list | endif'))
282
283 syn clear
284 syn match Fopi /asdf/
285 if 0
286 syn match Fopx /asdf/
287 endif
288 call assert_match('Fopi', execute('syntax'))
289 call assert_notmatch('Fopx', execute('syntax'))
290
291 syn clear
292 syn spell toplevel
293 call assert_match('spell toplevel', execute('syntax spell'))
294 if 0
295 syn spell notoplevel
296 endif
297 call assert_match('spell toplevel', execute('syntax spell'))
298 syn spell notoplevel
299 call assert_match('spell notoplevel', execute('syntax spell'))
300 syn spell default
301 call assert_match('spell default', execute('syntax spell'))
302
303 syn clear
304 if 0
305 syntax cluster Spell
306 endif
307 call assert_notmatch('Spell', execute('syntax'))
308
309 syn clear
310 syn keyword Foo foo
311 syn sync ccomment
312 syn sync maxlines=5
313 if 0
314 syn sync maxlines=11
315 endif
316 call assert_match('on C-style comments', execute('syntax sync'))
317 call assert_match('maximal 5 lines', execute('syntax sync'))
Bram Moolenaar58f60ca2017-01-17 17:19:00 +0100318 syn sync clear
Bram Moolenaarde318c52017-01-17 16:27:10 +0100319 if 0
320 syn sync ccomment
321 endif
322 call assert_notmatch('on C-style comments', execute('syntax sync'))
323
324 syn clear
325endfunc
326
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200327" Check for an error. Used when multiple errors are thrown and we are checking
328" for an earliest error.
329func AssertFails(cmd, errcode)
330 let save_exception = ''
331 try
332 exe a:cmd
333 catch
334 let save_exception = v:exception
335 endtry
336 call assert_match(a:errcode, save_exception)
337endfunc
338
Bram Moolenaarea588152017-04-10 22:45:30 +0200339func Test_syntax_invalid_arg()
Bram Moolenaar58f60ca2017-01-17 17:19:00 +0100340 call assert_fails('syntax case asdf', 'E390:')
Bram Moolenaard61e8aa2017-01-17 17:44:46 +0100341 if has('conceal')
342 call assert_fails('syntax conceal asdf', 'E390:')
343 endif
Bram Moolenaar58f60ca2017-01-17 17:19:00 +0100344 call assert_fails('syntax spell asdf', 'E390:')
Bram Moolenaarea588152017-04-10 22:45:30 +0200345 call assert_fails('syntax clear @ABCD', 'E391:')
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200346 call assert_fails('syntax include random_file', 'E484:')
347 call assert_fails('syntax include <afile>', 'E495:')
Bram Moolenaarea588152017-04-10 22:45:30 +0200348 call assert_fails('syntax sync x', 'E404:')
349 call assert_fails('syntax keyword Abc a[', 'E789:')
350 call assert_fails('syntax keyword Abc a[bc]d', 'E890:')
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200351 call assert_fails('syntax cluster Abc add=A add=', 'E475:')
Bram Moolenaar476a6132020-04-08 19:48:56 +0200352
353 " Test for too many \z\( and unmatched \z\(
354 " Not able to use assert_fails() here because both E50:/E879: and E475:
355 " messages are emitted.
356 set regexpengine=1
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200357 call AssertFails("syntax region MyRegion start='\\z\\(' end='\\*/'", 'E52:')
Bram Moolenaar476a6132020-04-08 19:48:56 +0200358
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200359 let cmd = "syntax region MyRegion start='"
360 let cmd ..= repeat("\\z\\(.\\)", 10) .. "' end='\*/'"
361 call AssertFails(cmd, 'E50:')
Bram Moolenaar476a6132020-04-08 19:48:56 +0200362
363 set regexpengine=2
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200364 call AssertFails("syntax region MyRegion start='\\z\\(' end='\\*/'", 'E54:')
Bram Moolenaar476a6132020-04-08 19:48:56 +0200365
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200366 let cmd = "syntax region MyRegion start='"
367 let cmd ..= repeat("\\z\\(.\\)", 10) .. "' end='\*/'"
368 call AssertFails(cmd, 'E879:')
Bram Moolenaar476a6132020-04-08 19:48:56 +0200369 set regexpengine&
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200370
371 call AssertFails('syntax keyword cMyItem grouphere G1', 'E393:')
372 call AssertFails('syntax sync match Abc grouphere MyItem "abc"', 'E394:')
373 call AssertFails('syn keyword Type contains int', 'E395:')
374 call assert_fails('syntax include @Xxx', 'E397:')
375 call AssertFails('syntax region X start', 'E398:')
376 call assert_fails('syntax region X start="{"', 'E399:')
377 call AssertFails('syntax cluster contains=Abc', 'E400:')
378 call AssertFails("syntax match Character /'.'", 'E401:')
379 call AssertFails("syntax match Character /'.'/a", 'E402:')
380 call assert_fails('syntax sync linecont /pat', 'E404:')
381 call assert_fails('syntax sync linecont', 'E404:')
382 call assert_fails('syntax sync linecont /pat1/ linecont /pat2/', 'E403:')
383 call assert_fails('syntax sync minlines=a', 'E404:')
384 call AssertFails('syntax match ABC /x/ contains=', 'E406:')
385 call AssertFails("syntax match Character contains /'.'/", 'E405:')
386 call AssertFails('syntax match ccFoo "Foo" nextgroup=ALLBUT,F', 'E407:')
387 call AssertFails('syntax region Block start="{" contains=F,ALLBUT', 'E408:')
388 call AssertFails("syntax match Characters contains=a.*x /'.'/", 'E409:')
Bram Moolenaar58f60ca2017-01-17 17:19:00 +0100389endfunc
390
391func Test_syn_sync()
392 syntax region HereGroup start=/this/ end=/that/
393 syntax sync match SyncHere grouphere HereGroup "pattern"
394 call assert_match('SyncHere', execute('syntax sync'))
395 syn sync clear
396 call assert_notmatch('SyncHere', execute('syntax sync'))
397 syn clear
398endfunc
399
400func Test_syn_clear()
401 syntax keyword Foo foo
Bram Moolenaard61e8aa2017-01-17 17:44:46 +0100402 syntax keyword Bar tar
Bram Moolenaar58f60ca2017-01-17 17:19:00 +0100403 call assert_match('Foo', execute('syntax'))
Bram Moolenaard61e8aa2017-01-17 17:44:46 +0100404 call assert_match('Bar', execute('syntax'))
Bram Moolenaarc96272e2017-03-26 13:50:09 +0200405 call assert_equal('Foo', synIDattr(hlID("Foo"), "name"))
Bram Moolenaar58f60ca2017-01-17 17:19:00 +0100406 syn clear Foo
407 call assert_notmatch('Foo', execute('syntax'))
Bram Moolenaard61e8aa2017-01-17 17:44:46 +0100408 call assert_match('Bar', execute('syntax'))
Bram Moolenaarc96272e2017-03-26 13:50:09 +0200409 call assert_equal('Foo', synIDattr(hlID("Foo"), "name"))
Bram Moolenaard61e8aa2017-01-17 17:44:46 +0100410 syn clear Foo Bar
Bram Moolenaar58f60ca2017-01-17 17:19:00 +0100411 call assert_notmatch('Foo', execute('syntax'))
Bram Moolenaard61e8aa2017-01-17 17:44:46 +0100412 call assert_notmatch('Bar', execute('syntax'))
413 hi clear Foo
Bram Moolenaarc96272e2017-03-26 13:50:09 +0200414 call assert_equal('Foo', synIDattr(hlID("Foo"), "name"))
Bram Moolenaard61e8aa2017-01-17 17:44:46 +0100415 hi clear Bar
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200416 call assert_fails('syntax clear invalid_syngroup', 'E28:')
Bram Moolenaar58f60ca2017-01-17 17:19:00 +0100417endfunc
Bram Moolenaar4007ed42017-01-17 18:14:54 +0100418
419func Test_invalid_name()
420 syn clear
421 syn keyword Nop yes
422 call assert_fails("syntax keyword Wr\x17ong bar", 'E669:')
423 syntax keyword @Wrong bar
424 call assert_match('W18:', execute('1messages'))
425 syn clear
426 hi clear Nop
427 hi clear @Wrong
428endfunc
Bram Moolenaarf8ec9982017-04-09 15:41:31 +0200429
430func Test_ownsyntax()
431 new Xfoo
432 call setline(1, '#define FOO')
433 syntax on
434 set filetype=c
435 ownsyntax perl
436 call assert_equal('perlComment', synIDattr(synID(line('.'), col('.'), 1), 'name'))
437 call assert_equal('c', b:current_syntax)
438 call assert_equal('perl', w:current_syntax)
439
440 " A new split window should have the original syntax.
441 split
442 call assert_equal('cDefine', synIDattr(synID(line('.'), col('.'), 1), 'name'))
443 call assert_equal('c', b:current_syntax)
444 call assert_equal(0, exists('w:current_syntax'))
445
446 wincmd x
447 call assert_equal('perlComment', synIDattr(synID(line("."), col("."), 1), "name"))
448
449 syntax off
450 set filetype&
451 %bw!
452endfunc
453
454func Test_ownsyntax_completion()
455 call feedkeys(":ownsyntax java\<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaarea7a08a2019-08-26 22:38:22 +0200456 call assert_equal('"ownsyntax java javacc javascript javascriptreact', @:)
Bram Moolenaarf8ec9982017-04-09 15:41:31 +0200457endfunc
Bram Moolenaarea588152017-04-10 22:45:30 +0200458
459func Test_highlight_invalid_arg()
460 if has('gui_running')
461 call assert_fails('hi XXX guifg=xxx', 'E254:')
462 endif
463 call assert_fails('hi DoesNotExist', 'E411:')
464 call assert_fails('hi link', 'E412:')
465 call assert_fails('hi link a', 'E412:')
466 call assert_fails('hi link a b c', 'E413:')
467 call assert_fails('hi XXX =', 'E415:')
468 call assert_fails('hi XXX cterm', 'E416:')
469 call assert_fails('hi XXX cterm=', 'E417:')
470 call assert_fails('hi XXX cterm=DoesNotExist', 'E418:')
471 call assert_fails('hi XXX ctermfg=DoesNotExist', 'E421:')
472 call assert_fails('hi XXX xxx=White', 'E423:')
473endfunc
474
Bram Moolenaar1615b362017-06-04 21:06:09 +0200475func Test_bg_detection()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200476 CheckNotGui
477
Bram Moolenaar1615b362017-06-04 21:06:09 +0200478 " auto-detection of &bg, make sure sure it isn't set anywhere before
479 " this test
480 hi Normal ctermbg=0
481 call assert_equal('dark', &bg)
482 hi Normal ctermbg=4
483 call assert_equal('dark', &bg)
484 hi Normal ctermbg=12
485 call assert_equal('light', &bg)
486 hi Normal ctermbg=15
487 call assert_equal('light', &bg)
488
Bram Moolenaar0b2eef22017-06-27 15:43:49 +0200489 " manually-set &bg takes precedence over auto-detection
Bram Moolenaar1615b362017-06-04 21:06:09 +0200490 set bg=light
491 hi Normal ctermbg=4
492 call assert_equal('light', &bg)
493 set bg=dark
494 hi Normal ctermbg=12
495 call assert_equal('dark', &bg)
Bram Moolenaar6acadda2018-02-24 16:51:32 +0100496
497 hi Normal ctermbg=NONE
Bram Moolenaar1615b362017-06-04 21:06:09 +0200498endfunc
Bram Moolenaar06f1ed22017-06-18 22:41:03 +0200499
500func Test_syntax_hangs()
501 if !has('reltime') || !has('float') || !has('syntax')
502 return
503 endif
504
505 " This pattern takes a long time to match, it should timeout.
506 new
507 call setline(1, ['aaa', repeat('abc ', 1000), 'ccc'])
508 let start = reltime()
509 set nolazyredraw redrawtime=101
510 syn match Error /\%#=1a*.*X\@<=b*/
511 redraw
512 let elapsed = reltimefloat(reltime(start))
513 call assert_true(elapsed > 0.1)
514 call assert_true(elapsed < 1.0)
515
516 " second time syntax HL is disabled
517 let start = reltime()
518 redraw
519 let elapsed = reltimefloat(reltime(start))
520 call assert_true(elapsed < 0.1)
521
522 " after CTRL-L the timeout flag is reset
523 let start = reltime()
524 exe "normal \<C-L>"
525 redraw
526 let elapsed = reltimefloat(reltime(start))
527 call assert_true(elapsed > 0.1)
528 call assert_true(elapsed < 1.0)
529
530 set redrawtime&
531 bwipe!
532endfunc
Bram Moolenaar4d785892017-06-22 22:00:50 +0200533
Bram Moolenaar4d785892017-06-22 22:00:50 +0200534func Test_conceal()
535 if !has('conceal')
536 return
537 endif
538
539 new
540 call setline(1, ['', '123456'])
541 syn match test23 "23" conceal cchar=X
542 syn match test45 "45" conceal
543
544 set conceallevel=0
545 call assert_equal('123456 ', ScreenLines(2, 7)[0])
Bram Moolenaarcc0750d2017-06-24 22:29:24 +0200546 call assert_equal([[0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)'))
Bram Moolenaar4d785892017-06-22 22:00:50 +0200547
548 set conceallevel=1
549 call assert_equal('1X 6 ', ScreenLines(2, 7)[0])
Bram Moolenaarcc0750d2017-06-24 22:29:24 +0200550 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)'))
Bram Moolenaar4d785892017-06-22 22:00:50 +0200551
552 set conceallevel=1
553 set listchars=conceal:Y
Bram Moolenaarcc0750d2017-06-24 22:29:24 +0200554 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)'))
Bram Moolenaar4d785892017-06-22 22:00:50 +0200555 call assert_equal('1XY6 ', ScreenLines(2, 7)[0])
556
557 set conceallevel=2
558 call assert_match('1X6 ', ScreenLines(2, 7)[0])
Bram Moolenaarcc0750d2017-06-24 22:29:24 +0200559 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)'))
Bram Moolenaar4d785892017-06-22 22:00:50 +0200560
561 set conceallevel=3
562 call assert_match('16 ', ScreenLines(2, 7)[0])
Bram Moolenaarcc0750d2017-06-24 22:29:24 +0200563 call assert_equal([[0, '', 0], [1, '', 1], [1, '', 1], [1, '', 2], [1, '', 2], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)'))
Bram Moolenaar4d785892017-06-22 22:00:50 +0200564
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200565 call AssertFails("syntax match Entity '&amp;' conceal cchar=\<Tab>", 'E844:')
566
Bram Moolenaar4d785892017-06-22 22:00:50 +0200567 syn clear
568 set conceallevel&
569 bw!
570endfunc
Bram Moolenaar0b2eef22017-06-27 15:43:49 +0200571
Bram Moolenaarda650582018-02-20 15:51:40 +0100572func Test_synstack_synIDtrans()
Bram Moolenaar0b2eef22017-06-27 15:43:49 +0200573 new
574 setfiletype c
575 syntax on
576 call setline(1, ' /* A comment with a TODO */')
577
578 call assert_equal([], synstack(1, 1))
579
580 norm f/
Bram Moolenaara74e4942019-08-04 17:35:53 +0200581 eval synstack(line("."), col("."))->map('synIDattr(v:val, "name")')->assert_equal(['cComment', 'cCommentStart'])
582 eval synstack(line("."), col("."))->map('synIDattr(synIDtrans(v:val), "name")')->assert_equal(['Comment', 'Comment'])
Bram Moolenaar0b2eef22017-06-27 15:43:49 +0200583
584 norm fA
585 call assert_equal(['cComment'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")'))
586 call assert_equal(['Comment'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")'))
587
588 norm fT
589 call assert_equal(['cComment', 'cTodo'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")'))
590 call assert_equal(['Comment', 'Todo'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")'))
591
Bram Moolenaar0e05de42020-03-25 22:23:46 +0100592 call assert_fails("let n=synIDtrans([])", 'E745:')
593
Bram Moolenaar0b2eef22017-06-27 15:43:49 +0200594 syn clear
595 bw!
596endfunc
Bram Moolenaarda650582018-02-20 15:51:40 +0100597
598" Check highlighting for a small piece of C code with a screen dump.
599func Test_syntax_c()
Bram Moolenaar494e9062020-05-31 21:28:02 +0200600 CheckRunVimInTerminal
Bram Moolenaarda650582018-02-20 15:51:40 +0100601 call writefile([
602 \ '/* comment line at the top */',
Bram Moolenaar83e9a1c2019-10-20 14:51:23 +0200603 \ 'int main(int argc, char **argv) { // another comment',
Bram Moolenaarda650582018-02-20 15:51:40 +0100604 \ '#if 0',
605 \ ' int not_used;',
606 \ '#else',
607 \ ' int used;',
608 \ '#endif',
609 \ ' printf("Just an example piece of C code\n");',
610 \ ' return 0x0ff;',
611 \ '}',
Bram Moolenaar82260af2019-10-20 13:16:22 +0200612 \ "\t\t ",
Bram Moolenaarda650582018-02-20 15:51:40 +0100613 \ ' static void',
614 \ 'myFunction(const double count, struct nothing, long there) {',
Bram Moolenaar84590062019-10-18 23:12:20 +0200615 \ "\t// 123: nothing to endif here",
Bram Moolenaar9115c612019-10-16 16:57:06 +0200616 \ "\tfor (int i = 0; i < count; ++i) {",
617 \ "\t break;",
618 \ "\t}",
Bram Moolenaarbbfd1562019-10-19 20:38:15 +0200619 \ "\tNote: asdf",
Bram Moolenaarda650582018-02-20 15:51:40 +0100620 \ '}',
621 \ ], 'Xtest.c')
Bram Moolenaarb7ea7cb2018-02-24 14:38:51 +0100622
623 " This makes the default for 'background' use "dark", check that the
624 " response to t_RB corrects it to "light".
625 let $COLORFGBG = '15;0'
626
Bram Moolenaar83e9a1c2019-10-20 14:51:23 +0200627 let buf = RunVimInTerminal('Xtest.c', {})
Bram Moolenaarbbfd1562019-10-19 20:38:15 +0200628 call term_sendkeys(buf, ":syn keyword Search Note\r")
Bram Moolenaar82260af2019-10-20 13:16:22 +0200629 call term_sendkeys(buf, ":syn match Error /^\\s\\+$/\r")
Bram Moolenaar84590062019-10-18 23:12:20 +0200630 call term_sendkeys(buf, ":set hlsearch\r")
631 call term_sendkeys(buf, "/endif\r")
632 call term_sendkeys(buf, "vjfC")
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +0100633 call VerifyScreenDump(buf, 'Test_syntax_c_01', {})
Bram Moolenaar84590062019-10-18 23:12:20 +0200634
635 call term_sendkeys(buf, "\<Esc>")
Bram Moolenaarda650582018-02-20 15:51:40 +0100636 call StopVimInTerminal(buf)
637
Bram Moolenaarb7ea7cb2018-02-24 14:38:51 +0100638 let $COLORFGBG = ''
Bram Moolenaarda650582018-02-20 15:51:40 +0100639 call delete('Xtest.c')
640endfun
Bram Moolenaarbcf94422018-06-23 14:21:42 +0200641
642" Using \z() in a region with NFA failing should not crash.
643func Test_syn_wrong_z_one()
644 new
645 call setline(1, ['just some text', 'with foo and bar to match with'])
646 syn region FooBar start="foo\z(.*\)bar" end="\z1"
647 call test_override("nfa_fail", 1)
648 redraw!
649 redraw!
650 call test_override("ALL", 0)
651 bwipe!
652endfunc
Bram Moolenaarc7f1e402019-08-03 13:29:46 +0200653
654func Test_syntax_after_bufdo()
655 call writefile(['/* aaa comment */'], 'Xaaa.c')
656 call writefile(['/* bbb comment */'], 'Xbbb.c')
657 call writefile(['/* ccc comment */'], 'Xccc.c')
658 call writefile(['/* ddd comment */'], 'Xddd.c')
659
660 let bnr = bufnr('%')
661 new Xaaa.c
662 badd Xbbb.c
663 badd Xccc.c
664 badd Xddd.c
665 exe "bwipe " . bnr
666 let l = []
667 bufdo call add(l, bufnr('%'))
668 call assert_equal(4, len(l))
669
670 syntax on
671
672 " This used to only enable syntax HL in the last buffer.
673 bufdo tab split
674 tabrewind
675 for tab in range(1, 4)
676 norm fm
677 call assert_equal(['cComment'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")'))
678 tabnext
679 endfor
680
681 bwipe! Xaaa.c
682 bwipe! Xbbb.c
683 bwipe! Xccc.c
684 bwipe! Xddd.c
685 syntax off
686 call delete('Xaaa.c')
687 call delete('Xbbb.c')
688 call delete('Xccc.c')
689 call delete('Xddd.c')
690endfunc
Bram Moolenaar0e05de42020-03-25 22:23:46 +0100691
Bram Moolenaare35a52a2020-05-31 19:48:53 +0200692func Test_syntax_foldlevel()
693 new
694 call setline(1, [
695 \ 'void f(int a)',
696 \ '{',
697 \ ' if (a == 1) {',
698 \ ' a = 0;',
699 \ ' } else if (a == 2) {',
700 \ ' a = 1;',
701 \ ' } else {',
702 \ ' a = 2;',
703 \ ' }',
704 \ ' if (a > 0) {',
705 \ ' if (a == 1) {',
706 \ ' a = 0;',
707 \ ' } /* missing newline */ } /* end of outer if */ else {',
708 \ ' a = 1;',
709 \ ' }',
710 \ ' if (a == 1)',
711 \ ' {',
712 \ ' a = 0;',
713 \ ' }',
714 \ ' else if (a == 2)',
715 \ ' {',
716 \ ' a = 1;',
717 \ ' }',
718 \ ' else',
719 \ ' {',
720 \ ' a = 2;',
721 \ ' }',
722 \ '}',
723 \ ])
724 setfiletype c
725 syntax on
726 set foldmethod=syntax
727
728 call assert_fails('syn foldlevel start start', 'E390')
729 call assert_fails('syn foldlevel not_an_option', 'E390')
730
731 set foldlevel=1
732
733 syn foldlevel start
734 redir @c
735 syn foldlevel
736 redir END
737 call assert_equal("\nsyntax foldlevel start", @c)
738 syn sync fromstart
739 let a = map(range(3,9), 'foldclosed(v:val)')
740 call assert_equal([3,3,3,3,3,3,3], a) " attached cascade folds together
741 let a = map(range(10,15), 'foldclosed(v:val)')
742 call assert_equal([10,10,10,10,10,10], a) " over-attached 'else' hidden
743 let a = map(range(16,27), 'foldclosed(v:val)')
744 let unattached_results = [-1,17,17,17,-1,21,21,21,-1,25,25,25]
745 call assert_equal(unattached_results, a) " unattached cascade folds separately
746
747 syn foldlevel minimum
748 redir @c
749 syn foldlevel
750 redir END
751 call assert_equal("\nsyntax foldlevel minimum", @c)
752 syn sync fromstart
753 let a = map(range(3,9), 'foldclosed(v:val)')
754 call assert_equal([3,3,5,5,7,7,7], a) " attached cascade folds separately
755 let a = map(range(10,15), 'foldclosed(v:val)')
756 call assert_equal([10,10,10,13,13,13], a) " over-attached 'else' visible
757 let a = map(range(16,27), 'foldclosed(v:val)')
758 call assert_equal(unattached_results, a) " unattached cascade folds separately
759
760 set foldlevel=2
761
762 syn foldlevel start
763 syn sync fromstart
764 let a = map(range(11,14), 'foldclosed(v:val)')
765 call assert_equal([11,11,11,-1], a) " over-attached 'else' hidden
766
767 syn foldlevel minimum
768 syn sync fromstart
769 let a = map(range(11,14), 'foldclosed(v:val)')
770 call assert_equal([11,11,-1,-1], a) " over-attached 'else' visible
771
772 quit!
773endfunc
774
Bram Moolenaaradc17a52020-06-06 18:37:51 +0200775func Test_search_syntax_skip()
776 new
777 let lines =<< trim END
778
779 /* This is VIM */
780 Another Text for VIM
781 let a = "VIM"
782 END
783 call setline(1, lines)
784 syntax on
785 syntax match Comment "^/\*.*\*/"
786 syntax match String '".*"'
787
788 " Skip argument using string evaluation.
789 1
790 call search('VIM', 'w', '', 0, 'synIDattr(synID(line("."), col("."), 1), "name") =~? "comment"')
791 call assert_equal('Another Text for VIM', getline('.'))
792 1
793 call search('VIM', 'w', '', 0, 'synIDattr(synID(line("."), col("."), 1), "name") !~? "string"')
794 call assert_equal(' let a = "VIM"', getline('.'))
795
796 " Skip argument using Lambda.
797 1
798 call search('VIM', 'w', '', 0, { -> synIDattr(synID(line("."), col("."), 1), "name") =~? "comment"})
799 call assert_equal('Another Text for VIM', getline('.'))
800
801 1
802 call search('VIM', 'w', '', 0, { -> synIDattr(synID(line("."), col("."), 1), "name") !~? "string"})
803 call assert_equal(' let a = "VIM"', getline('.'))
804
805 " Skip argument using funcref.
806 func InComment()
807 return synIDattr(synID(line("."), col("."), 1), "name") =~? "comment"
808 endfunc
809 func InString()
810 return synIDattr(synID(line("."), col("."), 1), "name") !~? "string"
811 endfunc
812 1
813 call search('VIM', 'w', '', 0, function('InComment'))
814 call assert_equal('Another Text for VIM', getline('.'))
815
816 1
817 call search('VIM', 'w', '', 0, function('InString'))
818 call assert_equal(' let a = "VIM"', getline('.'))
819
820 delfunc InComment
821 delfunc InString
822 bwipe!
823endfunc
824
Bram Moolenaar0e05de42020-03-25 22:23:46 +0100825" vim: shiftwidth=2 sts=2 expandtab