Different syntax highlighting within regions of a file
From Vim Tips Wiki
Tip 857 Previous Next created January 21, 2005 · complexity advanced · author Ivan Tishchenko · version 6.0
In many cases, you may want to apply different syntax highlighting from the rest of the file on specific sections of the file. Examples where this would be useful would be including C code snippets in a text file, or including Vim script inside <pre> sections on a web page or wiki entry. Vim allows you to do this! Try the following, in a new text file:
:syntax on :syntax include @CPP syntax/cpp.vim :syntax region cppSnip matchgroup=Snip start="@begin=cpp@" end="@end=cpp@" contains=@CPP :hi link Snip SpecialComment
Now type in the following text:
This is simple text, and following is C++:
@begin=cpp@
int q;
struct w { double e };
@end=cpp@
Now you have text between @begin=cpp@ and @end=cpp@ highlighted as C++, though filetype is not 'cpp'.
Here is a more useful version, which should work on any file, even those with a pre-existing syntax (i.e. not just text files):
function! TextEnableCodeSnip(filetype,start,end,textSnipHl) abort
let ft=toupper(a:filetype)
let group='textGroup'.ft
if exists('b:current_syntax')
let s:current_syntax=b:current_syntax
" Remove current syntax definition, as some syntax files (e.g. cpp.vim)
" do nothing if b:current_syntax is defined.
unlet b:current_syntax
endif
execute 'syntax include @'.group.' syntax/'.a:filetype.'.vim'
try
execute 'syntax include @'.group.' after/syntax/'.a:filetype.'.vim'
catch
endtry
if exists('s:current_syntax')
let b:current_syntax=s:current_syntax
else
unlet b:current_syntax
endif
execute 'syntax region textSnip'.ft.'
\ matchgroup='.a:textSnipHl.'
\ start="'.a:start.'" end="'.a:end.'"
\ contains=@'.group
endfunction
Now we can write something like:
call TextEnableCodeSnip( 'c', '@begin=c@', '@end=c@', SpecialComment)
call TextEnableCodeSnip('cpp', '@begin=cpp@', '@end=cpp@', SpecialComment)
call TextEnableCodeSnip('sql', '@begin=sql@', '@end=sql@', SpecialComment)
to enable highlighting of code pieces for c, cpp and sql. The begin and end markers are arbitrary; you can use whatever you want. For example, it might be useful is to use fold markers in the begin and end patterns, like this:
call TextEnableCodeSnip('html' ,'#{{{html' ,'#html}}}', SpecialComment)
This will allow you to fold snippet sections if you :set foldmethod=marker.
Setting up these function calls in your after/syntax directory will allow you to automatically allow such snippet sections in every file of a given type.
[edit] Notes
- If highlighting gets out of sync, try executing :syn sync fromstart to fix it.
- If you want this highlighting within other syntax items (like strings), you may need to tweak the syntax rules here or in the syntax file using contains and/or containedin. :help :syn-contains :help :syn-containedin
