Check out all the posts in our IntelliJ plugin development series:
No matter what your technical background as a developer looks like, you’ve probably come across or even used an IDE from JetBrains. Their product line features IDEs for various languages and technologies and they’re all built according to the same schema: Atop an extensible core (“IntelliJ platform”) sits a set of curated extensions that provides all of the “integrated” functionality of the IDE.
But what if you could extend your IDE further with your own plugins? Doing your own plugin for your workflows can improve your productivity drastically. In this post we’ll explore the IntelliJ API and build a simple plugin step-by-step to get you going.
Prerequisites
IntelliJ plugins run on the Java virtual machine (“JVM”), so naturally they’re written in a JVM-compatible language. The plugin APIs are best suited for Java and Kotlin. We’ll be using Java in this blog post. For development itself, we’ll be using the community edition of IntelliJ IDEA.
Getting started with IntelliJ plugin development
First, let’s create our project. The project creation wizard in IntelliJ IDEA provides a template called “IDE Plugin” which bootstraps an empty plugin built on top of Gradle. Make sure “Java” is selected and pick the JDK installed on your system from the “JDK” dropdown.
After clicking “Create” we’re greeted with a scaffold of everything we need to write and run our empty plugin on IntelliJ.
Run and debug your IntelliJ plugin
Our project uses Gradle. The project creation wizard created a bunch of Gradle tasks for us that are available at the “Gradle” panel to the right.
Clicking through these Gradle tasks shows tasks related to running, testing, signing and distribution but only a few of them are really relevant for day-to-day operations. For now, we’ll only need the runIde
task, which starts a new instance of IntelliJ IDEA with our plugin loaded.
But we don’t even need to mess with this panel all the time. The project template includes a run configuration called “Run Plugin” which lets us use the “Run” and “Debug” buttons in the top right toolbar to execute the runIde
task.
That’s great news: we’re hiring!
Create the context menu action for your IntelliJ plugin
In order to use our plugin we need to implement a so called “action”. Actions are commands in IntelliJ that can be triggered via the context menu, the action runner (CtrlShiftA) or a custom keyboard shortcut, depending on their configuration.
Let’s create a class called GoogleThis
in the com.example.demo
package and have it extend the AnAction
class.
package com.example.demo;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;
public class GoogleThis extends AnAction {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
}
}
As-is this is not doing anything yet. In order for IntelliJ to know that we are listening for the aforementioned events, we need to register our action inside the plugin.xml
file. This file contains general metadata about a plugin as well as declarations of what the plugin contributes to the relevant implementation classes.
You could add your action declaration by hand but in IntelliJ we can also just hover over the class name and click “Register Action” to register our class within the plugin.xml
file.
The name under which the entry should be displayed is “Google this please!”. EditorPopupMenu
defines where this action should live and we anchored it last, so it’s always displayed on the bottom. Last but not least we are assigning the keyboard shortcut CtrlAltG to our action.
After adding the action via the wizard we can verify that everything works, even if no implementation has been done yet, by running the plugin and checking the context menu. Just click the “Run” button in the top right corner and open any project in the new IDE instance. Then open any file and right-click to bring up the context menu.
So far so good!
Implement the functionality of your IntelliJ plugin
With our action registered we can click its context menu item but nothing happens when we do because its implementation is still completely blank. What should happen is the plugin reads the selected text, then constructs a URL to Google and opens a browser with that. A good place to start looking for the right interfaces to use when working on a plugin is the IntelliJ Platform Plugin SDK documentation. Failing that there’s also the IntelliJ Platform Explorer for finding real-world usages of APIs in open source plugins.
In this case, we use the CaretModel
of the editor, as described in the docs on the page “Editor Coordinates System. Positions and Offsets”. Invoking the browser is possible using a utility method in BrowserUtil
.
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
final Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
final CaretModel caretModel = editor.getCaretModel();
String selectedText = caretModel.getCurrentCaret().getSelectedText();
BrowserUtil.browse("https://www.google.com/search?q="+selectedText);
}
And with that we do have a working context menu item which searches for the highlighted text on Google. But there is now a bug where you can use the context menu even if you did not have any text highlighted which would simply search for null
. To avoid this we could check if selectedText
is null
and do nothing, or we can use the update
method of the AnAction
class to hide the context menu entirely.
@Override
public void update(AnActionEvent e) {
final Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
final CaretModel caretModel = editor.getCaretModel();
e.getPresentation().setEnabledAndVisible(caretModel.getCurrentCaret().hasSelection());
}
Now the Google this please!
context menu item is not visible if no text is selected.
That’s great news: we’re hiring!
Conclusion: how to get started with buildling plugins for IntelliJ IDEs
And that’s it. Congratulations, you’ve just written your first IntelliJ IDEA plugin! This plugin will not only work on IntelliJ IDEA: almost all JetBrains IDEs build upon the IntelliJ platform, so your plugins can be installed in all of them! (Provided they don’t depend on any exclusive functionality.) If you want to read more about plugin development, you can subscribe to our newsletter. In any case make sure to follow us on Twitter, Facebook or LinkedIn as well to get notified on posts about software development, software testing or if you are simple into memes.