aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIbby <33922797+SleepySwords@users.noreply.github.com>2023-04-03 22:13:15 +1000
committerbfredl <bjorn.linse@gmail.com>2023-05-22 13:49:42 +0200
commit5547b16c40f92fbc75ad1b9a7b3dd1f5ff50cbb2 (patch)
tree21750cf487a726b4411a3c09ad4a824eae83d1ae
parent75f350aac6cd952341d7ce88e64b0d6ed2aa694d (diff)
downloadrneovim-5547b16c40f92fbc75ad1b9a7b3dd1f5ff50cbb2.tar.gz
rneovim-5547b16c40f92fbc75ad1b9a7b3dd1f5ff50cbb2.tar.bz2
rneovim-5547b16c40f92fbc75ad1b9a7b3dd1f5ff50cbb2.zip
vim-patch:9.0.1067: in diff mode virtual text is highlighted incorrectly
Problem: In diff mode virtual text is highlighted incorrectly. (Rick Howe) Solution: Do not use diff attributes for virtual text. (closes vim/vim#11714) https://github.com/vim/vim/commit/d097af77797f030e0f29f9bbc298358a5addb2a5 Co-authored-by: Bram Moolenaar <Bram@vim.org>
-rw-r--r--src/nvim/drawline.c38
-rw-r--r--test/functional/ui/decorations_spec.lua43
2 files changed, 69 insertions, 12 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index 23b88413b1..84f0447ca6 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -105,9 +105,12 @@ typedef struct {
int c_extra; ///< extra chars, all the same
int c_final; ///< final char, mandatory if set
+ bool extra_for_extmark;
+
// saved "extra" items for when draw_state becomes WL_LINE (again)
int saved_n_extra;
char *saved_p_extra;
+ bool saved_extra_for_extmark;
int saved_c_extra;
int saved_c_final;
int saved_char_attr;
@@ -909,6 +912,7 @@ static void win_line_start(win_T *wp, winlinevars_T *wlv, bool save_extra)
wlv->draw_state = WL_START;
wlv->saved_n_extra = wlv->n_extra;
wlv->saved_p_extra = wlv->p_extra;
+ wlv->saved_extra_for_extmark = wlv->extra_for_extmark;
wlv->saved_c_extra = wlv->c_extra;
wlv->saved_c_final = wlv->c_final;
wlv->saved_char_attr = wlv->char_attr;
@@ -924,6 +928,7 @@ static void win_line_continue(winlinevars_T *wlv)
// Continue item from end of wrapped line.
wlv->n_extra = wlv->saved_n_extra;
wlv->saved_n_extra = 0;
+ wlv->extra_for_extmark = wlv->saved_extra_for_extmark;
wlv->c_extra = wlv->saved_c_extra;
wlv->c_final = wlv->saved_c_final;
wlv->p_extra = wlv->saved_p_extra;
@@ -1770,7 +1775,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
}
}
- if (wlv.n_extra == 0) {
+ if (wlv.n_extra == 0 || !wlv.extra_for_extmark) {
reset_extra_attr = false;
}
@@ -1778,6 +1783,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
VirtTextChunk vtc = kv_A(virt_inline, virt_inline_i);
wlv.p_extra = vtc.text;
wlv.n_extra = (int)strlen(wlv.p_extra);
+ wlv.extra_for_extmark = true;
wlv.c_extra = NUL;
wlv.c_final = NUL;
wlv.extra_attr = vtc.hl_id ? syn_id2attr(vtc.hl_id) : 0;
@@ -1835,12 +1841,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
}
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) {
+ 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);
@@ -1944,16 +1952,22 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
// Only restore search_attr and area_attr after "n_extra" in
// the next screen line is also done.
- if (wlv.n_extra <= 0 && wlv.saved_n_extra <= 0) {
- if (search_attr == 0) {
- search_attr = saved_search_attr;
- }
- if (area_attr == 0 && *ptr != NUL) {
- area_attr = saved_area_attr;
+ if (wlv.n_extra <= 0) {
+ if (wlv.saved_n_extra <= 0) {
+ if (search_attr == 0) {
+ search_attr = saved_search_attr;
+ }
+ if (area_attr == 0 && *ptr != NUL) {
+ area_attr = saved_area_attr;
+ }
+
+ if (wlv.extra_for_extmark) {
+ // wlv.extra_attr should be used at this position but not
+ // any further.
+ reset_extra_attr = true;
+ }
}
- // wlv.extra_attr should be used at this position but not
- // any further.
- reset_extra_attr = true;
+ wlv.extra_for_extmark = false;
}
} else if (foldinfo.fi_lines > 0) {
// skip writing the buffer line itself
diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua
index 292743e21a..4579fad53f 100644
--- a/test/functional/ui/decorations_spec.lua
+++ b/test/functional/ui/decorations_spec.lua
@@ -648,6 +648,9 @@ describe('extmark decorations', function()
[28] = {foreground = Screen.colors.SlateBlue};
[29] = {background = Screen.colors.Yellow1};
[30] = {reverse = true};
+ [31] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.LightMagenta};
+ [32] = {bold = true, reverse = true};
+ [33] = {background = Screen.colors.Red1, bold = true}
}
ns = meths.create_namespace 'test'
@@ -1913,6 +1916,46 @@ bbbbbbb]])
|
]]}
end)
+
+ it('in diff mode virtual text is highlighted correct', function()
+ insert([[
+ 9000
+ 0009
+ 0009
+ 9000
+ 0009
+ ]])
+ command("set diff")
+ meths.buf_set_extmark(0, ns, 0, 1,
+ { virt_text = { { 'test', 'Special' } }, virt_text_pos = 'inline', right_gravity = false })
+ command("vnew")
+ insert([[
+ 000
+ 000
+ 000
+ 000
+ 000
+ ]])
+ command("set diff")
+ feed('gg0')
+ screen:expect { grid = [[
+ {27:^000 }│{33:9}{31:test}{27:000 }|
+ {27:000 }│{27:000}{33:9}{27: }|
+ {27:000 }│{27:000}{33:9}{27: }|
+ {27:000 }│{33:9}{27:000 }|
+ {27:000 }│{27:000}{33:9}{27: }|
+ │ |
+ {1:~ }│{1:~ }|
+ {1:~ }│{1:~ }|
+ {1:~ }│{1:~ }|
+ {1:~ }│{1:~ }|
+ {1:~ }│{1:~ }|
+ {1:~ }│{1:~ }|
+ {1:~ }│{1:~ }|
+ {32:[No Name] [+] }{30:[No Name] [+] }|
+ |
+ ]]}
+ end)
end)
describe('decorations: virtual lines', function()