我的 vscode 扩展 tmLanguage 不是为 JavaScript 明确构建的,但我将使用它作为示例,因为它演示了最佳用例。举个例子:
1 function {
2 var p = 9;
3
4 function do() {
5 console.log(p);
6 }
7
8 var expr = function() {
9 console.log(p);
10 }
11
12 var cons = new Function('\tconsole.log(p);');
13
14 var arrow = () => { console.log(p); }
15 }
16
17 function
18 {
19 console.log('hello world');
20
21 return 'hello world';
22 }
我的目标是捕获第 1 行作为开始,第 15 行作为结束标记,第 2-14 行作为函数体标记。并分别对#17-22 行重复。请注意,我的函数起始行不是特定于空格的,并且可能会根据用户的判断在新行上。
我尝试了许多不同的方法,使用\G
锚或其他方法,下面的语法示例是我最接近的。但是,它在第一个找到的右大括号之后停止}
,或者在我上面的示例中的第 6 行之后。我希望它在第 15 行结束捕获
functions:
patterns:
- begin: (?:^|\s)(function)\s+
beginCaptures:
'1' : { name: meta.tag.function-name }
end : (?<=(\}))
endCaptures:
'1' : { name: entity.punctuation.definition.end }
patterns:
- begin: \{
beginCaptures:
'1' : { name: entity.punctuation.definition.start }
end : \}
patterns:
- begin: \s*
end : "[^\\}]*"
name: meta.tag.function-body
我的示例是使用 yaml,但是任何您喜欢使用的与 vscode 一起使用的东西都可以
编辑根据 Gama11 的反馈,我能够让它工作。本质上,该过程中最重要的部分是递归。所以基本上我没有改变任何东西,只是添加了一个递归正则表达式来查找{}
对。这是工作示例:
patterns:
- begin: (?:^|\s)(function)\s+
beginCaptures:
'1' : { name: meta.tag.function-name }
end : (?<=\})
patterns:
- begin : \{
beginCaptures:
'0' : { name: entity.punctuation.definition.start }
end : \}
endCaptures:
'0' : { name: entity.punctuation.definition.end }
contentName: meta.tag.function-body
patterns :
- include : '#parens'
repository:
parens:
- patterns:
- begin : \{
end : \}
patterns:
- include : '#parens'