本丸のエディタを作ってみました。テキストファイル内で、%%と%%に囲まれた場所だけをハイライトするテキストエディタを作ってみました。
import org.eclipse.ui.editors.text.TextEditor; public class ScriptEditor extends TextEditor { private ColorManager colorManager; <-Colorクラスを管理するユーティリティクラス public ScriptEditor() { super(); colorManager = new ColorManager(); ↓後述 setSourceViewerConfiguration(new ScriptConfiguration(colorManager)); setDocumentProvider(new ScriptDocumentProvider()); ↑後述 } public void dispose() { colorManager.dispose(); super.dispose(); } }
このクラスは、どのようにドキュメント(エディタが編集するテキスト)のパーティションを切るかを設定します。後に、ScriptDocumentProvider?クラス内で呼び出されます。
package nu.mine.kino.plugin.script.editors; import org.eclipse.jface.text.rules.IPredicateRule; import org.eclipse.jface.text.rules.IToken; import org.eclipse.jface.text.rules.MultiLineRule; import org.eclipse.jface.text.rules.RuleBasedPartitionScanner; import org.eclipse.jface.text.rules.Token; public class ScriptPartitionScanner extends RuleBasedPartitionScanner { public static final String SCRIPT_VAR = "__script_var"; public ScriptPartitionScanner() { IToken var = new Token(SCRIPT_VAR); IPredicateRule[] rules = new IPredicateRule[1]; // rules[1] = new TagRule(tag); rules[0] = new MultiLineRule("%%", "%%", var); setPredicateRules(rules); } }
これで、%% から %%で囲まれた場所は、SCRIPT_VARというパーティションであるという設定ができました。
ScriptEditor?の処理でsetDocumentProvider?の引数に指定されたScriptDocumentProvider? はFileDocumentProvider?を拡張しています。このクラスでFileDocumentProvider?#IDocument createDocument(Object element) throws CoreException? を Overrideします。そのメソッド内でIDocumentPartitioner?の実装クラスを設定しています。
protected IDocument createDocument(Object element) throws CoreException { logger.debug("createDocument(Object) - start"); IDocument document = super.createDocument(element); if (document != null) { IDocumentPartitioner partitioner = new FastPartitioner( new ScriptPartitionScanner(), <-さっき作ったヤツ new String[] { ScriptPartitionScanner.SCRIPT_VAR }); partitioner.connect(document); document.setDocumentPartitioner(partitioner); } logger.debug("createDocument(Object) - end"); return document; }
SourceViewerConfiguration?#public IPresentationReconciler? getPresentationReconciler? をOverride します。
public IPresentationReconciler getPresentationReconciler( ISourceViewer sourceViewer) { logger.debug("getPresentationReconciler(ISourceViewer) - start"); PresentationReconciler reconciler = new PresentationReconciler(); Color color = colorManager.getColor(IScriptColorConstants.SCRIPT_VAR); TextAttribute attribute = new TextAttribute(color); SingleTokenScanner singleTokenScanner = new SingleTokenScanner( attribute); DefaultDamagerRepairer dr = new DefaultDamagerRepairer( singleTokenScanner); reconciler.setDamager(dr, ScriptPartitionScanner.SCRIPT_VAR); reconciler.setRepairer(dr, ScriptPartitionScanner.SCRIPT_VAR); logger.debug("getPresentationReconciler(ISourceViewer) - end"); return reconciler; }
ここまでで、SCRIPT_VARというパーティション(ここは%%〜%%内という区画(パーティション)でした)にDefaultDamagerRepairer? というダメージャ、リペアラが設定されました。このDefaultDamagerRepairer?にはSingleTokenScanner? というスキャナを渡してあります。このスキャナは下記の通り。。
private class SingleTokenScanner extends BufferedRuleBasedScanner { public SingleTokenScanner(TextAttribute attribute) { setDefaultReturnToken(new Token(attribute)); } }
ちなみに他のクラスはこんな感じ。
public interface IScriptColorConstants { RGB SCRIPT_VAR = new RGB(255, 0, 0); <-赤。 }
public class ColorManager { protected Map fColorTable = new HashMap(10); public void dispose() { Iterator e = fColorTable.values().iterator(); while (e.hasNext()) ((Color) e.next()).dispose(); } public Color getColor(RGB rgb) { Color color = (Color) fColorTable.get(rgb); if (color == null) { color = new Color(Display.getCurrent(), rgb); fColorTable.put(rgb, color); } return color; } }
実際にEclipseでこのプラグインを実行してテキストファイルを開いてみると、%%〜%%内だけが赤字になっています。でもこれだとその外、つまりSCRIPT_VARのパーティション外の箇所にダメージャ・リペアラが設定されていないため、そこにダメージャ・リペアラを設定します。この、定義したパーティション以外の箇所はIDocument.DEFAULT_CONTENT_TYPE という名前がついています。よってgetPresentationReconciler?メソッド内に以下の記述を追加します。
Color defaultColor = colorManager .getColor(IScriptColorConstants.DEFAULT); TextAttribute defaultAttr = new TextAttribute(defaultColor); dr = new DefaultDamagerRepairer(new SingleTokenScanner(defaultAttr)); reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
プロパティシートを使うのと同様に、TextEditor?のサブクラスのgetAdapterメソッドをOverrideします。
public Object getAdapter(Class adapter) { if (IContentOutlinePage.class.equals(adapter)) { if (fOutlinePage == null) { fOutlinePage = new ScriptContentOutlinePage( getDocumentProvider(), this); if (getEditorInput() != null) { fOutlinePage.setInput(getEditorInput()); } fOutlinePage.addSelectionChangedListener(this); } return fOutlinePage; } return super.getAdapter(adapter); }
ScriptContentOutlinePage?はIContentOutlinePage?をimplementsしたクラスです。
例えば、アウトラインでクリックした箇所にカーソルを移動して、そこを選択状態にしたい場合*1
protectedな下記のメソッドが使用できます。
ISelection selection = event.getSelection(); if (!selection.isEmpty()) { int start = 開始位置 int length = 長さ getSourceViewer().getTextWidget().setSelectionRange(start, length); }
他に、
getSourceViewer().getTextWidget().setSelection(start,start + length);
や
ISourceViewer sourceViewer = getSourceViewer(); StyledText textWidget = getSourceViewer().getTextWidget(); try { textWidget.setRedraw(false); sourceViewer.revealRange(start, length); sourceViewer.setSelectedRange(start, length); } finally { textWidget.setRedraw(true); }
publicな下記のメソッドを使用します。
ITextEditor#selectAndReveal(int start, int length);
// ワークベンチの取得 IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); //アクティブなエディタの取得 IEditorPart editor = window.getActivePage().getActiveEditor(); AbstractTextEditor aEditor = (AbstractTextEditor) editor;
IDocument document = aEditor.getDocumentProvider().getDocument(editor.getEditorInput());
この記事は
現在のアクセス:25845