How can I make a syntax match be contained only inside of a specific syntax region without creating separate files?

Viewed 531

Is it possible to have a syntax match (not keyword) match only inside a certain syntax region? I had this issue a while ago and came up with this:

" lua.vim
syntax include @loveconf <sfile>:p:h/love-conf.vim
" Some time later
syntax region loveconfregion start="\<love\.conf\>" end="\<end\>"me=e-3,he=e-3,re=e-3 skipwhite skipempty containedin=ALLBUT,luaString,luaComment contains=ALL
highlight loveconf ctermfg=206

Where love-conf.vim looked like this:

" Simple example; actual file contains a regex
syntax match loveconf "\.window\.width" containedin=loveconfregion

I would like, if possible, to move it all to one file. Is there any way to do this?

As a guideline, here is an example file:

-- test.lua
t.window.width = 20
-- ^ Not colored

function randomFunction()
    t.window.width = 20
    -- ^ Also not colored
end

function love.conf( t )
    t.window.width = 20
    -- ^ Colored
end
1 Answers

Yes, this is possible and used by most syntax scripts. Here's a short example:

#start
match
#end
match

syntax region myRegion start="#start" end="#end" contains=myMatch
syntax match myMatch "match" contained
highlight link myMatch Identifier

Your example just misses the contained attribute. Because of that, loveconf matches anywhere, not just inside the loveconfregion (via containedin=):

syntax match loveconf "\.window\.width" contained containedin=loveconfregion

syntax include vs. one syntax

The main use case for :syntax include is embedding a (sub-)language in another one. Prominent examples are JavaScript inside HTML, or Python inside Vimscript. This avoids duplication and allows to conditionally include stuff (for example, the Vim syntax does not highlight embedded Python if Vim doesn't have support for it).

Another use case is one syntax being an extension of another (for example, Windows Scripting Host is XML). That usually would simply :runtime! syntax/xml.vim.

Related