Nested syntax highlighting

Joel Thornton 13 years ago updated by Trevor Allen 11 years ago 10
Support nested syntax highlighting.

Sublime Text 2 understands syntax in a manner that should make nested syntax highlighting possible.

Within a certain syntax scope, e.g. string.quoted.double.java, support the creation of rules by the user which will cause a syntax-mode switch for the contents of that text's scope.

For example, we might create a rule: when in string.quoted.double.java, if the contained text matches /^SELECT/, apply .SQL syntax highlighting to that text instead.

A set of reasonable default rules could be assembled, e.g. for detecting stringified HTML and SQL in many languages, for Javascript within HTML <script> tags, etc. Allow toggling of these rules with a new View menu item "Nested syntax highlighting".

This could also be used to support per-file syntax highlighting in the find-in-all-files result buffer.

Some additional rule/configuration may be required to handle comprehension of string concatenation which varies by language, e.g. "some" + "thing" and multiline concatenations. Sublime would need to apply a nexted syntax-mode to all the parts of such a string whenever the (whole) string matches a rule.

The rules' criteria should support arbitrary python for cases which don't match a regex well; that code should be able to examine the parent scopes' text to make its assessment (e.g. examining a string variable's declared name in one's code to determine the string's syntax).
In a given file the user should be able to arbitrarily change the syntax-mode of any individual syntax-scope in any buffer, through the right click context menu or other method.
This would be an awesome nearly invisible feature. It already somehow does this when I put SQL into php strings
Any luck with this? This feature would be super hot
I'm pretty sure embedded code is already supported in syntax highlighting.  Whenever I'm editing a PHP file that contains both HTML and PHP code, the PHP code is treated as embedded code and is highlighted appropriately.
This may be in place for some syntax combinations, but not all. My web2py view (template) files are html with Python code embedded (always between double curly braces {{ }}). The files are initially treated as plain text. When I set them manually to html the Python bits are not recognized (though javascript in the same files is recognized).

+1 for this idea. There are always questions about it and by using the original TextMate parsing engine, instead of the new TM2 one, we're missing out on some important features that even vim has ;)

If this is already possible (as the commenters talking about PHP claim), then perhaps the question is just one of publishing some documentation that explains how to do it for other mixtures?


Definitely - as with @Ian Scott, I cannot get it to recognize and highlight embedded syntax within HTML (as an example). Even on the forums and going through it - it would not:


It doesn't work in PHP either. 

For instance if I try to embed PHP into HTML like this: 

<form action="<?php echo $url?>" method="post">

everything between the quotation marks is colored evenly, it is treated the same way "post" is, just like a simple string.

This has been done for JavaScript but not for other languages. I personally would like to see this done for Clojure and Scheme.

An addition to previous indications that this capability already exists in a limited form: SQL statements in Python and regex patterns in Python. Paste these examples into SublimeText to see for yourself. 

SQL highlighting only recognizes a few SQL commands (e.g. "INSERT INTO" but not "CREATE TABLE"), and requires upper case syntax to be triggers: 

lowerCaseSQL1 = 'insert into tablename (columnName) values (value)'

upperCaseSQL1 = 'INSERT INTO TALBENAME (columnName) VALUES (value)'

lowerCaseSQL2 = 'select * from tablename'

upperCaseSQL2 = 'SELECT * FROM tablename'

failedSQL = 'CREATE TABLE IF NOT EXISTS tablename'

Regex highlighting is employed when using raw string notation:

regexString = r'^test[S]tring([a-z]+)\t\d{0,2}\d$'

nonRegexString = '^test[S]tring([a-z]+)\t\d{0,2}\d$'