2015年5月10日更新:Sublime Text 3 build 3084引入了全新的
sublime-syntax
格式,用于编写语法定义。它比旧系统更好,Sublime从TextMate继承了旧系统。新系统应该很快出现在公共ST3 beta版本中。由于ST3是
推荐使用的Sublime版本,建议使用
新系统而不是下面描述的系统编写任何新的高亮显示器。
这里是Sublime Text语法高亮的速成课程。
设置
首先,正如@lthreed指出的那样,你可以使用
PackageResourceViewer
查看Sublime Text附带的默认包。这些.tmLanguage文件都是以plist格式编写的,非常难以阅读和理解。
PackageDev
可以将plist文件转换为更易读的JSON或YAML格式。在查看默认包时,请确保首先将其转换为YAML。请注意,
PackageDev
可能无法完美地转换它。不要紧,你只需将代码用作参考即可。
plist是Sublime理解的本机格式,但这并不意味着你应该像那样编写它。我
强烈建议你使用YAML编写你的高亮器,并使用
PackageDev
将其转换为plist。不要用JSON编写它。JSON不支持原始字符串。所有正则表达式都必须进行双重转义。这是一场绝对的噩梦。只需使用YAML即可。
你可以通过打开命令面板(在Mac上按
cmd+shift+p
)并选择
PackageDev: New YAML Syntax Definition
来开始一个新的语法定义。当你准备好进行测试时,打开命令面板并选择
PackageDev: Convert (YAML, JSON, PList) to...
,PackageDev将会确定你有一个YAML文件并想要转换为plist。转换会将您的.YAML-tmLanguage文件转换为Sublime能够理解的.tmLanguage文件。将该文件放置在/Packages/User目录中,Sublime将会加载并应用它(您可能需要重新启动)。
Sublime的语法高亮是如何工作的?
您正在编写的语法定义不会直接为文本着色。它将“作用域名称”应用于文本。然后,像 Monokai 和 Solarized 这样的主题作者会制作文件,将作用域名称与颜色关联起来。您可以自己编写作用域名称,但应坚持使用
官方 TextMate 作用域名称。这些作用域名称可能对您匹配的代码毫无意义。没关系。尽力而为即可。如果必须编写一个作用域名称,请以 TextMate 作用域名称为起点。例如,不要使用
string.quoted.double.xxx
(其中 xxx 是您匹配的语言的文件扩展名),而是可以编写一个称为
string.quoted.triple.xxx
的作用域名称。
代码示例
下面是一个假想的 matt 语言的语法定义,其文件扩展名为 .matt。它只有两个规则:一个用于匹配一个带有管道分隔符的字符串,另一个用于匹配一个带有更复杂分隔符的字符串。
---
name: Mattlang
scopeName: source.matt
fileTypes: [matt]
patterns:
- include: '#pipe-string'
- include: '#complex-string'
repository:
pipe-string:
name: everything.matt
begin: \|
beginCaptures:
'0': {name: entire.begin.match.matt}
contentName: stuff.between.the.pipes.matt
patterns:
- include: '#hell'
- include: '#hello'
- end: \|
endCaptures:
'0': {name: entire.end.match.matt}
hell:
name: some.other.scope.matt
match: hell
hello:
name: some.scope.matt
match: hello
complex-string:
begin: (!(!))($)
beginCaptures:
'0': {name: full.match.matt}
'1': {name: both.exclamation.marks.matt}
'2': {name: second.exclamation.mark.matt}
'3': {name: dollar.sign.matt}
end: ((!)!)($)
endCaptures:
'0': {name: everything.matt}
'1': {name: both.exclamation.marks.matt}
'2': {name: first.exclamation.mark.matt}
'3': {name: dollar.sign.matt}