Search code examples
javascriptregexace-editor

Recursive blocks in Ace editor


We've got our own scripting language that we use. The language is quite simple, but it has one 'exclusive' thing: strings are defined using '[' and ']' (so "test" would be [test]), and these braces can be inside each other:

lateinit([concat([test], [blah])])

Also, there's no escaping character. How does one parse this block as one string (thus highlighting the [concat([test], [blah])] block)? I currently got the following rule:

     { token: 'punctuation.definition.string.begin.vcl',
       regex: '\\[',
       push: 
        [ 
          { token: 'punctuation.definition.string.end.vcl',
            regex: '\\]',
            next: 'pop' },
          { defaultToken: 'string.quoted.other.vcl' } ],
        },

But, as you might've guessed, this will stop at brace at the end of test: '[ concat([test ], [blah])]'...

Other examples are:

setexpratt(1, [if(comparetext([yes], [no]), msg([test expression]))]);
terminator([confirm([Are you sure you want to exit?])]);
registerfunction([testfunction], 1, 3, [], [msg(concat([Argument 1: ], p(1), [, Argument 2: ], p(2), [, Argument 3: ], p(3)))]);

Solution

  • You need to add rule for [ into the inner string state, try

    this.$rules = { 
        start: [
            { token: 'string.begin.vcl', regex: '\\[', push: "string" }
        ],
        string : [ 
            { token: 'string.begin.vcl', regex: '\\[', push: "string" },
            { token: 'string.end.vcl', regex: '\\]', next: 'pop' },
            { defaultToken: 'string.quoted.other.vcl' },
        ]
    };
    this.normalizeRules();