GradleでIntelliJ Plugin開発：簡易tool window pluginの作成


## 免責
本稿はitohiro73の個人的な技術メモであり、雇用主または所属する団体とは一切関係ありません。

This article is itohiro73's personal technical note and does not express the views or opinions of my employer.

## 目的

IntelliJ Pluginを作成する場合、[こちらの手順](http://qiita.com/Vexus2/items/e04a21f00e467b7ac8ad)等で紹介されているように、「New Project」から「IntelliJ Platform Plugin」を選んで作成するのが通常かと思います。

ただ、いったんこの方法でつくると、あれ、MavenとかGradleで依存性管理したいんだけどどうしたらいいの？とちょっと戸惑ったりします。また、とくにサンプルコード等が作成されるわけではないので、まず最初に何をすれば良いのか途方にくれたりたりします。

本稿では、ビルドツールとしてGradleを使ってIntelliJ Plugin開発環境を構築するための手順と、簡単なtool window pluginのサンプルを紹介します。Gradleに関しては[gradle-intellij-plugin](https://github.com/JetBrains/gradle-intellij-plugin)というツールがすであるので、そのまま使っちゃいます。

手っ取り早く立ち上げたい方は、本稿の手順でできた雛形プロジェクトをGitHubにあげてあるので、[こちら](https://github.com/itohiro73/intellij-plugin-toolwindow-template)からgit cloneするとそのまま試すことができます。

## Gradleプラグインの導入
IntelliJにGradleプラグインが入っていない場合は、[IntelliJ IDEA] -> [Preferences] -> [Plugins] -> [Browse repositories...] -> [Gradleを検索] -> [Install plugin]の手順でインストールしてください。

##Gradleプロジェクトの作成。
Gradleプロジェクトの作成方法をステップバイステップで説明します。この手順に慣れている方は飛ばして「build.gradleの編集」をご覧ください。

まずは「New Project」から「IntelliJ Platform Plugin」ではなく「Gradle」を選び、「Java」のチェックボックスを選んだ状態で「Next」ボタンをクリックします。
![kobito.1442227947.871084.png](https://qiita-image-store.s3.amazonaws.com/0/34316/b32ba5d2-a160-d89e-bf3f-0aee50719742.png "kobito.1442227947.871084.png")


GroupId、ArtifactId、Versionを適当にいれ、「Next」ボタンをクリックします。
![kobito.1442228305.406311.png](https://qiita-image-store.s3.amazonaws.com/0/34316/70074869-408f-96c3-4b93-fec6d7328f5d.png "kobito.1442228305.406311.png")


Gradleの設定はとりあえず"Use default gradle wrapper (recommended)"を選択しておけば良いと思います。設定は後から変更できるのでお好きなようにどうぞ。

![kobito.1442228464.945676.png](https://qiita-image-store.s3.amazonaws.com/0/34316/e8f89579-b042-8d7b-77aa-de1a60d4ba3d.png "kobito.1442228464.945676.png")

あとは「Project name」と「Project location」を適宜入れて「Finish」ボタンを押します。

ここまでの手順で下記のようなプロジェクト構成が作成されるはずです。

```
.
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── your-project-name.iml
└── settings.gradle

```

## build.gradleの編集
プロジェクトが作成されたら、build.gradleに[gradle-intellij-plugin](https://github.com/JetBrains/gradle-intellij-plugin)の設定を加えます。Gradleのバージョンは2.1以上を想定しています。2.1未満のバージョンはリンク先の設定をご覧ください。JavaのsourceCompatibilityは1.8にしています。ラムダ式やDateTime APIを使用したコードで実験してみましたがとくに問題なさそうです（問題あったら教えてください）。

```gradle:build.gradle
plugins {
    id "org.jetbrains.intellij" version "0.0.20"
}

apply plugin: 'org.jetbrains.intellij'
apply plugin: 'java'

sourceCompatibility = 1.8

intellij {
    version '14.1.4'
    plugins 'coverage'
    pluginName 'sample'
}

group 'sample'
version '0.0.1-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    testCompile 'junit:junit:4.12'
}

```

## 簡易tool window pluginの作成

下記のようなファイル構成を作成し、HellowWorldWindow.javaとplugin.xmlを下記のように編集します。

```
.
└── src
    └── main
        ├── java
        │   └── HelloWorldWindow.java
        └── resources
            └── META-INF
                └── plugin.xml
```

```HellowWorldWindow.java
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;

import javax.swing.*;

public class HelloWorldWindow implements ToolWindowFactory {
    @Override
    public void createToolWindowContent(Project project, ToolWindow toolWindow) {

        JComponent parent = toolWindow.getComponent();
        JPanel panel = new JPanel();
        JLabel label = new JLabel("Hello World!!");
        panel.add(label);
        parent.add(panel);
    }
}
```

```plugin.xml
<idea-plugin version="2">
  <id>com.yourcompany.unique.plugin.id</id>
  <name>Sample plugin</name>
  <version>0.0.1</version>
  <vendor email="dummy" url="dummy">dummy</vendor>

  <description><![CDATA[
      Sample plugin.<br>
    ]]></description>

  <change-notes><![CDATA[
      Release 0.0.1: Initial release.<br>
    ]]>
  </change-notes>

  <!-- please see https://confluence.jetbrains.com/display/IDEADEV/Build+Number+Ranges for description -->
  <idea-version since-build="131"/>

  <!-- please see https://confluence.jetbrains.com/display/IDEADEV/Plugin+Compatibility+with+IntelliJ+Platform+Products
       on how to target different products -->
  <!-- uncomment to enable plugin in all products
  <depends>com.intellij.modules.lang</depends>
  -->

  <extensions defaultExtensionNs="com.intellij">
    <toolWindow id="sample" anchor="bottom" factoryClass="HelloWorldWindow"/>
  </extensions>

  <application-components>
  </application-components>

  <project-components>
  </project-components>

  <actions>
  </actions>

</idea-plugin>
```

ここでは\<extensions>に\<toolWindow>のfactoryClass属性としてHellowWorldWindowを渡してあげています。これだけで、HellowWorldWindow内のcreateToolWindowContent()メソッドで作成されたSwingのコンポーネントがtool windowとして立ち上がるpluginの完成です。

動作を見るためにGradleからビルドしてIntelliJを立ち上げてみましょう。このためにgradle-intellij-pluginにはrunIdeaというタスクが定義されています。Gradle本体がインストールされていなくてもwrapperスクリプトから下記のように立ち上げることができます（Windowsの場合はgradlew.batを使用)。

```
# ./gradlew runIdea
```

コンソールに下記のようなエラーが出るかもしれませんが、[こちら](https://devnet.jetbrains.com/thread/472158)の情報によると無視して良いようです。でもちょっと気になっちゃいますね。。

```
[     68]   WARN - .intellij.util.EnvironmentUtil - can't get shell environment 
java.lang.Exception: bin:/Users/hiroshi/.gradle/caches/modules-2/files-2.1/com.jetbrains.intellij.idea/ideaIC/14.1.4/e1a65bb05a50274b0aea828df954df82296eecce/ideaIC-14.1.4/bin
        at com.intellij.util.EnvironmentUtil.getShellEnv(EnvironmentUtil.java:150)
        at com.intellij.util.EnvironmentUtil.access$000(EnvironmentUtil.java:41)
        at com.intellij.util.EnvironmentUtil$1.call(EnvironmentUtil.java:54)
        at com.intellij.util.EnvironmentUtil$1.call(EnvironmentUtil.java:50)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

```

一番最初に立ち上げる際は、いろいろ設定項目を聞かれるので、よしなに設定して適当なプロジェクトを開いてみましょう。

左下に現れるこちらのTool Window Quick Accessをクリックしてやると。。。

![Screen Shot 2015-09-15 at 9.32.33 AM.png](https://qiita-image-store.s3.amazonaws.com/0/34316/476af81b-8612-d5ec-7f32-62a358416753.png "Screen Shot 2015-09-15 at 9.32.33 AM.png")

「sample」という名のtool windowがあらわれます。

![kobito.1442277300.320142.png](https://qiita-image-store.s3.amazonaws.com/0/34316/46314d85-ff3d-6d06-0b9f-e025ac5dd029.png "kobito.1442277300.320142.png")

クリックして、Hellow Worldと表示されれば動作確認成功です。

![kobito.1442277431.577678.png](https://qiita-image-store.s3.amazonaws.com/0/34316/84a9ee9a-1bc6-b509-a676-ea615654d62d.png "kobito.1442277431.577678.png")

ここから先は、build.gradleにライブラリを足したり、HelloWorldWindowを編集したり、plugin.xmlを編集したりとIntelliJ Plugin開発の第一歩を進めていくと良いと思います。


## 作成したpluginのリリース・共有
[gradle-intellij-plugin](https://github.com/JetBrains/gradle-intellij-plugin)では、配布用zip作成のためのタスク"buildPlugin"も用意されています。

非常に簡単で、下記のタスクを走らせるだけです。

```
# ./gradlew buildPlugin
```

すると、下記のようにzipファイルが作成されるので、これをそのままリポジトリにリリースしたり、[Preferences] -> [Plugins] -> [Install plugin from disk...]からインストールしたりすることができます。

```
.
├─
├── README.md
├── build
│   ├── distributions
│   │   └── sample-0.0.1-SNAPSHOT.zip

```

## intellij-plugin-toolwindow-template
ここまでの手順でできたプロジェクトをGitHubにあげてあるので、[こちら](https://github.com/itohiro73/intellij-plugin-toolwindow-template)からgit cloneするとそのまま試すことができます。

本当ならmavenのarchetypeみたいなやつを[Gradle Templates Plugin](https://github.com/townsfolk/gradle-templates)用のテンプレート的な感じでつくれたらいいなと思っていたけれど、[Intellij Plugin勉強会#2](http://connpass.com/event/19438/)までにそこまでやる余裕がなかったのでこれくらいで。。


## 合わせて読みたい
[IntelliJ Plugin開発準備（Mac編）：IntelliJ IDEA Community EditionのSDKとソースコードをセットアップ](http://qiita.com/itohiro73/items/df23ffd4d89b3c43e4a8)