diff src/drawline.c @ 32981:2415680a2554 v9.0.1783

commit b557f4898208105b674df605403cac1b1292707b Author: zeertzjq <zeertzjq@outlook.com> Date: Tue Aug 22 22:07:34 2023 +0200 patch 9.0.1783: Display issues with virt text smoothscroll and showbreak Problem: Wrong display with wrapping virtual text or unprintable chars, 'showbreak' and 'smoothscroll'. Solution: Don't skip cells taken by 'showbreak' in screen lines before "w_skipcol". Combined "n_skip" and "skip_cells". closes: #12597 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: zeertzjq <zeertzjq@outlook.com>
author Christian Brabandt <cb@256bit.org>
date Thu, 24 Aug 2023 07:47:10 +0200
parents 8325b9a4c732
children 7d0357f70cf8
line wrap: on
line diff
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -1110,14 +1110,10 @@ win_line(
     int		n_attr3 = 0;	    // chars with overruling special attr
     int		saved_attr3 = 0;    // char_attr saved for n_attr3
 
-    int		n_skip = 0;		// nr of cells to skip for 'nowrap' or
-					// concealing
-#ifdef FEAT_PROP_POPUP
-    int		skip_cells = 0;		// nr of cells to skip for virtual text
-					// after the line, when w_skipcol is
-					// larger than the text length
-#endif
-
+    int		skip_cells = 0;		// nr of cells to skip for w_leftcol or
+					// w_skipcol or concealing
+    int		skipped_cells = 0;	// nr of skipped cells for virtual text
+					// to be added to wlv.vcol later
     int		fromcol_prev = -2;	// start of inverting after cursor
     int		noinvcur = FALSE;	// don't invert the cursor
     int		lnum_in_visual_area = FALSE;
@@ -1665,11 +1661,14 @@ win_line(
 	char_u		*prev_ptr = ptr;
 	chartabsize_T	cts;
 	int		charsize = 0;
+	int		head = 0;
 
 	init_chartabsize_arg(&cts, wp, lnum, wlv.vcol, line, ptr);
+	cts.cts_max_head_vcol = v;
 	while (cts.cts_vcol < v && *cts.cts_ptr != NUL)
 	{
-	    charsize = win_lbr_chartabsize(&cts, NULL);
+	    head = 0;
+	    charsize = win_lbr_chartabsize(&cts, &head);
 	    cts.cts_vcol += charsize;
 	    prev_ptr = cts.cts_ptr;
 	    MB_PTR_ADV(cts.cts_ptr);
@@ -1698,20 +1697,9 @@ win_line(
 	{
 	    wlv.vcol -= charsize;
 	    ptr = prev_ptr;
-	    // If the character fits on the screen, don't need to skip it.
-	    // Except for a TAB.
-	    if (((*mb_ptr2cells)(ptr) >= charsize || *ptr == TAB)
-							       && wlv.col == 0)
-	       n_skip = v - wlv.vcol;
 	}
-
-#ifdef FEAT_PROP_POPUP
-	// If there the text doesn't reach to the desired column, need to skip
-	// "skip_cells" cells when virtual text follows.
-	if ((!wp->w_p_wrap || (lnum == wp->w_topline && wp->w_skipcol > 0))
-							       && v > wlv.vcol)
-	    skip_cells = v - wlv.vcol;
-#endif
+	if (v > wlv.vcol)
+	    skip_cells = v - wlv.vcol - head;
 
 	// Adjust for when the inverted text is before the screen,
 	// and when the start of the inverted text is before the screen.
@@ -2205,6 +2193,7 @@ win_line(
 				wlv.n_attr_skip -= skip_cells;
 				if (wlv.n_attr_skip < 0)
 				    wlv.n_attr_skip = 0;
+				skipped_cells += skip_cells;
 				skip_cells = 0;
 			    }
 			    else
@@ -2212,6 +2201,7 @@ win_line(
 				// the whole text is left of the window, drop
 				// it and advance to the next one
 				skip_cells -= wlv.n_extra;
+				skipped_cells += wlv.n_extra;
 				wlv.n_extra = 0;
 				wlv.n_attr_skip = 0;
 				bail_out = TRUE;
@@ -2592,11 +2582,15 @@ win_line(
 #ifdef FEAT_LINEBREAK
 	    c0 = *ptr;
 #endif
+	    if (c == NUL)
+	    {
 #ifdef FEAT_PROP_POPUP
-	    if (c == NUL)
 		// text is finished, may display a "below" virtual text
 		did_line = TRUE;
 #endif
+		// no more cells to skip
+		skip_cells = 0;
+	    }
 
 	    if (has_mbyte)
 	    {
@@ -2762,7 +2756,7 @@ win_line(
 		// If a double-width char doesn't fit at the left side display
 		// a '<' in the first column.  Don't do this for unprintable
 		// characters.
-		if (n_skip > 0 && mb_l > 1 && wlv.n_extra == 0)
+		if (skip_cells > 0 && mb_l > 1 && wlv.n_extra == 0)
 		{
 		    wlv.n_extra = 1;
 		    wlv.c_extra = MB_FILLER_CHAR;
@@ -3438,10 +3432,10 @@ win_line(
 		    wlv.n_extra = 0;
 		    n_attr = 0;
 		}
-		else if (n_skip == 0)
+		else if (skip_cells == 0)
 		{
 		    is_concealing = TRUE;
-		    n_skip = 1;
+		    skip_cells = 1;
 		}
 		mb_c = c;
 		if (enc_utf8 && utf_char2len(c) > 1)
@@ -3459,7 +3453,7 @@ win_line(
 		is_concealing = FALSE;
 	    }
 
-	    if (n_skip > 0 && did_decrement_ptr)
+	    if (skip_cells > 0 && did_decrement_ptr)
 		// not showing the '>', put pointer back to avoid getting stuck
 		++ptr;
 
@@ -3472,7 +3466,7 @@ win_line(
 	if (!did_wcol && wlv.draw_state == WL_LINE
 		&& wp == curwin && lnum == wp->w_cursor.lnum
 		&& conceal_cursor_line(wp)
-		&& (int)wp->w_virtcol <= wlv.vcol + n_skip)
+		&& (int)wp->w_virtcol <= wlv.vcol + skip_cells)
 	{
 # ifdef FEAT_RIGHTLEFT
 	    if (wp->w_p_rl)
@@ -3797,7 +3791,7 @@ win_line(
 
 	// Store character to be displayed.
 	// Skip characters that are left of the screen for 'nowrap'.
-	if (wlv.draw_state < WL_LINE || n_skip <= 0)
+	if (wlv.draw_state < WL_LINE || skip_cells <= 0)
 	{
 	    // Store the character.
 #if defined(FEAT_RIGHTLEFT)
@@ -3893,7 +3887,7 @@ win_line(
 #ifdef FEAT_CONCEAL
 	else if (wp->w_p_cole > 0 && is_concealing)
 	{
-	    --n_skip;
+	    --skip_cells;
 	    ++wlv.vcol_off_co;
 	    if (wlv.n_extra > 0)
 		wlv.vcol_off_co += wlv.n_extra;
@@ -3973,7 +3967,13 @@ win_line(
 	}
 #endif // FEAT_CONCEAL
 	else
-	    --n_skip;
+	    --skip_cells;
+
+	if (wlv.draw_state > WL_NR && skipped_cells > 0)
+	{
+	    wlv.vcol += skipped_cells;
+	    skipped_cells = 0;
+	}
 
 	// Only advance the "wlv.vcol" when after the 'number' or
 	// 'relativenumber' column.