Eclipseプラグイン実践テクニック(2)
高機能なXMLエディタをプラグインとして作る


コードアシストの実装

 さて、統合開発環境に求められる重要な機能の1つとして、ソースコード上での入力補完(コードアシスト)が挙げられます。もちろんEclipseのJavaエディタでもコードアシストが利用可能です。XMLの場合はDTDやXMLスキーマなどでスキーマを定義することが多く、これらのスキーマを基に補完候補を表示できると便利でしょう。今回はサンプルということでDTDを使用した補完機能を実装してみます。

図3 XMLのコードアシスト

 テキストエディタにコードアシスト機能を追加するにはエディタのコンフィグレーションクラスのgetContentAssistant()メソッドを以下のようにオーバーライドします。

リスト4
public class XMLConfiguration extends
SourceViewerConfiguration {
  ...

  public IContentAssistant getContentAssistant
  (ISourceViewer sourceViewer) {
    ContentAssistant assistant = new ContentAssistant();
    assistant.setContextInformationPopupOrientation
    (IContentAssistant.CONTEXT_INFO_ABOVE);

    XMLAssistProcessor processor =
    new XMLAssistProcessor(); //
……(1)
    assistant.setContentAssistProcessor
    (processor,IDocument.DEFAULT_CONTENT_TYPE);
    assistant.setContentAssistProcessor
    (processor,XMLPartitionScanner.XML_TAG);

    assistant.install(sourceViewer);

    return assistant;
  }

}

 (1)のXMLAssistProcessorがコードアシスト機能を提供するクラスになります。このクラスの実装方法については後述します。ここではIDocument.DEFAULT_CONTENT_TYPEおよびXMLPartitionScanner.XML_TAGというパーティションに対してXMLAssistProcessorを設定していますが、パーティションごとに別々のアシストプロセッサを設定することもできます。

 次にエディタ側でcreateAction()メソッドをオーバーライドし、コードアシストを行うアクションを登録しておく必要があります。

リスト5
public class XMLEditor extends TextEditor ... {
  ...

  protected void createActions() {
    super.createActions();
    IAction action = new ContentAssistAction( //
…… (1)
      XMLEditorPlugin.getResourceBundle(),
      "ContentAssistProposal", this);
    action.setActionDefinitionId
    (ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
    setAction("ContentAssistProposal", action);
  }

}

 (1)のContentAssistActionがコードアシストを行うアクションなのですが、このクラスをインスタンス化する場合は、コンストラクタにアクションのラベルやアイコンなどを指定するためのResourceBundle を渡す必要があります。ここではプラグインクラス(XMLEditorPlugin)で保持しているメッセージ用のリソースを使用していますので、プロパティファイルに以下のエントリを追加します(実際には、このアクションはメニュー等には一切表示されないため、以下のエントリは追加しなくても特に動作上の問題はありません)。

messages.properties
...
ContentAssistProposal_label=Co&ntent Assist
messages_ja.properties
...
ContentAssistProposal_label=コンテンツ・アシスト(&N)

 最後にXMLAssistProcessorの実装を見てみましょう。アシストプロセッサはorg.eclipse.jface.text.contentassist.IContentAssistProcessorインターフェイスを実装し、ソースコードとキャレットの位置から、補完候補の一覧をorg.eclipse.jface.text.contentassist.ICompletionProposalの配列として返却します。
computeCompletionProposals()メソッドがこの処理を行っています。その他のメソッドは必要に応じて実装します。

リスト6
public class XMLAssistProcessor implements
IContentAssistProcessor {

  ...
  public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
    // 補完候補を格納するリスト
    List proposals = new ArrayList();
    // ソースコードを取得
    String source = viewer.getDocument().get();

    // 補完候補を検索し、proposalsに
    // org.eclipse.jface.text.contentassist.CompletionProposal
    // のインスタンスを追加していく
    ...

    // 補完候補を返却
    return (ICompletionProposal[])proposals.toArray
    (new ICompletionProposal[proposals.size()]);
  }

  public IContextInformation[]
  computeContextInformation(ITextViewer viewer, int offset) {
    return null;
  }

  public char[]
  getCompletionProposalAutoActivationCharacters() {
    return null;
  }

  public char[]
  getContextInformationAutoActivationCharacters() {
    return null;
  }

  public String getErrorMessage() {
    return null;
  }

  public IContextInformationValidator
  getContextInformationValidator() {
    return null;
  }

  ...
}

 computeCompletionProposals()メソッドは実際には以下のような処理を行っています。

  1. XMLで使用されているDTDをインターネット上から読み込む。
  2. DTDParserというライブラリを使用してDTDの情報を取得する。
  3. キャレット位置に応じて最適な補完候補をリストアップし、CompletionProposalインスタンスを生成する。

 ただ、この部分に関してはそれなりに力技が必要な処理であることと、Eclipseプラグイン開発とは直接かかわりのない部分であるため具体的な実装についてはここでは割愛します。詳細については、サンプルコードをダウンロードして参照してください。

2/4

 INDEX

第2回 高機能なXMLエディタをプラグインとして作る

  Page1
テキストエディタの拡張
Page2
コードアシストの実装
  Page3
ダブルクリック時の動作のカスタマイズ
  Page4
ハイパーリンク機能


Java Solution全記事一覧



Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間