Ecriture des plugins IntelliJ IDEA

1. Introduction

Au cours des dernières années, IntelliJ de JetBrains est rapidement devenu le meilleur IDE pour les développeurs Java. Dans notre plus récent Rapport sur l’état de Java , IntelliJ était l’IDE de choix pour 55% des répondants, contre 48% l’année précédente.

L’une des fonctionnalités qui rend IntelliJ si attrayant pour les développeurs Java est la possibilité d’étendre et de créer de nouvelles fonctionnalités à l’aide de plug-ins. Dans ce didacticiel, nous allons écrire un plug-in IntelliJ pour illustrer quelques-unes des méthodes permettant d’étendre l’EDI.

Et notez que si cet article est axé sur les plug-ins IntelliJ, tous les IDE JetBrains partagent le même code. Par conséquent, de nombreuses techniques utilisées ici peuvent être appliquées à d’autres IDE de JetBrain ** tels que PyCharm, RubyMine, etc.

2. Fonctionnalité du plugin

La fonctionnalité de plug-in pour IntelliJ tombe généralement dans l’une des 4 catégories suivantes:

  • Langages personnalisés : capacité d’écrire, d’interpréter et de compiler du code

écrit dans différentes langues Frameworks ** : prise en charge des infrastructures tierces telles que Spring

  • Outils : intégration avec des outils externes tels que Gradle

  • Modules d’interface utilisateur : nouveaux éléments de menu, fenêtres d’outils et boutons,

et plus

  • Les plugins tombent souvent dans plusieurs catégories ** . Par exemple, le Git plug-in fourni avec IntelliJ, interagit avec l’exécutable git installé sur le système. Le plugin fournit sa fenêtre d’outil et ses éléments de menu contextuels, tout en s’intégrant au flux de travail de création de projet, à la fenêtre de préférences, etc.

3. Créer un plugin

Le moyen le plus simple de se familiariser avec les plugins IntelliJ consiste à utiliser leur http://www.jetbrains.org/intellij/sdk/docs/basics/getting started/using dev kit.html[Plugin DevKit]. Vous pouvez y accéder à partir du menu Nouveau > Projet__:

  • Notez que nous devons utiliser un JDK JetBrains ** pour nous assurer que les classes de plug-in requises sont disponibles sur le chemin de classe. IntelliJ devrait être fourni avec un JDK approprié par défaut, mais sinon, nous pouvons en télécharger un à partir de here .

A ce jour, nous ne pouvons utiliser Java 8 que pour écrire des plugins IntelliJ . En effet, JetBrains ne fournit pas actuellement de JDK officiel pour Java 9 ou supérieur.

4. Exemple de plugin

Pour illustrer l’écriture d’un plug-in IntelliJ, nous allons créer un plug-in qui offre un accès rapide au site Web populaire Stack Overflow à partir de plusieurs zones de l’EDI. Nous ajouterons:

  • Un élément de menu Outils pour visiter la page Poser une question

  • Un élément de menu contextuel dans l’éditeur de texte et la sortie de la console pour rechercher

Dépassement de pile pour le texte en surbrillance.

4.1. Création d’actions

  • Les actions sont le composant principal utilisé pour écrire les plugins IntelliJ ** .

Les actions sont déclenchées par des événements dans l’EDI, tels que cliquer sur un élément de menu ou un bouton de la barre d’outils.

La première étape de la création d’une action consiste à créer une classe Java qui étend AnAction . Pour notre plug-in Stack Overflow, nous allons créer 2 actions.

La première action ouvre la page Poser une question dans une nouvelle fenêtre du navigateur:

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

Nous utilisons la classe BrowserUtil intégrée, car elle gère toutes les nuances de l’ouverture d’une page Web sur différents systèmes d’exploitation et navigateurs.

La deuxième action ouvre la page de recherche Stack Overflow et transmet le texte de la recherche sous forme de chaîne de requête. Cette fois, nous allons implémenter deux méthodes.

La première méthode que nous implémentons ressemble à notre première action et gère l’ouverture d’un navigateur Web.

Tout d’abord, nous devons collecter deux valeurs pour StackOverflow. L’une est la langue et l’autre le texte à rechercher.

Pour obtenir la balise de langue, nous allons utiliser l’interface http://www.jetbrains.org/intellij/sdk/docs/basics/architectural__overview/psi.html ]. Cette API analyse tous les fichiers d’un projet et fournit un moyen de les inspecter par programmation.

Dans ce cas, nous utilisons l’ISP pour déterminer le langage de programmation d’un fichier:

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

Notez que l’ISP fournit également des informations spécifiques à la langue sur un fichier.

Par exemple, nous pourrions utiliser le PSI pour trouver toutes les méthodes publiques dans une classe Java.

Pour obtenir le texte à rechercher, nous utiliserons __Editor __API pour récupérer le texte en surbrillance à l’écran:

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

Même si cette action est identique pour les fenêtres d’édition et de console, l’accès au texte sélectionné fonctionne de la même manière.

Maintenant, nous pouvons mettre tout cela ensemble dans une déclaration actionPerformed :

@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);
}

Cette action remplace également une deuxième méthode appelée update . Cela nous permet d’activer ou de désactiver l’action dans différentes conditions.

Dans ce cas, nous désactivons l’action de recherche lorsqu’il n’y a pas de texte sélectionné:

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

4.2. Enregistrement des actions

Une fois que nos actions sont écrites, nous devons les enregistrer auprès de l’IDE . Il y a deux façons de faire ça.

La première consiste à utiliser le fichier plugin.xml , créé pour nous lorsque nous démarrons un nouveau projet.

Par défaut, le fichier aura un élément <actions> vide, auquel nous ajouterons nos actions:

<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>

L’utilisation du fichier XML pour enregistrer les actions garantira leur enregistrement lors du démarrage de l’EDI, ce qui est généralement préférable.

La deuxième façon d’enregistrer des actions consiste à utiliser la classe ActionManager par programme:

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

Cela a l’avantage de nous permettre d’enregistrer dynamiquement des actions. Par exemple, si nous écrivons un plug-in à intégrer à une API distante, nous voudrons peut-être enregistrer un ensemble d’actions différent en fonction de la version de l’API que nous appelons.

L’inconvénient de cette approche est que les actions ne sont pas enregistrées au démarrage. Nous devons créer une instance de ApplicationComponent pour gérer les actions, ce qui nécessite davantage de codage et de configuration XML.

5. Tester le plugin

Comme pour tout programme, l’écriture d’un plugin IntelliJ nécessite des tests. Pour un petit plugin comme celui que nous avons écrit, il suffit de s’assurer que le plugin est compilé et que les actions que nous avons créées fonctionnent comme prévu lorsque vous cliquez dessus.

Nous pouvons tester (et déboguer) manuellement notre plugin en utilisant une configuration d’exécution du plugin:

Cela lancera une nouvelle instance d’IntelliJ avec notre plugin activé.

Cela nous permet de cliquer sur les différents éléments de menu que nous avons créés et de nous assurer que les pages de débordement de pile appropriées s’ouvrent.

Si vous souhaitez effectuer des tests unitaires plus traditionnels, IntelliJ fournit un headless environment pour exécuter des tests unitaires. Nous pouvons écrire des tests en utilisant n’importe quel framework de test que nous voulons, et les tests s’exécutent en utilisant de vrais composants non mockés de l’EDI.

6. Déploiement du plugin

Le plugin DevKit fournit un moyen simple de mettre en package des plugins afin que nous puissions les installer et les distribuer. Il vous suffit de cliquer avec le bouton droit de la souris sur le projet de plug-in et de sélectionner «Préparer le module de plug-in pour le déploiement». Cela générera un fichier JAR dans le répertoire du projet.

Le fichier JAR généré contient le code et les fichiers de configuration nécessaires au chargement dans IntelliJ. Vous pouvez l’installer localement ou le publier sur un plugin repository à des fins d’utilisation par d’autres.

La capture d’écran ci-dessous montre l’un des nouveaux éléments du menu Dépassement de pile en action:

lien:/uploads/intellij-stackoverflow-pluginjpg-100x41.jpg%20100w[]

7. Conclusion

Dans cet article, nous avons développé un plug-in simple qui met en évidence quelques-unes des manières dont nous pouvons améliorer IntelliJ IDE.

Bien que nous ayons principalement travaillé avec des actions, le kit de développement logiciel IntelliJ offre de nombreuses façons d’ajouter de nouvelles fonctionnalités à l’EDI. Pour en savoir plus, consultez le official Getting Started Guide .

Comme toujours, le code complet de notre exemple de plug-in est disponible dans notre référentiel GitHub .