Search code examples
intellij-ideamarkdownjsxremarkjs

Adding Markdown JSX Language Injection to IntelliJ


Short Summary

So, I’m trying to use MDX in my project. It’s just MarkDown with some JSX (including ES6 imports) mingled in. I want to use IntelliJ to edit the files and get proper syntax highlighting for both the Markdown bits and the JSX bits.

I think I should be able to configure a language injection for this, but I’m a bit stalled trying to move forward. It looks like I’ll need to write the XML myself, since the language syntax I want is JSX, and the only target languages in the UI are xml, js, sql, and a few other common ones.

What I've Tried

Looking at the source for the Groovy injections and the Java injections, I started to piece together what I'd need.

I looked at the PSI Structure of one of my sample MDX files (which I've told IntelliJ to treat as Markdown). I could see that my JSX tag was being registered as an HTML_TAG element.

<?xml version="1.0" encoding="UTF-8"?>
<component name="LanguageInjectionConfiguration">
    <injection language="JSX" injector-id="markdown">
        <display-name>JSX in Markdown</display-name>
        <place><![CDATA[psiElement().withElementType(org.intellij.plugins.markdown.lang.MarkdownTokenTypes.HTML_TAG)]]></place>
    </injection>
</component>

IntelliJ failed to import that with a message saying, "No new entries have been imported". Then I looked at a sample export, and saw that I should use the <LanguageInjectionConfiguration> tag, so I tried:

<LanguageInjectionConfiguration>
    <injection language="JSX" injector-id="markdown" enabled="true">
        <display-name>JSX in Markdown</display-name>
        <place><![CDATA[psiElement().withElementType(org.intellij.plugins.markdown.lang.MarkdownTokenTypes.HTML_TAG)]]></place>
    </injection>
</LanguageInjectionConfiguration>

...but, I received the same error.

Looking at the IntelliJ logs, it displays this error:

2018-10-23 12:17:28,680 [3894254] WARN - s.compiler.PatternCompilerImpl - JSX in Markdown: psiElement().withElementType(org.intellij.plugins.markdown.lang.MarkdownTokenTypes.HTML_TAG)

java.lang.IllegalStateException: 33(.): 'org.' method name start is invalid, '(' expected

at com.intellij.patterns.compiler.PatternCompilerImpl.throwError(PatternCompilerImpl.java:293)

...long, long stack trace...

at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

MarkdownTokenTypes.HTML_TAG is definitely of the IElementType required by one of the withElementType method signatures.

Conclusion

I fear that I'm over complicating this. Is there a good guide to writing custom language injection? It's not clear to me what the return type should be for the place tag, nor if I should favor using a pattern instead of a place.


Solution

  • According to a comment on this issue there is a planned Addon coming that will enable "basic support" for MDX in JetBrains products:

    comment picture

    Not clear yet on what "basic MDX support" means, but it will be more than just syntax highlighting and word completion. It will have "coding assistance" which I assume will be context actions, automatic imports, etc. I asked for clarity on the thread and will update this answer if I hear anything more.