> I like the idea, but I would prefer to use += and -=, just like :set.

Done.

> Also, can you write a test for correct behavior?

Added += and -= tests to test51.

I've split the "src/" diff into a "src/syntax.c" diff and a "src/testdir/" 
diff. Let me know if you prefer the diffs split up differently in the future.

> The documentation should mention what happens when trying to remove a
> 
> value that isn't there.  Is it a warning, error, or ignored?

It's ignored. I think this is the correct behavior, it allows you to do

highlight Unbold term-=bold

and apply it to any syntax group without worrying about whether or not it will 
apply.

Docs have been updated.

> The error for unexpected plus sign should be put in a function instead
> 
> of writing that code several times.

I extracted it into a function. It's not the cleanest, because the block of 
code has to set the local 'error' variable and do a break. I took the route of 
least replication.

-- 
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 -r 0d0dd54bb0be runtime/doc/syntax.txt
--- a/runtime/doc/syntax.txt	Sun Dec 02 01:21:06 2012 -0800
+++ b/runtime/doc/syntax.txt	Sun Dec 02 10:31:03 2012 -0800
@@ -4337,6 +4337,8 @@
 					*bold* *underline* *undercurl*
 					*inverse* *italic* *standout*
 term={attr-list}			*attr-list* *highlight-term* *E418*
+term+={attr-list}
+term-={attr-list}
 	attr-list is a comma separated list (without spaces) of the
 	following items (in any order):
 		bold
@@ -4354,6 +4356,18 @@
 	then "underline" is used.  In general "undercurl" is only available in
 	the GUI.  The color is set with |highlight-guisp|.
 
+	If += is used {attr-list} is appended to any previously set attr
+	list for the syntax group. For example >
+
+		highlight Comment term=underline termfg=green
+		highlight Comment term+=italic
+
+	< makes the Comment group use both bold and italic.
+
+	Similarly, -= can be used to remove attributes from existing
+	attribute lists. Removing an attribute that is not present has no
+	effect.
+
 start={term-list}				*highlight-start* *E422*
 stop={term-list}				*term-list* *highlight-stop*
 	These lists of terminal codes can be used to get
@@ -4386,6 +4400,8 @@
 2. highlight arguments for color terminals
 
 cterm={attr-list}					*highlight-cterm*
+cterm+={atttr-list}
+cterm-={atttr-list}
 	See above for the description of {attr-list} |attr-list|.
 	The "cterm" argument is likely to be different from "term", when
 	colors are used.  For example, in a normal terminal comments could
@@ -4483,6 +4499,8 @@
 3. highlight arguments for the GUI
 
 gui={attr-list}						*highlight-gui*
+gui+={attr-list}
+gui-={attr-list}
 	These give the attributes to use in the GUI mode.
 	See |attr-list| for a description.
 	Note that "bold" can be used here and by using a bold font.  They
diff -r 0d0dd54bb0be runtime/syntax/vim.vim
--- a/runtime/syntax/vim.vim	Sun Dec 02 01:21:06 2012 -0800
+++ b/runtime/syntax/vim.vim	Sun Dec 02 10:31:03 2012 -0800
@@ -509,10 +509,13 @@
  syn match	vimHiKeyError	contained	"\i\+="he=e-1
 endif
 syn match	vimHiTerm	contained	"\cterm="he=e-1		nextgroup=vimHiAttribList
+syn match	vimHiTerm	contained	"\cterm[+-]="he=e-2	nextgroup=vimHiAttribList
 syn match	vimHiStartStop	contained	"\c\(start\|stop\)="he=e-1	nextgroup=vimHiTermcap,vimOption
 syn match	vimHiCTerm	contained	"\ccterm="he=e-1		nextgroup=vimHiAttribList
+syn match	vimHiCTerm	contained	"\ccterm[+-]="he=e-2	nextgroup=vimHiAttribList
 syn match	vimHiCtermFgBg	contained	"\ccterm[fb]g="he=e-1	nextgroup=vimHiNmbr,vimHiCtermColor,vimFgBgAttrib,vimHiCtermError
 syn match	vimHiGui	contained	"\cgui="he=e-1		nextgroup=vimHiAttribList
+syn match	vimHiGui	contained	"\cgui[+-]="he=e-2	nextgroup=vimHiAttribList
 syn match	vimHiGuiFont	contained	"\cfont="he=e-1		nextgroup=vimHiFontname
 syn match	vimHiGuiFgBg	contained	"\cgui\%([fb]g\|sp\)="he=e-1	nextgroup=vimHiGroup,vimHiGuiFontname,vimHiGuiRgb,vimFgBgAttrib
 syn match	vimHiTermcap	contained	"\S\+"		contains=vimNotation
diff -r 0d0dd54bb0be src/testdir/test51.in
--- a/src/testdir/test51.in	Sun Dec 02 01:21:06 2012 -0800
+++ b/src/testdir/test51.in	Sun Dec 02 10:34:05 2012 -0800
@@ -10,10 +10,19 @@
 :hi NewGroup term=bold cterm=italic ctermfg=DarkBlue ctermbg=Grey gui= guifg=#00ff00 guibg=Cyan
 :hi Group2 term= cterm=
 :hi Group3 term=underline cterm=bold
+:hi Group4 term=bold
+:hi Group4 term+=italic
+:hi Group5 term=underline,italic
+:hi Group5 term-=underline
+:hi Group6 term=bold
+:hi Group6 term+=italic term-=bold
 :redir! >test.out
 :hi NewGroup
 :hi Group2
 :hi Group3
+:hi Group4
+:hi Group5
+:hi Group6
 :hi clear NewGroup
 :hi NewGroup
 :hi Group2
diff -r 0d0dd54bb0be src/testdir/test51.ok
--- a/src/testdir/test51.ok	Sun Dec 02 01:21:06 2012 -0800
+++ b/src/testdir/test51.ok	Sun Dec 02 10:34:05 2012 -0800
@@ -6,6 +6,12 @@
 
 Group3         xxx term=underline cterm=bold
 
+Group4         xxx term=bold,italic
+
+Group5         xxx term=italic
+
+Group6         xxx term=italic
+
 
 NewGroup       xxx cleared
 
diff -r 538ff809ae53 src/syntax.c
--- a/src/syntax.c	Thu Nov 29 20:10:00 2012 +0100
+++ b/src/syntax.c	Sun Dec 02 11:06:33 2012 -0800
@@ -64,6 +64,10 @@
 #define SG_GUI		4	/* gui has been set */
 #define SG_LINK		8	/* link has been set */
 
+#define ATTR_SET	1	/* Set attributes. */
+#define ATTR_ADD	2	/* Add attributes. */
+#define ATTR_REMOVE	3	/* Remove attributes. */
+
 static garray_T highlight_ga;	/* highlight groups for 'highlight' option */
 
 #define HL_TABLE() ((struct hl_group *)((highlight_ga.ga_data)))
@@ -6849,6 +6853,7 @@
     int		attr;
     int		id;
     int		idx;
+    int		attrmode;
     int		dodefault = FALSE;
     int		doclear = FALSE;
     int		dolink = FALSE;
@@ -7089,9 +7094,9 @@
       while (!ends_excmd(*linep))
       {
 	key_start = linep;
-	if (*linep == '=')
-	{
-	    EMSG2(_("E415: unexpected equal sign: %s"), key_start);
+	if (*linep == '+' || *linep == '-' || *linep == '=')
+	{
+	    EMSG2(_("E415: unexpected operator: %s"), key_start);
 	    error = TRUE;
 	    break;
 	}
@@ -7100,7 +7105,8 @@
 	 * Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg" or
 	 * "guibg").
 	 */
-	while (*linep && !vim_iswhite(*linep) && *linep != '=')
+	while (*linep && !vim_iswhite(*linep)
+		&& *linep != '=' && *linep != '+' && *linep != '-')
 	    ++linep;
 	vim_free(key);
 	key = vim_strnsave_up(key_start, (int)(linep - key_start));
@@ -7123,15 +7129,29 @@
 	}
 
 	/*
-	 * Check for the equal sign.
+	 * Check for the operator.
 	 */
-	if (*linep != '=')
-	{
-	    EMSG2(_("E416: missing equal sign: %s"), key_start);
+	if (STRNCMP(linep, "+=", 2) == 0)
+	{
+	    attrmode = ATTR_ADD;
+	    linep += 2;
+	}
+	else if (STRNCMP(linep, "-=", 2) == 0)
+	{
+	    attrmode = ATTR_REMOVE;
+	    linep += 2;
+	}
+	else if (*linep == '=')
+	{
+	    attrmode = ATTR_SET;
+	    ++linep;
+	}
+	else
+	{
+	    EMSG2(_("E416: missing operator: %s"), key_start);
 	    error = TRUE;
 	    break;
 	}
-	++linep;
 
 	/*
 	 * Isolate the argument.
@@ -7207,7 +7227,12 @@
 		{
 		    if (!init)
 			HL_TABLE()[idx].sg_set |= SG_TERM;
-		    HL_TABLE()[idx].sg_term = attr;
+		    if (attrmode == ATTR_ADD)
+			HL_TABLE()[idx].sg_term |= attr;
+		    else if (attrmode == ATTR_REMOVE)
+			HL_TABLE()[idx].sg_term &= ~attr;
+		    else
+			HL_TABLE()[idx].sg_term = attr;
 		}
 	    }
 	    else if (*key == 'C')
@@ -7216,7 +7241,12 @@
 		{
 		    if (!init)
 			HL_TABLE()[idx].sg_set |= SG_CTERM;
-		    HL_TABLE()[idx].sg_cterm = attr;
+		    if (attrmode == ATTR_ADD)
+			HL_TABLE()[idx].sg_cterm |= attr;
+		    else if (attrmode == ATTR_REMOVE)
+			HL_TABLE()[idx].sg_cterm &= ~attr;
+		    else
+			HL_TABLE()[idx].sg_cterm = attr;
 		    HL_TABLE()[idx].sg_cterm_bold = FALSE;
 		}
 	    }
@@ -7227,13 +7257,22 @@
 		{
 		    if (!init)
 			HL_TABLE()[idx].sg_set |= SG_GUI;
-		    HL_TABLE()[idx].sg_gui = attr;
+		    if (attrmode == ATTR_ADD)
+			HL_TABLE()[idx].sg_gui |= attr;
+		    else if (attrmode == ATTR_REMOVE)
+			HL_TABLE()[idx].sg_gui &= ~attr;
+		    else
+			HL_TABLE()[idx].sg_gui = attr;
 		}
 	    }
 #endif
 	}
 	else if (STRCMP(key, "FONT") == 0)
 	{
+	    /* Fonts can not be combined. */
+	    if (!require_set_operation(attrmode, key_start, &error))
+		break;
+
 	    /* in non-GUI fonts are simply ignored */
 #ifdef FEAT_GUI
 	    if (!gui.shell_created)
@@ -7288,6 +7327,10 @@
 	}
 	else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0)
 	{
+	    /* Colors can not be combined. */
+	    if (!require_set_operation(attrmode, key_start, &error))
+		break;
+
 	  if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM))
 	  {
 	    if (!init)
@@ -7494,6 +7537,10 @@
 	}
 	else if (STRCMP(key, "GUIFG") == 0)
 	{
+	    /* Colors can not be combined. */
+	    if (!require_set_operation(attrmode, key_start, &error))
+		break;
+
 #if defined(FEAT_GUI) || defined(FEAT_EVAL)
 	    if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
 	    {
@@ -7531,6 +7578,10 @@
 	}
 	else if (STRCMP(key, "GUIBG") == 0)
 	{
+	    /* Colors can not be combined. */
+	    if (!require_set_operation(attrmode, key_start, &error))
+		break;
+
 #if defined(FEAT_GUI) || defined(FEAT_EVAL)
 	    if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
 	    {
@@ -7568,6 +7619,10 @@
 	}
 	else if (STRCMP(key, "GUISP") == 0)
 	{
+	    /* Colors can not be combined. */
+	    if (!require_set_operation(attrmode, key_start, &error))
+		break;
+
 #if defined(FEAT_GUI) || defined(FEAT_EVAL)
 	    if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
 	    {
@@ -7593,6 +7648,9 @@
 	}
 	else if (STRCMP(key, "START") == 0 || STRCMP(key, "STOP") == 0)
 	{
+	    if (!require_set_operation(attrmode, key_start, &error))
+		break;
+
 	    char_u	buf[100];
 	    char_u	*tname;
 
@@ -7748,6 +7806,17 @@
     need_highlight_changed = TRUE;
 }
 
+int
+require_set_operation(int attrmode, char* context, int *error)
+{
+    if (attrmode != ATTR_SET)
+    {
+	EMSG2(_("E415: invalid operator: %s"), context);
+	*error = TRUE;
+    }
+    return attrmode == ATTR_SET;
+}
+
 #if defined(EXITFREE) || defined(PROTO)
     void
 free_highlight()

Raspunde prin e-mail lui