Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JavaScript] Basic support for syntax highlighting in tagged templates #4019

Merged
merged 5 commits into from
Jul 28, 2024

Conversation

deathaxe
Copy link
Collaborator

Resolves #179

This commit adds support for syntax highlighting of CSS/JS/JSON/HTML within tagged template strings.

grafik

JavaScript embeds extended syntax definitions to enable ${...} interpolation in highlighted template tags, very much like most other template syntaxes (e.g.: Go Templates, Jinja2, Liquid, ...).

As templates are embedded, impact on syntax cache size and complexity of JavaScript itself is negligible. They are loaded on demand and thus shouldn't effect other template languages, significantly.

Compatibility notes:

  1. Template syntaxes such as Jinja or Liquid need to take action, if they want to support their own interpolations such as {{ ... }} within tagged template tags.
  2. This PR might affect JS Custom, which also supports adding syntax highlighted tagged template tags.
  3. This PR uses a naive way to add JavaScript interpolation in js`...` tags very much like other template syntaxes do. JavaScript however already highlights ${...} as some sort of dollar variable in various situations. It's currently not clear, if that would be enough which would mean to remove prototype manipulations.

This commit adds support for syntax highlighting of CSS/JS/JSON/HTML
within tagged template strings.
@deathaxe deathaxe requested a review from Thom1729 July 28, 2024 10:46
keith-hall
keith-hall previously approved these changes Jul 28, 2024
@keith-hall
Copy link
Collaborator

There's a couple of test failures with the latest commit, otherwise looks good to me

This commit...

1. adds a `literal-string-templates` context to include templates
   into contexts without popping it off stack.
2. adjusts tag scopes to already existing `variable.function.tagged-template`.
3. adds support for whitespace between template tag and punctuation
4. drops supportt for block quotes between template tag and punctuation
   for simplicity reasons. It's jugdged unlikely enough to appear in real
   world code.
@deathaxe
Copy link
Collaborator Author

They revealed dome shortcommings of my implementation.

Those are fixed.

I am still a bit uncertain about tags' scopes.

  1. JS originally uses variable.function.tagged-template.
  2. Bash and Perl use entity.name.tag to scope such language specifiers in front of HEREDOCs
  3. Markdown just uses constant.other.language-name in fenced code blocks.

Does it make sense to specify a common scoped used everywhere?

@michaelblyons
Copy link
Collaborator

I am in favor of standardization, but it doesn't have to be in this PR necessarily.

This commit adjusts syntax definition and indentation rules to ensure
content of tagged templates is indented, automatically.

It includes consuming all trailing/leading whitespace after opening and
in front of closing string punctuation, to ensure JavaScript indentation
rules being applied, when hitting enter after an opening template punctuation.
@deathaxe
Copy link
Collaborator Author

Applied some changes to auto-indent content of tagged templates, correctly. This commit will create a conflict with #4015 and might need further tweak after that has been merged to apply changes to the new indentation rule file as well.

@keith-hall
Copy link
Collaborator

I am still a bit uncertain about tags' scopes.

  1. JS originally uses variable.function.tagged-template.
  2. Bash and Perl use entity.name.tag to scope such language specifiers in front of HEREDOCs
  3. Markdown just uses constant.other.language-name in fenced code blocks.

Does it make sense to specify a common scoped used everywhere?

Pretty sure 1 is due to how js calls a function for the tagged template literals so seems correct for js. 2 is likely a relic of html tag scoping - it shouldn't IMO be an entity if it isn't defining something which can be referenced later. Yes, I know it uses the same token to end the heredoc, but I vote that it doesn't count. 3 seems like the modern way to me.

keith-hall
keith-hall previously approved these changes Jul 28, 2024
This commit strips embedded source scope after opening and before closing
string punctuation only, if those are located on a separate line.

In single line tagged template strings, embedded scope is applied to leading
and trailing whitespace as well.
@deathaxe
Copy link
Collaborator Author

Tweaked patterns so embedded source scopes are stripped only, when needed - not in single line template strings.

Related with #4020.

@deathaxe deathaxe merged commit 65a7571 into sublimehq:master Jul 28, 2024
1 check passed
@deathaxe deathaxe deleted the pr/javascript/tagged-templates branch July 28, 2024 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[JavaScript] HTML and CSS syntax highlighting in tagged template strings
3 participants