Skip to content

[Feature Request] sublime-syntax push only for characters matched by lookahead, or the ability to pop after the first match #1597

Closed
@keith-hall

Description

@keith-hall

I would like to propose a new feature for .sublime-syntax files, whereby one can match a lookahead pattern, and then push into that context only for the characters matched by the lookahead, after which it automatically pops back out.

This would be really useful when including other syntaxes, without needing to modify those syntaxes for easier inclusion. For example, when developing a new syntax, one might want to include HTML tags and pop immediately afterwards. Rather than duplicating the matches and scopes, including a new context in the syntax being included to pop when desired, or resorting to a lookbehind which would reduce performance, one could use a simpler lookahead to find where the HTML tag ends and push that into the scope:text.html.basic context, knowing that it will pop automatically afterwards.

I believe this could also allow regular expressions inside JSON to be processed properly.

i.e. { "key": "following_text", "operator": "regex_match", "operand": ".*\\bexample" }

here, the first \ should be a JSON escape character, and the \b should be processed by the regex syntax definition. But currently there's no easy way to do it:

   - match: '(?=\S)'
     push:
        - include: scope:source.regexp#base-literal
      with_prototype:
        - match: '(?=")'
          pop: true
        - match: '\\\\(?=")'
          scope: constant.character.escape.json
          pop: true
        - match: '\\(?=\\.)'
          scope: constant.character.escape.slash.json
          #push: # / push_lookahead:
          #  - include: scope:source.regexp#base-literal # TODO: and pop after first match
        - match: '{{char_escape}}' # ignore the fact that variables don't work in `with_prototype` for now
          scope: constant.character.escape.json

the above would end up scoping the \b as a JSON escape, when it isn't one.

An alternative option that would be helpful is a way to say "pop this context after the first match", but this would get complicated if the match wants to push or set into another context.

- pop_after_first_match: true
- include: scope:source.regexp

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions