Possibility of using fileTypes key inside patterns key


#1

I am developing a language grammar package for TeX and its friends. It is hosted here.

In (La)TeX, we use commands called control word, which are composed of a sequence of certain letters and leading backslash (e.g., \foo). Available characters for control word are usually only Latin alphabet, small or capital, but @ can be also used under the following conditions (they actually do not cover all the possible cases, but are sufficient for the discussion).

  1. between \makeatletter and \makeatother (LaTeX only)
  • in a package/class file whose extension is sty / cls respectively

I want to make the parsing of control words sensitive to the condition above. I first defined a grammar for control words that do not contain @ like this:

  {
    'captures':
      '1':
        'name': 'punctuation.definition.function.tex'
    'match': '(\\\\)[A-Za-z]+'
    'name': 'support.function.general.tex'
  }

Then, I allow @ to be a part of control words between \makeatletter and \makeatother like this.

  {
    'begin': '\\\\makeatletter'
    'beginCaptures':
      '0':
        'name': 'support.function.makeatletter.tex'
    'end': '\\\\makeatother'
    'endCaptures':
      '0':
        'name': 'support.function.makeatother.tex'
    'patterns': [
      {
        'match': '\\\\([A-Za-z@]*@[A-Za-z@]+|[A-Za-z@]+@[A-Za-z@]*)'
        'name': 'support.function.general.tex'
      }
      {
        'include': '$base'
      }
    ]
  }

With these changes, I could implement a grammar sensitive to Condition 1.

I tried the following code to implement Condition 2 with the aid of fileTypes key, but failed.

  {
    'fileTypes': [
      'sty'
      'cls'
      'code.tex'
    ]
    'patterns': [
      {
        'match': '\\\\([A-Za-z@]*@[A-Za-z@]+|[A-Za-z@]+@[A-Za-z@]*)'
        'name': 'support.function.general.tex'
      }
      {
        'include': '$base'
      }
    ]
  }

results in

Is possible to use fileTypes in this manner?


#2

No. fileTypes has to be a root key. What you want to do is make two grammar files: one for stock LaTeX and one for sty/cls. Then you include the LaTeX grammar with

{
  include: 'text.tex.latex'
}

You can see an example of this in the C++ grammar.


#3

I’ve already used include feature in other grammar files, but I’m a bit reluctant on doing it in this case for some reasons. I should consider splitting into two grammars if using nested fileTypes is impossible, though.

Is this limitation documented anywhere? I checked Atom’s manual but couldn’t find relevant information.


#4

What reasons?

Is this limitation documented anywhere?

I spent a short amount of time looking and was unable to find it again, but somewhere there’s a URL pointing at a tutorial for TextMate grammars. Which, no, is not clear documentation, which is why I built my own. I haven’t submitted it as a pull request because it’s not finished, and there should be Flight Manual copy to go along with it, but I haven’t written that.


#5

I have currenlty four grammars, that is scoped as text.tex.latex.beamer, text.tex.latex.memoir, text.tex.latex and text.tex. The first two include the third one, which includes the last. If I add @-sensitive parsing, it means that I need to prepare four extra files. It seems too much for this feature, which I think is not so indispensable and not worth it.

The other reason is that there is no generic LaTeX term to indicate both class and package AFAIK, so I cannot come up with a good name, scopeName, etc. Maybe my poor vocabulary is to blame haha.


#6

You don’t have to prepare four extra files because you can use begin in the same way you use firstLineMatch. Try this:

    {
        begin: 'html'
        contentName: 'constant'
        patterns: [
            {
                include: 'text.html.basic'
            }
        ]
    }

Type “html” anywhere in the document and the rest of it will be styled with whatever color your syntax theme gives constants, except for anything that looks like HTML tags. You do one of those for each of your other grammar files.


#7

I once considered using that method, but there is no term to begin with that is always put in class and package files. The only way to detect to class and package files is their extension.

Yes, I myself can have a habit of writing some kind of declaration in each class/package file, but I cannot force other people to do the same thing.


#8

How do you determine if a class or package file is for Memoir or Beamer?


#9

Memoir and beamer themselves are class files of LaTeX, which are used for books and slides, and text.tex.latex.beamer and text.tex.latex.memoir are the scope names of LaTeX documents that use each class files.