From 6eda17d881c9b2880ccb2a4d11951939a58f233d Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 12 Sep 2022 19:25:11 +0100 Subject: [PATCH] patch 9.0.0452: Visual highlighting extends into virtual text prop Problem: Visual highlighting extends into virtual text prop. Solution: Do not highlight what isn't actually selected. Fix ordering of stored text props. --- src/drawline.c | 9 ++++++++- .../dumps/Test_prop_with_text_above_6.dump | 9 +++++++++ .../dumps/Test_prop_with_text_above_7.dump | 9 +++++++++ src/testdir/test_textprop.vim | 10 ++++++++++ src/textprop.c | 18 ++++++++++++++---- src/version.c | 2 ++ 6 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 src/testdir/dumps/Test_prop_with_text_above_6.dump create mode 100644 src/testdir/dumps/Test_prop_with_text_above_7.dump diff --git a/src/drawline.c b/src/drawline.c index 9dfa1749d..50d18ec97 100644 --- a/src/drawline.c +++ b/src/drawline.c @@ -670,6 +670,7 @@ win_line( int text_prop_follows = FALSE; // another text prop to display int saved_search_attr = 0; // search_attr to be used when n_extra // goes to zero + int saved_area_attr = 0; // idem for area_attr #endif #ifdef FEAT_SPELL int has_spell = FALSE; // this buffer has spell checking @@ -1846,8 +1847,12 @@ win_line( extra_for_textprop = TRUE; extra_attr = used_attr; n_attr = mb_charlen(p); + // restore search_attr and area_attr when n_extra + // is down to zero saved_search_attr = search_attr; - search_attr = 0; // restore when n_extra is zero + saved_area_attr = area_attr; + search_attr = 0; + area_attr = 0; text_prop_attr = 0; text_prop_attr_comb = 0; if (*ptr == NUL) @@ -2203,6 +2208,8 @@ win_line( in_linebreak = FALSE; if (search_attr == 0) search_attr = saved_search_attr; + if (area_attr == 0 && *ptr != NUL) + area_attr = saved_area_attr; } #endif } diff --git a/src/testdir/dumps/Test_prop_with_text_above_6.dump b/src/testdir/dumps/Test_prop_with_text_above_6.dump new file mode 100644 index 000000000..faf9af6b7 --- /dev/null +++ b/src/testdir/dumps/Test_prop_with_text_above_6.dump @@ -0,0 +1,9 @@ +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@1|1| |f+0#0000000#ffff4012|i|r|s|t| |t|h|i|n|g| |a|b|o|v|e| @36 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|s+0#0000000#ffd7ff255|e|c|o|n|d| |t|h|i|n|g| |a|b|o|v|e| @35 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|i+0#0000000#e0e0e08|n|s|e|r|t|e>d+0&#ffffff0| |o|n|e| |t|w|o| @37 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|b+0#0000000#5fd7ff255|e|l|o|w| +0&#ffffff0@48 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@1|2| |t+0#0000000&|h|r|e@1| |f|o|u|r| @43 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@1|3| | +0#0000000&@2|a+0&#ffff4012|n|o|t|h|e|r| |t|h|i|n|g| @37 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|f+0#0000000&|i|v|e| |s|i|x| @45 +|~+0#4040ff13&| @58 +|-+2#0000000&@1| |V|I|S|U|A|L| |-@1| +0&&@19|8| @8|1|,|8|-|1@1|6| @6|A|l@1| diff --git a/src/testdir/dumps/Test_prop_with_text_above_7.dump b/src/testdir/dumps/Test_prop_with_text_above_7.dump new file mode 100644 index 000000000..9caa3c303 --- /dev/null +++ b/src/testdir/dumps/Test_prop_with_text_above_7.dump @@ -0,0 +1,9 @@ +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@1|1| |f+0#0000000#ffff4012|i|r|s|t| |t|h|i|n|g| |a|b|o|v|e| @36 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|s+0#0000000#ffd7ff255|e|c|o|n|d| |t|h|i|n|g| |a|b|o|v|e| @35 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|i+0#0000000#e0e0e08|n|s|e|r|t|e>d+0&#ffffff0| +0&#e0e0e08|o|n|e| |t|w|o| +0&#ffffff0@37 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|b+0#0000000#5fd7ff255|e|l|o|w| +0#4040ff13#ffffff0| +0#0000000&@47 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@1|2| |t+0#0000000&|h|r|e@1| |f|o|u|r| @43 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@1|3| | +0#0000000&@2|a+0&#ffff4012|n|o|t|h|e|r| |t|h|i|n|g| @37 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|f+0#0000000&|i|v|e| |s|i|x| @45 +|~+0#4040ff13&| @58 +|-+2#0000000&@1| |V|I|S|U|A|L| |L|I|N|E| |-@1| +0&&@14|1| @8|1|,|8|-|1@1|6| @6|A|l@1| diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim index aaf9a8eba..235dd02ae 100644 --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -2855,11 +2855,15 @@ func Test_props_with_text_above() call setline(1, ['one two', 'three four', 'five six']) call prop_type_add('above1', #{highlight: 'Search'}) call prop_type_add('above2', #{highlight: 'DiffChange'}) + call prop_type_add('below', #{highlight: 'DiffAdd'}) call prop_add(1, 0, #{type: 'above1', text: 'first thing above', text_align: 'above'}) call prop_add(1, 0, #{type: 'above2', text: 'second thing above', text_align: 'above'}) call prop_add(3, 0, #{type: 'above1', text: 'another thing', text_align: 'above', text_padding_left: 3}) normal gglllj + func AddPropBelow() + call prop_add(1, 0, #{type: 'below', text: 'below', text_align: 'below'}) + endfunc END call writefile(lines, 'XscriptPropsWithTextAbove', 'D') let buf = RunVimInTerminal('-S XscriptPropsWithTextAbove', #{rows: 9, cols: 60}) @@ -2876,6 +2880,12 @@ func Test_props_with_text_above() call term_sendkeys(buf, ":set nowrap\gg$j") call VerifyScreenDump(buf, 'Test_prop_with_text_above_5', {}) + call term_sendkeys(buf, ":call AddPropBelow()\") + call term_sendkeys(buf, "ggve") + call VerifyScreenDump(buf, 'Test_prop_with_text_above_6', {}) + call term_sendkeys(buf, "V") + call VerifyScreenDump(buf, 'Test_prop_with_text_above_7', {}) + call StopVimInTerminal(buf) endfunc diff --git a/src/textprop.c b/src/textprop.c index 80b015167..be7225445 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -232,8 +232,9 @@ prop_add_one( for (lnum = start_lnum; lnum <= end_lnum; ++lnum) { - colnr_T col; // start column - long length; // in bytes + colnr_T col; // start column use in tp_col + colnr_T sort_col; // column where it appears + long length; // in bytes // Fetch the line to get the ml_line_len field updated. proplen = get_text_props(buf, lnum, &props, TRUE); @@ -248,6 +249,7 @@ prop_add_one( semsg(_(e_invalid_column_number_nr), (long)start_col); goto theend; } + sort_col = col; if (lnum == end_lnum) length = end_col - col; @@ -263,7 +265,9 @@ prop_add_one( length = 1; // text is placed on one character if (col == 0) { - col = MAXCOL; // after the line + col = MAXCOL; // before or after the line + if ((text_flags & TP_FLAG_ALIGN_ABOVE) == 0) + sort_col = MAXCOL; length += text_padding_left; } } @@ -280,9 +284,15 @@ prop_add_one( // the text, we need to copy them as bytes before using it as a struct. for (i = 0; i < proplen; ++i) { + colnr_T prop_col; + mch_memmove(&tmp_prop, props + i * sizeof(textprop_T), sizeof(textprop_T)); - if (tmp_prop.tp_col >= col) + // col is MAXCOL when the text goes above or after the line, when + // above we should use column zero for sorting + prop_col = (tmp_prop.tp_flags & TP_FLAG_ALIGN_ABOVE) + ? 0 : tmp_prop.tp_col; + if (prop_col >= sort_col) break; } newprops = newtext + textlen; diff --git a/src/version.c b/src/version.c index eafe0a4eb..26b8bf3a4 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 452, /**/ 451, /**/ -- 2.40.0