]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0901: textprop: wrong cursor line with truncated virtual text master v9.2.0901
authorHirohito Higashi <h.east.727@gmail.com>
Sun, 2 Aug 2026 19:25:12 +0000 (19:25 +0000)
committerChristian Brabandt <cb@256bit.org>
Sun, 2 Aug 2026 19:25:12 +0000 (19:25 +0000)
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) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/doc/todo.txt
src/charset.c
src/structs.h
src/testdir/test_textprop.vim
src/version.c

index a277a260f6bea8f778edc7ab1f28317918b2e53f..a8f9dff8e4a939127731379ab908b0c9f7c0b293 100644 (file)
@@ -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:
index c47180e2ce0fea592c4a70399926c1905b1e1a04..1c45688fe3b2c2876a78efe2c1cd285ce8378ee7 100644 (file)
@@ -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)
index b1ec3fa78868ce047ca302b794afc8d013822aff..fdba4ee835d301a9496a9344e2350ee2db3b87d5 100644 (file)
@@ -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
index a89ed55154151af45a3857c4e7f4947d74d5208d..86437354bb4b3e334e35b2591311a8fc3754e865 100644 (file)
@@ -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
index ac814a01ee20ed64976f62b3bb2a06029e2331b4..dcea5c2ab2b5341d79c5d9ad1d31daf3004c10a0 100644 (file)
@@ -763,6 +763,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    901,
 /**/
     900,
 /**/