IntelliJ IDEAプラグインを書く

1前書き

ここ数年の間に、JetBrainsのhttps://www.jetbrains.com/idea/[IntelliJ]はすぐにJava開発者のためのトップIDEになりました。最新のhttps://www.baeldung.com/java-in-2018[State of Java report]では、IntelliJが55%の回答者に選ばれたIDEで、前年の48%から増加しました。

IntelliJをJava開発者にとって非常に魅力的なものにする1つの機能は、プラグインを使用して新しい機能を拡張および作成する機能です。このチュートリアルでは、IDEを拡張するいくつかの方法を説明するためにIntelliJプラグインを書くことを検討します。

この記事はIntelliJプラグインに焦点を当てていますが、すべてのJetBrains IDEは共通のコードを共有しています。したがって、** ここで使用されている技術の多くは、PyCharm、RubyMineなどの他のJetBrainのIDEにも適用できます。

2プラグイン機能

IntelliJのプラグイン機能は通常、次の4つのカテゴリのいずれかに分類されます。

  • カスタム言語 :コードを書いて、解釈して、そしてコンパイルする能力

異なる言語で書かれた フレームワーク** :Springなどのサードパーティ製フレームワークのサポート

  • ツール :Gradleなどの外部ツールとの統合

  • ユーザーインターフェースアドオン :新しいメニュー項目、ツールウィンドウ、ボタン、

もっと

  • プラグインはしばしば複数のカテゴリに分類されます** 。たとえば、IntelliJに同梱されているhttps://www.jetbrains.com/help/idea/using-git-integration.html[Git plugin]は、システムにインストールされたgit実行可能ファイルと対話します。このプラグインは、ツールウィンドウとポップアップメニュー項目を提供すると同時に、プロジェクト作成ワークフロー、設定ウィンドウなどにも統合されています。

3プラグインを作成する

IntelliJプラグインを始める最も簡単な方法は、彼らのhttp://www.jetbrains.org/intellij/sdk/docs/basics/getting started/using dev kit.html[プラグインDevKit]を使うことです。これは New > Project__メニューからアクセスできます。

  • 必要なプラグインクラスがクラスパスで利用可能であることを保証するためにJetBrains JDK ** を使用しなければならないことに注意してください。 IntelliJにはデフォルトで適切なJDKが付属しているはずですが、そうでなければhttps://bintray.com/jetbrains/intellij-jdk[here]からダウンロードできます。

これを書いている時点で、IntelliJプラグインを書くためにJava 8しか使えません。これは、JetBrainsが現在Java 9以降の正式なJDKを提供していないためです。

4サンプルプラグイン

IntelliJプラグインの作成方法を説明するために、IDEの複数の領域から人気のあるStack Overflow Webサイトにすばやくアクセスできるプラグインを作成します。追加します:

  • [質問をする]ページにアクセスするための[ツール]メニュー項目

  • テキストエディタとコンソール出力の両方に表示されるポップアップメニュー項目

強調表示されたテキストのスタックオーバーフロー。

4.1. アクションを作成する

  • アクションはIntelliJプラグインを書くためのコアコンポーネントです** 。

メニュー項目やツールバーボタンのクリックなど、IDE内のイベントによってアクションが発生します。

アクションを作成する最初のステップは、 AnAction を拡張するJavaクラスを作成することです。 Stack Overflowプラグインの場合は、2つのアクションを作成します。

最初の操作で、新しいブラウザウィンドウに[Ask a Question]ページが開きます。

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

組み込みの BrowserUtil クラスを使用します。これは、さまざまなオペレーティングシステムやブラウザでWebページを開く際のあらゆるニュアンスを処理するためです。

2番目のアクションは、Stack Overflow検索ページを開き、検索文字列として検索テキストを渡します。今回は2つの方法を実装します。

私たちが実装する最初のメソッドは私たちの最初のアクションと全く同じで、Webブラウザを開くことを扱います。

ただし最初に、StackOverflowの2つの値を収集する必要があります。 1つは言語タグ、もう1つは検索するテキストです。

言語タグを取得するには、http://www.jetbrains.org/intellij/sdk/docs/basics/architectural__overview/psi.html[Program Structure Interface]を使用します。このAPIは、プロジェクト内のすべてのファイルを解析し、それらを検査するためのプログラム的な方法を提供します。

この場合、PSIを使用してファイルのプログラミング言語を決定します。

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

PSIはファイルに関する言語固有の詳細も提供します。

たとえば、** PSIを使用して、Javaクラス内のすべてのパブリックメソッドを見つけることができます。

テキストを検索するには、 __エディタ __APIを使用して、画面上でハイライト表示されたテキストを取得します。

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

この操作はエディタウィンドウとコンソールウィンドウの両方で同じですが、選択したテキストへのアクセスは同じように機能します。

さて、これをすべて 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);
}

このアクションは update という名前の2番目のメソッドもオーバーライドします。これにより、さまざまな条件下でアクションを有効または無効にすることができます。

この場合、テキストが選択されていないときに検索アクションを無効にします。

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

4.2. アクションを登録する

アクションを書いたら、それをIDEに登録する必要があります。これを行うには2つの方法があります。

最初の方法は、 plugin.xml ファイルを使用することです。このファイルは、新しいプロジェクトを開始したときに作成されます。

デフォルトでは、ファイルには空の <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>

XMLファイルを使用してアクションを登録すると、IDEの起動時にアクションが確実に登録されます。これは通常望ましい方法です。

アクションを登録する2つ目の方法は、 ActionManager クラスをプログラム的に使用することです。

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

これには、アクションを動的に登録できるという利点があります。たとえば、リモートAPIと統合するためのプラグインを作成する場合、呼び出すAPIのバージョンに基づいて異なる一連のアクションを登録することができます。

この方法の欠点は、起動時にアクションが登録されないことです。アクションを管理するために ApplicationComponent のインスタンスを作成する必要があります。これには、より多くのコーディングとXML構成が必要です。

5プラグインのテスト

他のプログラムと同様に、IntelliJプラグインを書くにはテストが必要です。私たちが書いたような小さなプラグインの場合は、プラグインがコンパイルされ、作成したアクションがクリックしたときに期待どおりに機能することを確認すれば十分です。

プラグイン実行設定を使用して、プラグインを手動でテスト(およびデバッグ)することができます。

これにより、プラグインがアクティブになった状態でIntelliJの新しいインスタンスが起動します。

これにより、作成したさまざまなメニュー項目をクリックして、適切なStack Overflowページを確実に開くことができます。

もっと伝統的な単体テストを行いたい場合は、IntelliJはhttp://www.jetbrains.org/intellij/sdk/docs/basics/testing__plugins.html[ヘッドレス環境]を提供して単体テストを実行します。必要なテストフレームワークを使用してテストを書くことができ、テストはIDEからの実際のモックアップされていないコンポーネントを使用して実行されます。

6. プラグインのデプロイ

プラグインDevKitはプラグインをパッケージ化する簡単な方法を提供するので、それらをインストールして配布することができます。プラグインプロジェクトを右クリックして「配置のためのプラグインモジュールの準備」を選択するだけです。これにより、プロジェクトディレクトリ内にJARファイルが生成されます。

生成されたJARファイルには、IntelliJへのロードに必要なコードと設定ファイルが含まれています。あなたはそれをローカルにインストールするか、他の人が使うためにhttp://www.jetbrains.org/intellij/sdk/docs/plugin__repository/index.html[plugin repository]に公開できます。

以下のスクリーンショットは、新しいスタックオーバーフローメニュー項目の1つを示しています。

7. 結論

この記事では、IntelliJ IDEを拡張する方法のほんの一部を説明する簡単なプラグインを開発しました。

私たちは主にアクションを扱っていましたが、IntelliJプラグインSDKはIDEに新しい機能を追加するいくつかの方法を提供します。詳しくは、http://www.jetbrains.org/intellij/sdk/docs/welcome.html[公式の入門ガイド]を参照してください。

いつものように、私たちのサンプルプラグインの完全なコードは私たちのhttps://github.com/eugenp/tutorials/tree/master/intelliJ[GitHub repository]にあります。