diff options
-rw-r--r-- | src/nvim/drawline.c | 57 | ||||
-rw-r--r-- | test/functional/ui/decorations_spec.lua | 49 | ||||
-rw-r--r-- | test/functional/ui/highlight_spec.lua | 35 |
3 files changed, 108 insertions, 33 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index d2d39e8ca8..c9a27ceedf 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -1073,7 +1073,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int mod_top, bo int saved_search_attr = 0; // search_attr to be used when n_extra // goes to zero int vcol_save_attr = 0; // saved attr for 'cursorcolumn' - int syntax_attr = 0; // attributes desired by syntax + int decor_attr = 0; // attributes desired by syntax and extmarks bool has_syntax = false; // this buffer has syntax highl. int folded_attr = 0; // attributes for folded line int save_did_emsg; @@ -1909,11 +1909,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int mod_top, bo wlv.char_attr = wlv.line_attr; } else { attr_pri = false; - if (has_syntax) { - wlv.char_attr = syntax_attr; - } else { - wlv.char_attr = 0; - } + wlv.char_attr = decor_attr; } if (folded_attr != 0) { @@ -2116,11 +2112,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int mod_top, bo } ptr++; + decor_attr = 0; if (extra_check) { bool no_plain_buffer = (wp->w_s->b_p_spo_flags & SPO_NPBUFFER) != 0; bool can_spell = !no_plain_buffer; - // Get syntax attribute, unless still at the start of the line + // Get extmark and syntax attributes, unless still at the start of the line // (double-wide char that doesn't fit). v = (ptr - line); if (has_syntax && v > 0) { @@ -2129,8 +2126,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int mod_top, bo save_did_emsg = did_emsg; did_emsg = false; - syntax_attr = get_syntax_attr((colnr_T)v - 1, - has_spell ? &can_spell : NULL, false); + decor_attr = get_syntax_attr((colnr_T)v - 1, + has_spell ? &can_spell : NULL, false); if (did_emsg) { // -V547 wp->w_s->b_syn_error = true; @@ -2148,17 +2145,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int mod_top, bo line = ml_get_buf(wp->w_buffer, lnum, false); ptr = line + v; - if (!attr_pri) { - if (wlv.cul_attr) { - wlv.char_attr = 0 != wlv.line_attr_lowprio - ? hl_combine_attr(wlv.cul_attr, syntax_attr) - : hl_combine_attr(syntax_attr, wlv.cul_attr); - } else { - wlv.char_attr = syntax_attr; - } - } else { - wlv.char_attr = hl_combine_attr(syntax_attr, wlv.char_attr); - } // no concealing past the end of the line, it interferes // with line highlighting. if (c == NUL) { @@ -2166,27 +2152,35 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int mod_top, bo } else { syntax_flags = get_syntax_info(&syntax_seqnr); } - } else if (!attr_pri) { - wlv.char_attr = 0; } if (has_decor && v > 0) { - if (extmark_attr != 0) { - if (!attr_pri) { - wlv.char_attr = hl_combine_attr(wlv.char_attr, extmark_attr); - } else { - wlv.char_attr = hl_combine_attr(extmark_attr, wlv.char_attr); - } - } + // extmarks take preceedence over syntax.c + decor_attr = hl_combine_attr(decor_attr, extmark_attr); decor_conceal = decor_state.conceal; if (decor_conceal && decor_state.conceal_char) { decor_conceal = 2; // really?? } - can_spell = TRISTATE_TO_BOOL(decor_state.spell, can_spell); } + if (decor_attr) { + if (!attr_pri) { + if (wlv.cul_attr) { + wlv.char_attr = 0 != wlv.line_attr_lowprio + ? hl_combine_attr(wlv.cul_attr, decor_attr) + : hl_combine_attr(decor_attr, wlv.cul_attr); + } else { + wlv.char_attr = decor_attr; + } + } else { + wlv.char_attr = hl_combine_attr(decor_attr, wlv.char_attr); + } + } else if (!attr_pri) { + wlv.char_attr = 0; + } + // Check spelling (unless at the end of the line). // Only do this when there is no syntax highlighting, the // @Spell cluster is not used or the current syntax item @@ -2197,8 +2191,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int mod_top, bo char *prev_ptr = ptr - mb_l; // do not calculate cap_col at the end of the line or when // only white space is following - if (c != 0 && (*skipwhite(prev_ptr) != NUL) - && ((!has_syntax && !no_plain_buffer) || can_spell)) { + if (c != 0 && (*skipwhite(prev_ptr) != NUL) && can_spell) { char *p; hlf_T spell_hlf = HLF_COUNT; v -= mb_l - 1; diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index 767ec54a7b..3ed31033fa 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -660,6 +660,8 @@ describe('extmark decorations', function() [25] = {background = Screen.colors.LightRed}; [26] = {background=Screen.colors.DarkGrey, foreground=Screen.colors.LightGrey}; [27] = {background = Screen.colors.Plum1}; + [28] = {underline = true, foreground = Screen.colors.SlateBlue}; + [29] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.LightGray, underline = true}; } ns = meths.create_namespace 'test' @@ -1254,8 +1256,53 @@ describe('extmark decorations', function() meths.buf_set_extmark(0, ns, 0, 3, { end_col = 6, hl_group = 'TestBold', priority = 20 }) screen:expect_unchanged(true) end) -end) + it('highlights the beginning of a TAB char correctly', function() + screen:try_resize(50, 3) + meths.buf_set_lines(0, 0, -1, true, {'this is the\ttab'}) + meths.buf_set_extmark(0, ns, 0, 11, { end_col = 15, hl_group = 'ErrorMsg' }) + screen:expect{grid=[[ + ^this is the{4: tab} | + {1:~ }| + | + ]]} + + meths.buf_clear_namespace(0, ns, 0, -1) + meths.buf_set_extmark(0, ns, 0, 12, { end_col = 15, hl_group = 'ErrorMsg' }) + screen:expect{grid=[[ + ^this is the {4:tab} | + {1:~ }| + | + ]]} + end) + + pending('highlight applies to a full Tab in visual block mode #23734', function() + screen:try_resize(50, 8) + meths.buf_set_lines(0, 0, -1, true, {'asdf', '\tasdf', '\tasdf', '\tasdf', 'asdf'}) + meths.buf_set_extmark(0, ns, 0, 0, {end_row = 5, end_col = 0, hl_group = 'Underlined'}) + screen:expect([[ + {28:^asdf} | + {28: asdf} | + {28: asdf} | + {28: asdf} | + {28:asdf} | + {1:~ }| + {1:~ }| + | + ]]) + feed('<C-V>Gll') + screen:expect([[ + {29:asd}{28:f} | + {29: }{28: asdf} | + {29: }{28: asdf} | + {29: }{28: asdf} | + {29:as}{28:^df} | + {1:~ }| + {1:~ }| + {24:-- VISUAL BLOCK --} | + ]]) + end) +end) describe('decorations: inline virtual text', function() local screen, ns diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua index 89b503141b..9a4be4573c 100644 --- a/test/functional/ui/highlight_spec.lua +++ b/test/functional/ui/highlight_spec.lua @@ -526,6 +526,41 @@ describe('highlight', function() }) end) + + it("'diff', syntax and extmark", function() + local screen = Screen.new(25,10) + screen:attach() + exec([[ + new + call setline(1, ['', '01234 6789']) + windo diffthis + wincmd w + syn match WarningMsg "^.*$" + call nvim_buf_add_highlight(0, -1, 'ErrorMsg', 1, 2, 8) + ]]) + screen:expect([[ + {1: }^ | + {1: }{2:01}{3:234 67}{2:89}{5: }| + {4:~ }| + {4:~ }| + {7:[No Name] [+] }| + {1: } | + {1: }{6:-----------------------}| + {4:~ }| + {8:[No Name] }| + | + ]],{ + [0] = {Screen.colors.WebGray, foreground = Screen.colors.DarkBlue}, + [1] = {background = Screen.colors.Grey, foreground = Screen.colors.Blue4}, + [2] = {foreground = Screen.colors.Red, background = Screen.colors.LightBlue}, + [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.LightBlue}, + [4] = {bold = true, foreground = Screen.colors.Blue}, + [5] = {background = Screen.colors.LightBlue}, + [6] = {bold = true, background = Screen.colors.LightCyan, foreground = Screen.colors.Blue1}, + [7] = {reverse = true, bold = true}, + [8] = {reverse = true}, + }) + end) end) describe("'listchars' highlight", function() |