IntelliJ IDEA-plug-ins schrijven

1. Inleiding

In de afgelopen jaren is IntelliJ van JetBrains snel uitgegroeid tot de beste IDE voor Java-ontwikkelaars. In ons meest recente State of Java-rapport was IntelliJ de IDE bij uitstek voor 55% van de respondenten, tegen 48% het jaar ervoor.

Een kenmerk dat IntelliJ zo aantrekkelijk maakt voor Java-ontwikkelaars, is de mogelijkheid om uit te breiden en nieuwe functionaliteit te creëren met behulp van plug-ins. In deze tutorial zullen we kijken naar het schrijven van een IntelliJ-plug-in om enkele manieren te demonstreren om de IDE uit te breiden.

En merk op dat hoewel dit artikel is gericht op IntelliJ-plug-ins, alle JetBrains IDE's gemeenschappelijke code delen. Daarom veel van de technieken die hier worden gebruikt, kunnen worden toegepast op andere JetBrain-IDE's zoals PyCharm, RubyMine en meer.

2. Plug-in functionaliteit

Plug-in-functionaliteit voor IntelliJ valt doorgaans in een van de vier categorieën:

  • Aangepaste talen: de mogelijkheid om code geschreven in verschillende talen te schrijven, interpreteren en compileren
  • Kaders: ondersteuning voor frameworks van derden, zoals Spring
  • Hulpmiddelen: integratie met externe tools zoals Gradle
  • Add-ons voor gebruikersinterface: nieuwe menu-items, toolvensters en knoppen, en meer

Plug-ins vallen vaak in meerdere categorieën. De Git-plug-in die bij IntelliJ wordt geleverd, werkt bijvoorbeeld samen met het uitvoerbare git-bestand dat op het systeem is geïnstalleerd. De plug-in biedt zijn toolvenster en pop-upmenu-items, terwijl hij ook wordt geïntegreerd in de workflow voor het maken van projecten, het voorkeurenvenster en meer.

3. Een plug-in maken

De eenvoudigste manier om met IntelliJ-plug-ins aan de slag te gaan, is door hun Plugin DevKit te gebruiken. Dit is toegankelijk via het Nieuw >Project menu:

Merk op dat we een JetBrains JDK moeten gebruiken om ervoor te zorgen dat de vereiste plug-in-klassen beschikbaar zijn op het klassenpad. IntelliJ zou standaard met een geschikte JDK moeten worden geleverd, maar zo niet, dan kunnen we er hier een downloaden.

Op het moment van schrijven, we kunnen alleen Java 8 gebruiken voor het schrijven van IntelliJ-plug-ins. Dit komt doordat JetBrains momenteel geen officiële JDK voor Java 9 of hoger biedt.

4. Voorbeeld plug-in

Om het schrijven van een IntelliJ-plug-in te demonstreren, maken we een plug-in die snelle toegang biedt tot de populaire Stack Overflow-website vanuit meerdere gebieden in de IDE. We zullen toevoegen:

  • Een menu-item Tools om de pagina Stel een vraag te bezoeken
  • Een pop-upmenu-item in zowel de teksteditor als de console-uitvoer om in Stack Overflow naar gemarkeerde tekst te zoeken.

4.1. Acties maken

Acties zijn de kerncomponent die wordt gebruikt voor het schrijven van IntelliJ-plug-ins. Acties worden geactiveerd door gebeurtenissen in de IDE, zoals het klikken op een menu-item of een werkbalkknop.

De eerste stap bij het maken van een actie is het maken van een Java-klasse die uitbreidt Een actie. Voor onze Stack Overflow-plug-in maken we 2 acties.

De eerste actie opent de pagina Stel een vraag in een nieuw browservenster:

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

We gebruiken de ingebouwde BrowserUtil class omdat het alle nuances van het openen van een webpagina op verschillende besturingssystemen en browsers verwerkt.

De tweede actie opent de Stack Overflow-zoekpagina en geeft zoektekst door als een querytekenreeks. Deze keer zullen we twee methoden implementeren.

De eerste methode die we implementeren is net als onze eerste actie en behandelt het openen van een webbrowser.

Eerst moeten we echter twee waarden verzamelen voor StackOverflow. De ene is de taalcode en de andere is de tekst waarnaar moet worden gezocht.

Om de taalcode te krijgen, gebruiken we de programmastructuurinterface. Deze API parseert alle bestanden in een project en biedt een programmatische manier om ze te inspecteren.

In dit geval gebruiken we de PSI om de programmeertaal van een bestand te bepalen:

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

Merk op dat de PSI ook taalspecifieke details over een bestand biedt. Bijvoorbeeld, we zouden de PSI kunnen gebruiken om alle openbare methoden in een Java-klasse te vinden.

Om de tekst te vinden waarnaar moet worden gezocht, gebruiken we de Editor API om gemarkeerde tekst op het scherm op te halen:

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

Hoewel deze actie hetzelfde is voor zowel editor- als consolevensters, werkt het openen van de geselecteerde tekst op dezelfde manier.

Nu kunnen we dit allemaal samenvoegen in een actie uitgevoerd verklaring:

@Override public void actionPerformed (AnActionEvent e) {PsiFile file = e.getData (CommonDataKeys.PSI_FILE); Taal 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 ("// stackoverflow.com/search?q=" + query); } 

Deze actie overschrijft ook een tweede methode met de naam bijwerken. Hierdoor kunnen we de actie onder verschillende omstandigheden in- of uitschakelen.

In dit geval schakelen we de zoekactie uit als er geen geselecteerde tekst is:

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

4.2. Acties registreren

Zodra we onze acties hebben geschreven, we moeten ze registreren bij de IDE. Dit kan op twee manieren.

De eerste manier is het gebruik van de plugin.xml bestand, dat voor ons wordt aangemaakt wanneer we een nieuw project starten.

Standaard heeft het bestand een leeg element, waar we onze acties zullen toevoegen:

Als u het XML-bestand gebruikt om acties te registreren, zorgt u ervoor dat ze worden geregistreerd tijdens het opstarten van IDE, wat meestal de voorkeur heeft.

De tweede manier om acties te registreren is programmatisch met behulp van de ActionManager klasse:

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

Dit heeft het voordeel dat we acties dynamisch kunnen registreren. Als we bijvoorbeeld een plug-in schrijven om te integreren met een externe API, willen we misschien een andere reeks acties registreren op basis van de versie van de API die we aanroepen.

Het nadeel van deze aanpak is dat acties niet worden geregistreerd bij het opstarten. We moeten een instantie maken van Toepassing Component om acties te beheren, wat meer codering en XML-configuratie vereist.

5. Testen van de plug-in

Zoals bij elk programma, moet het schrijven van een IntelliJ-plug-in worden getest. Voor een kleine plug-in zoals degene die we hebben geschreven, is het voldoende om ervoor te zorgen dat de plug-in compileert en dat de acties die we hebben gemaakt werken zoals verwacht wanneer we erop klikken.

We kunnen onze plug-in handmatig testen (en debuggen) met behulp van een plug-in-run-configuratie:

Hiermee wordt een nieuw exemplaar van IntelliJ gestart met onze plug-in geactiveerd. Hierdoor kunnen we op de verschillende menu-items klikken die we hebben gemaakt en ervoor zorgen dat de juiste Stack Overflow-pagina's worden geopend.

Als u meer traditionele unit-tests wilt doen, biedt IntelliJ een headless-omgeving om unit-tests uit te voeren. We kunnen tests schrijven met elk testraamwerk dat we willen, en de tests worden uitgevoerd met echte, niet-geblokkeerde componenten van de IDE.

6. Implementatie van de plug-in

De plug-in DevKit biedt een eenvoudige manier om plug-ins te verpakken, zodat we ze kunnen installeren en distribueren. Klik met de rechtermuisknop op het plug-in-project en selecteer "Plug-in-module voorbereiden voor implementatie". Dit genereert een JAR-bestand in de projectdirectory.

Het gegenereerde JAR-bestand bevat de code en configuratiebestanden die nodig zijn om in IntelliJ te laden. U kunt het lokaal installeren of het publiceren naar een plug-in-repository voor gebruik door anderen.

De onderstaande schermafbeelding toont een van de nieuwe menu-items van Stack Overflow in actie:

7. Conclusie

In dit artikel hebben we een eenvoudige plug-in ontwikkeld die slechts een paar voorbeelden laat zien van hoe we de IntelliJ IDE kunnen verbeteren.

Hoewel we voornamelijk met acties werkten, biedt de IntelliJ-plug-in SDK verschillende manieren om nieuwe functionaliteit aan de IDE toe te voegen. Raadpleeg de officiële handleiding Aan de slag voor meer informatie.

Zoals altijd is de volledige code voor onze voorbeeldplug-in te vinden in onze GitHub-repository.