如何复用Vim语法文件中syn-match的字符串匹配模式?
如何在Vim语法文件中复用字符串匹配模式适配不同上下文
我编写了如下Vim语法文件,实现了name关键字后的字符串匹配:
syntax match langString \ /\v[^"' ][^;]+|"[^"]*"|'[^']*'/ \ contained syntax keyword langName \ name \ nextgroup=langString
支持的语法示例:
name "Hello" name what name 'another example'
为了扩展语法支持define关键字后接字符串、分号再跟字符串的结构,我又定义了:
syntax match langOtherString \ /\v[^"' ][^;]+|"[^"]*"|'[^']*'/ \ contained \ nextgroup=langSemicolon \ skipwhite syntax match langSemicolon \ ";" \ contained \ nextgroup=langString \ skipwhite syntax keyword langDefinition \ define \ nextgroup=langOtherString
支持的语法示例:
define x ; 4 define y ; 10 define "so" ; "be it"
现在的问题是,langString和langOtherString的匹配模式完全相同,只是上下文相关的属性(比如nextgroup)不同,有没有办法只定义一次字符串匹配模式,来适配这两种不同的上下文?
当然可以,最直接的方式是把重复的匹配模式提取到Vim脚本变量中,然后在需要的syntax match命令里引用这个变量,这样就只需要维护一份模式定义,同时给不同的语法项设置各自的上下文属性。
修改后的代码如下:
" 定义通用的字符串匹配模式,仅需维护一次 let s:str_pattern = '/\v[^"'\' ][^;]+|"[^"]*"|'\''[^'\'']*'\''/' " 原有的name相关语法,使用通用模式 syntax match langString \ {s:str_pattern} \ contained syntax keyword langName \ name \ nextgroup=langString " 扩展的define相关语法,同样使用通用模式,但设置不同的nextgroup和skipwhite syntax match langOtherString \ {s:str_pattern} \ contained \ nextgroup=langSemicolon \ skipwhite syntax match langSemicolon \ ";" \ contained \ nextgroup=langString \ skipwhite syntax keyword langDefinition \ define \ nextgroup=langOtherString
这样修改后,langString和langOtherString共享同一个匹配模式,同时各自保留了针对不同上下文的属性设置,既避免了代码重复,也能正常支持两种语法场景。
如果不需要给这两个字符串语法项设置不同的高亮样式,还可以进一步简化:只定义一个通用的字符串语法项,然后通过containedin让它在不同的上下文里被激活,但这种方式相对复杂,不如使用变量提取模式的方法直观易维护。
内容的提问来源于stack exchange,提问作者cutecoder
相关产品推荐
相关产品推荐

