Motivation:

http://stackoverflow.com/questions/13640538/vim-syntax-files-add-to-cterm

Example:

    syntax region Italic start='_' end='_' modifier contains=Bold
    syntax region Bold start='\*' end='\*' modifier contains=Italic

    highlight Italic cterm=italic
    highlight Bold cterm=bold

    _this is both italic *and bold*_

The code is surprisingly simple, as vim already has a stack of syntax matches 
which it walks up to determine the attributes. It's trivial to add a flag which 
merges attributes instead of clobbering them.

I'm not sure how to add tests that test text color and format.

-- 
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 e00680fd7088 runtime/doc/syntax.txt
--- a/runtime/doc/syntax.txt	Sun Dec 02 11:32:21 2012 -0800
+++ b/runtime/doc/syntax.txt	Sun Dec 02 19:27:23 2012 -0800
@@ -3464,6 +3464,7 @@
 	contained
 	containedin
 	nextgroup
+	modifier
 	transparent
 	skipwhite
 	skipnl
@@ -3716,6 +3717,23 @@
 would include the first "Foo" and the last "Bar" in the line (see |pattern|).
 
 
+modifier						*:syn-modifier*
+
+Declares the syntax group as a modifier group. Attributes in this syntax group
+will be merged with attributes in the next matching group recursively until
+a non-modifier syntax group is found.
+
+Only terminal attributes (italic, bold, etc.) are merged; no color merging is
+performed. The colors defined in a modifier syntax group override the colors set
+in previous groups. >
+
+    syntax region Italic start="_" end="_" modifier contains=Bold
+    syntax region Bold start="\*" end="\*" modifier contains=Italic
+    highlight Italic term=italic
+    highlight Bold term=bold
+    " _The inner text is italic *and bold*_.
+
+
 skipwhite						*:syn-skipwhite*
 skipnl							*:syn-skipnl*
 skipempty						*:syn-skipempty*
@@ -3750,6 +3768,7 @@
 "contains" arguments to make that work (omitted for simplicity of the
 example).
 
+
 IMPLICIT CONCEAL					*:syn-conceal-implicit*
 
 :sy[ntax] conceal [on|off]
diff -r e00680fd7088 runtime/syntax/vim.vim
--- a/runtime/syntax/vim.vim	Sun Dec 02 11:32:21 2012 -0800
+++ b/runtime/syntax/vim.vim	Sun Dec 02 19:27:23 2012 -0800
@@ -421,14 +421,14 @@
 syn cluster	vimSynKeyGroup	contains=vimSynNextgroup,vimSynKeyOpt,vimSynKeyContainedin
 syn keyword	vimSynType	contained	keyword	skipwhite nextgroup=vimSynKeyRegion
 syn region	vimSynKeyRegion	contained oneline keepend	matchgroup=vimGroupName start="\k\+" skip="\\\\\|\\|" matchgroup=vimSep end="|\|$" contains=@vimSynKeyGroup
-syn match	vimSynKeyOpt	contained	"\<\(conceal\|contained\|transparent\|skipempty\|skipwhite\|skipnl\)\>"
+syn match	vimSynKeyOpt	contained	"\<\(conceal\|contained\|transparent\|skipempty\|skipwhite\|skipnl\|modifier\\)\>"
 syn cluster vimFuncBodyList add=vimSynType
 
 " Syntax: match {{{2
 syn cluster	vimSynMtchGroup	contains=vimMtchComment,vimSynContains,vimSynError,vimSynMtchOpt,vimSynNextgroup,vimSynRegPat,vimNotation
 syn keyword	vimSynType	contained	match	skipwhite nextgroup=vimSynMatchRegion
 syn region	vimSynMatchRegion	contained keepend	matchgroup=vimGroupName start="\k\+" matchgroup=vimSep end="|\|$" contains=@vimSynMtchGroup
-syn match	vimSynMtchOpt	contained	"\<\(conceal\|transparent\|contained\|excludenl\|skipempty\|skipwhite\|display\|extend\|skipnl\|fold\)\>"
+syn match	vimSynMtchOpt	contained	"\<\(conceal\|transparent\|contained\|excludenl\|skipempty\|skipwhite\|display\|extend\|skipnl\|fold\|modifier\\)\>"
 if has("conceal")
  syn match	vimSynMtchOpt	contained	"\<cchar="	nextgroup=vimSynMtchCchar
  syn match	vimSynMtchCchar	contained	"\S"
@@ -443,7 +443,7 @@
 syn cluster	vimSynRegGroup	contains=vimSynContains,vimSynNextgroup,vimSynRegOpt,vimSynReg,vimSynMtchGrp
 syn keyword	vimSynType	contained	region	skipwhite nextgroup=vimSynRegion
 syn region	vimSynRegion	contained keepend	matchgroup=vimGroupName start="\k\+" skip="\\\\\|\\|" end="|\|$" contains=@vimSynRegGroup
-syn match	vimSynRegOpt	contained	"\<\(conceal\(ends\)\=\|transparent\|contained\|excludenl\|skipempty\|skipwhite\|display\|keepend\|oneline\|extend\|skipnl\|fold\)\>"
+syn match	vimSynRegOpt	contained	"\<\(conceal\(ends\)\=\|transparent\|contained\|excludenl\|skipempty\|skipwhite\|display\|keepend\|oneline\|extend\|skipnl\|fold\|modifier\\)\>"
 syn match	vimSynReg	contained	"\(start\|skip\|end\)="he=e-1	nextgroup=vimSynRegPat
 syn match	vimSynMtchGrp	contained	"matchgroup="	nextgroup=vimGroup,vimHLGroup
 syn region	vimSynRegPat	contained extend	start="\z([-`~!@#$%^&*_=+;:'",./?]\)"  skip="\\\\\|\\\z1"  end="\z1"  contains=@vimSynRegPatGroup skipwhite nextgroup=vimSynPatMod,vimSynReg
diff -r e00680fd7088 src/syntax.c
--- a/src/syntax.c	Sun Dec 02 11:32:21 2012 -0800
+++ b/src/syntax.c	Sun Dec 02 19:27:16 2012 -0800
@@ -293,8 +293,9 @@
     int		si_end_idx;		/* group ID for end pattern or zero */
     int		si_ends;		/* if match ends before si_m_endpos */
     int		si_attr;		/* attributes in this state */
-    long	si_flags;		/* HL_HAS_EOL flag in this state, and
-					 * HL_SKIP* for si_next_list */
+    long	si_flags;		/* HL_HAS_EOL flag in this state,
+					 * HL_SKIP* for si_next_list, and
+					 * HL_MODIFIER for modifiers */
 #ifdef FEAT_CONCEAL
     int		si_seqnr;		/* sequence number */
     int		si_cchar;		/* substitution character for conceal */
@@ -319,7 +320,8 @@
  */
 typedef struct
 {
-    int		flags;		/* flags for contained and transparent */
+    int		flags;		/* flags for contained, transparent, and
+				   modifier. */
     int		keyword;	/* TRUE for ":syn keyword" */
     int		*sync_idx;	/* syntax item for "grouphere" argument, NULL
 				   if not allowed */
@@ -1865,6 +1867,7 @@
     int		cchar;
     short	*next_list;
     int		found_match;		    /* found usable match */
+    int		applied_modifier;	    /* Applied a syntax modifier */
     static int	try_next_column = FALSE;    /* must try in next col */
     int		do_keywords;
     regmmatch_T	regmatch;
@@ -2288,6 +2291,8 @@
      * If not, use attributes from the current-but-one state, etc.
      */
     current_attr = 0;
+    applied_modifier = FALSE;
+
 #ifdef FEAT_EVAL
     current_id = 0;
     current_trans_id = 0;
@@ -2311,17 +2316,27 @@
 			|| (current_lnum == sip->si_h_endpos.lnum
 			    && current_col < sip->si_h_endpos.col)))
 	    {
-		current_attr = sip->si_attr;
+		if (!applied_modifier)
+		{
 #ifdef FEAT_EVAL
-		current_id = sip->si_id;
-#endif
-		current_trans_id = sip->si_trans_id;
+		    current_id = sip->si_id;
+#endif
+		    current_trans_id = sip->si_trans_id;
 #ifdef FEAT_CONCEAL
-		current_flags = sip->si_flags;
-		current_seqnr = sip->si_seqnr;
-		current_sub_char = sip->si_cchar;
-#endif
-		break;
+		    current_flags = sip->si_flags;
+		    current_seqnr = sip->si_seqnr;
+		    current_sub_char = sip->si_cchar;
+#endif
+		}
+
+		if (applied_modifier)
+		    current_attr = hl_combine_attr(sip->si_attr, current_attr);
+		else
+		    current_attr = sip->si_attr;
+		if (sip->si_flags & HL_MODIFIER)
+		    applied_modifier = TRUE;
+		else
+		    break;
 	    }
 	}
 
@@ -3918,6 +3933,7 @@
 		    {HL_EXCLUDENL, "excludenl"},
 		    {HL_TRANSP, "transparent"},
 		    {HL_FOLD, "fold"},
+		    {HL_MODIFIER, "modifier"},
 #ifdef FEAT_CONCEAL
 		    {HL_CONCEAL, "conceal"},
 		    {HL_CONCEALENDS, "concealends"},
@@ -4471,12 +4487,13 @@
 		    {"fFoOlLdD",		0,	HL_FOLD},
 		    {"cCoOnNcCeEaAlL",		0,	HL_CONCEAL},
 		    {"cCoOnNcCeEaAlLeEnNdDsS",	0,	HL_CONCEALENDS},
+		    {"mMoOdDiIfFiIeErR",	0,	HL_MODIFIER},
 		    {"cCcChHaArR",		11,	0},
 		    {"cCoOnNtTaAiInNsS",	1,	0},
 		    {"cCoOnNtTaAiInNeEdDiInN",	2,	0},
 		    {"nNeExXtTgGrRoOuUpP",	3,	0},
 		};
-    static char *first_letters = "cCoOkKeEtTsSgGdDfFnN";
+    static char *first_letters = "cCoOkKeEtTsSgGdDfFnNmM";
 
     if (arg == NULL)		/* already detected error */
 	return NULL;
diff -r e00680fd7088 src/vim.h
--- a/src/vim.h	Sun Dec 02 11:32:21 2012 -0800
+++ b/src/vim.h	Sun Dec 02 19:27:16 2012 -0800
@@ -894,6 +894,7 @@
 # define HL_TRANS_CONT	0x10000 /* transparent item without contains arg */
 # define HL_CONCEAL	0x20000 /* can be concealed */
 # define HL_CONCEALENDS	0x40000 /* can be concealed */
+# define HL_MODIFIER	0x80000 /* modifies attributes instead of clobbering */
 #endif
 
 /* Values for 'options' argument in do_search() and searchit() */

Raspunde prin e-mail lui