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() */