文档和分区

平台文本框架为文本定义文档模型,并提供一个使用此模型来显示文本的查看器。我们将首先查看 Java 编辑器示例并了解它如何使用此模型。我们将不重点讨论注册编辑器扩展的基本结构,原因是我们已经在讨论 org.eclipse.ui.editors 的那一节中进行了讨论。但是,我们将了解示例中是如何实现编辑器类的细节。

文档提供程序和文档

在工作台中,当用户选择域元素(例如,一个文件或者存储在归档文件中的元素)并打开它时,通常都会打开编辑器。当创建编辑器时,编辑器就会与编辑器输入(IEditorInput)(它描述正在被编辑的对象)相关联。

当用户打开具有“*.jav”扩展的文件时,将打开 Java 编辑器示例。在这种情况中,编辑器的输入是 IFileEditorInput。平台文本框架很少对编辑器输入本身作出假设。它对输入使用称为 IDocument 的表示模型,因此,它可以有效地显示和处理文本。

这意味着必须具有一种方法从期望的域模型(编辑器输入)映射至表示模型。在 IDocumentProvider 中定义了此映射。只要给定编辑器输入,文档提供程序就会返回适当的 IDocument

Java 编辑器示例继承插件 org.eclipse.ui.editors 定义的 TextFileDocumentProvider。扩展 org.eclipse.ui.editors.documentProviders 用于定义编辑器输入类型(或文件扩展)与文档提供程序之间的映射。编辑器插件定义其文档提供程序,如下所示:

   <extension
         point="org.eclipse.ui.editors.documentProviders">
<provider 
            class="org.eclipse.ui.editors.text.TextFileDocumentProvider"
            inputTypes="org.eclipse.ui.IStorageEditorInput"
            id="org.eclipse.ui.editors.text.StorageDocumentProvider">
   </provider>
</extension>

此扩展点允许插件注册文档提供程序并将它们与文件扩展或编辑器输入类进行关联。因为 Java 编辑器示例未定义它自己的文件提供程序扩展,所以它会继承对属于 IStorageEditorInput 的所有输入类型指定的通用文档提供程序。当用户打开文件进行编辑时,平台会管理有关创建适当的文档提供程序实例的详细信息。如果为文件扩展注册了特定文档提供程序,则将使用该提供程序。如果该文件扩展没有特定文档提供程序,则将使用编辑器输入类型来查找相应的提供程序。

通过使用通用平台文档提供程序,Java 编辑器示例可利用该文档提供程序的所有功能,如文件缓冲和其它优化。

文档设置

既然 Java 编辑器使用平台文本文档提供程序,它会如何提供用于处理 Java 文件的任何专门行为呢?

扩展 org.eclipse.core.filebuffers.documentSetup 用于定义文件扩展与 IDocumentSetupParticipant 之间的映射。一旦向编辑器提供了该文档,设置参与者就会使用所有特殊功能设置该文档。

<extension
	id="ExampleJavaDocumentSetupParticipant"
	name="%documentSetupParticipantName"
	point="org.eclipse.core.filebuffers.documentSetup">
	<participant
		extensions="jav"
		class="org.eclipse.ui.examples.javaeditor.JavaDocumentSetupParticipant">
	</participant>
</extension>

此扩展定义允许示例设置该文档以执行特定于 Java 的任务。那么,JavaDocumentSetupParticipant 又该做些什么呢?我们来看一下 setup 方法的简化版本。

 	public void setup(IDocument document) {
		...
		IDocumentPartitioner partitioner= new FastPartitioner(JavaEditorExamplePlugin.getDefault().getJavaPartitionScanner(), JavaPartitionScanner.JAVA_PARTITION_TYPES);
		partitioner.connect(document);
		...
	}

设置代码配置称为分区程序(partitioner)的对象。

分区

分区程序(IDocumentPartitioner)负责将文档划分成不重叠的区域(称为分区)。分区(由 ITypedRegion 中表示)对于根据功能(例如,语法突出显示或格式化)来以不同方式处理文档的不同部分是很有用的。

对于 Java 编辑器示例,文档被划分成表示 javadoc 注释、多行注释和其它内容的分区。对每个区域都指定了内容类型以及它在文档中的位置。当用户编辑文本时,位置就会相应地更新。

基于规则进行文档分区

由每个编辑器来确定文档分区程序的适当实现。在 org.eclipse.jface.text.rules 中提供了对基于规则进行文档扫描的支持。使用基于规则的扫描程序允许编辑器使用由框架提供的 FastPartitioner

IDocumentPartitioner partitioner= new FastPartitioner(JavaEditorExamplePlugin.getDefault().getJavaPartitionScanner(), JavaPartitionScanner.JAVA_PARTITION_TYPES);

RuleBasedPartitionScanner 是基于规则的扫描程序的超类。子类负责枚举和实现一些规则,当扫描文档时,应当使用这些规则来区分标记(例如,行定界符、空格和类属模式)。示例的 JavaPartitionScanner 定义用于区分单行注释、字符常量、javadoc、多行注释和词语的规则。这是在扫描程序的构造函数中完成的:

public JavaPartitionScanner() {
	super();
	IToken javaDoc= new Token(JAVA_DOC);
	IToken comment= new Token(JAVA_MULTILINE_COMMENT);

	List rules= new ArrayList();
	// Add rule for single line comments.
	rules.add(new EndOfLineRule("//", Token.UNDEFINED)); 

	// Add rule for strings and character constants.
	rules.add(new SingleLineRule("\"", "\"", Token.UNDEFINED, '\\')); 
	rules.add(new SingleLineRule("'", "'", Token.UNDEFINED, '\\')); 

	// Add special case word rule.
	rules.add(new WordPredicateRule(comment));

	// Add rules for multi-line comments and javadoc.
	rules.add(new MultiLineRule("/**", "*/", javaDoc, (char) 0, true)); 
	rules.add(new MultiLineRule("/*", "*/", comment, (char) 0, true)); 

	IPredicateRule[] result= new IPredicateRule[rules.size()];
	rules.toArray(result);
	setPredicateRules(result);
}

有关定义规则以及可用的规则类型的更多详细信息,请参阅 org.eclipse.jface.text.rules 中的类。当我们查看语法着色时将再查看一下扫描程序。