ドキュメントのパーティショニング
Eclipseのエディタ(正確にはJFaceのテキストエディタ・フレームワーク)ではエディタで編集するドキュメントの内容をorg.eclipse.jface.text.IDocumentという抽象的なオブジェクトとして扱います。IDocumentオブジェクトはドキュメントプロバイダによって提供されます。今回のサンプルではXMLDocumentProviderがドキュメントプロバイダに当たります。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
ポイントとなるのは(1)でセットしているXMLPartitionScannerです。パーティションスキャナはドキュメントを意味的な区域に分割(パーティショニング)します。パーティショニングされた区域はそれぞれにシンタックスハイライトやコードアシストといった機能を設定することが可能です。Javaエディタを例にすると、Javadoc部分ではJavadocタグのアシスト、Javaコード部分ではJavaコードのアシスト、というようにコンテクストに応じた機能を提供することができます。
XMLPartitionScannerではコメント(XML_COMMENT)、タグ(XML_TAG)およびそれ以外の3つのパーティションに分割します。ではXMLPartitionScannerのソースコードを見てみましょう。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
ご覧のとおり、XMLPartitionScannerはRuleBasedPartitionScannerを継承して実装されています。XMLやプログラムのソースコードなど、ルールに基づいたドキュメントをパーティショニングする場合はorg.eclipse.jface.text.rules.RuleBasedPartitionScannerを使用できます。
(1)ではコメント区域のルールをorg.eclipse.jface.text.rules.MultiLineRuleとして定義しています。MultiLineRuleは開始文字列と終了文字列を指定してマッチする部分をパーティションとするルールです。また、(2)ではタグ区域のルールをTagRuleとして定義しています。タグ区域に関してもコメント区域と同じようにnew MultiLineTule("<",">",token)でよさそうな気がしますが、これだとコメントやXML宣言にもマッチしてしまいますのでTagRuleはリスト5のようにMultiLineRuleを継承して独自にマッチングの判定を行うようになっています。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
これらによってXMLドキュメントは図5のようなパーティションに分割されます。
エディタのコンフィグレーション
SourceViewerConfigurationはエディタの動作をカスタマイズするためのエントリポイントになります。自動生成されたサンプルではXMLConfigurationというorg.eclipse.jface.text.source.SourceViewerConfigurationを継承したクラスが使用されています。このようにSourceViewerConfigurationの各メソッドをオーバーライドすることで、以下のようなエディタの動作をカスタマイズすることができます。
- コードアシスト(入力補完)
- シンタックスハイライト(強調表示)
- ダブルクリック時の動作
- オートインデントの挙動
- ソースコードフォーマッタ(ソースの整形機能)
テンプレートで作成したXMLエディタはコードアシストやソースコードのフォーマットといった機能は備えていません。今回はシンタックスハイライトとダブルクリック時の動作、特にシンタックスハイライトの実装方法について詳しく見ていくことにします(コードアシストの実装については今後の連載で触れる予定です)。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
(1)のgetConfiguredContentType()メソッドでは、エディタがサポートするパーティションのタイプを返すよう実装します。また、(2)のgetDoubleClickStrategy()メソッドではダブルクリック時の動作を決定するorg.eclipse.jface.text.ITextDoubleClickStrategyの実装クラスを返却します。XMLDoubleClickStrategyの実装については本稿では深く触れませんが、ダブルクリックされた位置に応じてダブルクオートで囲まれた区域、もしくは単語を検出して範囲選択を行う実装になっています。そして(3)のgetPresentationReconciler()メソッドでエディタのプレゼンテーション(シンタックスハイライト)に関する設定を行います。
シンタックスハイライトはorg.eclipse.jface.text.presentation.PresentationReconcilerに対してパーティションごとにダメージャとリペアラを設定することで実現しています。PresentationReconcilerはテキストの変更を検出するとまずダメージャを呼び出しダメージ(テキストのプレゼンテーションを更新しなければならない範囲)を算出します。次にリペアラにダメージを通知し、新しいプレゼンテーションを取得します。
今回の例ではXML_TAG区域、DEFAULT_CONTENT_TYPE区域にはそれぞれXMLTagScanner、XMLScannerがセットされたorg.eclipse.jface.text.rules.DefaultDamagerRepairerが設定されています。XMLTagScannerの実装はリスト7のようになっています。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
これはXML_TAG区域においてダブルクオートもしくはシングルクオートで囲まれた領域をIXMLColorConstants.STRINGで定義された色でハイライトします。
XMLScannerの実装も類似しています。こちらはDEFAULT_CONTENT_TYPE区域において<?と?>で囲まれた領域をIXMLColorConstants.PROC_INSTRで定義された色でハイライトします。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
パーティション内でルールにマッチしなかった部分についてはsetDefaultReturnToken()で指定されたトークンが適用されます。また、XML_COMMENT区域はそれ以上分割する必要はありませんのでNonRuleBasedDamagerRepairerによって区域全体をIXMLColorConstants.XML_COMMENTで定義された色でハイライトします。
おわりに
テキストエディタの実装には多くのトピックがありますが、特に重要なのは今回重点的に解説したパーティショニングです。本稿で解説したとおり、シンタックスハイライトはパーティショニングされた区域に対して設定を行いますし、コードアシスト機能もパーティションごとにアシストプロセッサを設定することで実現します。本連載では今後、テキストエディタに関するより詳細なトピックにも触れていく予定ですのでご期待ください。
次回はEclipseのプリファレンスAPIを使用して、プラグインの各種設定を保存、読み込みを行う方法について解説したいと思います。
Copyright © ITmedia, Inc. All Rights Reserved.