Мои расширения 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, прекрасно
edit Основываясь на отзывах 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'