I’m creating a plugin that injects custom syntax in Java & Kotlin comments.
The initial implementation had an com.intellij.lang.InjectableLanguage
, which was added in PsiComment
elements. The downside is that the AST my parser created was separate from the original file, so I couldn’t access comment’s injected AST from other comments.
I was suggested to look into com.intellij.psi.templateLanguages.TemplateLanguage
functionality and I used the Handlebars plugin as a reference.
The current issue is that my lexer receives the entire Java file. What do I need to do to make it detect Java comments and use my lexer and parser only for those? The plugin code is available on GitHub. (Unfortunately I can’t add links to specific files, but all relevant implementation is in the linked directory)
Hello.
I’ve implemented language injection several times: in PHP strings and in Cron plugin.
Both time I did it with multiHostInjector
extension point.
multiHostInjector
allows you to mark suffixes (start / end) and text range inside the element. I think this is what you are looking for:
- Check if the PsiComment suites your custom syntax
- Find start and the end of the syntax
- And inject custom language
The main thing of language injecting is the target psi element must implement PsiLanguageInjectionHost
I’ve implemented MultiHostInjector
with
class StitcherInjector : MultiHostInjector, InjectionBackgroundSuppressor {
private val comments: List<Class<out PsiElement>> = listOf(PsiCommentImpl::class.java)
override fun getLanguagesToInject(registrar: MultiHostRegistrar, context: PsiElement) {
if (context is PsiLanguageInjectionHost && context.isStitcherComment) registrar
.startInjecting(StitcherLang)
.addPlace(null, null, context, ElementManipulators.getValueTextRange(context))
.doneInjecting()
}
override fun elementsToInjectIn(): List<Class<out PsiElement>> = comments
}
@Suppress("UnstableApiUsage")
class StitcherFileTypeOverrider : FileTypeOverrider {
override fun getOverriddenFileType(file: VirtualFile): FileType? =
if (file is LightVirtualFile && file.language == StitcherLang) StitcherFile.StitcherFileType else null
}
However, this doesn’t fix the issue. The injected elements are in their own PsiFile
-s, so I can’t access other snippets. I’m using the PsiViewer plugin to inspect the parsed structure, but it can’t access the comment syntax.