diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-08-18 14:00:12 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-18 14:00:12 +0800 |
commit | 81d5550d77d24a924e8c23873fccbf405bc39447 (patch) | |
tree | 4daa10d0c7967f95a7d8b2494a6344fa1f693b27 | |
parent | 8d7a2a1aea4a6954e2d550c887f2c7112459eec4 (diff) | |
download | rneovim-81d5550d77d24a924e8c23873fccbf405bc39447.tar.gz rneovim-81d5550d77d24a924e8c23873fccbf405bc39447.tar.bz2 rneovim-81d5550d77d24a924e8c23873fccbf405bc39447.zip |
vim-patch:9.0.1731: blockwise Visual highlight not working with virtual text (#24779)
Problem: blockwise Visual highlight not working with virtual text
Solution: Reset the correct variable at the end of virtual selection and
Check for double-width char inside virtual text.
closes: vim/vim#12606
https://github.com/vim/vim/commit/6e940d9a1d4ff122aad1b0821c784a60b507d45c
Need to remove area_active and use wlv.fromcol and wlv.tocol directly.
-rw-r--r-- | src/nvim/drawline.c | 50 | ||||
-rw-r--r-- | test/functional/ui/decorations_spec.lua | 148 |
2 files changed, 173 insertions, 25 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index d0cd11ccf3..d0142c6efa 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -106,7 +106,7 @@ typedef struct { int c_extra; ///< extra chars, all the same int c_final; ///< final char, mandatory if set - bool extra_for_extmark; + bool extra_for_extmark; ///< n_extra set for inline virtual text // saved "extra" items for when draw_state becomes WL_LINE (again) int saved_n_extra; @@ -1147,8 +1147,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl char buf_fold[FOLD_TEXT_LEN]; // Hold value returned by get_foldtext - bool area_active = false; - // 'cursorlineopt' has "screenline" and cursor is in this line bool cul_screenline = false; // margin columns for the screen line, needed for when 'cursorlineopt' @@ -1786,32 +1784,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl int extmark_attr = 0; if (wlv.draw_state == WL_LINE && (area_highlighting || spv->spv_has_spell || extra_check)) { - // handle Visual or match highlighting in this line - if (wlv.vcol == wlv.fromcol - || (wlv.vcol + 1 == wlv.fromcol - && ((wlv.n_extra == 0 && utf_ptr2cells(ptr) > 1) - || (wlv.n_extra > 0 && wlv.p_extra != NULL - && utf_ptr2cells(wlv.p_extra) > 1))) - || (vcol_prev == fromcol_prev - && vcol_prev < wlv.vcol // not at margin - && wlv.vcol < wlv.tocol)) { - area_attr = vi_attr; // start highlighting - if (area_highlighting) { - area_active = true; - } - } else if (area_attr != 0 && (wlv.vcol == wlv.tocol - || (noinvcur && wlv.vcol == wp->w_virtcol))) { - area_attr = 0; // stop highlighting - area_active = false; - } - if (wlv.n_extra == 0 || !wlv.extra_for_extmark) { wlv.reset_extra_attr = false; } if (has_decor && wlv.n_extra == 0) { - bool selected = (area_active || (area_highlighting && noinvcur - && wlv.vcol == wp->w_virtcol)); + bool selected = (area_highlighting + && ((wlv.vcol >= wlv.fromcol && wlv.vcol < wlv.tocol) + || (noinvcur && wlv.vcol == wp->w_virtcol))); extmark_attr = decor_redraw_col(wp, (colnr_T)v, wlv.off, selected, &decor_state); if (!has_fold && wp->w_buffer->b_virt_text_inline > 0) { @@ -1827,11 +1807,33 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl area_attr = 0; decor_attr = 0; search_attr_from_match = false; + } + if (wlv.n_extra > 0) { n_skip = 0; } } } + int *area_attr_p + = wlv.extra_for_extmark && wlv.virt_inline_hl_mode <= kHlModeReplace + ? &saved_area_attr : &area_attr; + + // handle Visual or match highlighting in this line + if (wlv.vcol == wlv.fromcol + || (wlv.vcol + 1 == wlv.fromcol + && ((wlv.n_extra == 0 && utf_ptr2cells(ptr) > 1) + || (wlv.n_extra > 0 && wlv.p_extra != NULL + && utf_ptr2cells(wlv.p_extra) > 1))) + || (vcol_prev == fromcol_prev + && vcol_prev < wlv.vcol // not at margin + && wlv.vcol < wlv.tocol)) { + *area_attr_p = vi_attr; // start highlighting + } else if (*area_attr_p != 0 + && (wlv.vcol == wlv.tocol + || (noinvcur && wlv.vcol == wp->w_virtcol))) { + *area_attr_p = 0; // stop highlighting + } + if (!has_fold && wlv.n_extra == 0) { // Check for start/end of 'hlsearch' and other matches. // After end, check for start/end of next match. diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index ef55784ca8..3a4a64361d 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -2146,7 +2146,7 @@ bbbbbbb]]) ]]} end) - it('visual select highlight is correct', function() + it('Visual select highlight is correct', function() insert('foo foo foo bar\nfoo foo foo bar') feed('gg0') meths.buf_set_extmark(0, ns, 0, 8, { virt_text = { { 'AAA', 'Special' } }, virt_text_pos = 'inline' }) @@ -2803,6 +2803,152 @@ bbbbbbb]]) | ]]} end) + + it('blockwise Visual highlight with double-width virtual text (replace)', function() + screen:try_resize(60, 6) + insert('123456789\n123456789\n123456789') + meths.buf_set_extmark(0, ns, 1, 1, { + virt_text = { { '-口-', 'Special' } }, + virt_text_pos = 'inline', + hl_mode = 'replace', + }) + feed('gg0') + screen:expect{grid=[[ + ^123456789 | + 1{10:-口-}23456789 | + 123456789 | + {1:~ }| + {1:~ }| + | + ]]} + feed('<C-V>2jl') + screen:expect{grid=[[ + {7:12}3456789 | + {7:1}{10:-口-}23456789 | + {7:1}^23456789 | + {1:~ }| + {1:~ }| + {8:-- VISUAL BLOCK --} | + ]]} + feed('l') + screen:expect{grid=[[ + {7:123}456789 | + {7:1}{10:-口-}23456789 | + {7:12}^3456789 | + {1:~ }| + {1:~ }| + {8:-- VISUAL BLOCK --} | + ]]} + feed('4l') + screen:expect{grid=[[ + {7:1234567}89 | + {7:1}{10:-口-}{7:23}456789 | + {7:123456}^789 | + {1:~ }| + {1:~ }| + {8:-- VISUAL BLOCK --} | + ]]} + feed('Ol') + screen:expect{grid=[[ + 1{7:234567}89 | + 1{10:-口-}{7:23}456789 | + 1^2{7:34567}89 | + {1:~ }| + {1:~ }| + {8:-- VISUAL BLOCK --} | + ]]} + feed('l') + screen:expect{grid=[[ + 12{7:34567}89 | + 1{10:-口-}{7:23}456789 | + 12^3{7:4567}89 | + {1:~ }| + {1:~ }| + {8:-- VISUAL BLOCK --} | + ]]} + feed('l') + screen:expect{grid=[[ + 123{7:4567}89 | + 1{10:-口-}{7:23}456789 | + 123^4{7:567}89 | + {1:~ }| + {1:~ }| + {8:-- VISUAL BLOCK --} | + ]]} + end) + + it('blockwise Visual highlight with double-width virtual text (combine)', function() + screen:try_resize(60, 6) + insert('123456789\n123456789\n123456789') + meths.buf_set_extmark(0, ns, 1, 1, { + virt_text = { { '-口-', 'Special' } }, + virt_text_pos = 'inline', + hl_mode = 'combine', + }) + feed('gg0') + screen:expect{grid=[[ + ^123456789 | + 1{10:-口-}23456789 | + 123456789 | + {1:~ }| + {1:~ }| + | + ]]} + feed('<C-V>2jl') + screen:expect{grid=[[ + {7:12}3456789 | + {7:1}{20:-}{10:口-}23456789 | + {7:1}^23456789 | + {1:~ }| + {1:~ }| + {8:-- VISUAL BLOCK --} | + ]]} + feed('l') + screen:expect{grid=[[ + {7:123}456789 | + {7:1}{20:-口}{10:-}23456789 | + {7:12}^3456789 | + {1:~ }| + {1:~ }| + {8:-- VISUAL BLOCK --} | + ]]} + feed('4l') + screen:expect{grid=[[ + {7:1234567}89 | + {7:1}{20:-口-}{7:23}456789 | + {7:123456}^789 | + {1:~ }| + {1:~ }| + {8:-- VISUAL BLOCK --} | + ]]} + feed('Ol') + screen:expect{grid=[[ + 1{7:234567}89 | + 1{20:-口-}{7:23}456789 | + 1^2{7:34567}89 | + {1:~ }| + {1:~ }| + {8:-- VISUAL BLOCK --} | + ]]} + feed('l') + screen:expect{grid=[[ + 12{7:34567}89 | + 1{10:-}{20:口-}{7:23}456789 | + 12^3{7:4567}89 | + {1:~ }| + {1:~ }| + {8:-- VISUAL BLOCK --} | + ]]} + feed('l') + screen:expect{grid=[[ + 123{7:4567}89 | + 1{10:-}{20:口-}{7:23}456789 | + 123^4{7:567}89 | + {1:~ }| + {1:~ }| + {8:-- VISUAL BLOCK --} | + ]]} + end) end) describe('decorations: virtual lines', function() |