如何在Vim中嵌套语法高亮?

时间:2014-07-20 22:39:09

标签: regex vim

如何在Vim中使用嵌套语法高亮显示语法?

我正在研究一种语言的语法文件,其中字符串可以包含来自其他语言的代码,特别是SQL,Groovy,JavaScript,PHP和AppleScript。我只是想让第一个工作,并希望通过在嵌入式语言中用注释开始这样的字符串来指明语言是什么,从而使自己变得容易。这是一个例子:

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

在我的语法文件中,我有以下几行代码:

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

目前此代码位于syntax/plugin.vim文件的末尾。但我也尝试将代码放在ftplugin/plugin.vim中,但使用autocmd来执行它:

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

到目前为止,代码的位置并没有改变结果。

我有一个映射,允许我按<c-s-p>查看当前字符的语法堆栈。

结果是,如上所述,当我的光标在字符串中时,我将堆栈视为['fm_sql_code', 'sqlString']。所以它正在检测嵌入式语法,但将其标记为字符串。问题是文本没有突出显示为SQL语言代码,就像字符串文字一样。

我的第一个想法是它正在这样做,因为我在该地区使用的正则表达式包括双引号,所以我尝试将其更改为以下内容:

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

但是根本没有将字符串视为SQL。上面示例的语法堆栈返回['fm_string_literal'],这是字符串的默认语法名称。

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:2)

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

编辑:

暂时取消设置b:current_syntax是必需的,因为当变量存在时,通常不会加载Vim语法文件。例如,syntax/sql.vim开头如下:

" 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