diff options
-rw-r--r-- | runtime/doc/syntax.txt | 8 | ||||
-rw-r--r-- | runtime/doc/vim_diff.txt | 1 | ||||
-rw-r--r-- | src/nvim/screen.c | 56 | ||||
-rw-r--r-- | test/functional/ui/highlight_spec.lua | 46 |
4 files changed, 84 insertions, 27 deletions
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index 88b45900a2..83030bf713 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -4841,15 +4841,13 @@ ColorColumn used for the columns set with 'colorcolumn' Conceal placeholder characters substituted for concealed text (see 'conceallevel') *hl-Cursor* -Cursor the character under the cursor +Cursor character under the cursor *hl-CursorIM* CursorIM like Cursor, but used when in IME mode |CursorIM| *hl-CursorColumn* -CursorColumn the screen column that the cursor is in when 'cursorcolumn' is - set +CursorColumn screen column at the cursor, when 'cursorcolumn' is set *hl-CursorLine* -CursorLine the screen line that the cursor is in when 'cursorline' is - set +CursorLine screen line at the cursor, when 'cursorline' is set *hl-Directory* Directory directory names (and other special names in listings) *hl-DiffAdd* diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 52f6b3d918..8bda114639 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -306,6 +306,7 @@ other arguments if used). Highlight groups: |hl-ColorColumn|, |hl-CursorColumn| are lower priority than most other groups + |hl-CursorLine| is low-priority unless foreground color is set Macro/|recording| behavior Replay of a macro recorded during :lmap produces the same actions as when it diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 4cb6575502..4c011e466b 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2173,6 +2173,7 @@ win_line ( colnr_T trailcol = MAXCOL; /* start of trailing spaces */ int need_showbreak = false; // overlong line, skip first x chars int line_attr = 0; // attribute for the whole line + int line_attr_lowprio = 0; // low-priority attribute for the line matchitem_T *cur; // points to the match list match_T *shl; // points to search_hl or a match int shl_flag; // flag to indicate whether search_hl @@ -2398,6 +2399,29 @@ win_line ( filler_lines = wp->w_topfill; filler_todo = filler_lines; + // Cursor line highlighting for 'cursorline' in the current window. Not + // when Visual mode is active, because it's not clear what is selected + // then. + if (wp->w_p_cul && lnum == wp->w_cursor.lnum + && !(wp == curwin && VIsual_active)) { + int cul_attr = win_hl_attr(wp, HLF_CUL); + HlAttrs *aep = syn_cterm_attr2entry(cul_attr); + + // We make a compromise here (#7383): + // * low-priority CursorLine if fg is not set + // * high-priority ("same as Vim" priority) CursorLine if fg is set + if (aep->rgb_fg_color == -1 && aep->cterm_fg_color == 0) { + line_attr_lowprio = cul_attr; + } else { + if (line_attr != 0 && !(State & INSERT) && bt_quickfix(wp->w_buffer) + && qf_current_entry(wp) == lnum) { + line_attr = hl_combine_attr(cul_attr, line_attr); + } else { + line_attr = cul_attr; + } + } + } + // If this line has a sign with line highlighting set line_attr. v = buf_getsigntype(wp->w_buffer, lnum, SIGN_LINEHL); if (v != 0) { @@ -2409,7 +2433,7 @@ win_line ( line_attr = win_hl_attr(wp, HLF_QFL); } - if (line_attr != 0) { + if (line_attr_lowprio || line_attr) { area_highlighting = true; } @@ -2631,20 +2655,6 @@ win_line ( cur = cur->next; } - // Cursor line highlighting for 'cursorline' in the current window. Not - // when Visual mode is active, because it's not clear what is selected - // then. - if (wp->w_p_cul && lnum == wp->w_cursor.lnum - && !(wp == curwin && VIsual_active)) { - if (line_attr != 0 && !(State & INSERT) && bt_quickfix(wp->w_buffer) - && qf_current_entry(wp) == lnum) { - line_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), line_attr); - } else { - line_attr = win_hl_attr(wp, HLF_CUL); - } - area_highlighting = true; - } - off = (unsigned)(current_ScreenLine - ScreenLines); int col = 0; // Visual column on screen. if (wp->w_p_rl) { @@ -3567,8 +3577,10 @@ win_line ( // Display a '$' after the line or highlight an extra // character if the line break is included. // For a diff line the highlighting continues after the "$". - if (diff_hlf == (hlf_T)0 && line_attr == 0) { - // In virtualedit, visual selections may extend beyond end of line. + if (diff_hlf == (hlf_T)0 + && line_attr == 0 + && line_attr_lowprio == 0) { + // In virtualedit, visual selections may extend beyond end of line if (area_highlighting && virtual_active() && tocol != MAXCOL && vcol < tocol) { n_extra = 0; @@ -3631,7 +3643,7 @@ win_line ( (col < wp->w_width))) { c = ' '; ptr--; // put it back at the NUL - } else if ((diff_hlf != (hlf_T)0 || line_attr != 0) + } else if ((diff_hlf != (hlf_T)0 || line_attr_lowprio || line_attr) && (wp->w_p_rl ? (col >= 0) : (col - boguscols < wp->w_width))) { @@ -3643,7 +3655,8 @@ 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_lowprio || line_attr) + && char_attr == search_attr && col > 0) { char_attr = line_attr; } if (diff_hlf == HLF_TXD) { @@ -4007,6 +4020,11 @@ win_line ( } } + // Apply lowest-priority line attr now, so everything can override it. + if (draw_state == WL_LINE) { + char_attr = hl_combine_attr(line_attr_lowprio, char_attr); + } + /* * Store character to be displayed. * Skip characters that are left of the screen for 'nowrap'. diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua index ab3b1c3cac..b46a6c1e46 100644 --- a/test/functional/ui/highlight_spec.lua +++ b/test/functional/ui/highlight_spec.lua @@ -541,7 +541,7 @@ describe("'listchars' highlight", function() ]]) feed_command('set cursorline') screen:expect([[ - {2:^>-------.}{1:abcd}{2:.}{1:Lorem}{4:>}| + {2:^>-------.}{1:abcd}{2:.}{1:Lorem}{3:>}| {5:>-------.}abcd{5:*}{4:¬} | {4:¬} | {4:~ }| @@ -549,7 +549,7 @@ describe("'listchars' highlight", function() ]]) feed('$') screen:expect([[ - {4:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }| + {3:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }| {4:<} | {4:<} | {4:~ }| @@ -630,7 +630,7 @@ describe("'listchars' highlight", function() feed('<esc>$') screen:expect([[ {4:<} | - {4:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }| + {3:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }| {4:<} | {4:~ }| | @@ -675,6 +675,46 @@ describe("'listchars' highlight", function() end) end) +describe('CursorLine highlight', function() + before_each(clear) + it('overridden by Error, ColorColumn if fg not set', function() + local screen = Screen.new(50,5) + screen:set_default_attr_ids({ + [1] = {foreground = Screen.colors.SlateBlue}, + [2] = {bold = true, foreground = Screen.colors.Brown}, + [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, + [4] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.Gray90}, + [5] = {background = Screen.colors.Gray90}, + [6] = {bold = true, foreground = Screen.colors.Blue1}, + [7] = {background = Screen.colors.LightRed}, + }) + screen:attach() + + feed_command('filetype on') + feed_command('syntax on') + feed_command('set cursorline ft=json') + feed('i{<cr>"a" : abc // 10;<cr>}<cr><esc>') + screen:expect([[ + {1:{} | + "{2:a}" : {3:abc} {3:// 10;} | + {1:}} | + {5:^ }| + | + ]]) + + feed_command('set colorcolumn=3') + feed('i <esc>') + screen:expect([[ + {1:{} {7: } | + "{2:a}{7:"} : {3:abc} {3:// 10;} | + {1:}} {7: } | + {5: ^ }{7: }{5: }| + | + ]]) + end) +end) + + describe("MsgSeparator highlight and msgsep fillchar", function() before_each(clear) it("works", function() |