This allows you to

    :highlight link BoldComment Comment cterm=bold

It's the analog of the :syntax combine option.

This makes things much easier on color scheme designers. As in the above 
example, they can create a base highlight group (Comment) and then link a 
number of related groups to it with minor modifications (BoldComment, etc.).

If the user ever changes Comment's color, BoldComment's color changes too.

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
index a8a66a4..437cc73 100644
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -4727,7 +4727,7 @@ group, and give the color attributes only for that group.
 
 To set a link:
 
-    :hi[ghlight][!] [default] link {from-group} {to-group}
+    :hi[ghlight][!] [default] link {from-group} {to-group} {key}={attr} ..
 
 To remove a link:
 
@@ -4736,6 +4736,8 @@ To remove a link:
 Notes:							*E414*
 - If the {from-group} and/or {to-group} doesn't exist, it is created.  You
   don't get an error message for a non-existing group.
+- Settings given in the {key}={attr} list take precedence over the same
+  variables set in {to-group}.
 - As soon as you use a ":highlight" command for a linked group, the link is
   removed.
 - If there are already highlight settings for the {from-group}, the link is
diff --git a/src/syntax.c b/src/syntax.c
index abaa025..32258a9 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -59,10 +59,11 @@ struct hl_group
 #endif
 };
 
-#define SG_TERM		1	/* term has been set */
-#define SG_CTERM	2	/* cterm has been set */
-#define SG_GUI		4	/* gui has been set */
-#define SG_LINK		8	/* link has been set */
+#define SG_TERM		0x01	/* term has been set */
+#define SG_CTERM	0x02	/* cterm has been set */
+#define SG_GUI		0x04	/* gui has been set */
+#define SG_LINK		0x08	/* link has been set */
+#define SG_INHERIT	0x10	/* link has been set */
 
 static garray_T highlight_ga;	/* highlight groups for 'highlight' option */
 
@@ -4015,7 +4016,10 @@ syn_list_one(id, syncing, link_only)
     if (HL_TABLE()[id - 1].sg_link && (did_header || link_only) && !got_int)
     {
 	(void)syn_list_header(did_header, 999, id);
-	msg_puts_attr((char_u *)"links to", attr);
+	if (HL_TABLE()[id - 1].sg_set & SG_INHERIT)
+	    msg_puts_attr((char_u *)"inherits from", attr);
+	else
+	    msg_puts_attr((char_u *)"links to", attr);
 	msg_putchar(' ');
 	msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name);
     }
@@ -6931,71 +6935,6 @@ do_highlight(line, forceit, init)
 	return;
     }
 
-    /*
-     * Handle ":highlight link {from} {to}" command.
-     */
-    if (dolink)
-    {
-	char_u	    *from_start = linep;
-	char_u	    *from_end;
-	char_u	    *to_start;
-	char_u	    *to_end;
-	int	    from_id;
-	int	    to_id;
-
-	from_end = skiptowhite(from_start);
-	to_start = skipwhite(from_end);
-	to_end	 = skiptowhite(to_start);
-
-	if (ends_excmd(*from_start) || ends_excmd(*to_start))
-	{
-	    EMSG2(_("E412: Not enough arguments: \":highlight link %s\""),
-								  from_start);
-	    return;
-	}
-
-	if (!ends_excmd(*skipwhite(to_end)))
-	{
-	    EMSG2(_("E413: Too many arguments: \":highlight link %s\""), from_start);
-	    return;
-	}
-
-	from_id = syn_check_group(from_start, (int)(from_end - from_start));
-	if (STRNCMP(to_start, "NONE", 4) == 0)
-	    to_id = 0;
-	else
-	    to_id = syn_check_group(to_start, (int)(to_end - to_start));
-
-	if (from_id > 0 && (!init || HL_TABLE()[from_id - 1].sg_set == 0))
-	{
-	    /*
-	     * Don't allow a link when there already is some highlighting
-	     * for the group, unless '!' is used
-	     */
-	    if (to_id > 0 && !forceit && !init
-				   && hl_has_settings(from_id - 1, dodefault))
-	    {
-		if (sourcing_name == NULL && !dodefault)
-		    EMSG(_("E414: group has settings, highlight link ignored"));
-	    }
-	    else
-	    {
-		if (!init)
-		    HL_TABLE()[from_id - 1].sg_set |= SG_LINK;
-		HL_TABLE()[from_id - 1].sg_link = to_id;
-#ifdef FEAT_EVAL
-		HL_TABLE()[from_id - 1].sg_scriptID = current_SID;
-#endif
-		redraw_all_later(SOME_VALID);
-	    }
-	}
-
-	/* Only call highlight_changed() once, after sourcing a syntax file */
-	need_highlight_changed = TRUE;
-
-	return;
-    }
-
     if (doclear)
     {
 	/*
@@ -7074,7 +7013,18 @@ do_highlight(line, forceit, init)
     /*
      * Find the group name in the table.  If it does not exist yet, add it.
      */
-    id = syn_check_group(line, (int)(name_end - line));
+    if (dolink)
+    {
+	/*
+	 * If we're linking the current name is 'link', not the highlight group.
+	 * Isolate the actual highlight group.
+	 */
+	name_end = skiptowhite(linep);
+	id = syn_check_group(linep, (int)(name_end - linep));
+	linep = skipwhite(name_end);
+    }
+    else
+	id = syn_check_group(line, (int)(name_end - line));
     if (id == 0)			/* failed (out of memory) */
 	return;
     idx = id - 1;			/* index is ID minus one */
@@ -7083,6 +7033,50 @@ do_highlight(line, forceit, init)
     if (dodefault && hl_has_settings(idx, TRUE))
 	return;
 
+    /*
+     * Handle the 'highlight link {child} {parent}' command.
+     */
+    if (dolink)
+    {
+	char_u	    *parent_end;
+	int	    parent_id;
+
+	parent_end = skiptowhite(linep);
+
+	if (ends_excmd(*linep))
+	{
+	    EMSG2(_("E412: Not enough arguments: \":highlight %s\""), line);
+	    return;
+	}
+
+	if (STRNCMP(linep, "NONE", 4) == 0)
+	    parent_id = 0;
+	else
+	    parent_id = syn_check_group(linep, (int)(parent_end - linep));
+
+	if (!init || HL_TABLE()[idx].sg_set == 0)
+	{
+	    /*
+	     * Don't allow a link when there already is some highlighting
+	     * for the group, unless '!' is used
+	     */
+	    if (parent_id > 0 && !forceit && !init
+				   && hl_has_settings(idx, dodefault))
+	    {
+		if (sourcing_name == NULL && !dodefault)
+		    EMSG(_("E414: group has settings, highlight inherit ignored"));
+	    }
+	    else
+	    {
+		if (!init)
+		    HL_TABLE()[idx].sg_set |= SG_LINK;
+		HL_TABLE()[idx].sg_link = parent_id;
+	    }
+	}
+
+	linep = skipwhite(parent_end);
+    }
+
     if (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0)
 	is_normal_group = TRUE;
 #ifdef FEAT_GUI_X11
@@ -7698,10 +7692,13 @@ do_highlight(line, forceit, init)
 	}
 
 	/*
-	 * When highlighting has been given for a group, don't link it.
+	 * When highlighting has been given for a group mark it as an inheritor.
 	 */
 	if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK))
-	    HL_TABLE()[idx].sg_link = 0;
+	    if (dolink)
+		HL_TABLE()[idx].sg_set |= SG_INHERIT;
+	    else
+		HL_TABLE()[idx].sg_link = 0;
 
 	/*
 	 * Continue with next argument.
@@ -8569,7 +8566,10 @@ highlight_list_one(id)
     {
 	(void)syn_list_header(didh, 9999, id);
 	didh = TRUE;
-	msg_puts_attr((char_u *)"links to", hl_attr(HLF_D));
+	if (sgp->sg_set & SG_INHERIT)
+	    msg_puts_attr((char_u *)"inherits from", hl_attr(HLF_D));
+	else
+	    msg_puts_attr((char_u *)"links to", hl_attr(HLF_D));
 	msg_putchar(' ');
 	msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name);
     }
@@ -9074,6 +9074,28 @@ syn_unadd_group()
 }
 
 /*
+ * Helper function to get the appropriate attr from an hl_group.
+ */
+    int
+sg_getattr(sgp)
+    struct hl_group*	sgp;
+{
+#ifdef FEAT_GUI
+    /*
+     * Only use GUI attr when the GUI is being used.
+     */
+    if (gui.in_use)
+	return sgp->sg_gui_attr;
+    else
+#endif
+	if (t_colors > 1)
+	    return sgp->sg_cterm_attr;
+	else
+	    return sgp->sg_term_attr;
+}
+
+
+/*
  * Translate a group ID to highlight attributes.
  */
     int
@@ -9082,23 +9104,28 @@ syn_id2attr(hl_id)
 {
     int			attr;
     struct hl_group	*sgp;
+    int			count;
 
     hl_id = syn_get_final_id(hl_id);
     sgp = &HL_TABLE()[hl_id - 1];	    /* index is ID minus one */
 
-#ifdef FEAT_GUI
     /*
-     * Only use GUI attr when the GUI is being used.
+     * Accumulate attributes from all inheriting links up to the final link.
+     * Look out for loops! Break after 100 links.
      */
-    if (gui.in_use)
-	attr = sgp->sg_gui_attr;
+    if (sgp->sg_set & SG_INHERIT)
+    {
+	attr = 0;
+	for (count = 100; --count >= 0; )
+	{
+	    attr = hl_combine_attr(sg_getattr(sgp), attr);
+	    if (sgp->sg_link == 0 || sgp->sg_link > highlight_ga.ga_len)
+		break;
+	    sgp = &HL_TABLE()[sgp->sg_link - 1];
+	}
+    }
     else
-#endif
-	if (t_colors > 1)
-	    attr = sgp->sg_cterm_attr;
-	else
-	    attr = sgp->sg_term_attr;
-
+	attr = sg_getattr(sgp);
     return attr;
 }
 
@@ -9114,13 +9141,39 @@ syn_id2colors(hl_id, fgp, bgp)
     guicolor_T	*bgp;
 {
     struct hl_group	*sgp;
+    int			attr;
+    int			count;
 
     hl_id = syn_get_final_id(hl_id);
     sgp = &HL_TABLE()[hl_id - 1];	    /* index is ID minus one */
 
-    *fgp = sgp->sg_gui_fg;
-    *bgp = sgp->sg_gui_bg;
-    return sgp->sg_gui;
+    /*
+     * If it's an inheritor group and some colors aren't set, keep looking up
+     * the chain for the colors.
+     * Look out for loops! Break after 100 links.
+     */
+    if (sgp->sg_set & SG_INHERIT)
+    {
+	attr = 0;
+	for (count = 100; --count >= 0; )
+	{
+	    attr = hl_combine_attr(sgp->sg_gui, attr);
+	    if (*fgp == INVALCOLOR)
+		*fgp = sgp->sg_gui_fg;
+	    if (*bgp == INVALCOLOR)
+		*bgp = sgp->sg_gui_fg;
+	    if (sgp->sg_link == 0 || sgp->sg_link > highlight_ga.ga_len)
+		break;
+	    sgp = &HL_TABLE()[sgp->sg_link - 1];
+	}
+    }
+    else
+    {
+	*fgp = sgp->sg_gui_fg;
+	*bgp = sgp->sg_gui_bg;
+	attr = sgp->sg_gui;
+    }
+    return attr;
 }
 #endif
 
@@ -9144,7 +9197,8 @@ syn_get_final_id(hl_id)
     for (count = 100; --count >= 0; )
     {
 	sgp = &HL_TABLE()[hl_id - 1];	    /* index is ID minus one */
-	if (sgp->sg_link == 0 || sgp->sg_link > highlight_ga.ga_len)
+	if (sgp->sg_set & SG_INHERIT
+		|| sgp->sg_link == 0 || sgp->sg_link > highlight_ga.ga_len)
 	    break;
 	hl_id = sgp->sg_link;
     }

Raspunde prin e-mail lui