IntelliJ IDEA Plugins schreiben

1. Einführung

In den letzten Jahren hat sich IntelliJ von JetBrains schnell zur besten IDE für Java-Entwickler entwickelt. In unserem neuesten State of Java report war IntelliJ die erste Wahl für 55% der Befragten (48% im Vorjahr).

Ein Feature, das IntelliJ für Java-Entwickler so interessant macht, ist die Möglichkeit, neue Funktionen mithilfe von Plugins zu erweitern und zu erstellen. In diesem Lernprogramm werden wir ein IntelliJ-Plugin schreiben, um einige Möglichkeiten zur Erweiterung der IDE zu veranschaulichen.

Beachten Sie, dass der Artikel zwar auf IntelliJ-Plugins ausgerichtet ist, aber alle IDEs von JetBrains denselben Code verwenden. Daher können viele der hier verwendeten Techniken auch auf andere IDEs von JetBrain angewendet werden, wie z. B. PyCharm, RubyMine und mehr.

2. Plugin-Funktionalität

Die Plugin-Funktionalität für IntelliJ fällt normalerweise in eine von 4 Kategorien:

  • Benutzerdefinierte Sprachen : Die Fähigkeit, Code zu schreiben, zu interpretieren und zu kompilieren

in verschiedenen Sprachen verfasst Frameworks ** : Unterstützung für Frameworks von Drittanbietern wie Spring

  • Tools : Integration mit externen Tools wie Gradle

  • Benutzeroberflächen-Add-Ons : neue Menüpunkte, Werkzeugfenster und Schaltflächen,

und mehr

  • Plugins fallen oft in mehrere Kategorien ** . Beispielsweise interagiert das mit IntelliJ gelieferte Git-Plugin mit der auf dem System installierten git-Programmdatei. Das Plugin stellt sein Toolfenster und Popup-Menüelemente bereit und integriert es außerdem in den Workflow der Projekterstellung, das Voreinstellungsfenster und mehr.

3. Plugin erstellen

Der einfachste Einstieg in IntelliJ-Plugins ist die Verwendung von http://www.jetbrains.org/intellij/sdk/docs/basics/getting started/using dev kit.html[Plugin DevKit]. Dies kann über das Menü New > Project__ erreicht werden:

  • Beachten Sie, dass wir ein JetBrains-JDK verwenden müssen, ** um sicherzustellen, dass die erforderlichen Plug-In-Klassen im Klassenpfad verfügbar sind. IntelliJ sollte standardmäßig mit einem geeigneten JDK geliefert werden. Andernfalls können wir eines unter https://bintray.com/jetbrains/intellij-jdk (hier) herunterladen.

Zum jetzigen Zeitpunkt können wir nur Java 8 zum Schreiben von IntelliJ-Plugins verwenden. Dies liegt daran, dass JetBrains derzeit kein offizielles JDK für Java 9 oder höher bereitstellt.

4. Beispiel Plugin

Um das Schreiben eines IntelliJ-Plugins zu demonstrieren, erstellen wir ein Plugin, das den schnellen Zugriff auf die beliebte Stack Overflow-Website aus verschiedenen Bereichen der IDE ermöglicht. Wir werden hinzufügen:

  • Ein Menüpunkt Extras, um die Seite Frage stellen zu besuchen

  • Ein Popup-Menüelement im Texteditor und in der Konsolenausgabe für die Suche

Stapelüberlauf für hervorgehobenen Text.

4.1. Aktionen erstellen

  • Aktionen sind die Kernkomponente zum Schreiben von IntelliJ-Plugins ** .

Aktionen werden durch Ereignisse in der IDE ausgelöst, z. B. durch Klicken auf ein Menüelement oder eine Symbolleistenschaltfläche.

Der erste Schritt beim Erstellen einer Aktion ist das Erstellen einer Java-Klasse, die AnAction erweitert. Für unser Stack Overflow-Plugin erstellen wir zwei Aktionen.

Die erste Aktion öffnet die Seite Frage stellen in einem neuen Browserfenster:

public class AskQuestionAction extends AnAction {
   @Override
   public void actionPerformed(AnActionEvent e) {
       BrowserUtil.browse("https://stackoverflow.com/questions/ask");
   }
}

Wir verwenden die eingebaute BrowserUtil -Klasse, da sie alle Nuancen beim Öffnen einer Webseite unter verschiedenen Betriebssystemen und Browsern handhabt.

Die zweite Aktion öffnet die Stack Overflow-Suchseite und übergibt den Suchtext als Abfragezeichenfolge. Dieses Mal implementieren wir zwei Methoden.

Die erste Methode, die wir implementieren, ist wie unsere erste Aktion und behandelt das Öffnen eines Webbrowsers.

Zunächst müssen wir jedoch zwei Werte für StackOverflow erfassen. Eines ist das Sprach-Tag und das andere ist der zu suchende Text.

Um das Sprach-Tag zu erhalten, verwenden wir die Program Structure Interface . Diese API analysiert alle Dateien in einem Projekt und bietet eine programmatische Möglichkeit, sie zu überprüfen.

In diesem Fall verwenden wir das PSI, um die Programmiersprache einer Datei zu bestimmen:

PsiFile file = e.getData(CommonDataKeys.PSI__FILE);
Language lang = e.getData(CommonDataKeys.PSI__FILE).getLanguage();
String languageTag = "+[" + lang.getDisplayName().toLowerCase() + "]";

Beachten Sie, dass das PSI auch sprachspezifische Details zu einer Datei bereitstellt.

Zum Beispiel können wir das PSI verwenden, um alle öffentlichen Methoden in einer Java-Klasse zu finden.

Um den zu suchenden Text zu erhalten, verwenden wir den __Editor __API, um markierten Text auf dem Bildschirm abzurufen:

final Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
CaretModel caretModel = editor.getCaretModel();
String selectedText = caretModel.getCurrentCaret().getSelectedText();

Obwohl diese Aktion für das Editor- und das Konsolenfenster gleich ist, funktioniert der Zugriff auf den ausgewählten Text auf dieselbe Weise.

Jetzt können wir dies alles in einer actionPerformed -Deklaration zusammenfassen:

@Override
public void actionPerformed(AnActionEvent e) {

    PsiFile file = e.getData(CommonDataKeys.PSI__FILE);
    Language lang = e.getData(CommonDataKeys.PSI__FILE).getLanguage();
    String languageTag = "+[" + lang.getDisplayName().toLowerCase() + "]";

    Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
    CaretModel caretModel = editor.getCaretModel();
    String selectedText = caretModel.getCurrentCaret().getSelectedText()

    String query = selectedText.replace(' ', '+') + languageTag;
    BrowserUtil.browse("https://stackoverflow.com/search?q=" + query);
}

Diese Aktion überschreibt auch eine zweite Methode mit dem Namen update . Dadurch können wir die Aktion unter verschiedenen Bedingungen aktivieren oder deaktivieren.

In diesem Fall deaktivieren wir die Suchaktion, wenn kein Text ausgewählt ist:

@Override
public void update(AnActionEvent e) {
     Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
     CaretModel caretModel = editor.getCaretModel();
     e.getPresentation().setEnabledAndVisible(caretModel.getCurrentCaret().hasSelection());
}

4.2. Aktionen registrieren

Sobald wir unsere Aktionen geschrieben haben, müssen wir sie bei der IDE registrieren. Dafür gibt es zwei Möglichkeiten.

Der erste Weg ist die Verwendung der Datei plugin.xml , die für uns erstellt wird, wenn wir ein neues Projekt beginnen.

Standardmäßig hat die Datei ein leeres <actions> -Element, in das wir unsere Aktionen einfügen werden:

<actions>
    <action
      id="StackOverflow.AskQuestion.ToolsMenu"
      class="com.baeldung.intellij.stackoverflowplugin.AskQuestionAction"
      text="Ask Question on Stack Overflow"
      description="Ask a Question on Stack Overflow">
        <add-to-group group-id="ToolsMenu" anchor="last"/>
    </action>
    <action
      id="StackOverflow.Search.Editor"
      class="com.baeldung.intellij.stackoverflowplugin.SearchAction"
      text="Search on Stack Overflow"
      description="Search on Stack Overflow">
        <add-to-group group-id="EditorPopupMenu" anchor="last"/>
    </action>
    <action
      id="StackOverflow.Search.Console"
      class="com.baeldung.intellij.stackoverflowplugin.SearchAction"
      text="Search on Stack Overflow"
      description="Search on Stack Overflow">
        <add-to-group group-id="ConsoleEditorPopupMenu" anchor="last"/>
    </action>
</actions>

Durch das Registrieren der Aktionen in der XML-Datei wird sichergestellt, dass sie sich während des Startens der IDE registrieren, was normalerweise zu bevorzugen ist.

Die zweite Möglichkeit, Aktionen zu registrieren, ist programmgesteuert die ActionManager -Klasse:

ActionManager.getInstance().registerAction("StackOverflow.SearchAction", new SearchAction());

Dies hat den Vorteil, dass wir Aktionen dynamisch registrieren lassen. Wenn wir zum Beispiel ein Plugin schreiben, um eine Remote-API zu integrieren, möchten wir möglicherweise einen anderen Satz von Aktionen basierend auf der Version der API registrieren, die wir aufrufen.

Der Nachteil dieses Ansatzes ist, dass sich die Aktionen beim Start nicht registrieren. Wir müssen eine Instanz von ApplicationComponent erstellen, um Aktionen zu verwalten, was mehr Codierung und XML-Konfiguration erfordert.

5. Plugin testen

Wie bei jedem Programm muss ein IntelliJ-Plugin geschrieben werden. Für ein kleines Plugin wie das, das wir geschrieben haben, reicht es aus, sicherzustellen, dass das Plugin kompiliert wird und dass die von uns erstellten Aktionen beim Klicken wie erwartet funktionieren.

Wir können unser Plugin mithilfe einer Plugin-Laufkonfiguration manuell testen (und debuggen):

Dadurch wird eine neue Instanz von IntelliJ mit aktiviertem Plugin gestartet.

Dadurch können wir auf die verschiedenen von uns erstellten Menüelemente klicken und sicherstellen, dass sich die richtigen Stapelüberlaufseiten öffnen.

Wenn Sie traditionellere Komponententests durchführen möchten, bietet IntelliJ eine http://www.jetbrains.org/intellij/sdk/docs/basics/testing__plugins.html ("headhead-Umgebung") zum Ausführen von Komponententests an. Wir können Tests mit jedem gewünschten Test-Framework schreiben, und die Tests werden mit realen, nicht gesperrten Komponenten aus der IDE ausgeführt.

6. Bereitstellung des Plugins

Das Plugin DevKit bietet eine einfache Möglichkeit, Plugins zu packen, damit wir sie installieren und verteilen können. Klicken Sie einfach mit der rechten Maustaste auf das Plugin-Projekt und wählen Sie "Plugin-Modul für die Bereitstellung vorbereiten". Dadurch wird eine JAR-Datei im Projektverzeichnis erstellt.

Die generierte JAR-Datei enthält den Code und die Konfigurationsdateien, die zum Laden in IntelliJ erforderlich sind. Sie können es lokal installieren oder in einem plugin-Repository zur Verwendung durch Dritte veröffentlichen.

Der Screenshot unten zeigt einen der neuen Menüpunkte des Stack Overflow-Menüs:

7. Fazit

In diesem Artikel haben wir ein einfaches Plugin entwickelt, das nur einige Beispiele für Verbesserungen der IntelliJ-IDE enthält.

Während wir hauptsächlich mit Aktionen gearbeitet haben, bietet das IntelliJ-Plugin-SDK mehrere Möglichkeiten, um der IDE neue Funktionen hinzuzufügen. Weitere Informationen finden Sie im Erste Schritte-Anleitung .

Den vollständigen Code für unser Beispiel-Plugin finden Sie wie immer in unserem Repository für GitHub .