Language injections in Rider

Just like ReSharper, Rider supports language injections. In almost every project there are cases where we want to (or have to) embed a piece of code in a string literal. For example, pieces of HTML inside a JavaScript string, or a quick JSON fragment inside a C# string. Let’s see how they work.

Note: In this blog post, we’ll look at some of the basics of language injections. They work similar in both Rider and ReSharper – check this deep-dive post on language injections in ReSharper to learn more.

Mark as injected language

Like all good things in Rider, Alt+Enter is where it starts. In the editor, we can place the caret on a string literal and mark it as an injected language.

Inject CSS into C# string literal

Whenever a string contains C#, regular expressions, CSS, HTML, JSON or JavaScript, Rider can treat it as a code fragment, providing highlighting and code analysis for them. Even quick-fixes are available, for example for selecting a specific CSS color or fixing a JavaScript comparison:

JavaScript language injection - quick-fix

Injection comments

Rider will remember this string is an injected language, but sometimes it’s impossible to keep track. For example after a large refactoring or moving classes or methods around, Rider may lose track and we may have to mark the string as injected language again.

We can make use of injection comments – a way of telling Rider the string literal following the comment should be treated as injected language. Here are some examples of using injection comments:

Language injection comments in Rider

Each injection comment should at least have the language specified, which can be CSS, HTML, JSON, JSREGEXP (a JavaScript regular expression), REGEXP (a .NET regular expression) or JAVASCRIPT.

We can also add a prefix and postfix, essentially telling Rider to treat the string literal as being “inside” the structure provided by prefix and postfix. In the above screenshot we are using this technique to get highlighting for CSS colors (see myColor) or on the attributes of an <a /> element without having the entire HTML element inside the string literal (see myAttributesForAnchor).

More examples of using language injection comments are available in the IntelliJ IDEA web help.

Right now it’s only possible to mark a single string literal as injected language (so no concatenations, nor a C# interpolated string). Also, injected language fragments are always scoped to the local string instead of the entire document. We’ll be working to address these limitations!

Give the latest Rider EAP build a try! We’d love to hear your feedback!

This entry was posted in How-To's and tagged , , , , , , , . Bookmark the permalink.

3 Responses to Language injections in Rider

  1. Jose says:

    The idea is cool, but sorry it is unusable.

    Missing two very important points:
    * injected code is 90% of the time multiline, seems not supported,
    * injected code has 90% of the time string interpolation, seems not supported either.

    Otherwise wonderful idea. Not usable yet though.

    • Maarten Balliauw says:

      Thanks Jose! Logged this in our YouTrack as well: https://youtrack.jetbrains.com/issue/RIDER-5748

    • Anton Lobov says:

      Thanks a lot for the feedback, Jose! This feature is already being upgraded for ReSharper 2017.2, and this upgrade comes to Rider as well, a bit later.

      Support for C# string interpolation, ES6 templates with arguments, and string concatenations is planned: https://youtrack.jetbrains.com/issue/RSRP-460083.

      It was postponed because arguments can appear in unpredictable places, can have unpredictable meaning, and can break target language syntax. We’ll add a special mean of dealing with this in ReSharper 2017.2 and then it comes to Rider as well (so that if it is a ‘normal’ syntax, it won’t require your additional interaction, but if it is a ‘broken’ syntax, you’ll need to specify some options).

      Multiline injects are already supported for C# verbatim strings and for ES6 template literals, as long as they don’t have arguments. Try this, for example:

      public class A
      {
      public void Foo()
      {
      // language=html
      var s = @”
      <html>
      <head>
      <title>My Page</title>
      </head>
      </html>
      “;
      }
      }

      If you’ll have more feedback about this feature, feel free to report it either here, or in our issue tracker here: https://youtrack.jetbrains.com/newIssue?project=RSRP&clearDraft=true&c=Subsystem+Language+injection&c=Assignee+Anton.Lobov&c=Type+Feature.

Leave a Reply

Your email address will not be published. Required fields are marked *