IntelliJ IDEAのプラグインを作ろう!(拡張ポイント)
まえがき
この記事シリーズのソースコードは以下のリポジトリで管理されています。
Qiita Artifact Plugin
目次
- プロジェクト作成と設定まで
- アクションの追加, 通知, ダイアログ
- 拡張ポイント(ここ)
はじめに
最初の記事で独自言語作りましょうとか言いつつここまでまだ何もしてません。
基礎って大事なんです。てことで今回はExtension Point
についてやります。
拡張ポイントとは
Extension Point
はIDEが様々な動作をする時呼び出されるものです。
引数を用いて結果を返すことでIDEの表示が変更されたり,ユーザーの操作の結果を受け取って裏で処理することなどができます。
拡張ポイントを利用するには
- それぞれの拡張ポイントに設定されている[クラス|インターフェース]を実装したクラスを作る。
-
plugin.xml
に拡張ポイントを使うことを宣言する。
という手順が必要です。
また、拡張ポイントを作成するには
- 呼び出したい[メソッド|フィールド]を定義した[クラス|インターフェース]を作る
-
plugin.xml
に拡張ポイントを登録する。 - 他のプラグイン等で宣言された拡張ポイントを取得し呼び出す。
という手順が必要です。
拡張ポイントを利用する
ここでは例としてeditorTabColorProvider
という拡張ポイントを利用してみます。
前に書いた手順に従って進みます。
クラスを作る。
editorTabColorProvider
ではEditorTabColorProvider
というインターフェースを実装するように指定されているので実装します。
TabColorExtensionImpl
クラスを作成し以下のように記述しましょう。
public class TabColorExtensionImpl implements EditorTabColorProvider {
@Nullable
@Override
public Color getEditorTabColor(@NotNull Project project, @NotNull VirtualFile virtualFile) {
switch (virtualFile.getFileType().getDefaultExtension()) {
case "txt":
return JBColor.GREEN;
case "xml":
return JBColor.BLUE;
case "java":
return JBColor.YELLOW;
default:
return null;
}
}
}
この例では開いたファイルの拡張子に従ってタブの色を変更します。
plugin.xml
に宣言する。
以下のようにplugin.xml
に追記してください。
<idea-plugin>
...
<extensions defaultExtensionNs="com.intellij">
<editorTabColorProvider implementation="<パッケージ名>.TabColorExtensionImpl" />
</extensions>
</idea-plugin>
<extensions>に宣言されている
defaultExtensionNs
はプラグインのidを指定することでそのプラグインで指定されている拡張ポイントを利用することができます。
例えば自分が作成しているEmojiPrefixの拡張ポイントであるemojiPanelFactory
を利用するにはdefaultExtensionNs
にcom.github.syuchan1005.emojiprefix
を指定します。
拡張ポイントの探し方(おまけ)
IntelliJ Platformで使用できる拡張ポイントは機能ごとに下の3つのXMLファイルにまとめられています。
基本はその名前で判断しますが,できないときはブレークポイントを設定しデバッグをして探すなどしましょう。
(そのうちこの辺もリストにしたいけどめんどくさいよねぇ)
拡張ポイントを作成する
今回は単純に何かが起きたらfireEvent
メソッドが呼び出されるといったものを作ります。
拡張ポイントの名前はfireEventListener
とします。
クラスの場合
(インターフェースの場合と混同しないよう,すべての項目にC
と接頭辞を浸けます)
(クラスの方どう作ればいいかよくわからなくて若干ゴリ押ししてます)
クラスの作成
public class CFireEventListener {
public static final ExtensionPointName<CFireEventListener> EP_NAME =
ExtensionPointName.create("<パッケージ名>.cFireEventListener");
@Attribute("implementationClass")
private String implementationClass;
public CFireEventListener() {}
public void fireEvent() {}
protected CFireEventListener getInstance() {
try {
Class<?> clazz = Class.forName(implementationClass);
return (CFireEventListener) clazz.getConstructor().newInstance();
} catch (ReflectiveOperationException e) {
return null;
}
}
}
plugin.xmlに拡張ポイントを登録
plugin.xml
に以下のように記述します
<idea-plugin>
...
<extensionPoints>
<extensionPoint name="cFireEventListener" beanClass="<パッケージ名>.CFireEventListener">
<with attribute="implementationClass" implements="<パッケージ名>.CFireEventListener"/>
</extensionPoint>
</extensionPoints>
</idea-plugin>
インターフェースの場合
(クラスの場合と混同しないよう,すべての項目にI
と接頭辞を浸けます)
インターフェースの作成
public interface IFireEventListener {
ExtensionPointName<IFireEventListener> EP_NAME =
ExtensionPointName.create("<パッケージ名>.iFireEventListener");
void fireEvent();
}
plugin.xmlに拡張ポイントを登録
plugin.xml
に以下のように記述します
<idea-plugin>
...
<extensionPoints>
<extensionPoint name="iFireEventListener" interface="<パッケージ名>.IFireEventListener"/>
</extensionPoints>
</idea-plugin>
拡張ポイントのテスト
テストのために拡張ポイントを呼び出すFireEventAction
クラスを作成し,Menuに追加します。
public class FireEventAction extends AnAction {
@Override
public void actionPerformed(AnActionEvent anActionEvent) {
for (CFireEventListener listener : CFireEventListener.EP_NAME.getExtensions()) {
listener.getInstance().fireEvent();
}
for (IFireEventListener listener : IFireEventListener.EP_NAME.getExtensions()) {
listener.fireEvent();
}
}
}
<action class="<パッケージ名>.FireEventAction" id="<プラグイン名>.FireEventAction"
text="Fire Action" icon="AllIcons.RunConfigurations.Scroll_down"/>
このままでは呼び出すことはできますが拡張ポイントが使われていないので,クラスを作成しplugin.xml
に登録します
public class CFireEventListenerImpl extends CFireEventListener {
@Override
public void fireEvent() {
Notifications.Bus.notify(new Notification("<プラグイン名>", "Fire Event", "Class", NotificationType.INFORMATION));
}
}
public class IFireEventListenerImpl implements IFireEventListener {
@Override
public void fireEvent() {
Notifications.Bus.notify(new Notification("<プラグイン名>", "Fire Event", "Interface", NotificationType.INFORMATION));
}
}
<idea-plugin>
...
<extensions defaultExtensionNs="<プラグインID>">
<cFireEventListener implementationClass="<パッケージ名>.CFireEventListenerImpl" />
<iFireEventListener implementation="<パッケージ名>.IFireEventListenerImpl" />
</extensions>
</idea-plugin>
これでメニューに追加されたFire Event
をクリックすることでExtension Point
が動いていれば通知が出ます。
Author And Source
この問題について(IntelliJ IDEAのプラグインを作ろう!(拡張ポイント)), 我々は、より多くの情報をここで見つけました https://qiita.com/syuchan1005/items/7dcb4c68c26aa0594e4e著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .