Text Formatting
Text Formatting(文本格式化)可以快速的将源代码按照预定的规则排版,JTF 只是定义了这个框架,将其发挥到极致的是 JDT。打开 Eclipse 的设置页,找到 General->Java->Code Style->Formatter,你会发现在这里可以编辑名目繁多的格式化选项。JDT 提供的代码格式化功能强大的令人眩目,但本文的目的是介绍这个强大功能下的基础设施。
IFormattingStrategy
IFormattingStrategy(格式化策略)是格式化真正完成的地方,它代表一种格式化的方式。格式化策略是和文本类型相关联的,所以可以为每一种文本类型创建一个格式化策略,这是 JTF 的一个基本做法,你还能回忆起还有哪些功能是和文本类型绑定在一起的吗?这个接口有一个扩展接口 IFormattingStrategyExtension,它引入了 Formatting Context(格式化上下文)的概念,下面会有介绍。
IContentFormatter
IContentFormatter 是最基本的接口,它代表了一个格式化器。既然实际的格式化工作应该放到 IFormattingStrategy 中,那 IContentFormatter 做什么呢?可以说,它基本上相当于一个调度器,它会决定要格式化的内容具有什么样的文本类型,然后调用不同的 IFormattingStrategy 实现。不过,这只是推荐行为,你可以在 IContentFormatter 的实现里做任何事,但是不推荐刻意超越这个架构的约束。JTF有这个接口的缺省实现:ContentFormatter,一般我们直接使用它就可以了。
IFormattingContext
IFormattingContext 为格式化提供附加信息,它采用键值对的方式保存信息,所以你可以存任何格式化需要知道的东西。不过这是一个相对较新的接口,从 Eclipse 3.0 开始才出现,你实现了 IFormattingStrategyExtension 才需要用到它。记住,不要忘了查查是否每个接口都有扩展接口,也许你会有很多新的发现,因为 JTF 中到处都是,或者说 Eclipse 中到处都是扩展接口。
实现文本格式化
实现 IFormattingStrategy
首先我使用 ExprFormattingStrategy 实现 IFormattingStrategy 接口,我没有实现 IFormattingStrategyExtension,因为例子中的语言太简单了,我不需要多少上下文信息就可以做格式化工作。另外一个原因是:文本格式化的算法因不同的情况而已,且和和 JTF 的架构关系不大,没有必要进行详细的演示。我的格式化方式很简单:每个符号之间会有空格分隔(除了分号),且每行只允许写一条语句。
配置
修改 ExprConfiguration,覆盖 getContentFormatter 方法。我使用缺省实现,并用 setFormattingStrategy 方法注册 ExprFormattingStrategy。出于简单至上的原则,我没有实现 IContentFormatter,如果你的软件需求必须要实现 IContentFormatter,请不要犹豫。
快捷键处理
和内容提示,快速帮助一样,需要一个快捷键来触发文本格式化。普通的文本编辑器并没有格式化的功能,如果我需要使用格式化的命令ID,需要依赖 org.eclipse.jdt.ui 插件,我不太想这样做。当然对我这个例子来说,这无所谓,但如果是正在开发一个真正的产品,我想你也不希望为了使用一个常量就把整个 JDT 都包含进来,所以我通过扩展定义了一个格式化命令,并绑定到 Ctrl+Shift+F。然后,仿照快速帮助时的做法,在 ExprViewer 的 createHandlers 方法中添加一个 handler。