diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/screen.c | 19 | ||||
| -rw-r--r-- | src/nvim/testdir/test_highlight.vim | 456 | ||||
| -rw-r--r-- | src/nvim/testdir/view_util.vim | 21 | 
3 files changed, 490 insertions, 6 deletions
diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 8e7a84c6b1..256a3ed4b5 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2197,7 +2197,7 @@ win_line (    match_T     *shl;                     // points to search_hl or a match    int shl_flag;                         // flag to indicate whether search_hl                                          // has been processed or not -  int prevcol_hl_flag;                  // flag to indicate whether prevcol +  bool prevcol_hl_flag;                 // flag to indicate whether prevcol                                          // equals startcol of search_hl or one                                          // of the matches    int prev_c = 0;                       // previous Arabic character @@ -3026,6 +3026,10 @@ 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; +        }        }        if (diff_hlf != (hlf_T)0) { @@ -3674,7 +3678,9 @@ win_line (            // don't do search HL for the rest of the line            if ((line_attr_lowprio || line_attr) -              && char_attr == search_attr && col > 0) { +              && char_attr == search_attr +              && (did_line_attr > 1 +                  || (wp->w_p_list && lcs_eol > 0))) {              char_attr = line_attr;            }            if (diff_hlf == HLF_TXD) { @@ -3833,9 +3839,12 @@ win_line (                     || lnum == VIsual.lnum                     || lnum == curwin->w_cursor.lnum)                 && c == NUL) -              /* highlight 'hlsearch' match at end of line */ -              || (prevcol_hl_flag == TRUE && did_line_attr <= 1) -              )) { +              // highlight 'hlsearch' match at end of line +              || (prevcol_hl_flag +                  && !(wp->w_p_cul && lnum == wp->w_cursor.lnum +                       && !(wp == curwin && VIsual_active)) +                  && diff_hlf == (hlf_T)0 +                  && did_line_attr <= 1))) {          int n = 0;          if (wp->w_p_rl) { diff --git a/src/nvim/testdir/test_highlight.vim b/src/nvim/testdir/test_highlight.vim index 927e8fdb3d..215490868a 100644 --- a/src/nvim/testdir/test_highlight.vim +++ b/src/nvim/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/nvim/testdir/view_util.vim b/src/nvim/testdir/view_util.vim index eb92630761..29ea073f97 100644 --- a/src/nvim/testdir/view_util.vim +++ b/src/nvim/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'  | 
