summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-09-30 21:23:55 +0200
committerBram Moolenaar <Bram@vim.org>2017-09-30 21:23:55 +0200
commit0aa398f55a327282c70f56e0bac2dcb9521da378 (patch)
tree456180a96037ce14db277909c08cd6fa286168a2
parent3a497e1a414dc44b3df6a6fca60838ecd8ff0ca6 (diff)
downloadvim-git-0aa398f55a327282c70f56e0bac2dcb9521da378.tar.gz
patch 8.0.1168: wrong highlighting with combination of match and 'cursorline'v8.0.1168
Problem: wrong highlighting with combination of match and 'cursorline'. Solution: Use "line_attr" when appropriate. (Ozaki Kiichi, closes #2111) But don't highlight more than one character.
-rw-r--r--src/screen.c14
-rw-r--r--src/testdir/test_highlight.vim456
-rw-r--r--src/testdir/view_util.vim21
-rw-r--r--src/version.c2
4 files changed, 491 insertions, 2 deletions
diff --git a/src/screen.c b/src/screen.c
index e505d941f..8349e5f6b 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -4168,6 +4168,9 @@ win_line(
if (shl != &search_hl && cur != NULL)
cur = cur->next;
}
+ /* Only highlight one character after the last column. */
+ if (*ptr == NUL && did_line_attr >= 1)
+ search_attr = 0;
}
#endif
@@ -5064,7 +5067,9 @@ win_line(
++did_line_attr;
/* don't do search HL for the rest of the line */
- if (line_attr != 0 && char_attr == search_attr && col > 0)
+ if (line_attr != 0 && char_attr == search_attr
+ && (did_line_attr > 1
+ || (wp->w_p_list && lcs_eol > 0)))
char_attr = line_attr;
# ifdef FEAT_DIFF
if (diff_hlf == HLF_TXD)
@@ -5320,6 +5325,13 @@ win_line(
#ifdef FEAT_SEARCH_EXTRA
/* highlight 'hlsearch' match at end of line */
|| (prevcol_hl_flag == TRUE
+# ifdef FEAT_SYN_HL
+ && !(wp->w_p_cul && lnum == wp->w_cursor.lnum
+ && !(wp == curwin && VIsual_active))
+# endif
+# ifdef FEAT_DIFF
+ && diff_hlf == (hlf_T)0
+# endif
# if defined(LINE_ATTR)
&& did_line_attr <= 1
# endif
diff --git a/src/testdir/test_highlight.vim b/src/testdir/test_highlight.vim
index acc29e2f0..5205d425e 100644
--- a/src/testdir/test_highlight.vim
+++ b/src/testdir/test_highlight.vim
@@ -1,4 +1,7 @@
-" Tests for ":highlight".
+" Tests for ":highlight" and highlighting.
+
+source view_util.vim
+
func Test_highlight()
" basic test if ":highlight" doesn't crash
highlight
@@ -34,3 +37,454 @@ func Test_highlight()
\ split(execute("hi Group3"), "\n")[0])
call assert_fails("hi Crash term='asdf", "E475:")
endfunc
+
+function! HighlightArgs(name)
+ return 'hi ' . substitute(split(execute('hi ' . a:name), '\n')[0], '\<xxx\>', '', '')
+endfunction
+
+function! IsColorable()
+ return has('gui_running') || str2nr(&t_Co) >= 8
+endfunction
+
+function! HiCursorLine()
+ let hiCursorLine = HighlightArgs('CursorLine')
+ if has('gui_running')
+ let guibg = matchstr(hiCursorLine, 'guibg=\w\+')
+ let hi_ul = 'hi CursorLine gui=underline guibg=NONE'
+ let hi_bg = 'hi CursorLine gui=NONE ' . guibg
+ else
+ let hi_ul = 'hi CursorLine cterm=underline ctermbg=NONE'
+ let hi_bg = 'hi CursorLine cterm=NONE ctermbg=Gray'
+ endif
+ return [hiCursorLine, hi_ul, hi_bg]
+endfunction
+
+func Test_highlight_eol_with_cursorline()
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 20)
+ call setline(1, 'abcd')
+ call matchadd('Search', '\n')
+
+ " expected:
+ " 'abcd '
+ " ^^^^ ^^^^^ no highlight
+ " ^ 'Search' highlight
+ let attrs0 = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs0[0]], 4), attrs0[0:3])
+ call assert_equal(repeat([attrs0[0]], 5), attrs0[5:9])
+ call assert_notequal(attrs0[0], attrs0[4])
+
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " 'abcd '
+ " ^^^^ underline
+ " ^^^^^^ 'Search' highlight with underline
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal([attrs[4]] + repeat([attrs[5]], 5), attrs[4:9])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[4], attrs[4])
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " 'abcd '
+ " ^^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal(repeat([attrs[5]], 5), attrs[5:9])
+ call assert_equal(attrs0[4], attrs[4])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[5], attrs[5])
+ endif
+
+ call CloseWindow()
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_with_cursorline_vertsplit()
+ if !has('vertsplit')
+ return
+ endif
+
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 5)
+ call setline(1, 'abcd')
+ call matchadd('Search', '\n')
+
+ let expected = "abcd |abcd "
+ let actual = ScreenLines(1, 15)[0]
+ call assert_equal(expected, actual)
+
+ " expected:
+ " 'abcd |abcd '
+ " ^^^^ ^^^^^^^^^ no highlight
+ " ^ 'Search' highlight
+ " ^ 'VertSplit' highlight
+ let attrs0 = ScreenAttrs(1, 15)[0]
+ call assert_equal(repeat([attrs0[0]], 4), attrs0[0:3])
+ call assert_equal(repeat([attrs0[0]], 9), attrs0[6:14])
+ call assert_notequal(attrs0[0], attrs0[4])
+ call assert_notequal(attrs0[0], attrs0[5])
+ call assert_notequal(attrs0[4], attrs0[5])
+
+ setlocal cursorline
+
+ " expected:
+ " 'abcd |abcd '
+ " ^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^ 'VertSplit' highlight
+ " ^^^^^^^^^ no highlight
+
+ " underline
+ exe hi_ul
+
+ let actual = ScreenLines(1, 15)[0]
+ call assert_equal(expected, actual)
+
+ let attrs = ScreenAttrs(1, 15)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal(repeat([attrs[6]], 9), attrs[6:14])
+ call assert_equal(attrs0[5:14], attrs[5:14])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[0], attrs[5])
+ call assert_notequal(attrs[0], attrs[6])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs[5], attrs[6])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[4], attrs[4])
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ let actual = ScreenLines(1, 15)[0]
+ call assert_equal(expected, actual)
+
+ let attrs = ScreenAttrs(1, 15)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal(repeat([attrs[6]], 9), attrs[6:14])
+ call assert_equal(attrs0[5:14], attrs[5:14])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[0], attrs[5])
+ call assert_notequal(attrs[0], attrs[6])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs[5], attrs[6])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_equal(attrs0[4], attrs[4])
+ endif
+
+ call CloseWindow()
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_with_cursorline_rightleft()
+ if !has('rightleft')
+ return
+ endif
+
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 10)
+ setlocal rightleft
+ call setline(1, 'abcd')
+ call matchadd('Search', '\n')
+ let attrs0 = ScreenAttrs(1, 10)[0]
+
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " ' dcba'
+ " ^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^^^ underline
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[9]], 4), attrs[6:9])
+ call assert_equal(repeat([attrs[4]], 5) + [attrs[5]], attrs[0:5])
+ call assert_notequal(attrs[9], attrs[5])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs0[9], attrs[9])
+ call assert_notequal(attrs0[5], attrs[5])
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " ' dcba'
+ " ^^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[9]], 4), attrs[6:9])
+ call assert_equal(repeat([attrs[4]], 5), attrs[0:4])
+ call assert_equal(attrs0[5], attrs[5])
+ call assert_notequal(attrs[9], attrs[5])
+ call assert_notequal(attrs[5], attrs[4])
+ call assert_notequal(attrs0[9], attrs[9])
+ call assert_notequal(attrs0[4], attrs[4])
+ endif
+
+ call CloseWindow()
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_with_cursorline_linewrap()
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 10)
+ call setline(1, [repeat('a', 51) . 'bcd', ''])
+ call matchadd('Search', '\n')
+
+ setlocal wrap
+ normal! gg$
+ let attrs0 = ScreenAttrs(5, 10)[0]
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " 'abcd '
+ " ^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^^^ underline
+ let attrs = ScreenAttrs(5, 10)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal([attrs[4]] + repeat([attrs[5]], 5), attrs[4:9])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[4], attrs[4])
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " 'abcd '
+ " ^^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(5, 10)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal(repeat([attrs[5]], 5), attrs[5:9])
+ call assert_equal(attrs0[4], attrs[4])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[5], attrs[5])
+ endif
+
+ setlocal nocursorline nowrap
+ normal! gg$
+ let attrs0 = ScreenAttrs(1, 10)[0]
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " 'aaabcd '
+ " ^^^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^ underline
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[0]], 6), attrs[0:5])
+ call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
+ call assert_notequal(attrs[0], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[6], attrs[6])
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " 'aaabcd '
+ " ^^^^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[0]], 6), attrs[0:5])
+ call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
+ call assert_equal(attrs0[6], attrs[6])
+ call assert_notequal(attrs[0], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[7], attrs[7])
+ endif
+
+ call CloseWindow()
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_with_cursorline_sign()
+ if !has('signs')
+ return
+ endif
+
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 10)
+ call setline(1, 'abcd')
+ call matchadd('Search', '\n')
+
+ sign define Sign text=>>
+ exe 'sign place 1 line=1 name=Sign buffer=' . bufnr('')
+ let attrs0 = ScreenAttrs(1, 10)[0]
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " '>>abcd '
+ " ^^ sign
+ " ^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^ underline
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
+ call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
+ call assert_notequal(attrs[2], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[2], attrs[2])
+ call assert_notequal(attrs0[6], attrs[6])
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " '>>abcd '
+ " ^^ sign
+ " ^^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
+ call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
+ call assert_equal(attrs0[6], attrs[6])
+ call assert_notequal(attrs[2], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[2], attrs[2])
+ call assert_notequal(attrs0[7], attrs[7])
+ endif
+
+ sign unplace 1
+ call CloseWindow()
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_with_cursorline_breakindent()
+ if !has('linebreak')
+ return
+ endif
+
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 10)
+ setlocal breakindent breakindentopt=min:0,shift:1 showbreak=>
+ call setline(1, ' ' . repeat('a', 9) . 'bcd')
+ call matchadd('Search', '\n')
+ let attrs0 = ScreenAttrs(2, 10)[0]
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " ' >bcd '
+ " ^^^ breakindent and showbreak
+ " ^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^ underline
+ let attrs = ScreenAttrs(2, 10)[0]
+ call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
+ call assert_equal(repeat([attrs[3]], 3), attrs[3:5])
+ call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
+ call assert_equal(attrs0[0], attrs[0])
+ call assert_notequal(attrs[0], attrs[2])
+ call assert_notequal(attrs[2], attrs[3])
+ call assert_notequal(attrs[3], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[2], attrs[2])
+ call assert_notequal(attrs0[3], attrs[3])
+ call assert_notequal(attrs0[6], attrs[6])
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " ' >bcd '
+ " ^^^ breakindent and showbreak
+ " ^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(2, 10)[0]
+ call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
+ call assert_equal(repeat([attrs[3]], 3), attrs[3:5])
+ call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
+ call assert_equal(attrs0[0], attrs[0])
+ call assert_equal(attrs0[6], attrs[6])
+ call assert_notequal(attrs[0], attrs[2])
+ call assert_notequal(attrs[2], attrs[3])
+ call assert_notequal(attrs[3], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[2], attrs[2])
+ call assert_notequal(attrs0[3], attrs[3])
+ call assert_notequal(attrs0[7], attrs[7])
+ endif
+
+ call CloseWindow()
+ set showbreak=
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_on_diff()
+ call setline(1, ['abcd', ''])
+ call matchadd('Search', '\n')
+ let attrs0 = ScreenAttrs(1, 10)[0]
+
+ diffthis
+ botright new
+ diffthis
+
+ " expected:
+ " ' abcd '
+ " ^^ sign
+ " ^^^^ ^^^ 'DiffAdd' highlight
+ " ^ 'Search' highlight
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
+ call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
+ call assert_equal(repeat([attrs[2]], 3), attrs[7:9])
+ call assert_equal(attrs0[4], attrs[6])
+ call assert_notequal(attrs[0], attrs[2])
+ call assert_notequal(attrs[0], attrs[6])
+ call assert_notequal(attrs[2], attrs[6])
+
+ bwipe!
+ diffoff
+endfunc
diff --git a/src/testdir/view_util.vim b/src/testdir/view_util.vim
index eb9263076..29ea073f9 100644
--- a/src/testdir/view_util.vim
+++ b/src/testdir/view_util.vim
@@ -1,5 +1,10 @@
" Functions about view shared by several tests
+" Only load this script once.
+if exists('*ScreenLines')
+ finish
+endif
+
" ScreenLines(lnum, width) or
" ScreenLines([start, end], width)
function! ScreenLines(lnum, width) abort
@@ -18,6 +23,22 @@ function! ScreenLines(lnum, width) abort
return lines
endfunction
+function! ScreenAttrs(lnum, width) abort
+ redraw!
+ if type(a:lnum) == v:t_list
+ let start = a:lnum[0]
+ let end = a:lnum[1]
+ else
+ let start = a:lnum
+ let end = a:lnum
+ endif
+ let attrs = []
+ for l in range(start, end)
+ let attrs += [map(range(1, a:width), 'screenattr(l, v:val)')]
+ endfor
+ return attrs
+endfunction
+
function! NewWindow(height, width) abort
exe a:height . 'new'
exe a:width . 'vsp'
diff --git a/src/version.c b/src/version.c
index 38743203f..a129ec97d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -762,6 +762,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1168,
+/**/
1167,
/**/
1166,