From 1050666c96c68abe3ef738359312e85c76607901 Mon Sep 17 00:00:00 2001 From: Hirohito Higashi Date: Sun, 2 Aug 2026 19:25:12 +0000 Subject: [PATCH] patch 9.2.0901: textprop: wrong cursor line with truncated virtual text Problem: The cursor is displayed in the wrong line when virtual text below an empty line is truncated. Solution: Do not count an extra column for an empty line that has virtual text below it, its width already includes filling up the line. (Hirohito Higashi). fixes: #12493 closes: #20917 Co-Authored-By: Claude Opus 5 (1M context) Signed-off-by: Hirohito Higashi Signed-off-by: Christian Brabandt --- runtime/doc/todo.txt | 1 - src/charset.c | 12 +++++++++--- src/structs.h | 2 ++ src/testdir/test_textprop.vim | 21 +++++++++++++++++++++ src/version.c | 2 ++ 5 files changed, 34 insertions(+), 4 deletions(-) diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index a277a260f6..a8f9dff8e4 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -48,7 +48,6 @@ without all the help files. Virtual text problems: - Virtual text aligned "above": Wrong indentation when using tabs (Issue #12232) -- truncated Virtual text below an empty line causes display error #12493 Errors when running tests with valgrind: - test_gui.vim: diff --git a/src/charset.c b/src/charset.c index c47180e2ce..1c45688fe3 100644 --- a/src/charset.c +++ b/src/charset.c @@ -921,9 +921,10 @@ win_linetabsize_cts(chartabsize_T *cts, colnr_T len) int head = 0; (void)win_lbr_chartabsize(cts, &head, NULL); vcol += cts->cts_cur_text_width + head; - // when properties are above or below the empty line must also be - // counted - if (cts->cts_ptr == cts->cts_line && cts->cts_prop_lines > 0) + // When properties are above the empty line must also be counted. For + // a property below the width already includes filling up the line. + if (cts->cts_ptr == cts->cts_line && cts->cts_prop_lines > 0 + && !cts->cts_has_below) ++vcol; cts->cts_vcol = vcol > MAXCOL ? MAXCOL : (int)vcol; } @@ -1260,6 +1261,7 @@ win_lbr_chartabsize( #if defined(FEAT_PROP_POPUP) cts->cts_cur_text_width = 0; + cts->cts_has_below = false; cts->cts_first_char = 0; #endif @@ -1381,8 +1383,12 @@ win_lbr_chartabsize( # endif if (tp->tp_col == MAXCOL && (tp->tp_flags & (TP_FLAG_ALIGN_ABOVE | TP_FLAG_ALIGN_BELOW))) + { // count extra line for property above/below ++cts->cts_prop_lines; + if (tp->tp_flags & TP_FLAG_ALIGN_BELOW) + cts->cts_has_below = true; + } } } if (tp->tp_col != MAXCOL && tp->tp_col - 1 > col) diff --git a/src/structs.h b/src/structs.h index b1ec3fa788..fdba4ee835 100644 --- a/src/structs.h +++ b/src/structs.h @@ -5361,6 +5361,8 @@ typedef struct { char cts_has_prop_with_text; // TRUE if a property inserts text int cts_cur_text_width; // width of current inserted text int cts_prop_lines; // nr of properties above or below + bool cts_has_below; // true if a text property below was + // counted, its width fills up the line int cts_first_char; // width text props above the line int cts_above_width; // width of text props above the line, // kept for the whole line diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim index a89ed55154..86437354bb 100644 --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -3229,6 +3229,27 @@ func Test_prop_with_text_above_below_empty() call StopVimInTerminal(buf) endfunc +func Test_prop_with_text_below_empty_truncated() + " Use a fixed size, the virtual text must be wider than the text area. + call NewWindow(12, 40) + setlocal number + call setline(1, ['11111', '', '33333', '', '55555']) + + call prop_type_add('belowprop', #{highlight: 'Directory'}) + for ln in range(1, 5) + call prop_add(ln, 0, #{type: 'belowprop', + \ text: repeat('+', winwidth(0)), text_align: 'below'}) + endfor + normal! G + redraw + + " Every line takes two screen lines: the line and the virtual text below it. + call assert_equal(9, winline()) + + call prop_type_delete('belowprop') + bwipe! +endfunc + func Test_prop_multiple_lines_above() CheckScreendump CheckRunVimInTerminal diff --git a/src/version.c b/src/version.c index ac814a01ee..dcea5c2ab2 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 901, /**/ 900, /**/ -- 2.47.3