My vscode extensions tmLanguage is not explicitly built for JavaScript, but I will use it as an example because it demonstrates the best use case. Take the following example:
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 }
My goal is to capture Line #1 as the beginning and line #15 as the end tokens and line #2-14 as the function-body token. And repeat respectively for lines #17-22. Note that my function starting line is not white-space specific and potentially be on a new line per users discretion.
I have tried many different ways, using \G
anchor or otherwise and the following grammar example is the closest I've been. However, it stops after the first found closing braces }
, or line #6 in my example above. I would like it to end capture at line #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
My example is using yaml but anything you're comfortable using that works with vscode is fine
edit Based on the Gama11's feedback I was able to get it working. Essentially the most important part of the process is recursion. So basically I didn't change anything but add a recursive regex for finding {}
pairs. Here is the working example:
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'