S-JIS[2013-08-24] 変更履歴

Xtext入力補完

Xtextの入力補完のメモ。


概要

Xtextで作ったエディターでは入力補完が出来る。
WindowsではCtrl+Space、UnixではAlt+「/」で、その場所に入力できる候補の一覧が出る。

これら以外の入力候補を出したい場合はIContentProposalProviderを実装すればよい。

xtextファイルをビルドすると、ProposalProviderクラスの空実装が作られる。
例えばDMDL.xtextの場合、DMDLProposalProviderxtendというファイルが作られる。(Xtext 2.4.2)
これはXtendという(Javaに似た)言語であり、ここに入力補完のカスタマイズを実装していく。


Javaソースへの変換

Xtext 2.4.2では、ソース整形クラスとして生成されるファイルはXtend用である。
個人的には新しい言語を覚えるよりJavaの方が分かり易いので、Javaで実装したい。

XtendはJavaに似ているので、Javaに変換するのも難しくない。

元のxtendファイルは、ファイル自体は削除せずに、中身を空にしておく。
中身が残っていると同じクラスがJavaとXtendの両方で定義されることになり、コンパイルエラーになる。
xtendファイル自体を消してしまうと、次にxtextファイルをビルドしたときにまた生成されてしまうので、ファイル自体は残しておく必要がある。

AbstractDMDLProposalProviderというクラスも生成されているが、こちらは修正する必要は無い。

DMDLProposalProvider.java(DMDLの例):

package jp.hishidama.xtext.dmdl_editor.ui.contentassist;
public class DMDLProposalProvider extends AbstractDMDLProposalProvider {
}

DMDLでは、集計モデルのときには集約関数(集約の種類:any・sum・max・min・count)を指定することが出来るので、それを定義してみる。

xtextファイル上は集約関数(aggregator)の種類を特に規定していない。(今回の例なら列挙ルールを使う方法でも出来るはず)

DMDL.xtext:

PropertyFolding:
	(description=Description)?
	(attributes=AttributeList)?
	aggregator=QualifiedName
	from=[Property|Name] ('->' | '=>') name=Name
	';';

DMDLProposalProvider.java:

	@Override
	public void completePropertyFolding_Aggregator(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		acceptor.accept(createCompletionProposal("any", context));
		acceptor.accept(createCompletionProposal("sum", context));
		acceptor.accept(createCompletionProposal("min", context));
		acceptor.accept(createCompletionProposal("max", context));
		acceptor.accept(createCompletionProposal("count", context));
	}

今回の例ではPropertyFoldingルールのaggregator変数を対象とするので、メソッド名の先頭にcompleteが付いた「completePropertyFolding_Aggregator」メソッドをオーバーライドする。
そして、acceptorに対して補完候補を登録してやればよい。


ついでに、「from -> name」のnameに当たる部分の補完候補を出してみる。
DMDLにおけるこの構文は“新しい名前が付けられる”ものだが、たいていは元の名前と同じだろうから、補完候補にはfromの名前を出す。

DMDLProposalProvider.java:

import jp.hishidama.xtext.dmdl_editor.dmdl.Property;
import jp.hishidama.xtext.dmdl_editor.dmdl.PropertyFolding;
	@Override
	public void completePropertyFolding_Name(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		PropertyFolding property = (PropertyFolding) model;
		Property ref = property.getFrom();
		if (ref != null) {
			acceptor.accept(createCompletionProposal(ref.getName(), context));
		}
	}

Xtext目次へ戻る / Eclipseへ戻る / 技術メモへ戻る
メールの送信先:ひしだま