diff options
-rw-r--r-- | src/nvim/drawline.c | 22 | ||||
-rw-r--r-- | test/functional/ui/decorations_spec.lua | 19 |
2 files changed, 31 insertions, 10 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 6b4ef2d3d9..2a6a76d509 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -1542,7 +1542,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl if (sign_num_attr == 0) { statuscol.num_attr = get_line_number_attr(wp, &wlv); } - v = (ptr - line); + v = ptr - line; draw_statuscol(wp, &wlv, lnum, wlv.row - startrow - wlv.filler_lines, &statuscol); if (wp->w_redr_statuscol) { break; @@ -1646,11 +1646,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl decor_need_recheck = false; } if (wlv.filler_todo <= 0) { - extmark_attr = decor_redraw_col(wp, (colnr_T)v, wlv.off, selected, &decor_state); + extmark_attr = decor_redraw_col(wp, (colnr_T)(ptr - line), wlv.off, selected, + &decor_state); } if (!has_fold && wp->w_buffer->b_virt_text_inline > 0) { - handle_inline_virtual_text(wp, &wlv, v); + handle_inline_virtual_text(wp, &wlv, ptr - line); if (wlv.n_extra > 0 && wlv.virt_inline_hl_mode <= kHlModeReplace) { // restore search_attr and area_attr when n_extra is down to zero // TODO(bfredl): this is ugly as fuck. look if we can do this some other way. @@ -1692,7 +1693,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // 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); + 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); @@ -1756,6 +1757,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl } if (draw_folded && wlv.n_extra == 0 && wlv.col == win_col_offset) { + v = ptr - line; linenr_T lnume = lnum + foldinfo.fi_lines - 1; memset(buf_fold, ' ', FOLD_TEXT_LEN); wlv.p_extra = get_foldtext(wp, lnum, lnume, foldinfo, buf_fold, &fold_vt); @@ -1943,7 +1945,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // Get extmark and syntax attributes, unless still at the start of the line // (double-wide char that doesn't fit). - v = (ptr - line); + v = ptr - line; if (has_syntax && v > 0) { // Get the syntax attribute for the character. If there // is an error, disable syntax highlighting. @@ -2001,7 +2003,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // Only do this when there is no syntax highlighting, the // @Spell cluster is not used or the current syntax item // contains the @Spell cluster. - v = (ptr - line); + v = ptr - line; if (spv->spv_has_spell && v >= word_end && v > cur_checked_col) { spell_attr = 0; // do not calculate cap_col at the end of the line or when @@ -2671,12 +2673,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl && !has_fold) { if (has_decor && *ptr == NUL && lcs_eol_one == 0) { // Tricky: there might be a virtual text just _after_ the last char - decor_redraw_col(wp, (colnr_T)v, wlv.off, false, &decor_state); + decor_redraw_col(wp, (colnr_T)(ptr - line), wlv.off, false, &decor_state); } if (*ptr != NUL || lcs_eol_one > 0 || (wlv.n_extra > 0 && (wlv.c_extra != NUL || *wlv.p_extra != NUL)) - || has_more_inline_virt(&wlv, v)) { + || has_more_inline_virt(&wlv, ptr - line)) { mb_c = wp->w_p_lcs_chars.ext; wlv.char_attr = win_hl_attr(wp, HLF_AT); mb_schar = schar_from_char(mb_c); @@ -2819,7 +2821,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // At the end of screen line: might need to peek for decorations just after // this position. if (!has_fold && wp->w_p_wrap && wlv.n_extra == 0) { - decor_redraw_col(wp, (int)(ptr - line), -3, false, &decor_state); + decor_redraw_col(wp, (colnr_T)(ptr - line), -3, false, &decor_state); // Check position/hiding of virtual text again on next screen line. decor_need_recheck = true; } else if (has_fold || !wp->w_p_wrap) { @@ -2837,7 +2839,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl || (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL && wlv.p_extra != at_end_str) || (wlv.n_extra != 0 && (wlv.c_extra != NUL || *wlv.p_extra != NUL)) - || has_more_inline_virt(&wlv, v))) { + || has_more_inline_virt(&wlv, ptr - line))) { bool wrap = wp->w_p_wrap // Wrapping enabled. && wlv.filler_todo <= 0 // Not drawing diff filler lines. && lcs_eol_one != -1 // Haven't printed the lcs_eol character. diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index be0f41ef6b..d78d7d06cc 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -762,6 +762,8 @@ describe('extmark decorations', function() [39] = {foreground = Screen.colors.Blue1, background = Screen.colors.LightCyan1, bold = true}; [40] = {reverse = true}; [41] = {bold = true, reverse = true}; + [42] = {undercurl = true, special = Screen.colors.Red}; + [43] = {background = Screen.colors.Yellow, undercurl = true, special = Screen.colors.Red}; } ns = meths.create_namespace 'test' @@ -1904,6 +1906,23 @@ describe('extmark decorations', function() ]]) end) + it('highlight works properly with multibyte text and spell #26771', function() + insert('口口\n') + screen:try_resize(50, 3) + meths.buf_set_extmark(0, ns, 0, 0, { end_col = 3, hl_group = 'Search' }) + screen:expect([[ + {34:口}口 | + ^ | + | + ]]) + command('setlocal spell') + screen:expect([[ + {43:口}{42:口} | + ^ | + | + ]]) + end) + it('supports multiline highlights', function() insert(example_text) feed 'gg' |