Skip to content
This repository has been archived by the owner on Aug 9, 2024. It is now read-only.

Support setting syntax highlighters for quasiquotes? #88

Open
iand675 opened this issue Sep 16, 2016 · 11 comments
Open

Support setting syntax highlighters for quasiquotes? #88

iand675 opened this issue Sep 16, 2016 · 11 comments

Comments

@iand675
Copy link

iand675 commented Sep 16, 2016

I often use quasiquoters for things like JSON, SQL queries, JavaScript code, etc. It would be great if there was a way to configure quasiquoters with specific names to syntax highlight for the syntax they implement.

Is such a thing possible now? Is it possible at all with Atom's syntax highlighting support?

@lierdakil
Copy link
Contributor

lierdakil commented Nov 16, 2016

Sorry for the belated reply, I somehow managed to miss this.

So, answer to your question is both yes and no. While it's entirely possible to embed other grammars into language-haskell, it comes with its own set of challenges. And it's definitely not configurable on the user-end, at least not without some dark and forbidden magic (which is fragile by definition)

So at best, I could eventually add support for TH quasiquotes, since those have rigid syntax definitions. For user-defined quasiquoters, that's just not worth it, IMO -- this would create more problems in the long run than solve, e.g. a flaky third-party grammar can easily break highlighting in Haskell files almost completely.

P.S. also, support for user-defined quasiquoters opens a whole another can of worms if it's not configurable on the user-end, which I don't want to even think about.

@tfausak
Copy link

tfausak commented Oct 7, 2017

I would also like to have this. I understand that the mappings are hard-coded into the grammar and can't be modified by the user, but I still think it would be useful. Something like this would be awesome:

capture

I've never made a Textmate/Sublime/Atom grammar before, so I mocked that one up with this simple grammar:

name: 'Haskell'
scopeName: 'source.haskell'
fileTypes: [ 'hs' ]
patterns: [
  {
    begin: '\\[json\\|'
    end: '\\|\\]'
    patterns: [ include: 'source.json' ]
  }
]

Obviously that's a bit simplistic. For the Real World ™️, two naive solutions come to mind:

  • Add hard-coded support for all the built-in language-* packages. That would cover most of the things people would be putting in quasi quotes (CSS, HTML, JSON, SQL, and so on). The downside is ignoring popular but not built in stuff like Docker or Nix.

  • Translate the quasi quote identifier into the source language. I don't know if Atom's grammar actually supports this, but if it does: Turning [Some.language| ... |] into a source.language section would neatly solve this problem without hard-coding anything. For example [Q.json| ... |] could be tagged as source.json. If this is possible, it would allow you to choose the inner syntax highlighting by choosing the appropriate identifier. (This is similar to language-ruby's heredoc syntax of <<-SQL.)

@lierdakil
Copy link
Contributor

Add hard-coded support for all the built-in language-* packages

I really don't like the idea of hard-coding this stuff, besides this grammar is used to highlight Haskell on GitHub as well, so I wonder if talking about language-* packages in Atom is even meaningful.

Adding all the "usual suspects" (json, yaml, sql, html, javascript, etc) would be possible in theory, but then it opens a can of worms of "why isn't X included". And with hardcoded prefixes there's another can of worms of "library Y uses prefix X for language Z". I'd personally much rather keep those proverbial cans closed.

Translate the quasi quote identifier into the source language.

Not possible. You'd need to include an external grammar based on what's parsed, and I'm pretty sure Atom's grammar model doesn't support this. I suspect partly because allowing something like that could break stuff really easily, and partly because it would be horribly inefficient (because you can't build a finite automaton if there are potentially infinite states)

@tfausak
Copy link

tfausak commented Oct 7, 2017

Bummer.

For comparison, language-ruby supports a few nested heredoc syntaxes. It's been around for a while and they haven't had a bunch of requests for more grammars. In fact, I could only find two: atom/language-ruby#187 and atom/language-ruby#199.

I feel like a partial solution here is better than nothing at all. Properly syntax highlighting SQL inside a quasi quote is definitely "nice to have"; treating it as a string is obviously okay. In my mind, supporting a couple of languages is a nice bonus rather than a "this needs to allow embedding everything under the sun".

@aryairani
Copy link

I came looking for a way to use SQL highlighting with the [here||] quasiquoter. I'd love to find or gain one!

@lierdakil
Copy link
Contributor

lierdakil commented Jun 24, 2020

With language-haskell v1.20 (just released), you can make a grammar package for that yourself quite easily (you could do this with earlier versions, but v1.20 makes it way easier):

  1. run the package-generator:generate-language-package command to create a new language package.
  2. Name it however you like
  3. Delete snippets, settings and spec directories (we don't need them and defaults are useless)
  4. Use the following template to write grammars/*.cson:
injectionSelector: 'quoted.quasiquotes.qq-<your-quasiquote-function-name-here>.haskell'
scopeName: '<grammar-scope>' # the same as below
patterns: [ { include: '<grammar-scope>' } ]
# <grammar-scope> is the root scope name of the grammar you 
# want to inject. To learn the root scope of any grammar,
# use `editor:log-cursor-scope` command

So, for instance to inject SQL grammar inside [here|...|] quasiquotes, one would do:

injectionSelector: 'quoted.quasiquotes.qq-here.haskell'
scopeName: 'source.sql'
patterns: [ { include: 'source.sql' } ]

Please be aware, that depending on the grammar being injected, it can easily escape the quasiquotes scope and basically "take over" the Haskell grammar with rather unappealing results:
image
This is not an issue with language-haskell.

@aryairani
Copy link

@lierdakil Thanks! I didn't quite get it working, but I'm very excited. Can you spot anything I'm doing wrong?

My language package:
image

I used apm link to install it:
image

Result, still no injected syntax highlighting; I sanity-checked the scopes:
image

I also tried restarting atom, but no change. 😅

@lierdakil
Copy link
Contributor

I can't see anything incorrect in the screenshots. Atom won't usually pick up the grammar injection package without a restart (or two), but usually running window:reload command a couple of times works too.

@aryairani
Copy link

I can't make it go (I even rebooted), but thanks for looking it over for me.

@aryairani
Copy link

@lierdakil blindly modeling after this gist, I switched the scopeName to match the injectionSelector, meaning I switched

injectionSelector: 'quoted.quasiquotes.qq-here.haskell'
scopeName: 'source.sql'
patterns: [ { include: 'source.sql' } ]

to

injectionSelector: 'quoted.quasiquotes.qq-here.haskell'
scopeName: 'quoted.quasiquotes.qq-here.haskell'
patterns: [ { include: 'source.sql' } ]

and that worked for me after a Window: Reload:
image
🎉 Thanks for your help.

@lierdakil
Copy link
Contributor

Huh. Curious. Thanks for letting me know.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants