diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 36163859eb..4722195fe4 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2180,7 +2180,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * wp->w_cursorline = win_cursorline_standout(wp) ? wp->w_cursor.lnum : 0; if (wp->w_p_cul) { - if (statuscol.foldinfo.fi_level > 0 && statuscol.foldinfo.fi_lines > 0) { + if (statuscol.foldinfo.fi_level != 0 && statuscol.foldinfo.fi_lines > 0) { wp->w_cursorline = statuscol.foldinfo.fi_lnum; } statuscol.use_cul = lnum == wp->w_cursorline && (wp->w_p_culopt_flags & CULOPT_NBR); diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index ced7e46287..49c4b6f32a 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -421,7 +421,7 @@ size_t fill_foldcolumn(char *p, win_T *wp, foldinfo_T foldinfo, linenr_T lnum) size_t char_counter = 0; int symbol = 0; int len = 0; - bool closed = foldinfo.fi_lines > 0; + bool closed = foldinfo.fi_level != 0 && foldinfo.fi_lines > 0; // Init to all spaces. memset(p, ' ', MAX_MCO * (size_t)fdc + 1); @@ -1813,13 +1813,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl area_active = false; } - if (!has_fold) { - if (has_decor && v >= 0) { - bool selected = (area_active || (area_highlighting && noinvcur - && wlv.vcol == wp->w_virtcol)); - extmark_attr = decor_redraw_col(wp, (colnr_T)v, wlv.off, - selected, &decor_state); + if (has_decor && v >= 0) { + bool selected = (area_active || (area_highlighting && noinvcur + && wlv.vcol == wp->w_virtcol)); + extmark_attr = decor_redraw_col(wp, (colnr_T)v, wlv.off, selected, &decor_state); + if (!has_fold) { bool do_save = false; handle_inline_virtual_text(wp, &wlv, v, &do_save); if (do_save) { @@ -1835,43 +1834,43 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl n_skip = 0; } } + } - if (wlv.n_extra == 0) { - // Check for start/end of 'hlsearch' and other matches. - // After end, check for start/end of next match. - // When another match, have to check for start again. - v = (ptr - line); - search_attr = update_search_hl(wp, lnum, (colnr_T)v, &line, &screen_search_hl, - &has_match_conc, &match_conc, lcs_eol_one, - &on_last_col, &search_attr_from_match); - ptr = line + v; // "line" may have been changed + if (wlv.n_extra == 0) { + // Check for start/end of 'hlsearch' and other matches. + // After end, check for start/end of next match. + // When another match, have to check for start again. + v = (ptr - line); + search_attr = update_search_hl(wp, lnum, (colnr_T)v, &line, &screen_search_hl, + &has_match_conc, &match_conc, lcs_eol_one, + &on_last_col, &search_attr_from_match); + ptr = line + v; // "line" may have been changed - // Do not allow a conceal over EOL otherwise EOL will be missed - // and bad things happen. - if (*ptr == NUL) { - has_match_conc = 0; - } + // Do not allow a conceal over EOL otherwise EOL will be missed + // and bad things happen. + if (*ptr == NUL) { + has_match_conc = 0; } + } - if (wlv.diff_hlf != (hlf_T)0) { - // When there is extra text (eg: virtual text) it gets the - // diff highlighting for the line, but not for changed text. - if (wlv.diff_hlf == HLF_CHD && ptr - line >= change_start - && wlv.n_extra == 0) { - wlv.diff_hlf = HLF_TXD; // changed text - } - if (wlv.diff_hlf == HLF_TXD && ((ptr - line > change_end && wlv.n_extra == 0) - || (wlv.n_extra > 0 && wlv.extra_for_extmark))) { - wlv.diff_hlf = HLF_CHD; // changed line - } - wlv.line_attr = win_hl_attr(wp, (int)wlv.diff_hlf); - // Overlay CursorLine onto diff-mode highlight. - if (wlv.cul_attr) { - wlv.line_attr = 0 != wlv.line_attr_lowprio // Low-priority CursorLine - ? hl_combine_attr(hl_combine_attr(wlv.cul_attr, wlv.line_attr), - hl_get_underline()) - : hl_combine_attr(wlv.line_attr, wlv.cul_attr); - } + if (wlv.diff_hlf != (hlf_T)0) { + // When there is extra text (eg: virtual text) it gets the + // diff highlighting for the line, but not for changed text. + if (wlv.diff_hlf == HLF_CHD && ptr - line >= change_start + && wlv.n_extra == 0) { + wlv.diff_hlf = HLF_TXD; // changed text + } + if (wlv.diff_hlf == HLF_TXD && ((ptr - line > change_end && wlv.n_extra == 0) + || (wlv.n_extra > 0 && wlv.extra_for_extmark))) { + wlv.diff_hlf = HLF_CHD; // changed line + } + wlv.line_attr = win_hl_attr(wp, (int)wlv.diff_hlf); + // Overlay CursorLine onto diff-mode highlight. + if (wlv.cul_attr) { + wlv.line_attr = 0 != wlv.line_attr_lowprio // Low-priority CursorLine + ? hl_combine_attr(hl_combine_attr(wlv.cul_attr, wlv.line_attr), + hl_get_underline()) + : hl_combine_attr(wlv.line_attr, wlv.cul_attr); } } @@ -1983,7 +1982,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl } wlv.extra_for_extmark = false; } - } else if (foldinfo.fi_lines > 0) { + } else if (has_fold) { // skip writing the buffer line itself c = NUL; } else { @@ -2753,8 +2752,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl ? 1 : 0); if (has_decor) { - has_virttext = decor_redraw_eol(wp, &decor_state, &wlv.line_attr, - wlv.col + eol_skip); + has_virttext = decor_redraw_eol(wp, &decor_state, &wlv.line_attr, wlv.col + eol_skip); } if (((wp->w_p_cuc @@ -2848,7 +2846,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl if (wp == curwin && lnum == curwin->w_cursor.lnum) { curwin->w_cline_row = startrow; curwin->w_cline_height = wlv.row - startrow; - curwin->w_cline_folded = foldinfo.fi_lines > 0; + curwin->w_cline_folded = has_fold; curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW); conceal_cursor_used = conceal_cursor_line(curwin); } diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index e05af6fbe5..28a029d758 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -1985,7 +1985,7 @@ static void win_update(win_T *wp, DecorProviders *providers) if (wp->w_p_cul) { // Make sure that the cursorline on a closed fold is redrawn cursorline_fi = fold_info(wp, wp->w_cursor.lnum); - if (cursorline_fi.fi_level > 0 && cursorline_fi.fi_lines > 0) { + if (cursorline_fi.fi_level != 0 && cursorline_fi.fi_lines > 0) { wp->w_cursorline = cursorline_fi.fi_lnum; } } @@ -2231,8 +2231,8 @@ static void win_update(win_T *wp, DecorProviders *providers) // Display one line spellvars_T zero_spv = { 0 }; - row = win_line(wp, lnum, srow, foldinfo.fi_lines ? srow : wp->w_grid.rows, false, - foldinfo.fi_lines ? &zero_spv : &spv, + row = win_line(wp, lnum, srow, foldinfo.fi_lines > 0 ? srow : wp->w_grid.rows, false, + foldinfo.fi_lines > 0 ? &zero_spv : &spv, foldinfo, &line_providers, &provider_err); if (foldinfo.fi_lines == 0) { diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index 54441984a3..cbf0178d28 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -666,6 +666,7 @@ describe('extmark decorations', function() [30] = {foreground = Screen.colors.DarkCyan, background = Screen.colors.LightGray, underline = true}; [31] = {underline = true, foreground = Screen.colors.DarkCyan}; [32] = {underline = true}; + [33] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGray}; } ns = meths.create_namespace 'test' @@ -1147,6 +1148,46 @@ describe('extmark decorations', function() ]]} end) + it('can have virtual text on folded line', function() + insert([[ + 11111 + 22222 + 33333]]) + command('1,2fold') + command('set nowrap') + screen:try_resize(50, 3) + feed('zb') + -- XXX: the behavior of overlay virtual text at non-zero column is strange: + -- 1. With 'wrap' it is never shown. + -- 2. With 'nowrap' it is shown only if the extmark is hidden before leftcol. + meths.buf_set_extmark(0, ns, 0, 0, { virt_text = {{'AA', 'Underlined'}}, hl_mode = 'combine', virt_text_pos = 'overlay' }) + meths.buf_set_extmark(0, ns, 0, 1, { virt_text = {{'BB', 'Underlined'}}, hl_mode = 'combine', virt_text_win_col = 10 }) + meths.buf_set_extmark(0, ns, 0, 2, { virt_text = {{'CC', 'Underlined'}}, hl_mode = 'combine', virt_text_pos = 'right_align' }) + screen:expect{grid=[[ + {29:AA}{33:- 2 lin}{29:BB}{33:: 11111·····························}{29:CC}| + 3333^3 | + | + ]]} + feed('zl') + screen:expect{grid=[[ + {29:AA}{33:- 2 lin}{29:BB}{33:: 11111·····························}{29:CC}| + 333^3 | + | + ]]} + feed('zl') + screen:expect{grid=[[ + {29:AA}{33:- 2 lin}{29:BB}{33:: 11111·····························}{29:CC}| + 33^3 | + | + ]]} + feed('zl') + screen:expect{grid=[[ + {29:AA}{33:- 2 lin}{29:BB}{33:: 11111·····························}{29:CC}| + 3^3 | + | + ]]} + end) + it('can have virtual text which combines foreground and background groups', function() screen:set_default_attr_ids { [1] = {bold=true, foreground=Screen.colors.Blue};