patch 8.2.3605: cannot clear and unlinke a highlight group with hlset()

Problem:    Cannot clear and unlinke a highlight group with hlset() in a
            single call.
Solution:   Add the "force" option. (Yegappan Lakshmanan, closes #9117)
diff --git a/src/highlight.c b/src/highlight.c
index a2935f5..7a32b22 100644
--- a/src/highlight.c
+++ b/src/highlight.c
@@ -4176,6 +4176,9 @@
 	link = HL_TABLE()[sgp->sg_link - 1].sg_name;
 	if (link != NULL && dict_add_string(dict, "linksto", link) == FAIL)
 	    goto error;
+
+	if (sgp->sg_deflink)
+	    dict_add_bool(dict, "default", VVAL_TRUE);
     }
     if (dict_len(dict) == 2)
 	// If only 'name' is present, then the highlight group is cleared.
@@ -4337,25 +4340,19 @@
 # ifdef FEAT_GUI
     char_u	*font;
 # endif
+    int		forceit = FALSE;
+    int		dodefault = FALSE;
+    int		done = FALSE;
 
     name = hldict_get_string(dict, (char_u *)"name", &error);
     if (name == NULL || error)
 	return FALSE;
 
-    if (dict_find(dict, (char_u *)"linksto", -1) != NULL)
-    {
-	char_u	*linksto;
+    if (dict_get_bool(dict, (char_u *)"force", VVAL_FALSE) == VVAL_TRUE)
+	forceit = TRUE;
 
-	// link highlight groups
-	linksto = hldict_get_string(dict, (char_u *)"linksto", &error);
-	if (linksto == NULL || error)
-	    return FALSE;
-
-	vim_snprintf((char *)IObuff, IOSIZE, "link %s %s", name, linksto);
-	do_highlight(IObuff, FALSE, FALSE);
-
-	return TRUE;
-    }
+    if (dict_get_bool(dict, (char_u *)"default", VVAL_FALSE) == VVAL_TRUE)
+	dodefault = TRUE;
 
     if (dict_find(dict, (char_u *)"cleared", -1) != NULL)
     {
@@ -4366,12 +4363,32 @@
 	if (cleared == TRUE)
 	{
 	    vim_snprintf((char *)IObuff, IOSIZE, "clear %s", name);
-	    do_highlight(IObuff, FALSE, FALSE);
+	    do_highlight(IObuff, forceit, FALSE);
+	    done = TRUE;
 	}
-
-	return TRUE;
     }
 
+    if (dict_find(dict, (char_u *)"linksto", -1) != NULL)
+    {
+	char_u	*linksto;
+
+	// link highlight groups
+	linksto = hldict_get_string(dict, (char_u *)"linksto", &error);
+	if (linksto == NULL || error)
+	    return FALSE;
+
+	vim_snprintf((char *)IObuff, IOSIZE, "%slink %s %s",
+				dodefault ? "default " : "", name, linksto);
+	do_highlight(IObuff, forceit, FALSE);
+
+	done = TRUE;
+    }
+
+    // If 'cleared' or 'linksto' are specified, then don't process the other
+    // attributes.
+    if (done)
+	return TRUE;
+
     start = hldict_get_string(dict, (char_u *)"start", &error);
     if (error)
 	return FALSE;
@@ -4434,7 +4451,8 @@
 	return TRUE;
 
     vim_snprintf((char *)IObuff, IOSIZE,
-	    "%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s",
+	    "%s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s",
+	    dodefault ? "default " : "",
 	    name,
 	    term_attr[0] != NUL ? "term=" : "",
 	    term_attr[0] != NUL ? term_attr : (char_u *)"",
@@ -4466,7 +4484,7 @@
 	    guisp != NULL ? guisp : (char_u *)""
 		);
 
-    do_highlight(IObuff, FALSE, FALSE);
+    do_highlight(IObuff, forceit, FALSE);
 
     return TRUE;
 }