blob: f668a508588ddf66236056930437917235f116e7 [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()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +020087 CheckFeature profile
Bram Moolenaar73b484c2016-12-11 15:11:17 +010088
89 syntax on
90 syntime on
91 let a = execute('syntime report')
92 call assert_equal("\nNo Syntax items defined for this buffer", a)
93
94 view ../memfile_test.c
95 setfiletype cpp
96 redraw
97 let a = execute('syntime report')
98 call assert_match('^ TOTAL *COUNT *MATCH *SLOWEST *AVERAGE *NAME *PATTERN', a)
99 call assert_match(' \d*\.\d* \+[^0]\d* .* cppRawString ', a)
100 call assert_match(' \d*\.\d* \+[^0]\d* .* cppNumber ', a)
101
102 syntime off
103 syntime clear
104 let a = execute('syntime report')
105 call assert_match('^ TOTAL *COUNT *MATCH *SLOWEST *AVERAGE *NAME *PATTERN', a)
106 call assert_notmatch('.* cppRawString *', a)
107 call assert_notmatch('.* cppNumber*', a)
108 call assert_notmatch('[1-9]', a)
109
Bram Moolenaare2e40752020-09-04 21:18:46 +0200110 call assert_fails('syntime abc', 'E475:')
Bram Moolenaar73b484c2016-12-11 15:11:17 +0100111
112 syntax clear
113 let a = execute('syntime report')
114 call assert_equal("\nNo Syntax items defined for this buffer", a)
115
116 bd
117endfunc
118
Bram Moolenaarb513d302018-12-02 14:55:08 +0100119func Test_syntime_completion()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200120 CheckFeature profile
Bram Moolenaarb513d302018-12-02 14:55:08 +0100121
122 call feedkeys(":syntime \<C-A>\<C-B>\"\<CR>", 'tx')
123 call assert_equal('"syntime clear off on report', @:)
124endfunc
125
Bram Moolenaar73b484c2016-12-11 15:11:17 +0100126func Test_syntax_list()
127 syntax on
128 let a = execute('syntax list')
129 call assert_equal("\nNo Syntax items defined for this buffer", a)
130
131 view ../memfile_test.c
132 setfiletype c
133
134 let a = execute('syntax list')
135 call assert_match('cInclude*', a)
136 call assert_match('cDefine', a)
137
138 let a = execute('syntax list cDefine')
139 call assert_notmatch('cInclude*', a)
140 call assert_match('cDefine', a)
141 call assert_match(' links to Macro$', a)
142
143 call assert_fails('syntax list ABCD', 'E28:')
144 call assert_fails('syntax list @ABCD', 'E392:')
145
146 syntax clear
147 let a = execute('syntax list')
148 call assert_equal("\nNo Syntax items defined for this buffer", a)
149
Bram Moolenaar08f41572020-04-20 16:50:00 +0200150 syntax keyword Type int containedin=g1 skipwhite skipempty skipnl nextgroup=Abc
151 let exp = "Type xxx containedin=g1 nextgroup=Abc skipnl skipwhite skipempty int"
152 call assert_equal(exp, split(execute("syntax list"), "\n")[1])
153
Bram Moolenaar73b484c2016-12-11 15:11:17 +0100154 bd
155endfunc
156
157func Test_syntax_completion()
158 call feedkeys(":syn \<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaare35a52a2020-05-31 19:48:53 +0200159 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 +0100160
161 call feedkeys(":syn case \<C-A>\<C-B>\"\<CR>", 'tx')
162 call assert_equal('"syn case ignore match', @:)
163
Bram Moolenaar2d028392017-01-08 18:28:22 +0100164 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
Bram Moolenaard61e8aa2017-01-17 17:44:46 +0100170 " 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
Bram Moolenaar73b484c2016-12-11 15:11:17 +0100176 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
Bram Moolenaarde318c52017-01-17 16:27:10 +0100182
Bram Moolenaar297610b2019-12-27 17:20:55 +0100183func Test_echohl_completion()
184 call feedkeys(":echohl no\<C-A>\<C-B>\"\<CR>", 'tx')
185 call assert_equal('"echohl NonText Normal none', @:)
186endfunc
187
Bram Moolenaarde318c52017-01-17 16:27:10 +0100188func Test_syntax_arg_skipped()
189 syn clear
190 syntax case ignore
191 if 0
192 syntax case match
193 endif
194 call assert_match('case ignore', execute('syntax case'))
195
196 syn keyword Foo foo
197 call assert_match('Foo', execute('syntax'))
198 syn clear
199 call assert_match('case match', execute('syntax case'))
200 call assert_notmatch('Foo', execute('syntax'))
201
202 if has('conceal')
203 syn clear
204 syntax conceal on
205 if 0
206 syntax conceal off
207 endif
208 call assert_match('conceal on', execute('syntax conceal'))
209 syn clear
210 call assert_match('conceal off', execute('syntax conceal'))
Bram Moolenaar58f60ca2017-01-17 17:19:00 +0100211
212 syntax conceal on
213 syntax conceal off
214 call assert_match('conceal off', execute('syntax conceal'))
Bram Moolenaarde318c52017-01-17 16:27:10 +0100215 endif
216
Bram Moolenaard61e8aa2017-01-17 17:44:46 +0100217 syntax region Bar start=/</ end=/>/
Bram Moolenaarde318c52017-01-17 16:27:10 +0100218 if 0
219 syntax region NotTest start=/</ end=/>/ contains=@Spell
220 endif
Bram Moolenaard61e8aa2017-01-17 17:44:46 +0100221 call assert_match('Bar', execute('syntax'))
Bram Moolenaarde318c52017-01-17 16:27:10 +0100222 call assert_notmatch('NotTest', execute('syntax'))
223 call assert_notmatch('Spell', execute('syntax'))
224
225 hi Foo ctermfg=blue
226 let a = execute('hi Foo')
227 if 0
228 syntax rest
229 endif
230 call assert_equal(a, execute('hi Foo'))
Bram Moolenaard61e8aa2017-01-17 17:44:46 +0100231 hi clear Bar
232 hi clear Foo
Bram Moolenaarde318c52017-01-17 16:27:10 +0100233
234 set ft=tags
235 syn off
236 if 0
237 syntax enable
238 endif
239 call assert_match('No Syntax items defined', execute('syntax'))
240 syntax enable
241 call assert_match('tagComment', execute('syntax'))
242 set ft=
243
244 syn clear
245 if 0
246 syntax include @Spell nothing
247 endif
248 call assert_notmatch('Spell', execute('syntax'))
249
250 syn clear
251 syn iskeyword 48-57,$,_
252 call assert_match('48-57,$,_', execute('syntax iskeyword'))
253 if 0
254 syn clear
255 syn iskeyword clear
256 endif
257 call assert_match('48-57,$,_', execute('syntax iskeyword'))
258 syn iskeyword clear
259 call assert_match('not set', execute('syntax iskeyword'))
260 syn iskeyword 48-57,$,_
261 syn clear
262 call assert_match('not set', execute('syntax iskeyword'))
263
264 syn clear
265 syn keyword Foo foo
266 if 0
267 syn keyword NotAdded bar
268 endif
269 call assert_match('Foo', execute('syntax'))
270 call assert_notmatch('NotAdded', execute('highlight'))
271
272 syn clear
273 syn keyword Foo foo
274 call assert_match('Foo', execute('syntax'))
275 call assert_match('Foo', execute('syntax list'))
276 call assert_notmatch('Foo', execute('if 0 | syntax | endif'))
277 call assert_notmatch('Foo', execute('if 0 | syntax list | endif'))
278
279 syn clear
280 syn match Fopi /asdf/
281 if 0
282 syn match Fopx /asdf/
283 endif
284 call assert_match('Fopi', execute('syntax'))
285 call assert_notmatch('Fopx', execute('syntax'))
286
287 syn clear
288 syn spell toplevel
289 call assert_match('spell toplevel', execute('syntax spell'))
290 if 0
291 syn spell notoplevel
292 endif
293 call assert_match('spell toplevel', execute('syntax spell'))
294 syn spell notoplevel
295 call assert_match('spell notoplevel', execute('syntax spell'))
296 syn spell default
297 call assert_match('spell default', execute('syntax spell'))
298
299 syn clear
300 if 0
301 syntax cluster Spell
302 endif
303 call assert_notmatch('Spell', execute('syntax'))
304
305 syn clear
306 syn keyword Foo foo
307 syn sync ccomment
308 syn sync maxlines=5
309 if 0
310 syn sync maxlines=11
311 endif
312 call assert_match('on C-style comments', execute('syntax sync'))
313 call assert_match('maximal 5 lines', execute('syntax sync'))
Bram Moolenaar58f60ca2017-01-17 17:19:00 +0100314 syn sync clear
Bram Moolenaarde318c52017-01-17 16:27:10 +0100315 if 0
316 syn sync ccomment
317 endif
318 call assert_notmatch('on C-style comments', execute('syntax sync'))
Bram Moolenaar99502802020-11-18 16:53:23 +0100319 syn sync fromstart
320 call assert_match('syncing starts at the first line', execute('syntax sync'))
Bram Moolenaarde318c52017-01-17 16:27:10 +0100321
322 syn clear
323endfunc
324
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200325" Check for an error. Used when multiple errors are thrown and we are checking
326" for an earliest error.
327func AssertFails(cmd, errcode)
328 let save_exception = ''
329 try
330 exe a:cmd
331 catch
332 let save_exception = v:exception
333 endtry
334 call assert_match(a:errcode, save_exception)
335endfunc
336
Bram Moolenaarea588152017-04-10 22:45:30 +0200337func Test_syntax_invalid_arg()
Bram Moolenaar58f60ca2017-01-17 17:19:00 +0100338 call assert_fails('syntax case asdf', 'E390:')
Bram Moolenaard61e8aa2017-01-17 17:44:46 +0100339 if has('conceal')
340 call assert_fails('syntax conceal asdf', 'E390:')
341 endif
Bram Moolenaar58f60ca2017-01-17 17:19:00 +0100342 call assert_fails('syntax spell asdf', 'E390:')
Bram Moolenaarea588152017-04-10 22:45:30 +0200343 call assert_fails('syntax clear @ABCD', 'E391:')
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200344 call assert_fails('syntax include random_file', 'E484:')
345 call assert_fails('syntax include <afile>', 'E495:')
Bram Moolenaarea588152017-04-10 22:45:30 +0200346 call assert_fails('syntax sync x', 'E404:')
347 call assert_fails('syntax keyword Abc a[', 'E789:')
348 call assert_fails('syntax keyword Abc a[bc]d', 'E890:')
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200349 call assert_fails('syntax cluster Abc add=A add=', 'E406:')
Bram Moolenaar476a6132020-04-08 19:48:56 +0200350
351 " Test for too many \z\( and unmatched \z\(
352 " Not able to use assert_fails() here because both E50:/E879: and E475:
353 " messages are emitted.
354 set regexpengine=1
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200355 call AssertFails("syntax region MyRegion start='\\z\\(' end='\\*/'", 'E52:')
Bram Moolenaar476a6132020-04-08 19:48:56 +0200356
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200357 let cmd = "syntax region MyRegion start='"
358 let cmd ..= repeat("\\z\\(.\\)", 10) .. "' end='\*/'"
359 call AssertFails(cmd, 'E50:')
Bram Moolenaar476a6132020-04-08 19:48:56 +0200360
361 set regexpengine=2
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200362 call AssertFails("syntax region MyRegion start='\\z\\(' end='\\*/'", 'E54:')
Bram Moolenaar476a6132020-04-08 19:48:56 +0200363
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200364 let cmd = "syntax region MyRegion start='"
365 let cmd ..= repeat("\\z\\(.\\)", 10) .. "' end='\*/'"
366 call AssertFails(cmd, 'E879:')
Bram Moolenaar476a6132020-04-08 19:48:56 +0200367 set regexpengine&
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200368
369 call AssertFails('syntax keyword cMyItem grouphere G1', 'E393:')
370 call AssertFails('syntax sync match Abc grouphere MyItem "abc"', 'E394:')
371 call AssertFails('syn keyword Type contains int', 'E395:')
372 call assert_fails('syntax include @Xxx', 'E397:')
373 call AssertFails('syntax region X start', 'E398:')
374 call assert_fails('syntax region X start="{"', 'E399:')
375 call AssertFails('syntax cluster contains=Abc', 'E400:')
376 call AssertFails("syntax match Character /'.'", 'E401:')
377 call AssertFails("syntax match Character /'.'/a", 'E402:')
Bram Moolenaar531be472020-09-23 22:38:05 +0200378 call assert_fails('syntax sync linecont /\%(/', 'E53:')
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200379 call assert_fails('syntax sync linecont /pat', 'E404:')
380 call assert_fails('syntax sync linecont', 'E404:')
381 call assert_fails('syntax sync linecont /pat1/ linecont /pat2/', 'E403:')
382 call assert_fails('syntax sync minlines=a', 'E404:')
383 call AssertFails('syntax match ABC /x/ contains=', 'E406:')
384 call AssertFails("syntax match Character contains /'.'/", 'E405:')
385 call AssertFails('syntax match ccFoo "Foo" nextgroup=ALLBUT,F', 'E407:')
386 call AssertFails('syntax region Block start="{" contains=F,ALLBUT', 'E408:')
387 call AssertFails("syntax match Characters contains=a.*x /'.'/", 'E409:')
Bram Moolenaar531be472020-09-23 22:38:05 +0200388 call assert_fails('syntax match Search /abc/ contains=ALLBUT,/\%(/', 'E53:')
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
Bram Moolenaard1f76af2020-09-13 22:37:34 +0200435
Bram Moolenaarf8ec9982017-04-09 15:41:31 +0200436 ownsyntax perl
Bram Moolenaard1f76af2020-09-13 22:37:34 +0200437 " this should not crash
438 set
439
Bram Moolenaarf8ec9982017-04-09 15:41:31 +0200440 call assert_equal('perlComment', synIDattr(synID(line('.'), col('.'), 1), 'name'))
441 call assert_equal('c', b:current_syntax)
442 call assert_equal('perl', w:current_syntax)
443
444 " A new split window should have the original syntax.
445 split
446 call assert_equal('cDefine', synIDattr(synID(line('.'), col('.'), 1), 'name'))
447 call assert_equal('c', b:current_syntax)
448 call assert_equal(0, exists('w:current_syntax'))
449
450 wincmd x
451 call assert_equal('perlComment', synIDattr(synID(line("."), col("."), 1), "name"))
452
453 syntax off
454 set filetype&
455 %bw!
456endfunc
457
458func Test_ownsyntax_completion()
459 call feedkeys(":ownsyntax java\<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaarea7a08a2019-08-26 22:38:22 +0200460 call assert_equal('"ownsyntax java javacc javascript javascriptreact', @:)
Bram Moolenaarf8ec9982017-04-09 15:41:31 +0200461endfunc
Bram Moolenaarea588152017-04-10 22:45:30 +0200462
463func Test_highlight_invalid_arg()
464 if has('gui_running')
465 call assert_fails('hi XXX guifg=xxx', 'E254:')
466 endif
467 call assert_fails('hi DoesNotExist', 'E411:')
468 call assert_fails('hi link', 'E412:')
469 call assert_fails('hi link a', 'E412:')
470 call assert_fails('hi link a b c', 'E413:')
471 call assert_fails('hi XXX =', 'E415:')
472 call assert_fails('hi XXX cterm', 'E416:')
473 call assert_fails('hi XXX cterm=', 'E417:')
474 call assert_fails('hi XXX cterm=DoesNotExist', 'E418:')
475 call assert_fails('hi XXX ctermfg=DoesNotExist', 'E421:')
476 call assert_fails('hi XXX xxx=White', 'E423:')
477endfunc
478
Bram Moolenaar1615b362017-06-04 21:06:09 +0200479func Test_bg_detection()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200480 CheckNotGui
481
Bram Moolenaar1615b362017-06-04 21:06:09 +0200482 " auto-detection of &bg, make sure sure it isn't set anywhere before
483 " this test
484 hi Normal ctermbg=0
485 call assert_equal('dark', &bg)
486 hi Normal ctermbg=4
487 call assert_equal('dark', &bg)
488 hi Normal ctermbg=12
489 call assert_equal('light', &bg)
490 hi Normal ctermbg=15
491 call assert_equal('light', &bg)
492
Bram Moolenaar0b2eef22017-06-27 15:43:49 +0200493 " manually-set &bg takes precedence over auto-detection
Bram Moolenaar1615b362017-06-04 21:06:09 +0200494 set bg=light
495 hi Normal ctermbg=4
496 call assert_equal('light', &bg)
497 set bg=dark
498 hi Normal ctermbg=12
499 call assert_equal('dark', &bg)
Bram Moolenaar6acadda2018-02-24 16:51:32 +0100500
501 hi Normal ctermbg=NONE
Bram Moolenaar1615b362017-06-04 21:06:09 +0200502endfunc
Bram Moolenaar06f1ed22017-06-18 22:41:03 +0200503
504func Test_syntax_hangs()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200505 CheckFunction reltimefloat
506 CheckFeature syntax
Bram Moolenaar06f1ed22017-06-18 22:41:03 +0200507
508 " This pattern takes a long time to match, it should timeout.
509 new
510 call setline(1, ['aaa', repeat('abc ', 1000), 'ccc'])
511 let start = reltime()
512 set nolazyredraw redrawtime=101
513 syn match Error /\%#=1a*.*X\@<=b*/
514 redraw
515 let elapsed = reltimefloat(reltime(start))
516 call assert_true(elapsed > 0.1)
517 call assert_true(elapsed < 1.0)
518
519 " second time syntax HL is disabled
520 let start = reltime()
521 redraw
522 let elapsed = reltimefloat(reltime(start))
523 call assert_true(elapsed < 0.1)
524
525 " after CTRL-L the timeout flag is reset
526 let start = reltime()
527 exe "normal \<C-L>"
528 redraw
529 let elapsed = reltimefloat(reltime(start))
530 call assert_true(elapsed > 0.1)
531 call assert_true(elapsed < 1.0)
532
533 set redrawtime&
534 bwipe!
535endfunc
Bram Moolenaar4d785892017-06-22 22:00:50 +0200536
Bram Moolenaar4d785892017-06-22 22:00:50 +0200537func Test_conceal()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200538 CheckFeature conceal
Bram Moolenaar4d785892017-06-22 22:00:50 +0200539
540 new
541 call setline(1, ['', '123456'])
542 syn match test23 "23" conceal cchar=X
543 syn match test45 "45" conceal
544
545 set conceallevel=0
546 call assert_equal('123456 ', ScreenLines(2, 7)[0])
Bram Moolenaarcc0750d2017-06-24 22:29:24 +0200547 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 +0200548
549 set conceallevel=1
550 call assert_equal('1X 6 ', ScreenLines(2, 7)[0])
Bram Moolenaarcc0750d2017-06-24 22:29:24 +0200551 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 +0200552
553 set conceallevel=1
554 set listchars=conceal:Y
Bram Moolenaarcc0750d2017-06-24 22:29:24 +0200555 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 +0200556 call assert_equal('1XY6 ', ScreenLines(2, 7)[0])
557
558 set conceallevel=2
559 call assert_match('1X6 ', ScreenLines(2, 7)[0])
Bram Moolenaarcc0750d2017-06-24 22:29:24 +0200560 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 +0200561
562 set conceallevel=3
563 call assert_match('16 ', ScreenLines(2, 7)[0])
Bram Moolenaarcc0750d2017-06-24 22:29:24 +0200564 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 +0200565
Bram Moolenaarfbf21222020-04-19 18:31:25 +0200566 call AssertFails("syntax match Entity '&amp;' conceal cchar=\<Tab>", 'E844:')
567
Bram Moolenaar4d785892017-06-22 22:00:50 +0200568 syn clear
569 set conceallevel&
570 bw!
571endfunc
Bram Moolenaar0b2eef22017-06-27 15:43:49 +0200572
Bram Moolenaarda650582018-02-20 15:51:40 +0100573func Test_synstack_synIDtrans()
Bram Moolenaar0b2eef22017-06-27 15:43:49 +0200574 new
575 setfiletype c
576 syntax on
577 call setline(1, ' /* A comment with a TODO */')
578
579 call assert_equal([], synstack(1, 1))
580
581 norm f/
Bram Moolenaara74e4942019-08-04 17:35:53 +0200582 eval synstack(line("."), col("."))->map('synIDattr(v:val, "name")')->assert_equal(['cComment', 'cCommentStart'])
583 eval synstack(line("."), col("."))->map('synIDattr(synIDtrans(v:val), "name")')->assert_equal(['Comment', 'Comment'])
Bram Moolenaar0b2eef22017-06-27 15:43:49 +0200584
585 norm fA
586 call assert_equal(['cComment'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")'))
587 call assert_equal(['Comment'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")'))
588
589 norm fT
590 call assert_equal(['cComment', 'cTodo'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")'))
591 call assert_equal(['Comment', 'Todo'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")'))
592
Bram Moolenaar0e05de42020-03-25 22:23:46 +0100593 call assert_fails("let n=synIDtrans([])", 'E745:')
594
Bram Moolenaar0b2eef22017-06-27 15:43:49 +0200595 syn clear
596 bw!
597endfunc
Bram Moolenaarda650582018-02-20 15:51:40 +0100598
599" Check highlighting for a small piece of C code with a screen dump.
600func Test_syntax_c()
Bram Moolenaar494e9062020-05-31 21:28:02 +0200601 CheckRunVimInTerminal
Bram Moolenaarda650582018-02-20 15:51:40 +0100602 call writefile([
603 \ '/* comment line at the top */',
Bram Moolenaar83e9a1c2019-10-20 14:51:23 +0200604 \ 'int main(int argc, char **argv) { // another comment',
Bram Moolenaarda650582018-02-20 15:51:40 +0100605 \ '#if 0',
606 \ ' int not_used;',
607 \ '#else',
608 \ ' int used;',
609 \ '#endif',
610 \ ' printf("Just an example piece of C code\n");',
611 \ ' return 0x0ff;',
612 \ '}',
Bram Moolenaar82260af2019-10-20 13:16:22 +0200613 \ "\t\t ",
Bram Moolenaarda650582018-02-20 15:51:40 +0100614 \ ' static void',
615 \ 'myFunction(const double count, struct nothing, long there) {',
Bram Moolenaar84590062019-10-18 23:12:20 +0200616 \ "\t// 123: nothing to endif here",
Bram Moolenaar9115c612019-10-16 16:57:06 +0200617 \ "\tfor (int i = 0; i < count; ++i) {",
618 \ "\t break;",
619 \ "\t}",
Bram Moolenaarbbfd1562019-10-19 20:38:15 +0200620 \ "\tNote: asdf",
Bram Moolenaarda650582018-02-20 15:51:40 +0100621 \ '}',
622 \ ], 'Xtest.c')
Bram Moolenaarb7ea7cb2018-02-24 14:38:51 +0100623
624 " This makes the default for 'background' use "dark", check that the
625 " response to t_RB corrects it to "light".
626 let $COLORFGBG = '15;0'
627
Bram Moolenaar83e9a1c2019-10-20 14:51:23 +0200628 let buf = RunVimInTerminal('Xtest.c', {})
Bram Moolenaarbbfd1562019-10-19 20:38:15 +0200629 call term_sendkeys(buf, ":syn keyword Search Note\r")
Bram Moolenaar82260af2019-10-20 13:16:22 +0200630 call term_sendkeys(buf, ":syn match Error /^\\s\\+$/\r")
Bram Moolenaar84590062019-10-18 23:12:20 +0200631 call term_sendkeys(buf, ":set hlsearch\r")
632 call term_sendkeys(buf, "/endif\r")
633 call term_sendkeys(buf, "vjfC")
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +0100634 call VerifyScreenDump(buf, 'Test_syntax_c_01', {})
Bram Moolenaar84590062019-10-18 23:12:20 +0200635
636 call term_sendkeys(buf, "\<Esc>")
Bram Moolenaarda650582018-02-20 15:51:40 +0100637 call StopVimInTerminal(buf)
638
Bram Moolenaarb7ea7cb2018-02-24 14:38:51 +0100639 let $COLORFGBG = ''
Bram Moolenaarda650582018-02-20 15:51:40 +0100640 call delete('Xtest.c')
641endfun
Bram Moolenaarbcf94422018-06-23 14:21:42 +0200642
643" Using \z() in a region with NFA failing should not crash.
644func Test_syn_wrong_z_one()
645 new
646 call setline(1, ['just some text', 'with foo and bar to match with'])
647 syn region FooBar start="foo\z(.*\)bar" end="\z1"
648 call test_override("nfa_fail", 1)
649 redraw!
650 redraw!
651 call test_override("ALL", 0)
652 bwipe!
653endfunc
Bram Moolenaarc7f1e402019-08-03 13:29:46 +0200654
655func Test_syntax_after_bufdo()
656 call writefile(['/* aaa comment */'], 'Xaaa.c')
657 call writefile(['/* bbb comment */'], 'Xbbb.c')
658 call writefile(['/* ccc comment */'], 'Xccc.c')
659 call writefile(['/* ddd comment */'], 'Xddd.c')
660
661 let bnr = bufnr('%')
662 new Xaaa.c
663 badd Xbbb.c
664 badd Xccc.c
665 badd Xddd.c
666 exe "bwipe " . bnr
667 let l = []
668 bufdo call add(l, bufnr('%'))
669 call assert_equal(4, len(l))
670
671 syntax on
672
673 " This used to only enable syntax HL in the last buffer.
674 bufdo tab split
675 tabrewind
676 for tab in range(1, 4)
677 norm fm
678 call assert_equal(['cComment'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")'))
679 tabnext
680 endfor
681
682 bwipe! Xaaa.c
683 bwipe! Xbbb.c
684 bwipe! Xccc.c
685 bwipe! Xddd.c
686 syntax off
687 call delete('Xaaa.c')
688 call delete('Xbbb.c')
689 call delete('Xccc.c')
690 call delete('Xddd.c')
691endfunc
Bram Moolenaar0e05de42020-03-25 22:23:46 +0100692
Bram Moolenaare35a52a2020-05-31 19:48:53 +0200693func Test_syntax_foldlevel()
694 new
695 call setline(1, [
696 \ 'void f(int a)',
697 \ '{',
698 \ ' if (a == 1) {',
699 \ ' a = 0;',
700 \ ' } else if (a == 2) {',
701 \ ' a = 1;',
702 \ ' } else {',
703 \ ' a = 2;',
704 \ ' }',
705 \ ' if (a > 0) {',
706 \ ' if (a == 1) {',
707 \ ' a = 0;',
708 \ ' } /* missing newline */ } /* end of outer if */ else {',
709 \ ' a = 1;',
710 \ ' }',
711 \ ' if (a == 1)',
712 \ ' {',
713 \ ' a = 0;',
714 \ ' }',
715 \ ' else if (a == 2)',
716 \ ' {',
717 \ ' a = 1;',
718 \ ' }',
719 \ ' else',
720 \ ' {',
721 \ ' a = 2;',
722 \ ' }',
723 \ '}',
724 \ ])
725 setfiletype c
726 syntax on
727 set foldmethod=syntax
728
Bram Moolenaare2e40752020-09-04 21:18:46 +0200729 call assert_fails('syn foldlevel start start', 'E390:')
730 call assert_fails('syn foldlevel not_an_option', 'E390:')
Bram Moolenaare35a52a2020-05-31 19:48:53 +0200731
732 set foldlevel=1
733
734 syn foldlevel start
735 redir @c
736 syn foldlevel
737 redir END
738 call assert_equal("\nsyntax foldlevel start", @c)
739 syn sync fromstart
Bram Moolenaar99502802020-11-18 16:53:23 +0100740 call assert_match('from the first line$', execute('syn sync'))
Bram Moolenaare35a52a2020-05-31 19:48:53 +0200741 let a = map(range(3,9), 'foldclosed(v:val)')
742 call assert_equal([3,3,3,3,3,3,3], a) " attached cascade folds together
743 let a = map(range(10,15), 'foldclosed(v:val)')
744 call assert_equal([10,10,10,10,10,10], a) " over-attached 'else' hidden
745 let a = map(range(16,27), 'foldclosed(v:val)')
746 let unattached_results = [-1,17,17,17,-1,21,21,21,-1,25,25,25]
747 call assert_equal(unattached_results, a) " unattached cascade folds separately
748
749 syn foldlevel minimum
750 redir @c
751 syn foldlevel
752 redir END
753 call assert_equal("\nsyntax foldlevel minimum", @c)
754 syn sync fromstart
755 let a = map(range(3,9), 'foldclosed(v:val)')
756 call assert_equal([3,3,5,5,7,7,7], a) " attached cascade folds separately
757 let a = map(range(10,15), 'foldclosed(v:val)')
758 call assert_equal([10,10,10,13,13,13], a) " over-attached 'else' visible
759 let a = map(range(16,27), 'foldclosed(v:val)')
760 call assert_equal(unattached_results, a) " unattached cascade folds separately
761
762 set foldlevel=2
763
764 syn foldlevel start
765 syn sync fromstart
766 let a = map(range(11,14), 'foldclosed(v:val)')
767 call assert_equal([11,11,11,-1], a) " over-attached 'else' hidden
768
769 syn foldlevel minimum
770 syn sync fromstart
771 let a = map(range(11,14), 'foldclosed(v:val)')
772 call assert_equal([11,11,-1,-1], a) " over-attached 'else' visible
773
774 quit!
775endfunc
776
Bram Moolenaaradc17a52020-06-06 18:37:51 +0200777func Test_search_syntax_skip()
778 new
779 let lines =<< trim END
780
781 /* This is VIM */
782 Another Text for VIM
783 let a = "VIM"
784 END
785 call setline(1, lines)
786 syntax on
787 syntax match Comment "^/\*.*\*/"
788 syntax match String '".*"'
789
790 " Skip argument using string evaluation.
791 1
792 call search('VIM', 'w', '', 0, 'synIDattr(synID(line("."), col("."), 1), "name") =~? "comment"')
793 call assert_equal('Another Text for VIM', getline('.'))
794 1
795 call search('VIM', 'w', '', 0, 'synIDattr(synID(line("."), col("."), 1), "name") !~? "string"')
796 call assert_equal(' let a = "VIM"', getline('.'))
797
798 " Skip argument using Lambda.
799 1
800 call search('VIM', 'w', '', 0, { -> synIDattr(synID(line("."), col("."), 1), "name") =~? "comment"})
801 call assert_equal('Another Text for VIM', getline('.'))
802
803 1
804 call search('VIM', 'w', '', 0, { -> synIDattr(synID(line("."), col("."), 1), "name") !~? "string"})
805 call assert_equal(' let a = "VIM"', getline('.'))
806
807 " Skip argument using funcref.
808 func InComment()
809 return synIDattr(synID(line("."), col("."), 1), "name") =~? "comment"
810 endfunc
811 func InString()
812 return synIDattr(synID(line("."), col("."), 1), "name") !~? "string"
813 endfunc
814 1
815 call search('VIM', 'w', '', 0, function('InComment'))
816 call assert_equal('Another Text for VIM', getline('.'))
817
818 1
819 call search('VIM', 'w', '', 0, function('InString'))
820 call assert_equal(' let a = "VIM"', getline('.'))
821
822 delfunc InComment
823 delfunc InString
824 bwipe!
825endfunc
826
Bram Moolenaar0e05de42020-03-25 22:23:46 +0100827" vim: shiftwidth=2 sts=2 expandtab