IntelliJ-laajennuksen luominen - rakennetaan yksinkertainen sanakirjahaku

Suurin osa meistä kehittäjistä käyttää IntelliJ-alustoja, joko IDEA, PHPStorm, WebStorm, Android Studio, PyCharm, ja luetteloa voidaan jatkaa. Joskus käytettäessä sitä kuitenkin havaitaan, että ominaisuus puuttuu, mutta meillä ei ole aavistustakaan, kuinka lisätä ominaisuus ja elää lopulta vain ilman sitä.

Tässä artikkelissa käsittelen, kuinka voimme luoda yksinkertaisen laajennuksen kaikille IntelliJ IDE: lle, joten kun lisäät project.dictiedoston, se lisää sen automaattisesti sanakirjoihisi. Se etsii tiedostoa myös paketeista, joten paketit voivat lisätä mukautettuja sanoja sanakirjaan. .dicTiedosto on yksinkertainen sanakirja, jossa jokainen rivi on sana sanakirjassa.

Projekti on vain esimerkki, jolla pääset alkuun omien laajennusten kehittämisessä. Mutta se on itse asiassa myös ominaisuus, josta olen puuttunut, koska kun kehitän mukautetun paketin, jossa on omat sanani, vihaan, että minun on lisättävä ne joka kerta projektitason sanakirjaan.

Projektin luominen

Kun luot laajennuksia IntelliJ: lle, meidän on valittava, että se tehdään joko Java tai Kotlin. Teen sen Java-sovelluksessa, koska useimmat käyttäjät tuntevat sen. Koska tämä on Java-projekti, käytämme IntelliJ IDEA: ta IDE: nä.

Kehitysoppaan mukaan suositeltava tapa luoda projekti on käyttää Gradlea. Aloitamme avaamalla preferencesja tarkista, Gradleja Plugin DevKitlisäosia on asennettu.

Laajennusten asentamisen ja IDE: n uudelleenkäynnistyksen jälkeen siirrymme uusien projektien kulkuun ja alle Gradle. Tässä on nyt vaihtoehto nimeltä nimeltä, IntelliJ Platform Pluginjota tarvitsemme.

Käy sitten läpi muu projektinluontivirta normaalisti - tässä projektissa valitsen seuraavan kokoonpanon.

Asettaa plugin.xml

Nyt kun meillä on projekti, meidän on määritettävä plugin.xmltiedosto ja build.gradle. plugin.xmlOn tiedosto käyttämä IntelliJ joka määrittelee kaikki tiedot plugin. Tämä sisältää nimen, riippuvuudet, mitä toimintoja sen pitäisi lisätä tai jos sen pitäisi laajentaa jotain IntelliJ: ssä. Periaatteessa tämä tiedosto määrittelee kaiken, mitä laajennuksesi pitäisi tehdä, ja se on projektisi perusta. Meidän build.gradletiedosto voimme määritellä joitakin arvoja plugin.xml, ja tietoja, kuten version IntelliJ haluamme testata laajennuksen, kun rakennus gradle.

Aloitetaan määrittelemällä plugin.xmltiedosto. Tiedosto löytyy src/main/resources/META-INF/plugin.xml. Haluamme, että laajennuksemme on saatavilla kaikissa IntelliJ IDE -laitteissa, joten asetamme dependenciessiihen com.intellij.modules.lang. Tällä hetkellä tiedostomme näyttää tältä:

 dk.lost_world.Dictionary Dictionary GitHub com.intellij.modules.lang

Tällä hetkellä sillä ei kuitenkaan ole logiikkaa, emmekä rekisteröi mitään IntelliJ-alustalle.

Koska tämä projekti löytää project.dictiedostoja projektista ja rekisteröi ne sanakirjoiksi kyseiseen projektiin, meidän on rekisteröitävä projektitasoinen komponentti. Tämä komponentti kutsutaan, kun projekti avataan ja suljetaan. Luodaan luokka ja toteutetaan ProjectComponentkäyttöliittymä. Kun viet hiiren luokan nimen päälle, se kertoo meille, että komponenttia ei ole rekisteröity.

Sitten voimme kutsua toiminnon kutsutuksi Register Project Componentja se rekisteröi sen meille plugin.xmltiedostoon.

Jos avataan plugin.xml, seuraava koodi on lisättävä. Jos sitä ei lisätty soitettaessa toimintoa, lisää se vain manuaalisesti.

  dk.lost_world.dictionary.DictionaryProjectComponent 

IntelliJ-tiedostojärjestelmä

Työskenneltäessä tiedostoja IntelliJ, käytämme V irtual F ile S rjestelm (VFS). VFS antaa meille universaalin API: n puhua tiedostojen kanssa, ilman että meidän tarvitsee miettiä, ovatko ne FTP: ltä, HTTP-palvelimelta vai vain paikalliselta levyltä.

Koska meidän plugin etsii tiedostoja kutsutaan project.dicse tietenkin täytyy puhua kanssa V irtual F ile S rjestelm. Kaikki VFS: n tiedostot ovat virtuaalitiedostoja. Tämä voi kuulostaa hieman pelottavalta, mutta todellisuudessa se on vain sovellusliittymä tiedostojärjestelmälle ja tiedostolle. Tapa ajatella se on vain, että V irtual F ile S rjestelm on tiedostojärjestelmä käyttöliittymän ja Virtual tiedostot ovat tiedostoja.

Oikeinkirjoituksen tarkistusasetukset

Koska IntelliJ: llä on jo tuki .dictiedostoille ja oikeinkirjoituksen tarkistukselle, ainoa asia, joka meidän on tehtävä, on rekisteröidä project.dictiedostomme oikeinkirjoituksen asetuksissa.

Kaikki oikeinkirjoituksen tarkistuksen asetukset tallennetaan luokkaan nimeltä com.intellij.spellchecker.settings.SpellCheckerSettings. Saadaksesi sen esiintymän, soita vain getInstancemenetelmälle (suurin osa IntelliJ-luokista sai getInstancemenetelmän, joka käyttää ServiceManageralla olevia IntelliJ: itä).

Asetusluokka sai menetelmän nimeltä, getCustomDictionariesPathsjoka palauttaa kaikki polut käyttäjän asentamiin sanakirjoihin.

Kun tarkastellaan menetelmän allekirjoitusta, näemme myös nimityksen AvailableSince. Käytämme myöhemmin tämän merkinnän arvoa määritelläksemme vaaditun vähimmäisversion laajennuksemme toimimiseksi.

Kun menetelmä palauttaa luettelon, voimme yksinkertaisesti pyytää addmenetelmää lisätäksesi uuden polun sanakirjaan.

Laajennuksen suorittaminen (build.gradle)

Koska tiedämme nyt, kuinka sanakirja lisätään oikeinkirjoituksen tarkistukseen, lisätään pieni koodiesimerkki DictionaryProjectComponentluokassamme tätä varten.

public class DictionaryProjectComponent implements ProjectComponent { private Project project; public DictionaryProjectComponent(Project project) { this.project = project; } @Override public void projectOpened() { SpellCheckerSettings .getInstance(project) .getCustomDictionariesPaths() .add("./project.dic"); }}

Tämä koodi rekisteröi project.dictiedoston projektimme juuresta aina, kun projekti avataan.

Testataksemme pienen esimerkkimme meidän on päivitettävä build.gradletiedostomme. Kun intellijosa gradle tiedoston lisäämme mitä versiota IntelliJ haluamme käyttää. Tämä versionumero on yksi luokan AvailableSincemerkinnästä SpellCheckerSettings.

plugins { id 'java' id 'org.jetbrains.intellij' version '0.4.4'}group 'dk.lost_world'version '1.0-SNAPSHOT'sourceCompatibility = 1.8repositories { mavenCentral()}dependencies { testCompile group: 'junit', name: 'junit', version: '4.12'}// See //github.com/JetBrains/gradle-intellij-plugin/intellij { pluginName 'Dictionary' version '181.2784.17' type 'IC' downloadSources true}

Käynnissä runIdekomennon gradle käynnistyy instanssi IntelliJ on tietyn version. IDE-testauksen aloittamisen jälkeen laajennuksen olisi pitänyt olla käynnissä. Jos avaamme preferences > Editor > Spelling > Dicosionioneja, voimme nähdä mukautettujen sanakirjojen alla, että esimerkissä määrittelemämme polku on nyt lisätty.

Voimme nyt testata laajennustamme, joten nyt on aika rakentaa se oikein, jotta se löytää project.dictiedostot ja rekisteröi ne meille.

Vuonna DictionaryProjectComponent::projectOpenedmenetelmässä, meidän täytyy ensin löytää kaikki tiedostot ovat project.dicja rekisteröidä ne ja lisätä tiedoston kuuntelija joten kun uusia project.dictiedostoja lisätään, ne rekisteröidään automaattisesti.

Sanakirja luokka

Meillä on luokka nimeltä Dictionary, tämä luokka sisältää logiikan, jolla voimme rekisteröidä ja poistaa tiedostoja sanakirjasta. Kurssilla on seuraavat julkiset menetelmät:

void registerAndNotify(Collection files)

void registerAndNotify(VirtualFile file)

void removeAndNotify(VirtualFile file)

void moveAndNotify(VirtualFile oldFile, VirtualFile newTiedosto)

Nämä menetelmät luovat myös ilmoituksen tapahtuneesta, joten loppukäyttäjä tietää, mikä muuttui mukautettujen sanakirjojen kanssa. Tämän lopputiedosto näyttää seuraavalta:

Kaikkien sanakirjatiedostojen etsiminen

Löytää kaikki sanakirjan tiedostot projektin nimeltään project.dickäytämme luokkaa FilenameIndex. Tiedosto on nimitilassa com.intellij.psi.search.FilenameIndex, sillä on menetelmä, getVirtualFilesByNamejolla voimme löytää project.dictiedostomme.

FilenameIndex.getVirtualFilesByName( project, "project.dic", false, GlobalSearchScope.allScope(project))

Tämä kutsu palauttaa kaikki hakukriteereitä vastaavat virtuaalitiedostot. Sitten laitamme palautustuloksen Sanakirja-luokan menetelmään registerAndNotify.

@Overridepublic void projectOpened() { Dictionary dictionary = new Dictionary(project); dictionary.registerAndNotify( FilenameIndex.getVirtualFilesByName( project, "project.dic", false, GlobalSearchScope.allScope(project) ) );}

Our code is now able to find project.dic files at start up and register them, if they are not already registered. It will also notify about the newly registered files.

Adding a Virtual File Listener

The next part is for us to listen for changes in virtual files. To do this we need a listener. For this we need the com.intellij.openapi.vfs.VirtualFileListener.

In the docblock for the listener class we can see that to register it we can use VirtualFilemanager#addVirtualFileListener.

Let’s create a class named DictionaryFileListener and implement the methods which we need for our project.

Then we update our projectOpened class to also add the VirtualFileListener.

@Overridepublic void projectOpened() { Dictionary dictionary = new Dictionary(project); dictionary.registerAndNotify( FilenameIndex.getVirtualFilesByName( project, "project.dic", false, GlobalSearchScope.allScope(project) ) ); VirtualFileManager.getInstance().addVirtualFileListener( new DictionaryFileListener(dictionary) );}

Our plugin is now able to find our dictionary files at startup, but also listen for if a dictionary file is added later on. The next thing we need is to add information for our plugin listing.

Adding plugin information

To add information about the plugin, we open the build.gradle file and edit the object patchPluginXml. In here we need to specify which build version is required for the plugin, version of the plugin, description and change notes.

patchPluginXml { sinceBuild intellij.version untilBuild null version project.version pluginDescription """Plugin for having a shared dictionary for all members of your project.

It will automatically find any project.dic files and add themto the list of dictionaries.

It will also search packages for dictionary files and add them to our list of dictionaries. """ changeNotes """

0.2

  • Added support for listening for when a project.dic file is added, moved, deleted, copied.

0.1

  • First edition of the plugin.
"""}

We also update the version property to '0.2'of the gradle project itself. The plugin can now run on all versions since the method for registering custom dictionaries was added.

To test if it generates the desired output, we can run the gradle task patchPluginXml and under build/patchedPluginXmlFiles our generated plugin.xml file will be there.

Since IntelliJ version 2019.1, all plugins supports icons. As this is fairly new a lot of plugins do not have an icon, and your plugin can stand out a lot by having one. The naming convention is pluginIcon.svg as the default icon and pluginIcon_dark.svg for the darcula theme.

The plugin icons should be listed together with the plugin.xml file in the path resources/META-INF.

Building for distribution

The plugin is now ready to be built and shipped. To do this we run the gradle task buildPlugin. Under build/distributions a zip file will appear which you can distribute and install manually in your IDE. Add this zip file as a release under your github repo, so users have the option to download it manually from you repo.

Publishing a plugin

To publish our plugin so it can be downloaded directly from IntelliJ’s plugin repository, we need to login on our JetBrains account on the Plugin Repository website. When in here, a dropdown from your profile name shows an option to upload a plugin.

Input all the information in the dialog (you have to add a license, but that is pretty straightforward with Github). Here we add the distribution zip file.

When you submit the form, you can now see your plugin in the plugin repository. However other users do not have access to it before IntelliJ has approved it. Approving your plugin normally takes 2–3 days.

Updating your plugin via Gradle

After the plugin has been created, we can update it programmatically. To do this the best practice is to create a token. Open up jetbrains hub and go to the authentification tab. From here press New token... and add the scope Plugin Repository.

When pressing create you get a token. Create a file called gradle.properties and add the token under the key intellijPublishToken (remember to git ignore this file).

In our build.gradle file, we simply add the following:

publishPlugin { token intellijPublishToken}

And we can now run the gradle task publishPlugin for publishing our new version. All versions numbers have to be unique or else it will fail updating. When an update is created, you have to wait 2–3 days again for them to approve the update.

After waiting some days our plugin has now been approved and can now be found in the plugin marketplace by searching for dictionary!

Johtopäätös

Toivon, että tämä artikkeli on antanut sinulle enemmän rohkeutta aloittaa omien laajennusten kehittäminen. Yksi suurimmista ongelmista, joita minulla oli kehitettäessä, oli selvittää, mitä luokkia käyttää. IntelliJ: llä on kattava opas, jota suosittelen lukemaan alusta loppuun, mutta monia luokkia ei mainita siellä. Tapauksissa, joissa juutut, heillä on Gitter-chat, josta on todella apua, ja siellä on myös IntelliJ: n ihmisiä auttamaan.

Tämän projektin lähdekoodi löytyy Githubista, ja luomamme laajennus on JetBrains-markkinapaikalla.