changeset 31297:d7a532c4d18d v9.0.0982

patch 9.0.0982: 'cursorline' not drawn before virtual text below Commit: https://github.com/vim/vim/commit/45e4eead2aaf9d883bcf19db779be47ffb4fa44a Author: Bram Moolenaar <Bram@vim.org> Date: Thu Dec 1 18:38:02 2022 +0000 patch 9.0.0982: 'cursorline' not drawn before virtual text below Problem: 'cursorline' not drawn before virtual text below. Solution: Add the 'cursorline' attribute to the empty space. (closes https://github.com/vim/vim/issues/11647)
author Bram Moolenaar <Bram@vim.org>
date Thu, 01 Dec 2022 19:45:03 +0100
parents a1577c99f9a2
children 3d32836ec216
files src/drawline.c src/testdir/dumps/Test_prop_with_text_below_cul_1.dump src/testdir/test_textprop.vim src/version.c
diffstat 4 files changed, 93 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -75,6 +75,12 @@ margin_columns_win(win_T *wp, int *left_
 }
 #endif
 
+#if defined(FEAT_SIGNS) || defined(FEAT_QUICKFIX) \
+	|| defined(FEAT_SYN_HL) || defined(FEAT_DIFF)
+// using an attribute for the whole line
+# define LINE_ATTR
+#endif
+
 // structure with variables passed between win_line() and other functions
 typedef struct {
     int		draw_state;	// what to draw next
@@ -106,6 +112,9 @@ typedef struct {
 #ifdef FEAT_SYN_HL
     int		cul_attr;	// set when 'cursorline' active
 #endif
+#ifdef LINE_ATTR
+    int		line_attr;	// for the whole line, includes 'cursorline'
+#endif
 
     int		screen_line_flags;  // flags for screen_line()
 
@@ -848,8 +857,11 @@ draw_screen_line(win_T *wp, winlinevars_
 		    && (int)wp->w_virtcol <
 			 (long)wp->w_width * (wlv->row - wlv->startrow + 1) + v
 			 && wlv->lnum != wp->w_cursor.lnum)
-	    || wlv->draw_color_col
-	    || wlv->win_attr != 0)
+		|| wlv->draw_color_col
+# ifdef LINE_ATTR
+		|| wlv->line_attr != 0
+# endif
+		|| wlv->win_attr != 0)
 # ifdef FEAT_RIGHTLEFT
 	    && !wp->w_p_rl
 # endif
@@ -877,14 +889,22 @@ draw_screen_line(win_T *wp, winlinevars_
 		wlv->draw_color_col = advance_color_col(
 						   VCOL_HLC, &wlv->color_cols);
 
+	    int attr = wlv->win_attr;
 	    if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol)
-		ScreenAttrs[wlv->off++] = HL_ATTR(HLF_CUC);
+		attr = HL_ATTR(HLF_CUC);
 	    else if (wlv->draw_color_col && VCOL_HLC == *wlv->color_cols)
-		ScreenAttrs[wlv->off++] = HL_ATTR(HLF_MC);
-	    else
-		ScreenAttrs[wlv->off++] = wlv->win_attr;
-
-	    if (VCOL_HLC >= rightmost_vcol && wlv->win_attr == 0)
+		attr = HL_ATTR(HLF_MC);
+# ifdef LINE_ATTR
+	    else if (wlv->line_attr != 0)
+		attr = wlv->line_attr;
+# endif
+	    ScreenAttrs[wlv->off++] = attr;
+
+	    if (VCOL_HLC >= rightmost_vcol
+# ifdef LINE_ATTR
+		    && wlv->line_attr == 0
+# endif
+		    && wlv->win_attr == 0)
 		break;
 
 	    ++wlv->vcol;
@@ -1085,10 +1105,7 @@ win_line(
     colnr_T	leadcol = 0;		// start of leading spaces
     int		in_multispace = FALSE;	// in multiple consecutive spaces
     int		multispace_pos = 0;	// position in lcs-multispace string
-#if defined(FEAT_SIGNS) || defined(FEAT_QUICKFIX) \
-	|| defined(FEAT_SYN_HL) || defined(FEAT_DIFF)
-# define LINE_ATTR
-    int		line_attr = 0;		// attribute for the whole line
+#ifdef LINE_ATTR
     int		line_attr_save = 0;
 #endif
     int		sign_present = FALSE;
@@ -1392,16 +1409,16 @@ win_line(
 
 #ifdef LINE_ATTR
 # ifdef FEAT_SIGNS
-    // If this line has a sign with line highlighting set line_attr.
+    // If this line has a sign with line highlighting set wlv.line_attr.
     if (sign_present)
-	line_attr = wlv.sattr.sat_linehl;
+	wlv.line_attr = wlv.sattr.sat_linehl;
 # endif
 # if defined(FEAT_QUICKFIX)
     // Highlight the current line in the quickfix window.
     if (bt_quickfix(wp->w_buffer) && qf_current_entry(wp) == lnum)
-	line_attr = HL_ATTR(HLF_QFL);
+	wlv.line_attr = HL_ATTR(HLF_QFL);
 # endif
-    if (line_attr != 0)
+    if (wlv.line_attr != 0)
 	area_highlighting = TRUE;
 #endif
 
@@ -1651,7 +1668,7 @@ win_line(
 	    wlv.cul_screenline = (wp->w_p_wrap
 				   && (wp->w_p_culopt_flags & CULOPT_SCRLINE));
 
-	    // Only set line_attr here when "screenline" is not present in
+	    // Only set wlv.line_attr here when "screenline" is not present in
 	    // 'cursorlineopt'.  Otherwise it's done later.
 	    if (!wlv.cul_screenline)
 	    {
@@ -1662,9 +1679,11 @@ win_line(
 		if (sign_present && wlv.sattr.sat_linehl > 0)
 		{
 		    if (wlv.sattr.sat_priority >= 100)
-			line_attr = hl_combine_attr(wlv.cul_attr, line_attr);
+			wlv.line_attr = hl_combine_attr(
+						  wlv.cul_attr, wlv.line_attr);
 		    else
-			line_attr = hl_combine_attr(line_attr, wlv.cul_attr);
+			wlv.line_attr = hl_combine_attr(
+						  wlv.line_attr, wlv.cul_attr);
 		}
 		else
 # endif
@@ -1672,14 +1691,15 @@ win_line(
 		    // let the line attribute overrule 'cursorline', otherwise
 		    // it disappears when both have background set;
 		    // 'cursorline' can use underline or bold to make it show
-		    line_attr = hl_combine_attr(wlv.cul_attr, line_attr);
+		    wlv.line_attr = hl_combine_attr(
+						  wlv.cul_attr, wlv.line_attr);
 # else
-		    line_attr = wlv.cul_attr;
+		    wlv.line_attr = wlv.cul_attr;
 # endif
 	    }
 	    else
 	    {
-		line_attr_save = line_attr;
+		line_attr_save = wlv.line_attr;
 		margin_columns_win(wp, &left_curline_col, &right_curline_col);
 	    }
 	    area_highlighting = TRUE;
@@ -1741,7 +1761,7 @@ win_line(
 	    if (wlv.cul_screenline)
 	    {
 		wlv.cul_attr = 0;
-		line_attr = line_attr_save;
+		wlv.line_attr = line_attr_save;
 	    }
 #endif
 	    if (wlv.draw_state == WL_CMDLINE - 1 && wlv.n_extra == 0)
@@ -1805,7 +1825,7 @@ win_line(
 		&& wlv.vcol < right_curline_col)
 	{
 	    wlv.cul_attr = HL_ATTR(HLF_CUL);
-	    line_attr = wlv.cul_attr;
+	    wlv.line_attr = wlv.cul_attr;
 	}
 #endif
 
@@ -2161,13 +2181,13 @@ win_line(
 		if (wlv.diff_hlf == HLF_TXD && ptr - line > change_end
 							   && wlv.n_extra == 0)
 		    wlv.diff_hlf = HLF_CHD;		// changed line
-		line_attr = HL_ATTR(wlv.diff_hlf);
+		wlv.line_attr = HL_ATTR(wlv.diff_hlf);
 		if (wp->w_p_cul && lnum == wp->w_cursor.lnum
 			&& wp->w_p_culopt_flags != CULOPT_NBR
 			&& (!wlv.cul_screenline || (wlv.vcol >= left_curline_col
 					    && wlv.vcol <= right_curline_col)))
-		    line_attr = hl_combine_attr(
-					  line_attr, HL_ATTR(HLF_CUL));
+		    wlv.line_attr = hl_combine_attr(
+					  wlv.line_attr, HL_ATTR(HLF_CUL));
 	    }
 #endif
 
@@ -2251,7 +2271,7 @@ win_line(
 #ifdef LINE_ATTR
 	    if (area_attr != 0)
 	    {
-		wlv.char_attr = hl_combine_attr(line_attr, area_attr);
+		wlv.char_attr = hl_combine_attr(wlv.line_attr, area_attr);
 		if (!highlight_match)
 		    // let search highlight show in Visual area if possible
 		    wlv.char_attr = hl_combine_attr(search_attr, wlv.char_attr);
@@ -2261,23 +2281,23 @@ win_line(
 	    }
 	    else if (search_attr != 0)
 	    {
-		wlv.char_attr = hl_combine_attr(line_attr, search_attr);
+		wlv.char_attr = hl_combine_attr(wlv.line_attr, search_attr);
 # ifdef FEAT_SYN_HL
 		wlv.char_attr = hl_combine_attr(syntax_attr, wlv.char_attr);
 # endif
 	    }
-	    else if (line_attr != 0
+	    else if (wlv.line_attr != 0
 		    && ((wlv.fromcol == -10 && wlv.tocol == MAXCOL)
 			      || wlv.vcol < wlv.fromcol
 			      || vcol_prev < fromcol_prev
 			      || wlv.vcol >= wlv.tocol))
 	    {
-		// Use line_attr when not in the Visual or 'incsearch' area
+		// Use wlv.line_attr when not in the Visual or 'incsearch' area
 		// (area_attr may be 0 when "noinvcur" is set).
 # ifdef FEAT_SYN_HL
-		wlv.char_attr = hl_combine_attr(syntax_attr, line_attr);
+		wlv.char_attr = hl_combine_attr(syntax_attr, wlv.line_attr);
 # else
-		wlv.char_attr = line_attr;
+		wlv.char_attr = wlv.line_attr;
 # endif
 		attr_pri = FALSE;
 	    }
@@ -3051,7 +3071,7 @@ win_line(
 #  endif
 # endif
 # ifdef LINE_ATTR
-			    line_attr == 0
+			    wlv.line_attr == 0
 # endif
 		       )
 #endif
@@ -3148,7 +3168,7 @@ win_line(
 # ifdef FEAT_TERMINAL
 			    wlv.win_attr != 0 ||
 # endif
-			    line_attr != 0
+			    wlv.line_attr != 0
 			) && (
 # ifdef FEAT_RIGHTLEFT
 			    wp->w_p_rl ? (wlv.col >= 0) :
@@ -3167,11 +3187,11 @@ win_line(
 		    ++did_line_attr;
 
 		    // don't do search HL for the rest of the line
-		    if (line_attr != 0 && wlv.char_attr == search_attr
+		    if (wlv.line_attr != 0 && wlv.char_attr == search_attr
 					&& (did_line_attr > 1
 					    || (wp->w_p_list &&
 						wp->w_lcs_chars.eol > 0)))
-			wlv.char_attr = line_attr;
+			wlv.char_attr = wlv.line_attr;
 # ifdef FEAT_DIFF
 		    if (wlv.diff_hlf == HLF_TXD)
 		    {
@@ -3202,9 +3222,9 @@ win_line(
 				wlv.char_attr = hl_combine_attr(
 					      wlv.char_attr, HL_ATTR(HLF_CUL));
 			}
-			else if (line_attr)
-			    wlv.char_attr = hl_combine_attr(wlv.char_attr,
-								    line_attr);
+			else if (wlv.line_attr)
+			    wlv.char_attr = hl_combine_attr(
+						 wlv.char_attr, wlv.line_attr);
 		    }
 # endif
 		}
@@ -3325,8 +3345,8 @@ win_line(
 		   ))
 	{
 #ifdef LINE_ATTR
-	    if (line_attr)
-		wlv.char_attr = hl_combine_attr(line_attr, wlv.extra_attr);
+	    if (wlv.line_attr)
+		wlv.char_attr = hl_combine_attr(wlv.line_attr, wlv.extra_attr);
 	    else
 #endif
 		wlv.char_attr = wlv.extra_attr;
new file mode 100644
--- /dev/null
+++ b/src/testdir/dumps/Test_prop_with_text_below_cul_1.dump
@@ -0,0 +1,6 @@
+>s+8&#ffffff0|o|m|e| |t|e|x|t| @50
+@4|T+8&#ffd7ff255|h|e| |q|u|i|c|k| |b|r|o|w|n| |f|o|x| |j|u|m|p|s| |o|v|e|r| |t|h|e| |l|a|z|y| |d|o|g| +8&#ffffff0@12
+|l+0&&|a|s|t| |l|i|n|e| @50
+|~+0#4040ff13&| @58
+|~| @58
+| +0#0000000&@41|1|,|1| @10|A|l@1| 
--- a/src/testdir/test_textprop.vim
+++ b/src/testdir/test_textprop.vim
@@ -2918,6 +2918,29 @@ func Test_props_with_text_after_nowrap()
   call StopVimInTerminal(buf)
 endfunc
 
+func Test_prop_with_text_below_cul()
+  CheckRunVimInTerminal
+
+  let lines =<< trim END
+      vim9script
+
+      setline(1, ['some text', 'last line'])
+      set cursorline nowrap
+      prop_type_add('test', {highlight: 'DiffChange'})
+      prop_add(1, 0, {
+          type: 'test',
+          text: 'The quick brown fox jumps over the lazy dog',
+          text_align: 'below',
+          text_padding_left: 4,
+      })
+  END
+  call writefile(lines, 'XscriptPropsBelowCurline', 'D')
+  let buf = RunVimInTerminal('-S XscriptPropsBelowCurline', #{rows: 6, cols: 60})
+  call VerifyScreenDump(buf, 'Test_prop_with_text_below_cul_1', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
 func Test_props_with_text_below_nowrap()
   CheckRunVimInTerminal
 
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    982,
+/**/
     981,
 /**/
     980,