個人的に手こずったEclipseプラグインのビュー開発Tips

この記事は[高知工科大学 Advent Calendar 2018](https://adventar.org/calendars/2959)の24日目の記事です．
クリスマスイブです．みなさんはいかがお過ごしでしょうか．私はこれ書いてます．
jsわからなかったので，最近なぜか触っているEclipseのプラグイン開発のTip的なやつ書きます．世に需要のあらんことを．

## はじめに
なんやかんやでEclipseのプラグインを開発しています．その際，実現したい機能の実装方法がなかなかわからず辛かったので，同じように苦しんでいる人の助けになればと思った次第です．
この記事ではEclipseのプラグインの中でも，ビューの開発について書きます（他は知らない）．

##### お品書き
- [ファイルを独自のエディタで開く](#ファイルを独自のエディタで開く)
- [マーカーを使ってエディタの指定範囲をハイライトする](#マーカーを使ってエディタの指定範囲をハイライトする)
- [別のビューに情報を渡す](#別のビューに情報を渡す)
- [エクスポートしたプラグインを他のEclipseで読み込む際の注意](#エクスポートしたプラグインを他のeclipseで読み込む際の注意)


## 環境
- Mac
- Eclipse2018-09 Mac 64bit Ultimate（[日本語化されたやつ](http://mergedoc.osdn.jp/)）
- JavaSE - 1.8
- plugin.xmlのeclipse version : 3.4
- フレームワーク : SWT

## Tips
### ファイルを独自のエディタで開く
`IDE.openEditor`を使うことで任意のファイルを開くことができます．この時，ファイルを開くエディタは，プラグインを使う側のEclipseの設定に依存するようです．つまり，設定されていなかったり，設定が変わっていたりすると，どのエディタで開かれるかわかりません．開くエディタを設定するには，例えば次のようにエディタのIDを引数に渡してやります．
エディタのIDは，自作エディタの場合は`<editor>`タグで指定したIDです．

```java
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
IWorkbenchPage page = window.getActivePage();
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IFile file  = root.getFile(/* File path */);
IEditorInput ie = new FileEditorInput(file);
try {
  IDE.openEditor(page, ie, /* Editor Id */);
} catch (PartInitException e) {
  e.printStackTrace();
}
```


### マーカーを使ってエディタの指定範囲をハイライトする
エディタの指定範囲をハイライトするのに，マーカーを利用できます．マーカーの`CHAR_START`と`CHAR_END`を設定することで`CHAR_START`から`CHAR_END`までをハイライトできます．次の例は，任意の行をハイライトする例です．ハイライトする色は，マーカー自体の設定ではなく，`org.eclipse.ui.editors.markerAnnotationSpecification`を拡張して，`colorPreferenceValue`属性で設定します．
マーカーの拡張が`org.eclipse.core.resources.markers`で，その設定をするのが`org.eclipse.ui.editors.annotationTypes`で，さらにその詳細を設定するのが`org.eclipse.ui.editors.markerAnnotationSpecification`なので注意（めんどい）．

```java
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
IWorkbenchPage page = window.getActivePage();
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IFile file  = root.getFile(/* File path */);
FileEditorInput input = new FileEditorInput(file);
FileDocumentProvider provider = new FileDocumentProvider();
try {
  provider.connect(input);
} catch (CoreException e) {
  throw new RuntimeException(e);
}
IDocument document = provider.getDocument(input);
IRegion r = null;
try {
  r = document.getLineInformation(/* Line number */); // 行の情報を取得
} catch (BadLocationException e) {
  e.printStackTrace();
}
IMarker marker = file.createMarker(/* Marker ID */);
marker.setAttribute(IMarker.CHAR_START, r.getOffset());
marker.setAttribute(IMarker.CHAR_END, r.getOffset() + r.getLength());
```

### 別のビューに情報を渡す
別のビューの情報を渡すには，そのビューに専用の関数を用意してやればよいです．次のコードのように，`workbenchPage.showView`で開いているビューを探せるので，関数（コード中の`hoge`，任意に実装してね）を実行することで情報を渡せます．

```java
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchPage workbenchPage =
  workbench.getActiveWorkbenchWindow().getActivePage();
try {
  /* View Class */ view =
    (/* View Class */) workbenchPage.showView(/* View ID */);
  view.hoge(/* 情報 */);
} catch (PartInitException e) {
}
```

### エクスポートしたプラグインを他のEclipseで読み込む際の注意
作成したプラグインをjarファイルにエクスポートすることで，Eclipseで読み込んで利用できます．ただし，読み込むにも`Eclipse Plug-in Development Environment`が必要です．インストールされているかどうかの確認や，インストール自体は，メニューバーからHelp -> Install New Software の順に開き，使っているEclipse用のリポジトリ（Eclipse2018-09なら`2018-09 - http://download.eclipse.org/releases/2018-09`）からできます．
それから，jarファイルを配置する場所ですが，Eclipseのバージョン（？）によっては`Contents/Eclipse/plugin`の下でも読み込んでくれるようですが，[公式](https://www.eclipse.org/)からダウンロードしたEclipse2018-09のEclipse IDE for Java Developersでは`Contents/Eclipse/dropins`の下でないと読み込んでくれませんでした．

## おわりに
需要があっても役に立つかどうかわからない記事ですが，億が一にでも誰かの助けになれれば幸いです．jsわかんないから仕方ない（仕方なくない）．ちょっと開発から間が空いて忘れてることあるかもなので，何か思い出したら追記するかも．

それではみなさまメリークリスマス，私は周回に戻ります．