# HG changeset patch # User Christian Brabandt # Date 1693587607 -7200 # Node ID 61fc08239937649680e893a7177149ff9f1c218b # Parent e8d7f4f40a2601adfc708895e5f3766af0cfe36e patch 9.0.1836: display wrong with virttext, linebreak and breakindent Commit: https://github.com/vim/vim/commit/ce53e3ea55d12d222a73510d772e786b7ae29c8d Author: zeertzjq Date: Fri Sep 1 18:49:30 2023 +0200 patch 9.0.1836: display wrong with virttext, linebreak and breakindent Problem: Wrong display with "above" virtual text and 'linebreak' or 'breakindent' and 'showbreak'. Solution: Exclude size of "above" virtual text when calculating them. closes: #13000 Signed-off-by: Christian Brabandt Co-authored-by: zeertzjq diff --git a/src/charset.c b/src/charset.c --- a/src/charset.c +++ b/src/charset.c @@ -1209,17 +1209,18 @@ win_lbr_chartabsize( cells = text_prop_position(wp, tp, vcol, (vcol + size) % (wp->w_width - col_off) + col_off, &n_extra, &p, NULL, NULL, FALSE); -#ifdef FEAT_LINEBREAK +# ifdef FEAT_LINEBREAK no_sbr = TRUE; // don't use 'showbreak' now -#endif +# endif } else cells = vim_strsize(p); cts->cts_cur_text_width += cells; if (tp->tp_flags & TP_FLAG_ALIGN_ABOVE) cts->cts_first_char += cells; + else + size += cells; cts->cts_start_incl = tp->tp_flags & TP_FLAG_START_INCL; - size += cells; if (*s == TAB) { // tab size changes because of the inserted text @@ -1263,9 +1264,9 @@ win_lbr_chartabsize( int col_off_prev = win_col_off(wp); int width2 = wp->w_width - col_off_prev + win_col_off2(wp); colnr_T wcol = vcol + col_off_prev; -#ifdef FEAT_PROP_POPUP +# ifdef FEAT_PROP_POPUP wcol -= wp->w_virtcol_first_char; -#endif +# endif colnr_T max_head_vcol = cts->cts_max_head_vcol; int added = 0; @@ -1319,7 +1320,7 @@ win_lbr_chartabsize( else if (max_head_vcol > vcol + head_prev + prev_rem) head += (max_head_vcol - (vcol + head_prev + prev_rem) + width2 - 1) / width2 * head_mid; -#ifdef FEAT_PROP_POPUP +# ifdef FEAT_PROP_POPUP else if (max_head_vcol < 0) { int off = 0; @@ -1329,7 +1330,7 @@ win_lbr_chartabsize( if (off >= prev_rem) head += (1 + (off - prev_rem) / width) * head_mid; } -#endif +# endif } } @@ -1385,6 +1386,9 @@ win_lbr_chartabsize( } } +# ifdef FEAT_PROP_POPUP + size += cts->cts_first_char; +# endif return size; # endif #endif diff --git a/src/drawline.c b/src/drawline.c --- a/src/drawline.c +++ b/src/drawline.c @@ -1650,6 +1650,18 @@ win_line( } #endif +#if defined(FEAT_LINEBREAK) || defined(FEAT_PROP_POPUP) + colnr_T vcol_first_char = 0; + if (wp->w_p_lbr && !number_only) + { + chartabsize_T cts; + init_chartabsize_arg(&cts, wp, lnum, 0, line, line); + (void)win_lbr_chartabsize(&cts, NULL); + vcol_first_char = cts.cts_first_char; + clear_chartabsize_arg(&cts); + } +#endif + // 'nowrap' or 'wrap' and a single line that doesn't fit: Advance to the // first character to be displayed. if (wp->w_p_wrap) @@ -2879,7 +2891,11 @@ win_line( char_u *p = ptr - (mb_off + 1); chartabsize_T cts; - init_chartabsize_arg(&cts, wp, lnum, wlv.vcol, line, p); + init_chartabsize_arg(&cts, wp, lnum, wlv.vcol +# ifdef FEAT_PROP_POPUP + - vcol_first_char, +# endif + line, p); # ifdef FEAT_PROP_POPUP // do not want virtual text counted here cts.cts_has_prop_with_text = FALSE; diff --git a/src/testdir/dumps/Test_prop_above_and_before_1.dump b/src/testdir/dumps/Test_prop_above_and_before_1.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_prop_above_and_before_1.dump @@ -0,0 +1,6 @@ +|a+0&#ffffff0| @73 +| +0#e000e06&@1|1|2|3| +0#0000000&@69 +@2|b|:+0#e000e06&| |4|5|6| +0#0000000&>c| @64 +|~+0#4040ff13&| @73 +|~| @73 +| +0#0000000&@56|2|,|5|-|8|5| @7|A|l@1| diff --git a/src/testdir/dumps/Test_prop_above_and_before_2.dump b/src/testdir/dumps/Test_prop_above_and_before_2.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_prop_above_and_before_2.dump @@ -0,0 +1,6 @@ +|a+0&#ffffff0| @73 +| +0#e000e06&@1|1|2|3| +0#0000000&@69 +@2|b|:+0#e000e06&| |4|5|6> +0#0000000&|c| @64 +|~+0#4040ff13&| @73 +|~| @73 +| +0#0000000&@56|2|,|4|-|8|4| @7|A|l@1| diff --git a/src/testdir/dumps/Test_prop_above_and_before_3.dump b/src/testdir/dumps/Test_prop_above_and_before_3.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_prop_above_and_before_3.dump @@ -0,0 +1,6 @@ +|a+0&#ffffff0| @73 +| +0#e000e06&@1|1|2|3| +0#0000000&@69 +@2>b|:+0#e000e06&| |4|5|6| +0#0000000&|c| @64 +|~+0#4040ff13&| @73 +|~| @73 +| +0#0000000&@56|2|,|3|-|7|8| @7|A|l@1| diff --git a/src/testdir/dumps/Test_prop_above_and_before_4.dump b/src/testdir/dumps/Test_prop_above_and_before_4.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_prop_above_and_before_4.dump @@ -0,0 +1,6 @@ +|a+0&#ffffff0| @73 +| +0#e000e06&@1|1|2|3| +0#0000000&@69 +@1> |b|:+0#e000e06&| |4|5|6| +0#0000000&|c| @64 +|~+0#4040ff13&| @73 +|~| @73 +| +0#0000000&@56|2|,|2|-|7@1| @7|A|l@1| diff --git a/src/testdir/dumps/Test_prop_above_and_before_5.dump b/src/testdir/dumps/Test_prop_above_and_before_5.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_prop_above_and_before_5.dump @@ -0,0 +1,6 @@ +|a+0&#ffffff0| @73 +| +0#e000e06&@1|1|2|3| +0#0000000&@69 +> @1|b|:+0#e000e06&| |4|5|6| +0#0000000&|c| @64 +|~+0#4040ff13&| @73 +|~| @73 +| +0#0000000&@56|2|,|1|-|7|6| @7|A|l@1| diff --git a/src/testdir/dumps/Test_prop_above_linebreak_1.dump b/src/testdir/dumps/Test_prop_above_linebreak_1.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_prop_above_linebreak_1.dump @@ -0,0 +1,6 @@ +|1+0#e000e06#ffffff0|2|3| +0#0000000&@71 +|a| |b| @71 +|c| >d| @71 +|~+0#4040ff13&| @73 +|~| @73 +| +0#0000000&@56|2|,|3| @10|A|l@1| diff --git a/src/testdir/dumps/Test_prop_above_linebreak_2.dump b/src/testdir/dumps/Test_prop_above_linebreak_2.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_prop_above_linebreak_2.dump @@ -0,0 +1,6 @@ +|1+0#e000e06#ffffff0|2|3| +0#0000000&@71 +|a| >b| @71 +|c| |d| @71 +|~+0#4040ff13&| @73 +|~| @73 +| +0#0000000&@56|1|,|3|-|7|8| @7|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 @@ -3523,6 +3523,51 @@ func Test_prop_above_with_number() call StopVimInTerminal(buf) endfunc +func Test_prop_above_with_linebreak() + CheckRunVimInTerminal + + let lines =<< trim END + setlocal linebreak breakindent breakindentopt=shift:4 + call setline(1, ["a b", "c d"]) + call prop_type_add('theprop' , #{highlight: 'Special'}) + call prop_add(1, 0, #{type: 'theprop', text: '123', text_align: 'above'}) + normal! 2gg$ + END + call writefile(lines, 'XscriptPropAboveLinebreak', 'D') + let buf = RunVimInTerminal('-S XscriptPropAboveLinebreak', #{rows: 6}) + call VerifyScreenDump(buf, 'Test_prop_above_linebreak_1', {}) + call term_sendkeys(buf, 'k') + call VerifyScreenDump(buf, 'Test_prop_above_linebreak_2', {}) + + call StopVimInTerminal(buf) +endfunc + +func Test_prop_above_and_before() + CheckRunVimInTerminal + + let lines =<< trim END + setlocal linebreak breakindent breakindentopt=shift:2 + call setline(1, ["a", " b c"]) + call prop_type_add('theprop' , #{highlight: 'Special'}) + call prop_add(2, 0, #{type: 'theprop', text: ' 123', text_align: 'above'}) + call prop_add(2, 4, #{type: 'theprop', text: ': 456'} ) + normal! 2gg$ + END + call writefile(lines, 'XscriptPropAboveAndBefore', 'D') + let buf = RunVimInTerminal('-S XscriptPropAboveAndBefore', #{rows: 6}) + call VerifyScreenDump(buf, 'Test_prop_above_and_before_1', {}) + call term_sendkeys(buf, 'h') + call VerifyScreenDump(buf, 'Test_prop_above_and_before_2', {}) + call term_sendkeys(buf, 'h') + call VerifyScreenDump(buf, 'Test_prop_above_and_before_3', {}) + call term_sendkeys(buf, 'h') + call VerifyScreenDump(buf, 'Test_prop_above_and_before_4', {}) + call term_sendkeys(buf, 'h') + call VerifyScreenDump(buf, 'Test_prop_above_and_before_5', {}) + + call StopVimInTerminal(buf) +endfunc + func Test_prop_below_split_line() CheckRunVimInTerminal diff --git a/src/textprop.c b/src/textprop.c --- a/src/textprop.c +++ b/src/textprop.c @@ -759,13 +759,12 @@ text_prop_compare(const void *s1, const tp2 = &text_prop_compare_props[idx2]; col1 = tp1->tp_col; col2 = tp2->tp_col; - if (col1 == MAXCOL && col2 == MAXCOL) + if (col1 == MAXCOL || col2 == MAXCOL) { int order1 = text_prop_order(tp1->tp_flags); int order2 = text_prop_order(tp2->tp_flags); - // both props add text before or after the line, sort on order where it - // is added + // sort on order where it is added if (order1 != order2) return order1 < order2 ? 1 : -1; } diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -700,6 +700,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1836, +/**/ 1835, /**/ 1834,