Syntax theme, nested elements ? recursivity for pattern?


#1

Hi everybody,

I am trying to understand the syntax grammar theme behavior.

I read some topics but I still have questions.

Is Atom offer another way to color part of code, let’s say dynamically or anyway the grammar has to be implemented with regex ?

As I understood, begin and end have to be match/non capturing group. (except if we use beginCapturing or endCapturing)
And pattern has to be a capturing group.
Right ?

In that case, how to use nested code ?

if () begin

end else if () being
    if () begin
         //blabla
    end
end else if () begin

end

How can I find the corresponding end to the first if ?
If it possible to include the pattern itself, kind of recursive pattern ?

I would like to catch some basic errors in order to save time later.
Example: If I forget a end or if I forget a ; etc…

Thank you.


#2

Not easily, but it can be done (see pigments and linter packages). The grammars and syntax themes are the main way to color TextBuffer content.

As I understood, begin and end have to be match/non capturing group. (except if we use beginCapturing or endCapturing)
And pattern has to be a capturing group.

You do not have to use non-capturing groups at all.

In that case, how to use nested code ?

{
  begin: '(else )?(if) \\(\\) begin'
  beginCaptures:
    0:
      name: 'keyword.control'
  end: 'end'
  endCaptures:
    0:
      name: 'keyword.control'
  patterns: [
    {
      include: '$self'
    }
  ]
}

Here is an example from the language-javascript package.


#3

Thank you for your reply.
I was afraid of that because I don’t see how it’s possible to give a priority to patterns.

No error, I want a color for every lines inside the instance.

module instance(
.aaa(bbb),
.ddd(ggg),
.ttt(agg),
.ppp(ooo)
);

Error, a , is missing. => Want to give a red color to this line.

module instance(
.aaa(bbb),
.ddd(ggg)
.ttt(agg),
.ppp(ooo)
);

I’ll need to write a lot of grammar patterns to do it.

But now if I want to set a red color to the module instance( line instead of to the error line. It’s impossible without using very complicated regex pattern.

I will read pigments and yes I knew linter packages but it uses an external software/application.

Atom could be so better with these kind of possibilities. Even morem if I take back my previous example with if and else:

if () begin

end else if () being
    if () begin
         //blabla
    end
end else if () begin

end

If I click on the first begin, I want to get the corresponding end. Maybe possible by changing Bracket matcher package…

Anyway, I hope Atom will be more like smart IDE (jetbrains rubymine etc…).


#4

The pattern that comes first in the grammar will get matched first, and once a segment of text is matched, it’s not going to be matched to anything else unless you have a nested include.

Anyway, I hope Atom will be more like smart IDE (jetbrains rubymine etc…).

It is not an IDE. It’s a text editor that’s highly hackable and can be made smarter.


#5

I see, from what you said, I’ll make some tests.

Thank you :wink:


#6

I want to set a new color for value .something(value).
My code is:

  'module_inst_inside':
    'patterns': [
        {
            'match': '(\\.[a-zA-Z1-9_]+\\()([a-zA-Z1-9_]+)(\\))'
            'captures':
              '1':
                'name': 'entity.name.class.module.insideinst.verilog'
              '2':
                'name': 'entity.name.class.module.insideinst.value.verilog'
              '3':
                'name': 'entity.name.class.module.insideinst.verilog'
        }
        {
          'include': '#comments'
        }
        {
          'include': '#constants'
        }
        {
          'include': '#strings'
        }
    ]

I can give a new color with ‘entity.name.class.module.insideinst.value.verilog’ but sometimes it matches with something in 'include': '#constants' but this class is highest priority entity.name.class.module.insideinst.value.verilog.

How to make something like this:

              '2':
                'name': 'entity.name.class.module.insideinst.value.verilog'
                'include': '#constants'

If it doesnt find something constants, give the entity.name.class.module.insideinst.value.verilog class.

Edit :

I did like this:

              '2':
                'patterns': [
                    {
                        'include': '#constants'
                    }
                    {
                        'match': '([a-zA-Z1-9\'_]+)'
                        'name': 'entity.name.class.module.insideinst.value.verilog'
                    }
                ]