With this patch you can do the following:
syntax match Foo 'foo'
highlight Foo cterm=bold ctermfg=red
highlight Foo cterm+italic
and now Foo is both bold and italic.
Motivation:
http://stackoverflow.com/questions/13640538/vim-syntax-files-add-to-cterm
This makes it far easier to use terminal attributes on nested syntax regions,
e.g. to add bold to text that is already underlined without losing the color.
The patch also allows terminal attributes to be removed.
--
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 02:04:57 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,17 @@
then "underline" is used. In general "undercurl" is only available in
the GUI. The color is set with |highlight-guisp|.
+ If '+' is used in place of '=', {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.
+
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 +4399,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 +4498,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 02:04:57 2012 -0800
@@ -508,11 +508,11 @@
if !exists("g:vimsyn_noerror") && !exists("g:vimsyn_vimhikeyerror")
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-1 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-1 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-1 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/syntax.c
--- a/src/syntax.c Sun Dec 02 01:21:06 2012 -0800
+++ b/src/syntax.c Sun Dec 02 02:04:46 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;
@@ -7107,7 +7112,8 @@
* Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg" or
* "guibg").
*/
- while (*linep && !vim_iswhite(*linep) && *linep != '=' && *linep != '+')
+ while (*linep && !vim_iswhite(*linep)
+ && *linep != '=' && *linep != '+' && *linep != '-')
++linep;
vim_free(key);
key = vim_strnsave_up(key_start, (int)(linep - key_start));
@@ -7132,13 +7138,15 @@
/*
* Check for the equal sign.
*/
- if (*linep != '=' && *linep != '+')
+ if (*linep != '=' && *linep != '+' && *linep != '-')
{
EMSG2(_("E416: missing equal or plus sign: %s"), key_start);
error = TRUE;
break;
}
-
+ attrmode = *linep == '+' ? ATTR_ADD
+ : *linep == '-' ? ATTR_REMOVE
+ : ATTR_SET;
++linep;
/*
@@ -7213,9 +7221,14 @@
{
if (!init || !(HL_TABLE()[idx].sg_set & SG_TERM))
{
- if (!init || addmode)
+ 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')
@@ -7224,7 +7237,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;
}
}
@@ -7235,13 +7253,26 @@
{
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 (attrmode != ATTR_SET)
+ {
+ EMSG2(_("E415: unexpected plus sign: %s"), key_start);
+ error = TRUE;
+ break;
+ }
+
/* in non-GUI fonts are simply ignored */
#ifdef FEAT_GUI
if (!gui.shell_created)
@@ -7296,6 +7327,14 @@
}
else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0)
{
+ /* Colors can not be combined. */
+ if (attrmode != ATTR_SET)
+ {
+ EMSG2(_("E415: unexpected plus sign: %s"), key_start);
+ error = TRUE;
+ break;
+ }
+
if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM))
{
if (!init)
@@ -7502,6 +7541,14 @@
}
else if (STRCMP(key, "GUIFG") == 0)
{
+ /* Colors can not be combined. */
+ if (attrmode != ATTR_SET)
+ {
+ EMSG2(_("E415: unexpected plus sign: %s"), key_start);
+ error = TRUE;
+ break;
+ }
+
#if defined(FEAT_GUI) || defined(FEAT_EVAL)
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
{
@@ -7539,6 +7586,14 @@
}
else if (STRCMP(key, "GUIBG") == 0)
{
+ /* Colors can not be combined. */
+ if (attrmode != ATTR_SET)
+ {
+ EMSG2(_("E415: unexpected plus sign: %s"), key_start);
+ error = TRUE;
+ break;
+ }
+
#if defined(FEAT_GUI) || defined(FEAT_EVAL)
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
{
@@ -7576,6 +7631,14 @@
}
else if (STRCMP(key, "GUISP") == 0)
{
+ /* Colors can not be combined. */
+ if (attrmode != ATTR_SET)
+ {
+ EMSG2(_("E415: unexpected plus sign: %s"), key_start);
+ error = TRUE;
+ break;
+ }
+
#if defined(FEAT_GUI) || defined(FEAT_EVAL)
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
{
@@ -7601,6 +7664,14 @@
}
else if (STRCMP(key, "START") == 0 || STRCMP(key, "STOP") == 0)
{
+ /* start+ / stop+ don't make sense. */
+ if (attrmode != ATTR_SET)
+ {
+ EMSG2(_("E415: unexpected plus sign: %s"), key_start);
+ error = TRUE;
+ break;
+ }
+
char_u buf[100];
char_u *tname;