Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I nest syntax highlighting in Vim?

Tags:

regex

vim

How do I get nest syntax highlight in Vim to actually highlight the syntax?

I'm working on a syntax file for a language where strings can contain code from other languages, specifically, SQL, Groovy, JavaScript, PHP and AppleScript. I'm just trying to get the first one working and hoping to make it easy on myself by beginning such strings with a comment in the embedded language that specifies what the language is. Here's an example:

ExecuteSQL( "/*lang=sql*/ SELECT *
                          FROM table
                          WHERE id = ?";
                          ""; "";
                          456
)

In my syntax file I have the following lines of code:

runtime! syntax/sql.vim
unlet b:current_syntax
syntax include @sql_code syntax/sql.vim
syntax region fm_sql_code start /"\/\*lang=sql\*\// keepend end=/\v"/ contains=@sql_code

At the moment this code is at the end of my syntax/plugin.vim file. But I've also tried putting the code in ftplugin/plugin.vim but using autocmds to execute it:

au FileType fmcalc runtime! syntax/sql.vim
au FileType fmcalc unlet b:current_syntax
au FileType fmcalc syntax include @sql_code syntax/sql.vim
au FileType fmcalc syntax region fm_sql_code start /"\/\*lang=sql\*\// keepend end=/\v"/ contains=@sql_code

So far the location of the code hasn't changed the result.

I have a mapping that allows me to see the syntax stack for the current character by pressing <c-s-p>.

The result is that with the above, when my cursor is in the string I see the stack as ['fm_sql_code', 'sqlString']. So it's detecting the embedded syntax but flagging it as a string. The problem is that the text isn't highlighted as SQL language code, just as a string literal.

My first thought was that it was doing this because the regex I'm using for the region is including the double-quotes, so I tried changing that to the following:

syntax region fm_sql_code  start=/"\@=\/\*lang=sql\*\// keepend end=/"\@=/ contains=@sql_code

But that fails to see the strings as SQL at all. The syntax stack for the above example returns ['fm_string_literal'], which is the default syntax name for strings.

Any help would be appreciated.

like image 317
Chuck Avatar asked Jan 29 '26 18:01

Chuck


1 Answers

let csyn = b:current_syntax
unlet b:current_syntax
syntax include @sql syntax/sql.vim
syntax region sqlSnip start='\(\)\(/\* *lang=sql *\*/\)\@=' end='\(\)"\@=' contains=@sql containedin=ALL
let b:current_syntax = csyn
unlet csyn

EDIT:

Temporarily unsetting b:current_syntax is required since Vim syntax files are usually not loaded when the variable exists. For example, syntax/sql.vim starts as follows:

" For version 5.x: Clear all syntax items
" For version 6.x: Quit when a syntax file was already loaded
if version < 600
    syntax clear
elseif exists("b:current_syntax")
    finish
endif
like image 176
Junegunn Choi Avatar answered Jan 31 '26 10:01

Junegunn Choi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!