# HG changeset patch # User Bram Moolenaar # Date 1663007406 -7200 # Node ID 8d660a45299f29fc04298e9dc6303bf6379ee234 # Parent b0eb842f1c1579aa7361eedae170c4819c1511cd patch 9.0.0452: Visual highlighting extends into virtual text prop Commit: https://github.com/vim/vim/commit/6eda17d881c9b2880ccb2a4d11951939a58f233d Author: Bram Moolenaar Date: Mon Sep 12 19:25:11 2022 +0100 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. diff --git a/src/drawline.c b/src/drawline.c --- 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 --- /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 --- /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 --- 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 --- 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 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 452, +/**/ 451, /**/ 450,