Implement multiple languages in plugin

Is it possible to implement HTML language and Java for a custom language plugin?

 

So the plugin should handle 3 languages:

1. rythm (custom language)

2. HTML

3. Java

13 comments
Comment actions Permalink

Actually, you may support a custom language in your plugin, and configure dependency of your plugin on other language plugins, as needed.

For example, the Groovy plugin depends on the Java plugin, so it's able to interoperate with it and reuse the code from it.

0
Comment actions Permalink

How can I configure the dependency?

My plugin can handle now HTML and rythm. It would be great if I could add java language to the plugin.

0
Comment actions Permalink

You need to add the line <depends>com.intellij.modules.java</depends> to your plugin's META-INF/plugin.xml, and add a dependency to java-impl in your module's properties.

Here's how it's done in JavaFX: https://github.com/JetBrains/intellij-community/blob/306d705e1829bd3c74afc2489bfb7ed59d686b84/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml - there are dependencies on Java and on Properties plugins.

 

0
Comment actions Permalink

Thanks Pavel.

I'll try that. :)

0
Comment actions Permalink

After adding java-impl to the module's properties this error appears

Did I forgot something?

 

Edit:

Ok after I added java-impl to Global Libraries it looks alright.

But I still can't use Java features in my plugin.

0
Comment actions Permalink

Sorry for misleading comment, the java-impl is already bundled within IntelliJ IDEA, so you don't need to add it as a dependency.

Please remove it, and try to use a Java-specific class in your code, like JavaElementVisitor to see if it's available.

0
Comment actions Permalink

I added these extensions to the plugin.xml but it's still not working.

<depends>com.intellij.modules.java</depends>


<extensions defaultExtensionNs="org.intellij.intelliLang"></extensions>

<extensions defaultExtensionNs="com.intellij">

<errorOptionsProvider instance="com.intellij.profile.codeInspection.ui.JavaErrorOptionsProvider"/>
<autoImportOptionsProvider instance="com.intellij.application.options.editor.JavaAutoImportOptions"/>
<completion.confidence language="JAVA" implementationClass="com.intellij.codeInsight.completion.JavaReferenceCompletionConfidence"/>
<completion.confidence language="JAVA" implementationClass="com.intellij.codeInsight.completion.JavadocCompletionConfidence" id="javadoc" order="before javaComments"/>
<completion.confidence language="JAVA" implementationClass="com.intellij.psi.impl.source.resolve.reference.impl.JavaReflectionCompletionConfidence" id="javaReflection" />
<completion.contributor language="any" implementationClass="com.intellij.codeInsight.completion.JavaClassReferenceCompletionContributor"
id="javaClassReference" order="before legacy"/>
<completion.contributor language="any" implementationClass="com.intellij.codeInsight.completion.JavaMethodMergingContributor" id="methodMerger"
order="before javaLegacy, before default"/>
<completion.contributor language="JAVA" implementationClass="com.intellij.codeInsight.completion.JavaMemberNameCompletionContributor" id="javaMemberName"
order="before javaOverride"/>
<completion.contributor language="any" implementationClass="com.intellij.codeInsight.completion.JavaClassNameCompletionContributor" id="javaClassName"
order="last, before default"/>
<lang.syntaxHighlighterFactory language="JAVA" implementationClass="com.intellij.lang.java.JavaSyntaxHighlighterFactory"/>
<syntaxHighlighter id="java.class" key="CLASS" factoryClass="com.intellij.lang.java.JavaSyntaxHighlighterFactory"/>

I also tried to change to:

<depends>com.intellij.modules.java</depends>


<extensions defaultExtensionNs="org.intellij.intelliLang"></extensions>

<extensions defaultExtensionNs="com.intellij">

<errorOptionsProvider instance="com.intellij.profile.codeInspection.ui.JavaErrorOptionsProvider"/>
<autoImportOptionsProvider instance="com.intellij.application.options.editor.JavaAutoImportOptions"/>
<completion.confidence language="RythmTemplateLanguage" implementationClass="com.intellij.codeInsight.completion.JavaReferenceCompletionConfidence"/>
<completion.confidence language="RythmTemplateLanguage" implementationClass="com.intellij.codeInsight.completion.JavadocCompletionConfidence" id="javadoc" order="before javaComments"/>
<completion.confidence language="RythmTemplateLanguage" implementationClass="com.intellij.psi.impl.source.resolve.reference.impl.JavaReflectionCompletionConfidence" id="javaReflection" />
<completion.contributor language="any" implementationClass="com.intellij.codeInsight.completion.JavaClassReferenceCompletionContributor"
id="javaClassReference" order="before legacy"/>
<completion.contributor language="any" implementationClass="com.intellij.codeInsight.completion.JavaMethodMergingContributor" id="methodMerger"
order="before javaLegacy, before default"/>
<completion.contributor language="RythmTemplateLanguage" implementationClass="com.intellij.codeInsight.completion.JavaMemberNameCompletionContributor" id="javaMemberName"
order="before javaOverride"/>
<completion.contributor language="any" implementationClass="com.intellij.codeInsight.completion.JavaClassNameCompletionContributor" id="javaClassName"
order="last, before default"/>
<lang.syntaxHighlighterFactory language="RythmTemplateLanguage" implementationClass="com.intellij.lang.java.JavaSyntaxHighlighterFactory"/>
<syntaxHighlighter id="java.class" key="CLASS" factoryClass="com.intellij.lang.java.JavaSyntaxHighlighterFactory"/>

 For example I want to get a code completion for packages.

0
Comment actions Permalink

Unfortunately it's not that easy, and it depends on what you're going to achieve.

If you want to mix Java and your language in the same file, it's definitely possible, but very difficult.

If your language is only going to use classes and methods written in Java, it's much easier, but not for free anyway. You still need to provide your own implementation of completion, syntax highlighting, and everything, but you can reuse the Java language API, e.g. to get the Java packages and classes defined in your project.

For example, the Groovy and JavaFX plugins do that, maybe you can do something similar.

0
Comment actions Permalink

Okay, thanks Pavel.

Option 2 is what I need.

The plugin already can Highlight HTML and my custom language. Code completion for my custom language is also working.

Now the only thing I want to implement is the Java language.

Is there anything I need to change or add in my project structure?

 

For me it looks like Groovy is using language injection to implement java language.

0
Comment actions Permalink

Could you please be more specific on what you need from the Java language?

For example, how the things in your language are connected with Java? Or which things from Java you're going to reuse?

0
Comment actions Permalink

I need the Java package and classes completion contributor and also Java keyword highlighting.

The plugin should support rythm (which is a template engine).

The syntax from rythm starts with @. It's pretty much the same as java.

0
Comment actions Permalink

The completion of packages and classes is done via JavaClassReference. You don't need to create it yourself, just use JavaClassReferenceProvider like it's done in org.jetbrains.plugins.javaFX.fxml.refs.ImportReferenceProvider. In the line "@import a.b.C" each of the identifiers a, b, and C should have a JavaClassReference to the corresponding package or class.

Regarding the highlighting, do you want the Java fields and methods to be colored? If so, you need to use reference to PsiMethod (or PsiField) on each your identifier referencing Java method (or field). You'll be able to check if the method or field exists (and highlight with red if it doesn't), and you'll get the navigation to Java code.

 

0
Comment actions Permalink

Thanks a lot, Pavel!! 

0

Please sign in to leave a comment.