Регулярное выражение tmLanguage для захвата функции, которая может содержать много функций - PullRequest
0 голосов
/ 25 мая 2019

Мои расширения 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'
...