Skip to content

Conversation

@Monkatraz
Copy link
Contributor

@Monkatraz Monkatraz commented Oct 30, 2020

Practically fixes #295, and helps with #106

About

Adds improved syntax highlighting when using Pug with Svelte. It assumes the user is using svelte-preprocessor, as the highlighting matches against the mixins that come with that plugin. As far as I can tell, all of the usual features of Svelte appear mostly natural in Pug now, albeit surrounded in quotation marks for anything embedded.

Please note: this is only a bunch of Textmate bundles. This does not add any additional functionality beyond highlighting and embedding, unfortunately. If less clunky Pug support was to be added, I suspect it would require a modified Pug compiler, or at least a lot of preprocessing with regex.

Neat Features:

  • Does not clone the original Pug grammar, it instead injects into Pug whenever Pug appears inside a source.svelte scope
  • Has absolutely no effect on normal Pug files, and probably allows for any extensions interacting with Pug to continue to do so within Svelte
  • Validates interpolated {...} blocks in certain contexts
    • Checks for mismatched quotes on attribute assignment selections
    • Warns against using a single unsafe = instead of !=
    • Checks if you just forgot quotes entirely
  • Specially handles Svelte's element directives, making it more clear about what type of value you are binding/assigning
  • Has a special {...} interpolation case, {{...}} for object literals instead of statement blocks. This means that when setting opts. objects for functions the syntax highlighting will be appropriate for a JS/TS object
  • Handles Pug's wacky shorthand syntax, e.g. div: Component()
  • Handles inlined Pug, e.g. p Some text #[+if('someVar') more text] even more text
  • It may actually be more feature-rich than Svelte's native highlighting which I find funny

Compromises:

  • Requires three separate injected grammars to work properly. I couldn't find any other way to do this - you cannot override an embedded language from a parent language as far as I can tell.
  • Most of the scopes only work on one line. This was to make the grammar less agonizing to create. I suspect in 95% of use cases this will be suitable.
  • Some of the ways the highlighting works is... dubious, due to it's inherit 'duct-tape on top of duct-tape' nature. I suspect there is edge cases I haven't seen.

What's missing?

  • Doesn't do anything special with the svelte:[something] elements. Doesn't break the highlighting either, though.

The bad:

  • It's not particularly tested, but I figured I'd rather get it out there and trialed by fire. It's simply too difficult to know how the grammar will be used.
  • Textmate grammars are terrible.
  • I think Regex took my soul.

Some images

Code_RwJdTdoFvw
Code_R3OhOElzqf
Code_MB7ry1UTdL

Adds improved syntax highlighting when using Pug with Svelte. Uses injected grammars - this way the original Pug grammar is kept as it is, and does not have to be cloned.
Copy link
Member

@dummdidumm dummdidumm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for this! It indeed looks better highlighting-wise than the existing "normal" Svelte highlighting. You are welcome to add some additional highlighting to that, too, if your head is not too blurry already from this PR 😄

One thing that needs a second look though is that I now get slightly different syntax highlighting in Svelte without Pug, too. I think it's because the injectionSelector contains meta.tag.other which matches not just template tags, but every html tag according to svelte.tmlanguage.json. I'm not sure if that could just be omitted.

@Monkatraz
Copy link
Contributor Author

One thing that needs a second look though is that I now get slightly different syntax highlighting in Svelte without Pug, too. I think it's because the injectionSelector contains meta.tag.other which matches not just template tags, but every html tag according to svelte.tmlanguage.json.

Fixed. Probably. I somehow totally blanked on making sure that injector was only specific to Pug. Funny enough, all you have to do is just prepend it with "text.pug" to make it work.

Injection selectors (aka scope selectors) are utterly undocumented. The more complex ones in this PR I have no idea if they're actually correct. They work, is all I know. I seriously question why VS Code chose to exclusively support Textmate grammars, when they already have a much, much better system with Monarch - with documentation. It's literally implemented into the editor, just only on the browser version.

Copy link
Member

@dummdidumm dummdidumm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍
Yeah this style of writing syntax highlighting is kinda messy.

@dummdidumm dummdidumm merged commit a6ba62d into sveltejs:master Oct 30, 2020
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.

Pug syntax highlight

2 participants