Skrivning af IntelliJ IDEA-plugins

1. Introduktion

I løbet af de sidste par år er IntelliJ fra JetBrains hurtigt blevet den bedste IDE for Java-udviklere. I vores seneste State of Java-rapport var IntelliJ den valgte IDE for 55% af respondenterne, op fra 48% året før.

En funktion, der gør IntelliJ så tiltalende for Java-udviklere, er evnen til at udvide og oprette ny funktionalitet ved hjælp af plugins. I denne vejledning ser vi på at skrive et IntelliJ-plugin for at demonstrere et par af måderne til at udvide IDE.

Og bemærk, at mens denne artikel er fokuseret på IntelliJ-plugins, deler alle JetBrains IDEs fælles kode. Derfor, mange af de anvendte teknikker kan anvendes på andre JetBrains IDE'er såsom PyCharm, RubyMine og mere.

2. Plugin-funktionalitet

Plugin-funktionalitet til IntelliJ falder typisk ind i en af ​​4 kategorier:

  • Brugerdefinerede sprog: evnen til at skrive, fortolke og kompilere kode skrevet på forskellige sprog
  • Rammer: understøttelse af 3. parts rammer såsom Spring
  • Værktøjer: integration med eksterne værktøjer som Gradle
  • Tilføjelser til brugergrænseflade: nye menupunkter, værktøjsvinduer og knapper med mere

Plugins falder ofte i flere kategorier. For eksempel interagerer Git-pluginet, der leveres med IntelliJ, med den git-eksekverbare version, der er installeret på systemet. Pluginet giver sit værktøjsvindue og pop op-menupunkter, mens det også integreres i projektoprettelsesarbejdsprocessen, præferencevinduet og mere.

3. Oprettelse af et plugin

Den nemmeste måde at komme i gang med IntelliJ-plugins er at bruge deres Plugin DevKit. Dette kan tilgås fra Ny >Projekt menu:

Bemærk, at vi skal bruge en JetBrains JDK for at sikre, at de krævede plugin-klasser er tilgængelige på klassestien. IntelliJ skal leveres med en passende JDK som standard, men hvis ikke, kan vi downloade en herfra.

I skrivende stund vi kan kun bruge Java 8 til at skrive IntelliJ-plugins. Dette skyldes, at JetBrains i øjeblikket ikke leverer en officiel JDK til Java 9 eller højere.

4. Eksempel på plugin

For at demonstrere skrivning af et IntelliJ-plugin opretter vi et plugin, der giver hurtig adgang til det populære Stack Overflow-websted fra flere områder i IDE. Vi tilføjer:

  • Et menupunkt Værktøjer til besøg på siden Stil et spørgsmål
  • Et popup-menupunkt i både teksteditor og konsoloutput til søgning i Stack Overflow efter fremhævet tekst.

4.1. Oprettelse af handlinger

Handlinger er kernekomponenten, der bruges til at skrive IntelliJ-plugins. Handlinger udløses af begivenheder i IDE, såsom at klikke på et menupunkt eller en knap på værktøjslinjen.

Det første trin i oprettelse af en handling er at oprette en Java-klasse, der udvides En handling. For vores Stack Overflow-plugin opretter vi 2 handlinger.

Den første handling åbner siden Stil et spørgsmål i et nyt browservindue:

offentlig klasse AskQuestionAction udvider AnAction {@Override public void actionPerformed (AnActionEvent e) {BrowserUtil.browse ("// stackoverflow.com/questions/ask"); }}

Vi bruger den indbyggede BrowserUtil klasse, fordi den håndterer alle nuancer ved at åbne en webside på forskellige operativsystemer og browsere.

Den anden handling åbner søgesiden Stack Overflow og videresender søgetekst som en forespørgselsstreng. Denne gang implementerer vi to metoder.

Den første metode, vi implementerer, er ligesom vores første handling og håndterer åbning af en webbrowser.

Først skal vi dog samle to værdier til StackOverflow. Den ene er sprogmærket, og den anden er teksten, der skal søges efter.

For at få sprogmærket bruger vi grænsefladen til programstruktur. Denne API analyserer alle filerne i et projekt og giver en programmatisk måde at inspicere dem på.

I dette tilfælde bruger vi PSI til at bestemme programmeringssproget for en fil:

PsiFile-fil = e.getData (CommonDataKeys.PSI_FILE); Sprog lang = e.getData (CommonDataKeys.PSI_FILE) .getLanguage (); String languageTag = "+ [" + lang.getDisplayName (). ToLowerCase () + "]";

Bemærk, at PSI også giver sprogspecifikke detaljer om en fil. For eksempel, vi kunne bruge PSI til at finde alle offentlige metoder i en Java-klasse.

For at få teksten til at søge efter bruger vi Redaktør API til at hente fremhævet tekst på skærmen:

endelig Editor editor = e.getRequiredData (CommonDataKeys.EDITOR); CaretModel caretModel = editor.getCaretModel (); Streng valgtText = caretModel.getCurrentCaret (). GetSelectedText ();

Selvom denne handling er den samme for både editor- og konsolvinduer, fungerer adgang til den valgte tekst på samme måde.

Nu kan vi sætte det hele sammen i en handling udført erklæring:

@ Overstyr offentlig ugyldig handling Udført (AnActionEvent e) {PsiFile-fil = e.getData (CommonDataKeys.PSI_FILE); Sprog lang = e.getData (CommonDataKeys.PSI_FILE) .getLanguage (); String languageTag = "+ [" + lang.getDisplayName (). ToLowerCase () + "]"; Editor editor = e.getRequiredData (CommonDataKeys.EDITOR); CaretModel caretModel = editor.getCaretModel (); Streng valgtText = caretModel.getCurrentCaret (). GetSelectedText () Strengeforespørgsel = valgtText.replace ('', '+') + sprogTag; BrowserUtil.browse ("// stackoverflow.com/search?q=" + forespørgsel); } 

Denne handling tilsidesætter også en anden navngivet metode opdatering. Dette giver os mulighed for at aktivere eller deaktivere handlingen under forskellige forhold.

I dette tilfælde deaktiverer vi søgefunktionen, når der ikke er valgt markeret tekst:

@Override offentlig ugyldig opdatering (AnActionEvent e) {Editor editor = e.getRequiredData (CommonDataKeys.EDITOR); CaretModel caretModel = editor.getCaretModel (); e.getPresentation (). setEnabledAndVisible (caretModel.getCurrentCaret (). hasSelection ()); } 

4.2. Registrering af handlinger

Når vi har skrevet vores handlinger, vi er nødt til at registrere dem med IDE. Der er to måder at gøre dette på.

Den første måde er at bruge plugin.xml fil, som oprettes for os, når vi starter et nyt projekt.

Som standard har filen en tom element, hvor vi vil tilføje vores handlinger:

Brug af XML-filen til at registrere handlinger vil sikre, at de registreres under IDE-opstart, hvilket normalt er at foretrække.

Den anden måde at registrere handlinger på er programmatisk at bruge ActionManager klasse:

ActionManager.getInstance (). RegisterAction ("StackOverflow.SearchAction", ny SearchAction ());

Dette har fordelen ved at lade os dynamisk registrere handlinger. For eksempel, hvis vi skriver et plugin, der skal integreres med en ekstern API, vil vi måske registrere et andet sæt handlinger baseret på den version af API'en, som vi kalder.

Ulempen ved denne tilgang er, at handlinger ikke registreres ved opstart. Vi er nødt til at oprette en forekomst af ApplicationComponent til at styre handlinger, hvilket kræver mere kodning og XML-konfiguration.

5. Test af pluginet

Som med ethvert program kræver skrivning af et IntelliJ-plugin test. For et lille plugin som det, vi har skrevet, er det tilstrækkeligt at sikre, at pluginet kompileres, og at de handlinger, vi oprettede, fungerer som forventet, når vi klikker på dem.

Vi kan manuelt teste (og fejle) vores plugin ved hjælp af en Plugin-kørselskonfiguration:

Dette starter en ny forekomst af IntelliJ med vores plugin aktiveret. Dette giver os mulighed for at klikke på de forskellige menupunkter, vi oprettede, og sikre, at de rigtige Stack Overflow-sider åbnes.

Hvis du ønsker at udføre mere traditionel enhedstest, giver IntelliJ et hovedløst miljø til at køre enhedstest. Vi kan skrive tests ved hjælp af de testrammer, vi ønsker, og testene kører ved hjælp af ægte, ikke-mockede komponenter fra IDE.

6. Implementering af pluginet

Plugin DevKit giver en enkel måde at pakke plugins på, så vi kan installere og distribuere dem. Højreklik blot på plugin-projektet, og vælg “Forbered plugin-modul til implementering”. Dette genererer en JAR-fil inde i projektmappen.

Den genererede JAR-fil indeholder de kode- og konfigurationsfiler, der er nødvendige for at indlæse i IntelliJ. Du kan installere det lokalt eller udgive det til et plugin-lager til brug for andre.

Skærmbilledet nedenfor viser et af de nye Stack Overflow-menupunkter i aktion:

7. Konklusion

I denne artikel udviklede vi et simpelt plugin, der kun fremhæver nogle få af, hvordan vi kan forbedre IntelliJ IDE.

Mens vi primært arbejdede med handlinger, tilbyder IntelliJ plugin SDK flere måder at tilføje ny funktionalitet til IDE. For yderligere læsning, se den officielle startvejledning.

Som altid kan den fulde kode til vores eksempel-plugin findes i vores GitHub-lager.