Как встроить синтаксический объект в другой в определениях языка TextMate, tmLanguage - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь поддержать Clojure игнорировать текстовую форму , #_, (своего рода комментарий) в VS Code, который использует tmLanguage для своих определений грамматики. Поскольку обычно отключать блок кода с помощью #_, я хочу, чтобы отключенный блок кода сохранял подсветку синтаксиса и просто выделил его курсивом, указывая его состояние.

Но мое отсутствие навыков использования tmLanguage, кажется, останавливает меня. Это одна из неудачных попыток (фрагмент cson):

  'comment-constants':
    'begin': '#_\\s*(?=\'?#?[^\\s\',"\\(\\)\\[\\]\\{\\}]+)'
    'beginCaptures':
      '0':
        'name': 'punctuation.definition.comment.begin.clojure'
    'end': '(?=[\\s\',"\\(\\)\\[\\]\\{\\}])'
    'name': 'meta.comment-expression.clojure'
    'patterns':
      [
        {
          'include': '#constants'
        }
      ]

С constants, определяющим некоторые объекты-константы Clojure, например keyword:

  'keyword':
    'match': '(?<=(\\s|\\(|\\[|\\{)):[\\w\\#\\.\\-\\_\\:\\+\\=\\>\\<\\/\\!\\?\\*]+(?=(\\s|\\)|\\]|\\}|\\,))'
    'name': 'constant.keyword.clojure'

Я хочу, чтобы определения constants использовались «внутри» комментария. Для ключевых слов у меня есть (не работает) spec:

  it "tokenizes keywords", ->
    tests =
      "meta.expression.clojure": ["(:foo)"]
      "meta.map.clojure": ["{:foo}"]
      "meta.vector.clojure": ["[:foo]"]
      "meta.quoted-expression.clojure": ["'(:foo)", "`(:foo)"]
      "meta.comment-expression.clojure": ["#_:foo"]

    for metaScope, lines of tests
      for line in lines
        {tokens} = grammar.tokenizeLine line
        expect(tokens[1]).toEqual value: ":foo", scopes: ["source.clojure", metaScope, "constant.keyword.clojure"]

(последний тест в этом списке). Ошибка с этим сообщением:

Expected
{  value : ':foo',
  scopes : [ 'source.clojure', 'meta.comment-expression.clojure' ] }
to equal
{  value : ':foo',
  scopes : [ 'source.clojure', 'meta.comment-expression.clojure', 'constant.keyword.clojure' ] }.

Это означает, что я не получаю область действия constant.keyword.clojure и, следовательно, мне не нужна раскраска ключевых слов. ?

Кто-нибудь знает, как это сделать?

1 Ответ

0 голосов
/ 09 января 2019

Ваше регулярное выражение keyword начинается с заглядывания назад, которое требует, чтобы перед ключевыми словами был один пробел, (, [ или {. _ из #_ не соответствует этому требованию.

(?<=(\\s|\\(|\\[|\\{))

Вы можете просто добавить _ в список разрешенных символов:

(?<=(\\s|\\(|\\[|\\{|_))

Обратите внимание, что этот все равно не будет работать как есть для вашего "#_:foo" контрольного примера из-за аналогичного просмотра в конце. Вы могли бы разрешить $ там, сделать сопоставление необязательным или изменить контрольный пример.

...