1" Tests for ":highlight" and highlighting.
2
3source view_util.vim
4source screendump.vim
5source check.vim
6source script_util.vim
7source vim9.vim
8
9func Test_highlight()
10  " basic test if ":highlight" doesn't crash
11  highlight
12  hi Search
13
14  " test setting colors.
15  " test clearing one color and all doesn't generate error or warning
16  silent! hi NewGroup term=bold cterm=italic ctermfg=DarkBlue ctermbg=Grey gui= guifg=#00ff00 guibg=Cyan
17  silent! hi Group2 term= cterm=
18  hi Group3 term=underline cterm=bold
19
20  let res = split(execute("hi NewGroup"), "\n")[0]
21  " filter ctermfg and ctermbg, the numbers depend on the terminal
22  let res = substitute(res, 'ctermfg=\d*', 'ctermfg=2', '')
23  let res = substitute(res, 'ctermbg=\d*', 'ctermbg=3', '')
24  call assert_equal("NewGroup       xxx term=bold cterm=italic ctermfg=2 ctermbg=3",
25				\ res)
26  call assert_equal("Group2         xxx cleared",
27				\ split(execute("hi Group2"), "\n")[0])
28  call assert_equal("Group3         xxx term=underline cterm=bold",
29				\ split(execute("hi Group3"), "\n")[0])
30
31  hi clear NewGroup
32  call assert_equal("NewGroup       xxx cleared",
33				\ split(execute("hi NewGroup"), "\n")[0])
34  call assert_equal("Group2         xxx cleared",
35				\ split(execute("hi Group2"), "\n")[0])
36  hi Group2 NONE
37  call assert_equal("Group2         xxx cleared",
38				\ split(execute("hi Group2"), "\n")[0])
39  hi clear
40  call assert_equal("Group3         xxx cleared",
41				\ split(execute("hi Group3"), "\n")[0])
42  call assert_fails("hi Crash term='asdf", "E475:")
43endfunc
44
45func HighlightArgs(name)
46  return 'hi ' . substitute(split(execute('hi ' . a:name), '\n')[0], '\<xxx\>', '', '')
47endfunc
48
49func IsColorable()
50  return has('gui_running') || str2nr(&t_Co) >= 8
51endfunc
52
53func HiCursorLine()
54  let hiCursorLine = HighlightArgs('CursorLine')
55  if has('gui_running')
56    let guibg = matchstr(hiCursorLine, 'guibg=\w\+')
57    let hi_ul = 'hi CursorLine gui=underline guibg=NONE'
58    let hi_bg = 'hi CursorLine gui=NONE ' . guibg
59  else
60    let hi_ul = 'hi CursorLine cterm=underline ctermbg=NONE'
61    let hi_bg = 'hi CursorLine cterm=NONE ctermbg=Gray'
62  endif
63  return [hiCursorLine, hi_ul, hi_bg]
64endfunc
65
66func Check_lcs_eol_attrs(attrs, row, col)
67  let save_lcs = &lcs
68  set list
69
70  call assert_equal(a:attrs, ScreenAttrs(a:row, a:col)[0])
71
72  set nolist
73  let &lcs = save_lcs
74endfunc
75
76func Test_highlight_eol_with_cursorline()
77  let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
78
79  call NewWindow('topleft 5', 20)
80  call setline(1, 'abcd')
81  call matchadd('Search', '\n')
82
83  " expected:
84  " 'abcd      '
85  "  ^^^^ ^^^^^   no highlight
86  "      ^        'Search' highlight
87  let attrs0 = ScreenAttrs(1, 10)[0]
88  call assert_equal(repeat([attrs0[0]], 4), attrs0[0:3])
89  call assert_equal(repeat([attrs0[0]], 5), attrs0[5:9])
90  call assert_notequal(attrs0[0], attrs0[4])
91
92  setlocal cursorline
93
94  " underline
95  exe hi_ul
96
97  " expected:
98  " 'abcd      '
99  "  ^^^^         underline
100  "      ^        'Search' highlight with underline
101  "       ^^^^^   underline
102  let attrs = ScreenAttrs(1, 10)[0]
103  call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
104  call assert_equal([attrs[4]] + repeat([attrs[5]], 5), attrs[4:9])
105  call assert_notequal(attrs[0], attrs[4])
106  call assert_notequal(attrs[4], attrs[5])
107  call assert_notequal(attrs0[0], attrs[0])
108  call assert_notequal(attrs0[4], attrs[4])
109  call Check_lcs_eol_attrs(attrs, 1, 10)
110
111  if IsColorable()
112    " bg-color
113    exe hi_bg
114
115    " expected:
116    " 'abcd      '
117    "  ^^^^         bg-color of 'CursorLine'
118    "      ^        'Search' highlight
119    "       ^^^^^   bg-color of 'CursorLine'
120    let attrs = ScreenAttrs(1, 10)[0]
121    call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
122    call assert_equal(repeat([attrs[5]], 5), attrs[5:9])
123    call assert_equal(attrs0[4], attrs[4])
124    call assert_notequal(attrs[0], attrs[4])
125    call assert_notequal(attrs[4], attrs[5])
126    call assert_notequal(attrs0[0], attrs[0])
127    call assert_notequal(attrs0[5], attrs[5])
128    call Check_lcs_eol_attrs(attrs, 1, 10)
129  endif
130
131  call CloseWindow()
132  exe hiCursorLine
133endfunc
134
135func Test_highlight_eol_with_cursorline_vertsplit()
136  let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
137
138  call NewWindow('topleft 5', 5)
139  call setline(1, 'abcd')
140  call matchadd('Search', '\n')
141
142  let expected = "abcd |abcd     "
143  let actual = ScreenLines(1, 15)[0]
144  call assert_equal(expected, actual)
145
146  " expected:
147  " 'abcd |abcd     '
148  "  ^^^^  ^^^^^^^^^   no highlight
149  "      ^             'Search' highlight
150  "       ^            'VertSplit' highlight
151  let attrs0 = ScreenAttrs(1, 15)[0]
152  call assert_equal(repeat([attrs0[0]], 4), attrs0[0:3])
153  call assert_equal(repeat([attrs0[0]], 9), attrs0[6:14])
154  call assert_notequal(attrs0[0], attrs0[4])
155  call assert_notequal(attrs0[0], attrs0[5])
156  call assert_notequal(attrs0[4], attrs0[5])
157
158  setlocal cursorline
159
160  " expected:
161  " 'abcd |abcd     '
162  "  ^^^^              underline
163  "      ^             'Search' highlight with underline
164  "       ^            'VertSplit' highlight
165  "        ^^^^^^^^^   no highlight
166
167  " underline
168  exe hi_ul
169
170  let actual = ScreenLines(1, 15)[0]
171  call assert_equal(expected, actual)
172
173  let attrs = ScreenAttrs(1, 15)[0]
174  call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
175  call assert_equal(repeat([attrs[6]], 9), attrs[6:14])
176  call assert_equal(attrs0[5:14], attrs[5:14])
177  call assert_notequal(attrs[0], attrs[4])
178  call assert_notequal(attrs[0], attrs[5])
179  call assert_notequal(attrs[0], attrs[6])
180  call assert_notequal(attrs[4], attrs[5])
181  call assert_notequal(attrs[5], attrs[6])
182  call assert_notequal(attrs0[0], attrs[0])
183  call assert_notequal(attrs0[4], attrs[4])
184  call Check_lcs_eol_attrs(attrs, 1, 15)
185
186  if IsColorable()
187    " bg-color
188    exe hi_bg
189
190    let actual = ScreenLines(1, 15)[0]
191    call assert_equal(expected, actual)
192
193    let attrs = ScreenAttrs(1, 15)[0]
194    call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
195    call assert_equal(repeat([attrs[6]], 9), attrs[6:14])
196    call assert_equal(attrs0[5:14], attrs[5:14])
197    call assert_notequal(attrs[0], attrs[4])
198    call assert_notequal(attrs[0], attrs[5])
199    call assert_notequal(attrs[0], attrs[6])
200    call assert_notequal(attrs[4], attrs[5])
201    call assert_notequal(attrs[5], attrs[6])
202    call assert_notequal(attrs0[0], attrs[0])
203    call assert_equal(attrs0[4], attrs[4])
204    call Check_lcs_eol_attrs(attrs, 1, 15)
205  endif
206
207  call CloseWindow()
208  exe hiCursorLine
209endfunc
210
211func Test_highlight_eol_with_cursorline_rightleft()
212  CheckFeature rightleft
213
214  let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
215
216  call NewWindow('topleft 5', 10)
217  setlocal rightleft
218  call setline(1, 'abcd')
219  call matchadd('Search', '\n')
220  let attrs0 = ScreenAttrs(1, 10)[0]
221
222  setlocal cursorline
223
224  " underline
225  exe hi_ul
226
227  " expected:
228  " '      dcba'
229  "        ^^^^   underline
230  "       ^       'Search' highlight with underline
231  "  ^^^^^        underline
232  let attrs = ScreenAttrs(1, 10)[0]
233  call assert_equal(repeat([attrs[9]], 4), attrs[6:9])
234  call assert_equal(repeat([attrs[4]], 5) + [attrs[5]], attrs[0:5])
235  call assert_notequal(attrs[9], attrs[5])
236  call assert_notequal(attrs[4], attrs[5])
237  call assert_notequal(attrs0[9], attrs[9])
238  call assert_notequal(attrs0[5], attrs[5])
239  call Check_lcs_eol_attrs(attrs, 1, 10)
240
241  if IsColorable()
242    " bg-color
243    exe hi_bg
244
245    " expected:
246    " '      dcba'
247    "        ^^^^   bg-color of 'CursorLine'
248    "       ^       'Search' highlight
249    "  ^^^^^        bg-color of 'CursorLine'
250    let attrs = ScreenAttrs(1, 10)[0]
251    call assert_equal(repeat([attrs[9]], 4), attrs[6:9])
252    call assert_equal(repeat([attrs[4]], 5), attrs[0:4])
253    call assert_equal(attrs0[5], attrs[5])
254    call assert_notequal(attrs[9], attrs[5])
255    call assert_notequal(attrs[5], attrs[4])
256    call assert_notequal(attrs0[9], attrs[9])
257    call assert_notequal(attrs0[4], attrs[4])
258    call Check_lcs_eol_attrs(attrs, 1, 10)
259  endif
260
261  call CloseWindow()
262  exe hiCursorLine
263endfunc
264
265func Test_highlight_eol_with_cursorline_linewrap()
266  let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
267
268  call NewWindow('topleft 5', 10)
269  call setline(1, [repeat('a', 51) . 'bcd', ''])
270  call matchadd('Search', '\n')
271
272  setlocal wrap
273  normal! gg$
274  let attrs0 = ScreenAttrs(5, 10)[0]
275  setlocal cursorline
276
277  " underline
278  exe hi_ul
279
280  " expected:
281  " 'abcd      '
282  "  ^^^^         underline
283  "      ^        'Search' highlight with underline
284  "       ^^^^^   underline
285  let attrs = ScreenAttrs(5, 10)[0]
286  call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
287  call assert_equal([attrs[4]] + repeat([attrs[5]], 5), attrs[4:9])
288  call assert_notequal(attrs[0], attrs[4])
289  call assert_notequal(attrs[4], attrs[5])
290  call assert_notequal(attrs0[0], attrs[0])
291  call assert_notequal(attrs0[4], attrs[4])
292  call Check_lcs_eol_attrs(attrs, 5, 10)
293
294  if IsColorable()
295    " bg-color
296    exe hi_bg
297
298    " expected:
299    " 'abcd      '
300    "  ^^^^         bg-color of 'CursorLine'
301    "      ^        'Search' highlight
302    "       ^^^^^   bg-color of 'CursorLine'
303    let attrs = ScreenAttrs(5, 10)[0]
304    call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
305    call assert_equal(repeat([attrs[5]], 5), attrs[5:9])
306    call assert_equal(attrs0[4], attrs[4])
307    call assert_notequal(attrs[0], attrs[4])
308    call assert_notequal(attrs[4], attrs[5])
309    call assert_notequal(attrs0[0], attrs[0])
310    call assert_notequal(attrs0[5], attrs[5])
311    call Check_lcs_eol_attrs(attrs, 5, 10)
312  endif
313
314  setlocal nocursorline nowrap
315  normal! gg$
316  let attrs0 = ScreenAttrs(1, 10)[0]
317  setlocal cursorline
318
319  " underline
320  exe hi_ul
321
322  " expected:
323  " 'aaabcd    '
324  "  ^^^^^^       underline
325  "        ^      'Search' highlight with underline
326  "         ^^^   underline
327  let attrs = ScreenAttrs(1, 10)[0]
328  call assert_equal(repeat([attrs[0]], 6), attrs[0:5])
329  call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
330  call assert_notequal(attrs[0], attrs[6])
331  call assert_notequal(attrs[6], attrs[7])
332  call assert_notequal(attrs0[0], attrs[0])
333  call assert_notequal(attrs0[6], attrs[6])
334  call Check_lcs_eol_attrs(attrs, 1, 10)
335
336  if IsColorable()
337    " bg-color
338    exe hi_bg
339
340    " expected:
341    " 'aaabcd    '
342    "  ^^^^^^       bg-color of 'CursorLine'
343    "        ^      'Search' highlight
344    "         ^^^   bg-color of 'CursorLine'
345    let attrs = ScreenAttrs(1, 10)[0]
346    call assert_equal(repeat([attrs[0]], 6), attrs[0:5])
347    call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
348    call assert_equal(attrs0[6], attrs[6])
349    call assert_notequal(attrs[0], attrs[6])
350    call assert_notequal(attrs[6], attrs[7])
351    call assert_notequal(attrs0[0], attrs[0])
352    call assert_notequal(attrs0[7], attrs[7])
353    call Check_lcs_eol_attrs(attrs, 1, 10)
354  endif
355
356  call CloseWindow()
357  exe hiCursorLine
358endfunc
359
360func Test_highlight_eol_with_cursorline_sign()
361  CheckFeature signs
362
363  let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
364
365  call NewWindow('topleft 5', 10)
366  call setline(1, 'abcd')
367  call matchadd('Search', '\n')
368
369  sign define Sign text=>>
370  exe 'sign place 1 line=1 name=Sign buffer=' . bufnr('')
371  let attrs0 = ScreenAttrs(1, 10)[0]
372  setlocal cursorline
373
374  " underline
375  exe hi_ul
376
377  " expected:
378  " '>>abcd    '
379  "  ^^           sign
380  "    ^^^^       underline
381  "        ^      'Search' highlight with underline
382  "         ^^^   underline
383  let attrs = ScreenAttrs(1, 10)[0]
384  call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
385  call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
386  call assert_notequal(attrs[2], attrs[6])
387  call assert_notequal(attrs[6], attrs[7])
388  call assert_notequal(attrs0[2], attrs[2])
389  call assert_notequal(attrs0[6], attrs[6])
390  call Check_lcs_eol_attrs(attrs, 1, 10)
391
392  if IsColorable()
393    " bg-color
394    exe hi_bg
395
396    " expected:
397    " '>>abcd    '
398    "  ^^           sign
399    "    ^^^^       bg-color of 'CursorLine'
400    "        ^      'Search' highlight
401    "         ^^^   bg-color of 'CursorLine'
402    let attrs = ScreenAttrs(1, 10)[0]
403    call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
404    call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
405    call assert_equal(attrs0[6], attrs[6])
406    call assert_notequal(attrs[2], attrs[6])
407    call assert_notequal(attrs[6], attrs[7])
408    call assert_notequal(attrs0[2], attrs[2])
409    call assert_notequal(attrs0[7], attrs[7])
410    call Check_lcs_eol_attrs(attrs, 1, 10)
411  endif
412
413  sign unplace 1
414  call CloseWindow()
415  exe hiCursorLine
416endfunc
417
418func Test_highlight_eol_with_cursorline_breakindent()
419  CheckFeature linebreak
420
421  let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
422
423  call NewWindow('topleft 5', 10)
424  set showbreak=xxx
425  setlocal breakindent breakindentopt=min:0,shift:1 showbreak=>
426  call setline(1, ' ' . repeat('a', 9) . 'bcd')
427  call matchadd('Search', '\n')
428  let attrs0 = ScreenAttrs(2, 10)[0]
429  setlocal cursorline
430
431  " underline
432  exe hi_ul
433
434  " expected:
435  " '  >bcd    '
436  "  ^^^          breakindent and showbreak
437  "     ^^^       underline
438  "        ^      'Search' highlight with underline
439  "         ^^^   underline
440  let attrs = ScreenAttrs(2, 10)[0]
441  call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
442  call assert_equal(repeat([attrs[3]], 3), attrs[3:5])
443  call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
444  call assert_equal(attrs0[0], attrs[0])
445  call assert_notequal(attrs[0], attrs[2])
446  call assert_notequal(attrs[2], attrs[3])
447  call assert_notequal(attrs[3], attrs[6])
448  call assert_notequal(attrs[6], attrs[7])
449  call assert_notequal(attrs0[2], attrs[2])
450  call assert_notequal(attrs0[3], attrs[3])
451  call assert_notequal(attrs0[6], attrs[6])
452  call Check_lcs_eol_attrs(attrs, 2, 10)
453
454  if IsColorable()
455    " bg-color
456    exe hi_bg
457
458    " expected:
459    " '  >bcd    '
460    "  ^^^          breakindent and showbreak
461    "     ^^^       bg-color of 'CursorLine'
462    "        ^      'Search' highlight
463    "         ^^^   bg-color of 'CursorLine'
464    let attrs = ScreenAttrs(2, 10)[0]
465    call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
466    call assert_equal(repeat([attrs[3]], 3), attrs[3:5])
467    call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
468    call assert_equal(attrs0[0], attrs[0])
469    call assert_equal(attrs0[6], attrs[6])
470    call assert_notequal(attrs[0], attrs[2])
471    call assert_notequal(attrs[2], attrs[3])
472    call assert_notequal(attrs[3], attrs[6])
473    call assert_notequal(attrs[6], attrs[7])
474    call assert_notequal(attrs0[2], attrs[2])
475    call assert_notequal(attrs0[3], attrs[3])
476    call assert_notequal(attrs0[7], attrs[7])
477    call Check_lcs_eol_attrs(attrs, 2, 10)
478  endif
479
480  call CloseWindow()
481  set showbreak=
482  setlocal showbreak=
483  exe hiCursorLine
484endfunc
485
486func Test_highlight_eol_on_diff()
487  call setline(1, ['abcd', ''])
488  call matchadd('Search', '\n')
489  let attrs0 = ScreenAttrs(1, 10)[0]
490
491  diffthis
492  botright new
493  diffthis
494
495  " expected:
496  " '  abcd    '
497  "  ^^           sign
498  "    ^^^^ ^^^   'DiffAdd' highlight
499  "        ^      'Search' highlight
500  let attrs = ScreenAttrs(1, 10)[0]
501  call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
502  call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
503  call assert_equal(repeat([attrs[2]], 3), attrs[7:9])
504  call assert_equal(attrs0[4], attrs[6])
505  call assert_notequal(attrs[0], attrs[2])
506  call assert_notequal(attrs[0], attrs[6])
507  call assert_notequal(attrs[2], attrs[6])
508  call Check_lcs_eol_attrs(attrs, 1, 10)
509
510  bwipe!
511  diffoff
512endfunc
513
514func Test_termguicolors()
515  CheckOption termguicolors
516  if has('vtp') && !has('vcon') && !has('gui_running')
517    " Win32: 'guicolors' doesn't work without virtual console.
518    call assert_fails('set termguicolors', 'E954:')
519    return
520  endif
521
522  " Basic test that setting 'termguicolors' works with one color.
523  set termguicolors
524  redraw
525  set t_Co=1
526  redraw
527  set t_Co=0
528  redraw
529endfunc
530
531func Test_cursorline_after_yank()
532  CheckScreendump
533
534  call writefile([
535	\ 'set cul rnu',
536	\ 'call setline(1, ["","1","2","3",""])',
537	\ ], 'Xtest_cursorline_yank')
538  let buf = RunVimInTerminal('-S Xtest_cursorline_yank', {'rows': 8})
539  call TermWait(buf)
540  call term_sendkeys(buf, "Gy3k")
541  call TermWait(buf)
542  call term_sendkeys(buf, "jj")
543
544  call VerifyScreenDump(buf, 'Test_cursorline_yank_01', {})
545
546  " clean up
547  call StopVimInTerminal(buf)
548  call delete('Xtest_cursorline_yank')
549endfunc
550
551" test for issue #4862
552func Test_put_before_cursorline()
553  new
554  only!
555  call setline(1, 'A')
556  redraw
557  let std_attr = screenattr(1, 1)
558  set cursorline
559  redraw
560  let cul_attr = screenattr(1, 1)
561  normal yyP
562  redraw
563  " Line 1 has cursor so it should be highlighted with CursorLine.
564  call assert_equal(cul_attr, screenattr(1, 1))
565  " And CursorLine highlighting from the second line should be gone.
566  call assert_equal(std_attr, screenattr(2, 1))
567  set nocursorline
568  bwipe!
569endfunc
570
571func Test_cursorline_with_visualmode()
572  CheckScreendump
573
574  call writefile([
575	\ 'set cul',
576	\ 'call setline(1, repeat(["abc"], 50))',
577	\ ], 'Xtest_cursorline_with_visualmode')
578  let buf = RunVimInTerminal('-S Xtest_cursorline_with_visualmode', {'rows': 12})
579  call TermWait(buf)
580  call term_sendkeys(buf, "V\<C-f>kkkjk")
581
582  call VerifyScreenDump(buf, 'Test_cursorline_with_visualmode_01', {})
583
584  " clean up
585  call StopVimInTerminal(buf)
586  call delete('Xtest_cursorline_with_visualmode')
587endfunc
588
589func Test_wincolor()
590  CheckScreendump
591  " make sure the width is enough for the test
592  set columns=80
593
594  let lines =<< trim END
595	set cursorline cursorcolumn rnu
596	call setline(1, ["","1111111111","22222222222","3 here 3","","the cat is out of the bag"])
597	set wincolor=Pmenu
598	hi CatLine guifg=green ctermfg=green
599	hi Reverse gui=reverse cterm=reverse
600	syn match CatLine /^the.*/
601	call prop_type_add("foo", {"highlight": "Reverse", "combine": 1})
602	call prop_add(6, 12, {"type": "foo", "end_col": 15})
603	/here
604  END
605  call writefile(lines, 'Xtest_wincolor')
606  let buf = RunVimInTerminal('-S Xtest_wincolor', {'rows': 8})
607  call TermWait(buf)
608  call term_sendkeys(buf, "2G5lvj")
609  call TermWait(buf)
610
611  call VerifyScreenDump(buf, 'Test_wincolor_01', {})
612
613  " clean up
614  call term_sendkeys(buf, "\<Esc>")
615  call StopVimInTerminal(buf)
616  call delete('Xtest_wincolor')
617endfunc
618
619func Test_wincolor_listchars()
620  CheckScreendump
621  CheckFeature conceal
622
623  let lines =<< trim END
624	call setline(1, ["one","\t\tsome random text enough long to show 'extends' and 'precedes' includingnbsps, preceding tabs and trailing spaces    ","three"])
625	set wincolor=Todo
626	set nowrap cole=1 cocu+=n
627	set list lcs=eol:$,tab:>-,space:.,trail:_,extends:>,precedes:<,conceal:*,nbsp:#
628	call matchadd('Conceal', 'text')
629	normal 2G5zl
630  END
631  call writefile(lines, 'Xtest_wincolorlcs')
632  let buf = RunVimInTerminal('-S Xtest_wincolorlcs', {'rows': 8})
633
634  call VerifyScreenDump(buf, 'Test_wincolor_lcs', {})
635
636  " clean up
637  call term_sendkeys(buf, "\<Esc>")
638  call StopVimInTerminal(buf)
639  call delete('Xtest_wincolorlcs')
640endfunc
641
642func Test_colorcolumn()
643  CheckScreendump
644
645  " check that setting 'colorcolumn' when entering a buffer works
646  let lines =<< trim END
647	split
648	edit X
649	call setline(1, ["1111111111","22222222222","3333333333"])
650	set nomodified
651	set colorcolumn=3,9
652	set number cursorline cursorlineopt=number
653	wincmd w
654	buf X
655  END
656  call writefile(lines, 'Xtest_colorcolumn')
657  let buf = RunVimInTerminal('-S Xtest_colorcolumn', {'rows': 10})
658  call term_sendkeys(buf, ":\<CR>")
659  call TermWait(buf)
660  call VerifyScreenDump(buf, 'Test_colorcolumn_1', {})
661
662  " clean up
663  call StopVimInTerminal(buf)
664  call delete('Xtest_colorcolumn')
665endfunc
666
667func Test_colorcolumn_bri()
668  CheckScreendump
669
670  " check 'colorcolumn' when 'breakindent' is set
671  let lines =<< trim END
672	call setline(1, 'The quick brown fox jumped over the lazy dogs')
673  END
674  call writefile(lines, 'Xtest_colorcolumn_bri')
675  let buf = RunVimInTerminal('-S Xtest_colorcolumn_bri', {'rows': 10,'columns': 40})
676  call term_sendkeys(buf, ":set co=40 linebreak bri briopt=shift:2 cc=40,41,43\<CR>")
677  call TermWait(buf)
678  call VerifyScreenDump(buf, 'Test_colorcolumn_2', {})
679
680  " clean up
681  call StopVimInTerminal(buf)
682  call delete('Xtest_colorcolumn_bri')
683endfunc
684
685func Test_colorcolumn_sbr()
686  CheckScreendump
687
688  " check 'colorcolumn' when 'showbreak' is set
689  let lines =<< trim END
690	call setline(1, 'The quick brown fox jumped over the lazy dogs')
691  END
692  call writefile(lines, 'Xtest_colorcolumn_srb')
693  let buf = RunVimInTerminal('-S Xtest_colorcolumn_srb', {'rows': 10,'columns': 40})
694  call term_sendkeys(buf, ":set co=40 showbreak=+++>\\  cc=40,41,43\<CR>")
695  call TermWait(buf)
696  call VerifyScreenDump(buf, 'Test_colorcolumn_3', {})
697
698  " clean up
699  call StopVimInTerminal(buf)
700  call delete('Xtest_colorcolumn_srb')
701endfunc
702
703" This test must come before the Test_cursorline test, as it appears this
704" defines the Normal highlighting group anyway.
705func Test_1_highlight_Normalgroup_exists()
706  let hlNormal = HighlightArgs('Normal')
707  if !has('gui_running')
708    call assert_match('hi Normal\s*clear', hlNormal)
709  elseif has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
710    " expect is DEFAULT_FONT of gui_gtk_x11.c
711    call assert_match('hi Normal\s*font=Monospace 10', hlNormal)
712  elseif has('gui_motif') || has('gui_athena')
713    " expect is DEFAULT_FONT of gui_x11.c
714    call assert_match('hi Normal\s*font=7x13', hlNormal)
715  elseif has('win32')
716    " expect any font
717    call assert_match('hi Normal\s*font=.*', hlNormal)
718  endif
719endfunc
720
721" Do this test last, sometimes restoring the columns doesn't work
722func Test_z_no_space_before_xxx()
723  let l:org_columns = &columns
724  set columns=17
725  let l:hi_StatusLineTermNC = join(split(execute('hi StatusLineTermNC')))
726  call assert_match('StatusLineTermNC xxx', l:hi_StatusLineTermNC)
727  let &columns = l:org_columns
728endfunc
729
730" Test for :highlight command errors
731func Test_highlight_cmd_errors()
732  if has('gui_running')
733    " This test doesn't fail in the MS-Windows console version.
734    call assert_fails('hi Xcomment ctermbg=fg', 'E419:')
735    call assert_fails('hi Xcomment ctermfg=bg', 'E420:')
736    call assert_fails('hi Xcomment ctermfg=ul', 'E453:')
737  endif
738
739  " Try using a very long terminal code. Define a dummy terminal code for this
740  " test.
741  let &t_fo = "\<Esc>1;"
742  let c = repeat("t_fo,", 100) . "t_fo"
743  call assert_fails('exe "hi Xgroup1 start=" . c', 'E422:')
744  let &t_fo = ""
745endfunc
746
747" Test for 'highlight' option
748func Test_highlight_opt()
749  let save_hl = &highlight
750  call assert_fails('set highlight=j:b', 'E474:')
751  set highlight=f\ r
752  call assert_equal('f r', &highlight)
753  set highlight=fb
754  call assert_equal('fb', &highlight)
755  set highlight=fi
756  call assert_equal('fi', &highlight)
757  set highlight=f-
758  call assert_equal('f-', &highlight)
759  set highlight=fr
760  call assert_equal('fr', &highlight)
761  set highlight=fs
762  call assert_equal('fs', &highlight)
763  set highlight=fu
764  call assert_equal('fu', &highlight)
765  set highlight=fc
766  call assert_equal('fc', &highlight)
767  set highlight=ft
768  call assert_equal('ft', &highlight)
769  call assert_fails('set highlight=fr:Search', 'E474:')
770  set highlight=f:$#
771  call assert_match('W18:', v:statusmsg)
772  let &highlight = save_hl
773endfunc
774
775" Test for User group highlighting used in the statusline
776func Test_highlight_User()
777  CheckNotGui
778  hi User1 ctermfg=12
779  redraw!
780  call assert_equal('12', synIDattr(synIDtrans(hlID('User1')), 'fg'))
781  hi clear
782endfunc
783
784" Test for using RGB color values in a highlight group
785func Test_xxlast_highlight_RGB_color()
786  CheckCanRunGui
787  gui -f
788  hi MySearch guifg=#110000 guibg=#001100 guisp=#000011
789  call assert_equal('#110000', synIDattr(synIDtrans(hlID('MySearch')), 'fg#'))
790  call assert_equal('#001100', synIDattr(synIDtrans(hlID('MySearch')), 'bg#'))
791  call assert_equal('#000011', synIDattr(synIDtrans(hlID('MySearch')), 'sp#'))
792  hi clear
793endfunc
794
795" Test for using default highlighting group
796func Test_highlight_default()
797  highlight MySearch ctermfg=7
798  highlight default MySearch ctermfg=5
799  let hlSearch = HighlightArgs('MySearch')
800  call assert_match('ctermfg=7', hlSearch)
801
802  highlight default QFName ctermfg=3
803  call assert_match('ctermfg=3', HighlightArgs('QFName'))
804  hi clear
805endfunc
806
807" Test for 'ctermul in a highlight group
808func Test_highlight_ctermul()
809  CheckNotGui
810  call assert_notmatch('ctermul=', HighlightArgs('Normal'))
811  highlight Normal ctermul=3
812  call assert_match('ctermul=3', HighlightArgs('Normal'))
813  call assert_equal('3', synIDattr(synIDtrans(hlID('Normal')), 'ul'))
814  highlight Normal ctermul=NONE
815endfunc
816
817" Test for specifying 'start' and 'stop' in a highlight group
818func Test_highlight_start_stop()
819  hi HlGrp1 start=<Esc>[27h;<Esc>[<Space>r;
820  call assert_match("start=^[[27h;^[[ r;", HighlightArgs('HlGrp1'))
821  hi HlGrp1 start=NONE
822  call assert_notmatch("start=", HighlightArgs('HlGrp1'))
823  hi HlGrp2 stop=<Esc>[27h;<Esc>[<Space>r;
824  call assert_match("stop=^[[27h;^[[ r;", HighlightArgs('HlGrp2'))
825  hi HlGrp2 stop=NONE
826  call assert_notmatch("stop=", HighlightArgs('HlGrp2'))
827  hi clear
828endfunc
829
830" Test for setting various 'term' attributes
831func Test_highlight_term_attr()
832  hi HlGrp3 term=bold,underline,undercurl,strikethrough,reverse,italic,standout
833  call assert_equal('hi HlGrp3          term=bold,standout,underline,undercurl,italic,reverse,strikethrough', HighlightArgs('HlGrp3'))
834  hi HlGrp3 term=NONE
835  call assert_equal('hi HlGrp3          cleared', HighlightArgs('HlGrp3'))
836  hi clear
837endfunc
838
839func Test_highlight_clear_restores_links()
840  let aaa_id = hlID('aaa')
841  call assert_equal(aaa_id, 0)
842
843  " create default link aaa --> bbb
844  hi def link aaa bbb
845  let id_aaa = hlID('aaa')
846  let hl_aaa_bbb = HighlightArgs('aaa')
847
848  " try to redefine default link aaa --> ccc; check aaa --> bbb
849  hi def link aaa ccc
850  call assert_equal(HighlightArgs('aaa'), hl_aaa_bbb)
851
852  " clear aaa; check aaa --> bbb
853  hi clear aaa
854  call assert_equal(HighlightArgs('aaa'), hl_aaa_bbb)
855
856  " link aaa --> ccc; clear aaa; check aaa --> bbb
857  hi link aaa ccc
858  let id_ccc = hlID('ccc')
859  call assert_equal(synIDtrans(id_aaa), id_ccc)
860  hi clear aaa
861  call assert_equal(HighlightArgs('aaa'), hl_aaa_bbb)
862
863  " forcibly set default link aaa --> ddd
864  hi! def link aaa ddd
865  let id_ddd = hlID('ddd')
866  let hl_aaa_ddd = HighlightArgs('aaa')
867  call assert_equal(synIDtrans(id_aaa), id_ddd)
868
869  " link aaa --> eee; clear aaa; check aaa --> ddd
870  hi link aaa eee
871  let eee_id = hlID('eee')
872  call assert_equal(synIDtrans(id_aaa), eee_id)
873  hi clear aaa
874  call assert_equal(HighlightArgs('aaa'), hl_aaa_ddd)
875endfunc
876
877func Test_highlight_clear_restores_context()
878  func FuncContextDefault()
879    hi def link Context ContextDefault
880  endfun
881
882  func FuncContextRelink()
883    " Dummy line
884    hi link Context ContextRelink
885  endfunc
886
887  let scriptContextDefault = MakeScript("FuncContextDefault")
888  let scriptContextRelink = MakeScript("FuncContextRelink")
889  let patContextDefault = fnamemodify(scriptContextDefault, ':t') .. ' line 1'
890  let patContextRelink = fnamemodify(scriptContextRelink, ':t') .. ' line 2'
891
892  exec 'source ' .. scriptContextDefault
893  let hlContextDefault = execute("verbose hi Context")
894  call assert_match(patContextDefault, hlContextDefault)
895
896  exec 'source ' .. scriptContextRelink
897  let hlContextRelink = execute("verbose hi Context")
898  call assert_match(patContextRelink, hlContextRelink)
899
900  hi clear
901  let hlContextAfterClear = execute("verbose hi Context")
902  call assert_match(patContextDefault, hlContextAfterClear)
903
904  delfunc FuncContextDefault
905  delfunc FuncContextRelink
906  call delete(scriptContextDefault)
907  call delete(scriptContextRelink)
908endfunc
909
910func Test_highlight_default_colorscheme_restores_links()
911  hi link TestLink Identifier
912  hi TestHi ctermbg=red
913
914  let hlTestLinkPre = HighlightArgs('TestLink')
915  let hlTestHiPre = HighlightArgs('TestHi')
916
917  " Test colorscheme
918  hi clear
919  if exists('syntax_on')
920    syntax reset
921  endif
922  let g:colors_name = 'test'
923  hi link TestLink ErrorMsg
924  hi TestHi ctermbg=green
925
926  " Restore default highlighting
927  colorscheme default
928  " 'default' should work no matter if highlight group was cleared
929  hi def link TestLink Identifier
930  hi def TestHi ctermbg=red
931  let hlTestLinkPost = HighlightArgs('TestLink')
932  let hlTestHiPost = HighlightArgs('TestHi')
933  call assert_equal(hlTestLinkPre, hlTestLinkPost)
934  call assert_equal(hlTestHiPre, hlTestHiPost)
935  hi clear
936endfunc
937
938func Test_colornames_assignment_and_lookup()
939  " Ensure highlight command can find custom color.
940  let v:colornames['a redish white'] = '#ffeedd'
941  highlight Normal guifg='a redish white'
942  highlight clear
943endfunc
944
945func Test_colornames_default_list()
946  " Ensure default lists are loaded automatically and can be used for all gui fields.
947  highlight Normal guifg='rebecca purple' guibg='rebecca purple' guisp='rebecca purple'
948  highlight clear
949endfunc
950
951func Test_colornames_overwrite_default()
952  " Ensure entries in v:colornames can be overwritten.
953  " Load default color scheme to trigger default color list loading.
954  colorscheme default
955  let old_rebecca_purple = v:colornames['rebecca purple']
956  highlight Normal guifg='rebecca purple' guibg='rebecca purple'
957  let v:colornames['rebecca purple'] = '#550099'
958  highlight Normal guifg='rebecca purple' guibg='rebecca purple'
959  let v:colornames['rebecca purple'] = old_rebecca_purple
960  highlight clear
961endfunc
962
963func Test_colornames_assignment_and_unassignment()
964  " Ensure we cannot overwrite the v:colornames dict.
965  call assert_fails("let v:colornames = {}", 'E46:')
966
967  " Ensure we can delete entries from the v:colornames dict.
968  let v:colornames['x1'] = '#111111'
969  call assert_equal(v:colornames['x1'], '#111111')
970  unlet v:colornames['x1']
971  call assert_fails("echo v:colornames['x1']")
972endfunc
973
974" Test for the hlget() function
975func Test_hlget()
976  let lines =<< trim END
977    call assert_notequal([], filter(hlget(), 'v:val.name == "Visual"'))
978    call assert_equal([], hlget('SomeHLGroup'))
979    highlight MyHLGroup term=standout cterm=reverse ctermfg=10 ctermbg=Black
980    call assert_equal([{'id': hlID('MyHLGroup'), 'ctermfg': '10', 'name': 'MyHLGroup', 'term': {'standout': v:true}, 'ctermbg': '0', 'cterm': {'reverse': v:true}}], hlget('MyHLGroup'))
981    highlight clear MyHLGroup
982    call assert_equal(v:true, hlget('MyHLGroup')[0].cleared)
983    highlight link MyHLGroup IncSearch
984    call assert_equal('IncSearch', hlget('MyHLGroup')[0].linksto)
985    highlight clear MyHLGroup
986    call assert_equal([], hlget(test_null_string()))
987    call assert_equal([], hlget(""))
988  END
989  call CheckLegacyAndVim9Success(lines)
990
991  " Test for resolving highlight group links
992  let lines =<< trim END
993    highlight hlgA term=bold
994    VAR hlgAid = hlID('hlgA')
995    highlight link hlgB hlgA
996    VAR hlgBid = hlID('hlgB')
997    highlight link hlgC hlgB
998    VAR hlgCid = hlID('hlgC')
999    call assert_equal('hlgA', hlget('hlgB')[0].linksto)
1000    call assert_equal('hlgB', hlget('hlgC')[0].linksto)
1001    call assert_equal([{'id': hlgAid, 'name': 'hlgA',
1002                      \ 'term': {'bold': v:true}}], hlget('hlgA'))
1003    call assert_equal([{'id': hlgBid, 'name': 'hlgB',
1004                      \ 'linksto': 'hlgA'}], hlget('hlgB'))
1005    call assert_equal([{'id': hlgCid, 'name': 'hlgC',
1006                      \ 'linksto': 'hlgB'}], hlget('hlgC'))
1007    call assert_equal([{'id': hlgAid, 'name': 'hlgA',
1008                      \ 'term': {'bold': v:true}}], hlget('hlgA', v:false))
1009    call assert_equal([{'id': hlgBid, 'name': 'hlgB',
1010                      \ 'linksto': 'hlgA'}], hlget('hlgB', 0))
1011    call assert_equal([{'id': hlgCid, 'name': 'hlgC',
1012                      \ 'linksto': 'hlgB'}], hlget('hlgC', v:false))
1013    call assert_equal([{'id': hlgAid, 'name': 'hlgA',
1014                      \ 'term': {'bold': v:true}}], hlget('hlgA', v:true))
1015    call assert_equal([{'id': hlgBid, 'name': 'hlgB',
1016                      \ 'term': {'bold': v:true}}], hlget('hlgB', 1))
1017    call assert_equal([{'id': hlgCid, 'name': 'hlgC',
1018                      \ 'term': {'bold': v:true}}], hlget('hlgC', v:true))
1019  END
1020  call CheckLegacyAndVim9Success(lines)
1021
1022  call assert_fails('call hlget([])', 'E1174:')
1023  call assert_fails('call hlget("abc", "xyz")', 'E1212:')
1024endfunc
1025
1026" Test for the hlset() function
1027func Test_hlset()
1028  let lines =<< trim END
1029    call assert_equal(0, hlset(test_null_list()))
1030    call assert_equal(0, hlset([]))
1031    call assert_fails('call hlset(["Search"])', 'E715:')
1032    call hlset(hlget())
1033    call hlset([{'name': 'NewHLGroup', 'cterm': {'reverse': v:true}, 'ctermfg': '10'}])
1034    call assert_equal({'reverse': v:true}, hlget('NewHLGroup')[0].cterm)
1035    call hlset([{'name': 'NewHLGroup', 'cterm': {'bold': v:true}}])
1036    call assert_equal({'bold': v:true}, hlget('NewHLGroup')[0].cterm)
1037    call hlset([{'name': 'NewHLGroup', 'cleared': v:true}])
1038    call assert_equal(v:true, hlget('NewHLGroup')[0].cleared)
1039    call hlset([{'name': 'NewHLGroup', 'linksto': 'Search'}])
1040    call assert_false(has_key(hlget('NewHLGroup')[0], 'cleared'))
1041    call assert_equal('Search', hlget('NewHLGroup')[0].linksto)
1042    call assert_fails("call hlset([{'name': [], 'ctermfg': '10'}])", 'E928:')
1043    call assert_fails("call hlset([{'name': 'NewHLGroup', 'cleared': []}])",
1044          \ 'E745:')
1045    call assert_fails("call hlset([{'name': 'NewHLGroup', 'cterm': 'Blue'}])",
1046          \ 'E715:')
1047    call assert_fails("call hlset([{'name': 'NewHLGroup', 'ctermbg': []}])",
1048          \ 'E928:')
1049    call assert_fails("call hlset([{'name': 'NewHLGroup', 'ctermfg': []}])",
1050          \ 'E928:')
1051    call assert_fails("call hlset([{'name': 'NewHLGroup', 'ctermul': []}])",
1052          \ 'E928:')
1053    if has('gui')
1054      call assert_fails("call hlset([{'name': 'NewHLGroup', 'font': []}])",
1055            \ 'E928:')
1056    endif
1057    call assert_fails("call hlset([{'name': 'NewHLGroup', 'gui': 'Cyan'}])",
1058          \ 'E715:')
1059    call assert_fails("call hlset([{'name': 'NewHLGroup', 'guibg': []}])",
1060          \ 'E928:')
1061    call assert_fails("call hlset([{'name': 'NewHLGroup', 'guifg': []}])",
1062          \ 'E928:')
1063    call assert_fails("call hlset([{'name': 'NewHLGroup', 'guisp': []}])",
1064          \ 'E928:')
1065    call assert_fails("call hlset([{'name': 'NewHLGroup', 'linksto': []}])",
1066          \ 'E928:')
1067    call assert_fails("call hlset([{'name': 'NewHLGroup', 'start': []}])",
1068          \ 'E928:')
1069    call assert_fails("call hlset([{'name': 'NewHLGroup', 'stop': []}])",
1070          \ 'E928:')
1071    call assert_fails("call hlset([{'name': 'NewHLGroup', 'term': 'Cyan'}])",
1072          \ 'E715:')
1073    call assert_equal('Search', hlget('NewHLGroup')[0].linksto)
1074    highlight clear NewHLGroup
1075  END
1076  call CheckLegacyAndVim9Success(lines)
1077
1078  " Test for clearing the 'term', 'cterm' and 'gui' attributes of a highlight
1079  " group.
1080  let lines =<< trim END
1081    highlight myhlg1 term=bold cterm=italic gui=standout
1082    VAR id = hlID('myhlg1')
1083    call hlset([{'name': 'myhlg1', 'term': {}}])
1084    call assert_equal([{'id': id, 'name': 'myhlg1',
1085                \ 'cterm': {'italic': v:true}, 'gui': {'standout': v:true}}],
1086                \ hlget('myhlg1'))
1087    call hlset([{'name': 'myhlg1', 'cterm': {}}])
1088    call assert_equal([{'id': id, 'name': 'myhlg1',
1089                \ 'gui': {'standout': v:true}}], hlget('myhlg1'))
1090    call hlset([{'name': 'myhlg1', 'gui': {}}])
1091    call assert_equal([{'id': id, 'name': 'myhlg1', 'cleared': v:true}],
1092                \ hlget('myhlg1'))
1093    highlight clear myhlg1
1094  END
1095  call CheckLegacyAndVim9Success(lines)
1096
1097  " Test for setting all the 'term', 'cterm' and 'gui' attributes of a
1098  " highlight group
1099  let lines =<< trim END
1100    VAR attr = {'bold': v:true, 'underline': v:true, 'undercurl': v:true,
1101                \ 'strikethrough': v:true, 'reverse': v:true, 'italic': v:true,
1102                \ 'standout': v:true, 'nocombine': v:true}
1103    call hlset([{'name': 'myhlg2', 'term': attr, 'cterm': attr, 'gui': attr}])
1104    VAR id2 = hlID('myhlg2')
1105    VAR output =<< trim END
1106      myhlg2         xxx term=bold,standout,underline,undercurl,italic,reverse,nocombine,strikethrough
1107                         cterm=bold,standout,underline,undercurl,italic,reverse,nocombine,strikethrough
1108                         gui=bold,standout,underline,undercurl,italic,reverse,nocombine,strikethrough
1109    END
1110    call assert_equal(output, execute('highlight myhlg2')->split("\n"))
1111    call assert_equal([{'id': id2, 'name': 'myhlg2', 'gui': attr,
1112                      \ 'term': attr, 'cterm': attr}], hlget('myhlg2'))
1113  END
1114  call CheckLegacyAndVim9Success(lines)
1115
1116  " Test for clearing some of the 'term', 'cterm' and 'gui' attributes of a
1117  " highlight group
1118  let lines =<< trim END
1119    VAR attr = {'bold': v:false, 'underline': v:true, 'strikethrough': v:true}
1120    call hlset([{'name': 'myhlg2', 'term': attr, 'cterm': attr, 'gui': attr}])
1121    VAR id2 = hlID('myhlg2')
1122    VAR output =<< trim END
1123      myhlg2         xxx term=underline,strikethrough cterm=underline,strikethrough
1124                         gui=underline,strikethrough
1125    END
1126    call assert_equal(output, execute('highlight myhlg2')->split("\n"))
1127    LET attr = {'underline': v:true, 'strikethrough': v:true}
1128    call assert_equal([{'id': id2, 'name': 'myhlg2', 'gui': attr,
1129                      \ 'term': attr, 'cterm': attr}], hlget('myhlg2'))
1130  END
1131  call CheckLegacyAndVim9Success(lines)
1132endfunc
1133
1134" vim: shiftwidth=2 sts=2 expandtab
1135