1" Tests for ":highlight" and highlighting.
2
3source view_util.vim
4source screendump.vim
5
6func Test_highlight()
7  " basic test if ":highlight" doesn't crash
8  highlight
9  hi Search
10
11  " test setting colors.
12  " test clearing one color and all doesn't generate error or warning
13  silent! hi NewGroup term=bold cterm=italic ctermfg=DarkBlue ctermbg=Grey gui= guifg=#00ff00 guibg=Cyan
14  silent! hi Group2 term= cterm=
15  hi Group3 term=underline cterm=bold
16
17  let res = split(execute("hi NewGroup"), "\n")[0]
18  " filter ctermfg and ctermbg, the numbers depend on the terminal
19  let res = substitute(res, 'ctermfg=\d*', 'ctermfg=2', '')
20  let res = substitute(res, 'ctermbg=\d*', 'ctermbg=3', '')
21  call assert_equal("NewGroup       xxx term=bold cterm=italic ctermfg=2 ctermbg=3",
22				\ res)
23  call assert_equal("Group2         xxx cleared",
24				\ split(execute("hi Group2"), "\n")[0])
25  call assert_equal("Group3         xxx term=underline cterm=bold",
26				\ split(execute("hi Group3"), "\n")[0])
27
28  hi clear NewGroup
29  call assert_equal("NewGroup       xxx cleared",
30				\ split(execute("hi NewGroup"), "\n")[0])
31  call assert_equal("Group2         xxx cleared",
32				\ split(execute("hi Group2"), "\n")[0])
33  hi Group2 NONE
34  call assert_equal("Group2         xxx cleared",
35				\ split(execute("hi Group2"), "\n")[0])
36  hi clear
37  call assert_equal("Group3         xxx cleared",
38				\ split(execute("hi Group3"), "\n")[0])
39  call assert_fails("hi Crash term='asdf", "E475:")
40endfunc
41
42func HighlightArgs(name)
43  return 'hi ' . substitute(split(execute('hi ' . a:name), '\n')[0], '\<xxx\>', '', '')
44endfunc
45
46func IsColorable()
47  return has('gui_running') || str2nr(&t_Co) >= 8
48endfunc
49
50func HiCursorLine()
51  let hiCursorLine = HighlightArgs('CursorLine')
52  if has('gui_running')
53    let guibg = matchstr(hiCursorLine, 'guibg=\w\+')
54    let hi_ul = 'hi CursorLine gui=underline guibg=NONE'
55    let hi_bg = 'hi CursorLine gui=NONE ' . guibg
56  else
57    let hi_ul = 'hi CursorLine cterm=underline ctermbg=NONE'
58    let hi_bg = 'hi CursorLine cterm=NONE ctermbg=Gray'
59  endif
60  return [hiCursorLine, hi_ul, hi_bg]
61endfunc
62
63func Check_lcs_eol_attrs(attrs, row, col)
64  let save_lcs = &lcs
65  set list
66
67  call assert_equal(a:attrs, ScreenAttrs(a:row, a:col)[0])
68
69  set nolist
70  let &lcs = save_lcs
71endfunc
72
73func Test_highlight_eol_with_cursorline()
74  let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
75
76  call NewWindow('topleft 5', 20)
77  call setline(1, 'abcd')
78  call matchadd('Search', '\n')
79
80  " expected:
81  " 'abcd      '
82  "  ^^^^ ^^^^^   no highlight
83  "      ^        'Search' highlight
84  let attrs0 = ScreenAttrs(1, 10)[0]
85  call assert_equal(repeat([attrs0[0]], 4), attrs0[0:3])
86  call assert_equal(repeat([attrs0[0]], 5), attrs0[5:9])
87  call assert_notequal(attrs0[0], attrs0[4])
88
89  setlocal cursorline
90
91  " underline
92  exe hi_ul
93
94  " expected:
95  " 'abcd      '
96  "  ^^^^         underline
97  "      ^        'Search' highlight with underline
98  "       ^^^^^   underline
99  let attrs = ScreenAttrs(1, 10)[0]
100  call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
101  call assert_equal([attrs[4]] + repeat([attrs[5]], 5), attrs[4:9])
102  call assert_notequal(attrs[0], attrs[4])
103  call assert_notequal(attrs[4], attrs[5])
104  call assert_notequal(attrs0[0], attrs[0])
105  call assert_notequal(attrs0[4], attrs[4])
106  call Check_lcs_eol_attrs(attrs, 1, 10)
107
108  if IsColorable()
109    " bg-color
110    exe hi_bg
111
112    " expected:
113    " 'abcd      '
114    "  ^^^^         bg-color of 'CursorLine'
115    "      ^        'Search' highlight
116    "       ^^^^^   bg-color of 'CursorLine'
117    let attrs = ScreenAttrs(1, 10)[0]
118    call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
119    call assert_equal(repeat([attrs[5]], 5), attrs[5:9])
120    call assert_equal(attrs0[4], attrs[4])
121    call assert_notequal(attrs[0], attrs[4])
122    call assert_notequal(attrs[4], attrs[5])
123    call assert_notequal(attrs0[0], attrs[0])
124    call assert_notequal(attrs0[5], attrs[5])
125    call Check_lcs_eol_attrs(attrs, 1, 10)
126  endif
127
128  call CloseWindow()
129  exe hiCursorLine
130endfunc
131
132func Test_highlight_eol_with_cursorline_vertsplit()
133  let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
134
135  call NewWindow('topleft 5', 5)
136  call setline(1, 'abcd')
137  call matchadd('Search', '\n')
138
139  let expected = "abcd |abcd     "
140  let actual = ScreenLines(1, 15)[0]
141  call assert_equal(expected, actual)
142
143  " expected:
144  " 'abcd |abcd     '
145  "  ^^^^  ^^^^^^^^^   no highlight
146  "      ^             'Search' highlight
147  "       ^            'VertSplit' highlight
148  let attrs0 = ScreenAttrs(1, 15)[0]
149  call assert_equal(repeat([attrs0[0]], 4), attrs0[0:3])
150  call assert_equal(repeat([attrs0[0]], 9), attrs0[6:14])
151  call assert_notequal(attrs0[0], attrs0[4])
152  call assert_notequal(attrs0[0], attrs0[5])
153  call assert_notequal(attrs0[4], attrs0[5])
154
155  setlocal cursorline
156
157  " expected:
158  " 'abcd |abcd     '
159  "  ^^^^              underline
160  "      ^             'Search' highlight with underline
161  "       ^            'VertSplit' highlight
162  "        ^^^^^^^^^   no highlight
163
164  " underline
165  exe hi_ul
166
167  let actual = ScreenLines(1, 15)[0]
168  call assert_equal(expected, actual)
169
170  let attrs = ScreenAttrs(1, 15)[0]
171  call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
172  call assert_equal(repeat([attrs[6]], 9), attrs[6:14])
173  call assert_equal(attrs0[5:14], attrs[5:14])
174  call assert_notequal(attrs[0], attrs[4])
175  call assert_notequal(attrs[0], attrs[5])
176  call assert_notequal(attrs[0], attrs[6])
177  call assert_notequal(attrs[4], attrs[5])
178  call assert_notequal(attrs[5], attrs[6])
179  call assert_notequal(attrs0[0], attrs[0])
180  call assert_notequal(attrs0[4], attrs[4])
181  call Check_lcs_eol_attrs(attrs, 1, 15)
182
183  if IsColorable()
184    " bg-color
185    exe hi_bg
186
187    let actual = ScreenLines(1, 15)[0]
188    call assert_equal(expected, actual)
189
190    let attrs = ScreenAttrs(1, 15)[0]
191    call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
192    call assert_equal(repeat([attrs[6]], 9), attrs[6:14])
193    call assert_equal(attrs0[5:14], attrs[5:14])
194    call assert_notequal(attrs[0], attrs[4])
195    call assert_notequal(attrs[0], attrs[5])
196    call assert_notequal(attrs[0], attrs[6])
197    call assert_notequal(attrs[4], attrs[5])
198    call assert_notequal(attrs[5], attrs[6])
199    call assert_notequal(attrs0[0], attrs[0])
200    call assert_equal(attrs0[4], attrs[4])
201    call Check_lcs_eol_attrs(attrs, 1, 15)
202  endif
203
204  call CloseWindow()
205  exe hiCursorLine
206endfunc
207
208func Test_highlight_eol_with_cursorline_rightleft()
209  if !has('rightleft')
210    return
211  endif
212
213  let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
214
215  call NewWindow('topleft 5', 10)
216  setlocal rightleft
217  call setline(1, 'abcd')
218  call matchadd('Search', '\n')
219  let attrs0 = ScreenAttrs(1, 10)[0]
220
221  setlocal cursorline
222
223  " underline
224  exe hi_ul
225
226  " expected:
227  " '      dcba'
228  "        ^^^^   underline
229  "       ^       'Search' highlight with underline
230  "  ^^^^^        underline
231  let attrs = ScreenAttrs(1, 10)[0]
232  call assert_equal(repeat([attrs[9]], 4), attrs[6:9])
233  call assert_equal(repeat([attrs[4]], 5) + [attrs[5]], attrs[0:5])
234  call assert_notequal(attrs[9], attrs[5])
235  call assert_notequal(attrs[4], attrs[5])
236  call assert_notequal(attrs0[9], attrs[9])
237  call assert_notequal(attrs0[5], attrs[5])
238  call Check_lcs_eol_attrs(attrs, 1, 10)
239
240  if IsColorable()
241    " bg-color
242    exe hi_bg
243
244    " expected:
245    " '      dcba'
246    "        ^^^^   bg-color of 'CursorLine'
247    "       ^       'Search' highlight
248    "  ^^^^^        bg-color of 'CursorLine'
249    let attrs = ScreenAttrs(1, 10)[0]
250    call assert_equal(repeat([attrs[9]], 4), attrs[6:9])
251    call assert_equal(repeat([attrs[4]], 5), attrs[0:4])
252    call assert_equal(attrs0[5], attrs[5])
253    call assert_notequal(attrs[9], attrs[5])
254    call assert_notequal(attrs[5], attrs[4])
255    call assert_notequal(attrs0[9], attrs[9])
256    call assert_notequal(attrs0[4], attrs[4])
257    call Check_lcs_eol_attrs(attrs, 1, 10)
258  endif
259
260  call CloseWindow()
261  exe hiCursorLine
262endfunc
263
264func Test_highlight_eol_with_cursorline_linewrap()
265  let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
266
267  call NewWindow('topleft 5', 10)
268  call setline(1, [repeat('a', 51) . 'bcd', ''])
269  call matchadd('Search', '\n')
270
271  setlocal wrap
272  normal! gg$
273  let attrs0 = ScreenAttrs(5, 10)[0]
274  setlocal cursorline
275
276  " underline
277  exe hi_ul
278
279  " expected:
280  " 'abcd      '
281  "  ^^^^         underline
282  "      ^        'Search' highlight with underline
283  "       ^^^^^   underline
284  let attrs = ScreenAttrs(5, 10)[0]
285  call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
286  call assert_equal([attrs[4]] + repeat([attrs[5]], 5), attrs[4:9])
287  call assert_notequal(attrs[0], attrs[4])
288  call assert_notequal(attrs[4], attrs[5])
289  call assert_notequal(attrs0[0], attrs[0])
290  call assert_notequal(attrs0[4], attrs[4])
291  call Check_lcs_eol_attrs(attrs, 5, 10)
292
293  if IsColorable()
294    " bg-color
295    exe hi_bg
296
297    " expected:
298    " 'abcd      '
299    "  ^^^^         bg-color of 'CursorLine'
300    "      ^        'Search' highlight
301    "       ^^^^^   bg-color of 'CursorLine'
302    let attrs = ScreenAttrs(5, 10)[0]
303    call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
304    call assert_equal(repeat([attrs[5]], 5), attrs[5:9])
305    call assert_equal(attrs0[4], attrs[4])
306    call assert_notequal(attrs[0], attrs[4])
307    call assert_notequal(attrs[4], attrs[5])
308    call assert_notequal(attrs0[0], attrs[0])
309    call assert_notequal(attrs0[5], attrs[5])
310    call Check_lcs_eol_attrs(attrs, 5, 10)
311  endif
312
313  setlocal nocursorline nowrap
314  normal! gg$
315  let attrs0 = ScreenAttrs(1, 10)[0]
316  setlocal cursorline
317
318  " underline
319  exe hi_ul
320
321  " expected:
322  " 'aaabcd    '
323  "  ^^^^^^       underline
324  "        ^      'Search' highlight with underline
325  "         ^^^   underline
326  let attrs = ScreenAttrs(1, 10)[0]
327  call assert_equal(repeat([attrs[0]], 6), attrs[0:5])
328  call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
329  call assert_notequal(attrs[0], attrs[6])
330  call assert_notequal(attrs[6], attrs[7])
331  call assert_notequal(attrs0[0], attrs[0])
332  call assert_notequal(attrs0[6], attrs[6])
333  call Check_lcs_eol_attrs(attrs, 1, 10)
334
335  if IsColorable()
336    " bg-color
337    exe hi_bg
338
339    " expected:
340    " 'aaabcd    '
341    "  ^^^^^^       bg-color of 'CursorLine'
342    "        ^      'Search' highlight
343    "         ^^^   bg-color of 'CursorLine'
344    let attrs = ScreenAttrs(1, 10)[0]
345    call assert_equal(repeat([attrs[0]], 6), attrs[0:5])
346    call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
347    call assert_equal(attrs0[6], attrs[6])
348    call assert_notequal(attrs[0], attrs[6])
349    call assert_notequal(attrs[6], attrs[7])
350    call assert_notequal(attrs0[0], attrs[0])
351    call assert_notequal(attrs0[7], attrs[7])
352    call Check_lcs_eol_attrs(attrs, 1, 10)
353  endif
354
355  call CloseWindow()
356  exe hiCursorLine
357endfunc
358
359func Test_highlight_eol_with_cursorline_sign()
360  if !has('signs')
361    return
362  endif
363
364  let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
365
366  call NewWindow('topleft 5', 10)
367  call setline(1, 'abcd')
368  call matchadd('Search', '\n')
369
370  sign define Sign text=>>
371  exe 'sign place 1 line=1 name=Sign buffer=' . bufnr('')
372  let attrs0 = ScreenAttrs(1, 10)[0]
373  setlocal cursorline
374
375  " underline
376  exe hi_ul
377
378  " expected:
379  " '>>abcd    '
380  "  ^^           sign
381  "    ^^^^       underline
382  "        ^      'Search' highlight with underline
383  "         ^^^   underline
384  let attrs = ScreenAttrs(1, 10)[0]
385  call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
386  call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
387  call assert_notequal(attrs[2], attrs[6])
388  call assert_notequal(attrs[6], attrs[7])
389  call assert_notequal(attrs0[2], attrs[2])
390  call assert_notequal(attrs0[6], attrs[6])
391  call Check_lcs_eol_attrs(attrs, 1, 10)
392
393  if IsColorable()
394    " bg-color
395    exe hi_bg
396
397    " expected:
398    " '>>abcd    '
399    "  ^^           sign
400    "    ^^^^       bg-color of 'CursorLine'
401    "        ^      'Search' highlight
402    "         ^^^   bg-color of 'CursorLine'
403    let attrs = ScreenAttrs(1, 10)[0]
404    call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
405    call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
406    call assert_equal(attrs0[6], attrs[6])
407    call assert_notequal(attrs[2], attrs[6])
408    call assert_notequal(attrs[6], attrs[7])
409    call assert_notequal(attrs0[2], attrs[2])
410    call assert_notequal(attrs0[7], attrs[7])
411    call Check_lcs_eol_attrs(attrs, 1, 10)
412  endif
413
414  sign unplace 1
415  call CloseWindow()
416  exe hiCursorLine
417endfunc
418
419func Test_highlight_eol_with_cursorline_breakindent()
420  if !has('linebreak')
421    return
422  endif
423
424  let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
425
426  call NewWindow('topleft 5', 10)
427  setlocal breakindent breakindentopt=min:0,shift:1 showbreak=>
428  call setline(1, ' ' . repeat('a', 9) . 'bcd')
429  call matchadd('Search', '\n')
430  let attrs0 = ScreenAttrs(2, 10)[0]
431  setlocal cursorline
432
433  " underline
434  exe hi_ul
435
436  " expected:
437  " '  >bcd    '
438  "  ^^^          breakindent and showbreak
439  "     ^^^       underline
440  "        ^      'Search' highlight with underline
441  "         ^^^   underline
442  let attrs = ScreenAttrs(2, 10)[0]
443  call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
444  call assert_equal(repeat([attrs[3]], 3), attrs[3:5])
445  call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
446  call assert_equal(attrs0[0], attrs[0])
447  call assert_notequal(attrs[0], attrs[2])
448  call assert_notequal(attrs[2], attrs[3])
449  call assert_notequal(attrs[3], attrs[6])
450  call assert_notequal(attrs[6], attrs[7])
451  call assert_notequal(attrs0[2], attrs[2])
452  call assert_notequal(attrs0[3], attrs[3])
453  call assert_notequal(attrs0[6], attrs[6])
454  call Check_lcs_eol_attrs(attrs, 2, 10)
455
456  if IsColorable()
457    " bg-color
458    exe hi_bg
459
460    " expected:
461    " '  >bcd    '
462    "  ^^^          breakindent and showbreak
463    "     ^^^       bg-color of 'CursorLine'
464    "        ^      'Search' highlight
465    "         ^^^   bg-color of 'CursorLine'
466    let attrs = ScreenAttrs(2, 10)[0]
467    call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
468    call assert_equal(repeat([attrs[3]], 3), attrs[3:5])
469    call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
470    call assert_equal(attrs0[0], attrs[0])
471    call assert_equal(attrs0[6], attrs[6])
472    call assert_notequal(attrs[0], attrs[2])
473    call assert_notequal(attrs[2], attrs[3])
474    call assert_notequal(attrs[3], attrs[6])
475    call assert_notequal(attrs[6], attrs[7])
476    call assert_notequal(attrs0[2], attrs[2])
477    call assert_notequal(attrs0[3], attrs[3])
478    call assert_notequal(attrs0[7], attrs[7])
479    call Check_lcs_eol_attrs(attrs, 2, 10)
480  endif
481
482  call CloseWindow()
483  set showbreak=
484  exe hiCursorLine
485endfunc
486
487func Test_highlight_eol_on_diff()
488  call setline(1, ['abcd', ''])
489  call matchadd('Search', '\n')
490  let attrs0 = ScreenAttrs(1, 10)[0]
491
492  diffthis
493  botright new
494  diffthis
495
496  " expected:
497  " '  abcd    '
498  "  ^^           sign
499  "    ^^^^ ^^^   'DiffAdd' highlight
500  "        ^      'Search' highlight
501  let attrs = ScreenAttrs(1, 10)[0]
502  call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
503  call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
504  call assert_equal(repeat([attrs[2]], 3), attrs[7:9])
505  call assert_equal(attrs0[4], attrs[6])
506  call assert_notequal(attrs[0], attrs[2])
507  call assert_notequal(attrs[0], attrs[6])
508  call assert_notequal(attrs[2], attrs[6])
509  call Check_lcs_eol_attrs(attrs, 1, 10)
510
511  bwipe!
512  diffoff
513endfunc
514
515func Test_termguicolors()
516  if !exists('+termguicolors')
517    return
518  endif
519  if has('vtp') && !has('vcon')
520    " Win32: 'guicolors' doesn't work without virtual console.
521    call assert_fails('set termguicolors', 'E954:')
522    return
523  endif
524
525  " Basic test that setting 'termguicolors' works with one color.
526  set termguicolors
527  redraw
528  set t_Co=1
529  redraw
530  set t_Co=0
531  redraw
532endfunc
533
534func Test_cursorline_after_yank()
535  if !CanRunVimInTerminal()
536    return
537  endif
538
539  call writefile([
540	\ 'set cul rnu',
541	\ 'call setline(1, ["","1","2","3",""])',
542	\ ], 'Xtest_cursorline_yank')
543  let buf = RunVimInTerminal('-S Xtest_cursorline_yank', {'rows': 8})
544  call term_wait(buf)
545  call term_sendkeys(buf, "Gy3k")
546  call term_wait(buf)
547  call term_sendkeys(buf, "jj")
548
549  call VerifyScreenDump(buf, 'Test_cursorline_yank_01', {})
550
551  " clean up
552  call StopVimInTerminal(buf)
553  call delete('Xtest_cursorline_yank')
554endfunc
555
556func Test_cursorline_with_visualmode()
557  if !CanRunVimInTerminal()
558    return
559  endif
560
561  call writefile([
562	\ 'set cul',
563	\ 'call setline(1, repeat(["abc"], 50))',
564	\ ], 'Xtest_cursorline_with_visualmode')
565  let buf = RunVimInTerminal('-S Xtest_cursorline_with_visualmode', {'rows': 12})
566  call term_wait(buf)
567  call term_sendkeys(buf, "V\<C-f>kkkjk")
568
569  call VerifyScreenDump(buf, 'Test_cursorline_with_visualmode_01', {})
570
571  " clean up
572  call StopVimInTerminal(buf)
573  call delete('Xtest_cursorline_with_visualmode')
574endfunc
575