Sublime Forum

Extending existing syntax definitions

#1

Hi,

what is the best way to extend an existing syntax definition? Say I am working on a Javascript file with the promise library Bluebird and I use coroutine for my function definitions:

var myFunction = Promise.coroutine(function* (x + y) {

})

The default syntax doesn’t recognize that as a function definition, it doesn’t get indexed as a symbol etc. What is the best way to extend the existing syntax definition? It would be great if I could do that without overwriting the existing definition so that updates to the ST javascript syntax don’t require any changes for my extended definition. It would even be better if I could extend an existing syntax without creating a new one that imports ST’s definition.

Thanks!

1 Like

YAML Macros 2.0: Extend existing syntaxes with new functionality
#2

Create a syntax file (must end with .sublime-syntax) with something like this:

%YAML1.2
---

name: My Custom Javascript

file_extensions:
  - js

scope: source.js

contexts:
  main:
    - match: |
        (?xi)
        \b
        (?> coroutine
          | otherFunction
          | anotherOne
        )\b
      scope: support.function.js
    # Normal javascript...
    - include: JavaScript.sublime-syntax

The xi means:

x : Ignore spaces
i : Case insenstive

I normally use rubular to test the regexes, there you can learn more about how it works.

PS: I got the name for the javascript file from the github repository and I really recommend that you read the official documentation to really understand how the syntax files works.

0 Likes

#3

Unfortunately that is a really poor “integration” that will accomplish almost nothing considering how the current JavaScript.sublime-syntax is structured. Most importantly, it doesn’t add to the symbol indexer and thus cannot be searched for.

Back on topic, the problem is rather complex and non-trivial with how deeply intertwined modification to support your syntax and the original would have to be. Thus, I can not provide any help for this unfortunately.

It would probably be best to look at the default syntax and modify it in-place, inspired by current prototype function matching.

2 Likes

#4

Yeah, I know, it’s just a “hack” that will work on some cases but I agree that is impossible to extend the core syntax without making changes to it.

0 Likes

#5

Thanks! Just a quick follow-up:

  1. What is the best way to modify the default syntax? Can I use PackageResourceViewer: Open Resource -> JavaScript -> JavaScript.sublime-syntax? When I save the file that opens, it’s placed in the Package folder and overwrites the zipped Javascript stuff package, no? What happens when ST updates the default javascript syntax?
  2. Can you point me at a current prototype function matching?
0 Likes

#6
  1. Your modified version will always override the default one. As such, I’d recommend saving the modified syntax under a different name in your user folder and just selecting it when needed (or making all .js files open with that syntax).

  2. I wnated to refer to this, but I realize that this wouldn’t really help.
    Anyway, what you need to do is match the line in a look-ahead pattern (var)\s+({{identifier}})(?=\s*=\s*Promise\.coroutine\(), then apply the entity.name.function scope to the identifier and take care of setting/pushing/not changing a context that takes care of matching the rest of this assignment.
    Make sure to arrange this match before the literal var keyword is matched: https://github.com/sublimehq/Packages/blob/211a27c8c6b5fb42a85a5139028ca5efc5470e58/JavaScript/JavaScript.sublime-syntax#L703

1 Like