MT管理器语法文件强化语法, 主要作用就是可以自动展开regexp include定义中的颜色组
例如如下代码
{
name: ["TEST", ".test"],
hide: false,
defines: [
//!includeBegin
string-escape = /\\(?:[nrt'"\\]|(.))/
$0: "strEscape"
$1: "error"
string = /"(?:[^"\\]|/ @string-escape /)*"/
string-def := @string
$recordAllGroups: true
$0: "string"
r-string-def := /r/ @string
$recordAllGroups: true
$0: "keyword2"
num = /\b\d+\b/
$0: "number"
value-def := {
::string-def
::r-string-def
: @num
}
//!includeEnd
]
contains: [
{include: "value-def"}
]
}
将被编译为
{
name: ["TEST", ".test"],
hide: false,
defines: [
// Generated by mtsyntax-plus begin
"string-escape": /(\\(?:[nrt'"\\]|(.)))/
"string": /"(?:[^"\\]|/ + include("string-escape") + /)*"/
"string-def": {
match: /(/ + include("string") + /)/
recordAllGroups: true
1: "string"
2: "strEscape"
3: "error"
}
"r-string-def": {
match: /(r/ + include("string") + /)/
recordAllGroups: true
1: "keyword2"
2: "strEscape"
3: "error"
}
"num": /(\b\d+\b)/
"value-def": [
{include: "string-def"}
{include: "r-string-def"}
{
match: include("num")
1: "number"
}
]
// Generated by mtsyntax-plus end
]
contains: [
{include: "value-def"}
]
}
该程序将处理由独占单行的注释 //!includeBegin
直至 //!includeEnd
间的内容
//
表示注释
使用=
来定义正则, 使用:=
来定义匹配器, 使用:= { ... }
来定义匹配器组
匹配器定义由若干匹配组成, 尾随一系列属性定义, 与颜色定义
或一个匹配器组定义
表示基本的匹配单元, 可使用的匹配如下:
-
普通的正则, 如
/[a-z]+/
,"[a-z]+"
,([0-9]+)[a-z]*
, 该方法参与本地组计数 -
使用
@name
来引用内部定义的正则, 会展开定义正则时附带的颜色组, 该方法不参与本地组计数 -
使用
&name(count)
来引入外部定义的正则, 这种方法不会展开定义正则时附带的颜色组- 当
(count)
被省略时, 默认该正则不含捕获组 - 当
count
为一个数字时, 手动指定含有多少个捕获组 - 当
count
为@
时, 将在内部定义的正则中查找捕获组数量, 通常用于覆盖定义正则时附带的颜色组
该方法参与本地组计数
- 当
-
使用
include(name, count)
,, count
可省略, 类似&name(count)
, 但是count
只能为一个数字, 用于方便迁移的语法 -
使用
(
,(?:
,|
,)
,)*
,)+
,){1,2}
,)+?
,){1,2}?
, 此种方法用于快速表示常用正则操作符, 例如(
表示/(/
,|
表示/|/
, 该方法参与本地组计数 -
使用
($color
定义一个内联颜色组, 表示/(/
但是不参与本地组计数, 展开时会生成如1: "color"
的颜色 -
使用
keywordsToRegex("...")
来定义一系列关键字, 就像在MT语法文件中直接编写那样, 没有多大区别, 参与本地组计数
每个匹配通过可选的加号连接, 如 @foo + @bar
和 @foo @bar
是等价的
在匹配器组 := { ... }
中, 可以编写如下语法:
- 使用
:
表示创建一个匹配器, 后面尾随一个匹配器 - 使用
::
表示引用一个匹配器, 后面尾随匹配器名称, 相当于{include: "..."}
- 直接定义匹配器, 而无需使用
:
, 该种用法只能写一个匹配器
定义本地捕获组的颜色, 当该捕获组成功匹配将会使用该颜色对其上色
例如:
foo := /"([^"]*)"/
$0: "string"
$1: "keyword"
将生成出如下内容
"foo": {
match: /("([^"]*)")/
1: "string"
2: "keyword"
}
表示将整个匹配结果染色为 "string"
, 将引号中内容染色为 "keyword"
定义匹配器的属性, 也就是非颜色组的其它属性
例如将之前的例子改变一下:
foo := /"([^"])*"/
$recordAllGroups: true
$0: "string"
$1: "keyword"
将生成出如下内容
"foo": {
match: /("([^"])*")/
recordAllGroups: true
1: "string"
2: "keyword"
}
当你使用参与本地组计数的匹配时, 你可以在当前的正则或匹配器中直接引用局部的捕获组编号
例如@foo
不参与本地组计数, 而普通的正则匹配参与本地组计数:
foo = /(b)/
bar := /(a)/ @foo /(c)/
$1: "string"
$2: "string"
将生成出如下内容
"foo": /(b)/
"bar": {
match: /(a)/ + include("foo") + /(c)/
1: "string"
3: "string"
}
由于 @foo
不参与本地组计数, 而 /(a)/
和 /(b)/
参与本地组计数,
所以对于颜色组编号来说, 不参与本地组计数的 @foo
中的颜色组是 "不存在的"
所以 $2
表示的 "第二个颜色组" 就是 /(c)/
,
而不是 @foo
内部 "不存在的" 颜色组
你可以从 Releases 下载已经编译好的成品进行使用, 又或者你可以手动编译, 如下:
在拥有rust编译环境的情况下, 在项目目录下输入
cargo run
即可编译并运行, 要处理的文件从标准输入重定向给程序, 结果会输出到标准输出
编辑MT语法文件的话, 有一个vim对MT语法文件的高亮MT高亮