Fork a Language Definition

I’m attempting to build a language definition for EJS (Embedded Javascript Templating), which is based on HTML. I figure the easiest way to do it is to use the HTML language definition and build on top of that. Where can I find it?

1 Like

Nova uses extensions for its syntax definitions internally, the only special thing about them being they are located inside the application bundle: right click in Finder, select “Show Bundle Contents”, navigate to Contents → SharedSupport → Extensions → HTML.novaextension, repeat bundle opening operation with that. However.

Forking a builtin syntax is a maintenance nightmare: you will have to repeat that every single time Nova’s own syntax definitions update, which is about every release, lest the users of your extension remain saddled with bugs the main HTML definition has fixed, or miss features it has added. It’s preferable to extend the builtin HTML syntax, the only trouble with this being Nova does not have an API for that.

The good news is that, for HTML based template languages, you still can get quite far extending the syntax without such an official extension point. The exact approach depends on if your specific syntax inclusions are terminal or not. By that I mean: are your template tags only found in the content area of ordinary HTML and do they only contain content and other template constructs?

  • If the answer to that is yes, injecting them is a simple matter of including the builtin HTML syntax and adding your own scope collection(s), like the Swift Stencil extension does.
  • If the answer is no, you can still inject your scopes by using Template Scopes. This has a few drawbacks, but it still compares advantageously to maintaining a syntax fork IMO. Check out the Perch extension for a solution following this pattern.

This thread has a few good snippets of information on the issue.


By that I mean: are your template tags only found in the content area of ordinary HTML and do they only contain content and other template constructs?

I’m not sure what you mean, could you expand on this a bit?
It uses stuff like <%= and %> as tags to work with Javascript within what’s virtually an HTML file.
Here’s an example of the syntax.

<% if (user) { %>
  <h2><%= %></h2>
<% } %>

Judging from your code snippet, yours is the second case, non-terminal template tags (there is a vanilla HTML tag, h2, inside your template tag). I’d recommend you go the Template Scope route like the Perch extension did. See the links in my first answer.

I want to change the single comment for php from // to #. I created an extension to overwrite it… but that didn’t work.

I changed the syntax inside Contents → SharedSupport → Extensions → PHP.novaextension but also didn’t work, probably the extension needs to be refreshed but I don’t know how to do that

I wouldn’t edit Nova’s included syntax definitions I were you, because your edits will be lost the next time Nova updates, but if you must, I suppose you’ll have to restart Nova to have the change take effect.

1 Like

Whoops. Changing files inside an Apple double-signed application is a no-no; at best, Nova will stop working, and you’ll need to install it again. I’m speaking of my own experience :wink: — because, obviously, I just had to try that and see if it worked :smile_cat:

The whole idea with the application signing is not only to make sure that you did, indeed, install a legitimate copy of the Nova editor from Panic — but also to make sure that it does not get tampered with, and that essentially means not allowing users to change whatever files are inside the package…

You can, however, make a copy of Panic’s original extension to somewhere else, change it at will (especially the name and version, etc., so that there are no conflicts), and activate it as any other extension. That should be 100% safe.

If you didn’t get any errors running Nova after making those changes, you’re probably overriding the macOS security features. You can certainly do that, but it’s a big security issue!

Also, with any upcoming upgrades, as @kopischke said, the changes you made will very likely be overwritten anyway…

1 Like

I created a new extension but that didn’t override the single comment from // to #. So my second option was to override the core extension. Nova didn’t crash but the extension is not reloaded and the change don’t take effect. Bummer

Just chiming in - I also have attempted to override Nova’s language definition to solve syntax highlighting issue · Issue #68 · apexskier/nova-typescript · GitHub, but wasn’t able to get anything working.

Nova’s built-in languages, while containing the XML files for the definition, are precompiled into the app during our build phase for performance. Nova itself does not reference the XML files for built-in definitions, so in addition to the codesigning concerns mentioned above, any changes to those files will not be reflected in Nova’s actual behavior.