patch 8.2.3664: cannot adjust sign highlighting for 'cursorline'

Problem:    Cannot adjust sign highlighting for 'cursorline'.
Solution:   Add CursorLineSign and CursorLineFold highlight groups.
            (Gregory Anders, closes #9201)
diff --git a/src/drawline.c b/src/drawline.c
index 7d6f669..e68a602 100644
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -77,6 +77,17 @@
 
 #ifdef FEAT_SIGNS
 /*
+ * Return TRUE if CursorLineSign highlight is to be used.
+ */
+    static int
+use_cursor_line_sign(win_T *wp, linenr_T lnum)
+{
+    return wp->w_p_cul
+	    && lnum == wp->w_cursor.lnum
+	    && (wp->w_p_culopt_flags & CULOPT_NBR);
+}
+
+/*
  * Get information needed to display the sign in line 'lnum' in window 'wp'.
  * If 'nrcol' is TRUE, the sign is going to be displayed in the number column.
  * Otherwise the sign is going to be displayed in the sign column.
@@ -85,7 +96,7 @@
 get_sign_display_info(
 	int		nrcol,
 	win_T		*wp,
-	linenr_T	lnum UNUSED,
+	linenr_T	lnum,
 	sign_attrs_T	*sattr,
 	int		wcr_attr,
 	int		row,
@@ -111,7 +122,10 @@
 	*n_extrap = number_width(wp) + 1;
     else
     {
-	*char_attrp = hl_combine_attr(wcr_attr, HL_ATTR(HLF_SC));
+	if (use_cursor_line_sign(wp, lnum))
+	    *char_attrp = hl_combine_attr(wcr_attr, HL_ATTR(HLF_CLS));
+	else
+	    *char_attrp = hl_combine_attr(wcr_attr, HL_ATTR(HLF_SC));
 	*n_extrap = 2;
     }
 
@@ -176,7 +190,11 @@
 		    *c_finalp = NUL;
 		    *n_extrap = (int)STRLEN(*pp_extra);
 		}
-		*char_attrp = sattr->sat_texthl;
+
+		if (use_cursor_line_sign(wp, lnum) && sattr->sat_culhl > 0)
+		    *char_attrp = sattr->sat_culhl;
+		else
+		    *char_attrp = sattr->sat_texthl;
 	    }
     }
 }
@@ -1051,7 +1069,12 @@
 			p_extra = p_extra_free;
 			c_extra = NUL;
 			c_final = NUL;
-			char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_FC));
+			if (use_cursor_line_sign(wp, lnum))
+			    char_attr =
+				   hl_combine_attr(wcr_attr, HL_ATTR(HLF_CLF));
+			else
+			    char_attr =
+				    hl_combine_attr(wcr_attr, HL_ATTR(HLF_FC));
 		    }
 		}
 	    }
diff --git a/src/highlight.c b/src/highlight.c
index 77ad0bc..fe4f089 100644
--- a/src/highlight.c
+++ b/src/highlight.c
@@ -153,6 +153,8 @@
     "lCursor guibg=fg guifg=bg", // should be different, but what?
 #endif
     "default link QuickFixLine Search",
+    "default link CursorLineSign SignColumn",
+    "default link CursorLineFold FoldColumn",
     CENT("Normal cterm=NONE", "Normal gui=NONE"),
     NULL
 };
diff --git a/src/optiondefs.h b/src/optiondefs.h
index d85c233..d46cfad 100644
--- a/src/optiondefs.h
+++ b/src/optiondefs.h
@@ -298,7 +298,7 @@
 # define ISP_LATIN1 (char_u *)"@,161-255"
 #endif
 
-# define HIGHLIGHT_INIT "8:SpecialKey,~:EndOfBuffer,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow,N:CursorLineNr,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC"
+# define HIGHLIGHT_INIT "8:SpecialKey,~:EndOfBuffer,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow,N:CursorLineNr,G:CursorLineSign,O:CursorLineFold,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC"
 
 // Default python version for pyx* commands
 #if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
diff --git a/src/popupwin.c b/src/popupwin.c
index d5f8d26..0ff26e1 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -632,7 +632,7 @@
 
 	    if (syn_name2id((char_u *)linehl) == 0)
 		linehl = "PmenuSel";
-	    sign_define_by_name(sign_name, NULL, (char_u *)linehl, NULL, NULL);
+	    sign_define_by_name(sign_name, NULL, (char_u *)linehl, NULL, NULL, NULL);
 	}
 
 	sign_place(&sign_id, (char_u *)"PopUpMenu", sign_name,
diff --git a/src/proto/sign.pro b/src/proto/sign.pro
index bda8372..4e8abb3 100644
--- a/src/proto/sign.pro
+++ b/src/proto/sign.pro
@@ -8,7 +8,7 @@
 int buf_signcount(buf_T *buf, linenr_T lnum);
 void buf_delete_signs(buf_T *buf, char_u *group);
 void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after);
-int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl);
+int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl, char_u *culhl);
 int sign_exists_by_name(char_u *name);
 int sign_undefine_by_name(char_u *name, int give_error);
 int sign_place(int *sign_id, char_u *sign_group, char_u *sign_name, buf_T *buf, linenr_T lnum, int prio);
diff --git a/src/sign.c b/src/sign.c
index ea584df..a4c8967 100644
--- a/src/sign.c
+++ b/src/sign.c
@@ -32,6 +32,7 @@
     char_u	*sn_text;	// text used instead of pixmap
     int		sn_line_hl;	// highlight ID for line
     int		sn_text_hl;	// highlight ID for text
+    int		sn_cul_hl;	// highlight ID for text on current line when 'cursorline' is set
 };
 
 static sign_T	*first_sign = NULL;
@@ -517,6 +518,8 @@
 		sattr->sat_texthl = syn_id2attr(sp->sn_text_hl);
 	    if (sp->sn_line_hl > 0)
 		sattr->sat_linehl = syn_id2attr(sp->sn_line_hl);
+	    if (sp->sn_cul_hl > 0)
+		sattr->sat_culhl = syn_id2attr(sp->sn_cul_hl);
 	    sattr->sat_priority = sign->se_priority;
 
 	    // If there is another sign next with the same priority, may
@@ -540,6 +543,8 @@
 			sattr->sat_texthl = syn_id2attr(next_sp->sn_text_hl);
 		    if (sp->sn_line_hl <= 0 && next_sp->sn_line_hl > 0)
 			sattr->sat_linehl = syn_id2attr(next_sp->sn_line_hl);
+		    if (sp->sn_cul_hl <= 0 && next_sp->sn_cul_hl > 0)
+			sattr->sat_culhl = syn_id2attr(next_sp->sn_cul_hl);
 		}
 	    }
 	    return TRUE;
@@ -1035,7 +1040,8 @@
 	char_u	*icon,
 	char_u	*linehl,
 	char_u	*text,
-	char_u	*texthl)
+	char_u	*texthl,
+	char_u	*culhl)
 {
     sign_T	*sp_prev;
     sign_T	*sp;
@@ -1077,6 +1083,9 @@
     if (texthl != NULL)
 	sp->sn_text_hl = syn_check_group(texthl, (int)STRLEN(texthl));
 
+    if (culhl != NULL)
+	sp->sn_cul_hl = syn_check_group(culhl, (int)STRLEN(culhl));
+
     return OK;
 }
 
@@ -1298,6 +1307,7 @@
     char_u	*text = NULL;
     char_u	*linehl = NULL;
     char_u	*texthl = NULL;
+    char_u	*culhl = NULL;
     int failed = FALSE;
 
     // set values for a defined sign.
@@ -1327,6 +1337,11 @@
 	    arg += 7;
 	    texthl = vim_strnsave(arg, p - arg);
 	}
+	else if (STRNCMP(arg, "culhl=", 6) == 0)
+	{
+	    arg += 6;
+	    culhl = vim_strnsave(arg, p - arg);
+	}
 	else
 	{
 	    semsg(_(e_invarg2), arg);
@@ -1336,12 +1351,13 @@
     }
 
     if (!failed)
-	sign_define_by_name(sign_name, icon, linehl, text, texthl);
+	sign_define_by_name(sign_name, icon, linehl, text, texthl, culhl);
 
     vim_free(icon);
     vim_free(text);
     vim_free(linehl);
     vim_free(texthl);
+    vim_free(culhl);
 }
 
 /*
@@ -1712,6 +1728,13 @@
 	    p = (char_u *)"NONE";
 	dict_add_string(retdict, "texthl", (char_u *)p);
     }
+    if (sp->sn_cul_hl > 0)
+    {
+	p = get_highlight_name_ext(NULL, sp->sn_cul_hl - 1, FALSE);
+	if (p == NULL)
+	    p = (char_u *)"NONE";
+	dict_add_string(retdict, "culhl", (char_u *)p);
+    }
 }
 
 /*
@@ -1883,6 +1906,15 @@
 	else
 	    msg_puts((char *)p);
     }
+    if (sp->sn_cul_hl > 0)
+    {
+	msg_puts(" culhl=");
+	p = get_highlight_name_ext(NULL, sp->sn_cul_hl - 1, FALSE);
+	if (p == NULL)
+	    msg_puts("NONE");
+	else
+	    msg_puts((char *)p);
+    }
 }
 
 /*
@@ -2173,6 +2205,7 @@
     char_u	*linehl = NULL;
     char_u	*text = NULL;
     char_u	*texthl = NULL;
+    char_u	*culhl = NULL;
     int		retval = -1;
 
     if (name_arg == NULL)
@@ -2191,9 +2224,10 @@
 	linehl = dict_get_string(dict, (char_u *)"linehl", TRUE);
 	text = dict_get_string(dict, (char_u *)"text", TRUE);
 	texthl = dict_get_string(dict, (char_u *)"texthl", TRUE);
+	culhl = dict_get_string(dict, (char_u *)"culhl", TRUE);
     }
 
-    if (sign_define_by_name(name, icon, linehl, text, texthl) == OK)
+    if (sign_define_by_name(name, icon, linehl, text, texthl, culhl) == OK)
 	retval = 0;
 
 cleanup:
@@ -2202,6 +2236,7 @@
     vim_free(linehl);
     vim_free(text);
     vim_free(texthl);
+    vim_free(culhl);
 
     return retval;
 }
diff --git a/src/structs.h b/src/structs.h
index 9e0f64e..d9d3e30 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -853,6 +853,7 @@
     char_u	*sat_text;
     int		sat_texthl;
     int		sat_linehl;
+    int		sat_culhl;
     int		sat_priority;
 } sign_attrs_T;
 
diff --git a/src/testdir/test_signs.vim b/src/testdir/test_signs.vim
index b77725c..80f7160 100644
--- a/src/testdir/test_signs.vim
+++ b/src/testdir/test_signs.vim
@@ -15,13 +15,13 @@
   " the icon name when listing signs.
   sign define Sign1 text=x
 
-  call Sign_command_ignore_error('sign define Sign2 text=xy texthl=Title linehl=Error icon=../../pixmaps/stock_vim_find_help.png')
+  call Sign_command_ignore_error('sign define Sign2 text=xy texthl=Title linehl=Error culhl=Search icon=../../pixmaps/stock_vim_find_help.png')
 
   " Test listing signs.
   let a=execute('sign list')
   call assert_match('^\nsign Sign1 text=x \nsign Sign2 ' .
 	      \ 'icon=../../pixmaps/stock_vim_find_help.png .*text=xy ' .
-	      \ 'linehl=Error texthl=Title$', a)
+	      \ 'linehl=Error texthl=Title culhl=Search$', a)
 
   let a=execute('sign list Sign1')
   call assert_equal("\nsign Sign1 text=x ", a)
@@ -392,19 +392,21 @@
   call sign_undefine()
 
   " Tests for sign_define()
-  let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
+  let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error',
+              \ 'culhl': 'Visual'}
   call assert_equal(0, "sign1"->sign_define(attr))
   call assert_equal([{'name' : 'sign1', 'texthl' : 'Error',
-	      \ 'linehl' : 'Search', 'text' : '=>'}], sign_getdefined())
+	      \ 'linehl' : 'Search', 'culhl' : 'Visual', 'text' : '=>'}],
+              \ sign_getdefined())
 
   " Define a new sign without attributes and then update it
   call sign_define("sign2")
   let attr = {'text' : '!!', 'linehl' : 'DiffAdd', 'texthl' : 'DiffChange',
-	      \ 'icon' : 'sign2.ico'}
+	      \ 'culhl': 'DiffDelete', 'icon' : 'sign2.ico'}
   call Sign_define_ignore_error("sign2", attr)
   call assert_equal([{'name' : 'sign2', 'texthl' : 'DiffChange',
-	      \ 'linehl' : 'DiffAdd', 'text' : '!!', 'icon' : 'sign2.ico'}],
-	      \ "sign2"->sign_getdefined())
+	      \ 'linehl' : 'DiffAdd', 'culhl' : 'DiffDelete', 'text' : '!!',
+              \ 'icon' : 'sign2.ico'}], "sign2"->sign_getdefined())
 
   " Test for a sign name with digits
   call assert_equal(0, sign_define(0002, {'linehl' : 'StatusLine'}))
diff --git a/src/version.c b/src/version.c
index b4e2464..4356be1 100644
--- a/src/version.c
+++ b/src/version.c
@@ -758,6 +758,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3664,
+/**/
     3663,
 /**/
     3662,
diff --git a/src/vim.h b/src/vim.h
index 6c5a109..7c4d12c 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1411,6 +1411,8 @@
     , HLF_LNA	    // LineNrAbove
     , HLF_LNB	    // LineNrBelow
     , HLF_CLN	    // current line number
+    , HLF_CLS	    // current line sign column
+    , HLF_CLF	    // current line fold
     , HLF_R	    // return to continue message and yes/no questions
     , HLF_S	    // status lines
     , HLF_SNC	    // status lines of not-current windows
@@ -1451,7 +1453,7 @@
 // The HL_FLAGS must be in the same order as the HLF_ enums!
 // When changing this also adjust the default for 'highlight'.
 #define HL_FLAGS {'8', '~', '@', 'd', 'e', 'h', 'i', 'l', 'm', 'M', \
-		  'n', 'a', 'b', 'N', 'r', 's', 'S', 'c', 't', 'v', 'V', \
+		  'n', 'a', 'b', 'N', 'G', 'O', 'r', 's', 'S', 'c', 't', 'v', 'V', \
 		  'w', 'W', 'f', 'F', 'A', 'C', 'D', 'T', '-', '>', \
 		  'B', 'P', 'R', 'L', \
 		  '+', '=', 'x', 'X', '*', '#', '_', '!', '.', 'o', 'q', \