1. 序章

過去数年間で、JetBrainsのIntelliJはすぐにJava開発者のトップIDEになりました。 最新のJavaの状態レポートでは、IntelliJが55 % o fの回答者に選ばれたIDEであり、前年の48% tから増加しました。

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

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

2. プラグインの機能

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

  • カスタム言語:さまざまな言語で記述されたコードを記述、解釈、およびコンパイルする機能
  • Frameworks :Springなどのサードパーティフレームワークのサポート
  • ツール:Gradleなどの外部ツールとの統合
  • ユーザーインターフェイスアドオン:新しいメニュー項目、ツールウィンドウとボタンなど

プラグインは多くの場合、複数のカテゴリに分類されます。 たとえば、IntelliJに同梱されている Gitプラグインは、システムにインストールされているgit実行可能ファイルと相互作用します。 プラグインは、ツールウィンドウとポップアップメニュー項目を提供すると同時に、プロジェクト作成ワークフロー、設定ウィンドウなどにも統合されます。

3. プラグインの作成

IntelliJプラグインを使い始める最も簡単な方法は、プラグインDevKitを使用することです。 これは、 New > Projectメニューからアクセスできます。

必要なプラグインクラスがクラスパスで使用可能であることを確認するには、JetBrainsJDKを使用する必要があることに注意してください。 IntelliJにはデフォルトで適切なJDKが付属しているはずですが、そうでない場合は、こちらからダウンロードできます。

この記事の執筆時点では、IntelliJプラグインの作成に使用できるのはJava8のみです。 これは、JetBrainsが現在Java9以降の公式JDKを提供していないためです。

4. プラグインの例

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

  • [質問する]ページにアクセスするための[ツール]メニュー項目
  • 強調表示されたテキストのスタックオーバーフローを検索するためのテキストエディタとコンソール出力の両方のポップアップメニュー項目。

4.1. アクションの作成

アクションは、IntelliJプラグインの作成に使用されるコアコンポーネントです。 アクションは、メニュー項目やツールバーボタンのクリックなど、IDEのイベントによってトリガーされます。

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

最初のアクションは、新しいブラウザウィンドウで[質問をする]ページを開きます。

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

組み込みのBrowserUtilクラスを使用します。これは、さまざまなオペレーティングシステムやブラウザーでWebページを開く際の微妙な違いをすべて処理するためです。

2番目のアクションは、スタックオーバーフロー検索ページを開き、検索テキストをクエリ文字列として渡します。 今回は2つのメソッドを実装します。

実装する最初のメソッドは、最初のアクションと同じで、Webブラウザーを開く処理を行います。

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

言語タグを取得するには、 Program StructureInterfaceを使用します。 この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クラス内のすべてのパブリックメソッドを検索できます。

検索するテキストを取得するには、 Editor 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>
    <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の新しいインスタンスが起動します。 これにより、作成したさまざまなメニュー項目をクリックして、適切なStackOverflowページが開くようになります。

従来の単体テストを実行したい場合、IntelliJは単体テストを実行するためのヘッドレス環境を提供します。 必要なテストフレームワークを使用してテストを記述でき、テストはIDEの実際のモックされていないコンポーネントを使用して実行されます。

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

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

生成されたJARファイルには、IntelliJにロードするために必要なコードと構成ファイルが含まれています。 ローカルにインストールすることも、プラグインリポジトリに公開して他の人が使用できるようにすることもできます。

以下のスクリーンショットは、動作中の新しいStackOverflowメニュー項目の1つを示しています。

7. 結論

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

私たちは主にアクションを扱いましたが、IntelliJプラグインSDKは、IDEに新しい機能を追加するいくつかの方法を提供します。 詳細については、公式スタートガイドをご覧ください。

いつものように、サンプルプラグインの完全なコードは、GitHubリポジトリにあります。