eclipse插件开发:写一个你自己的编辑器 ,语法着色

目的

      无论是Visual stuio还是Eclipse等众多IDE,映入我们眼帘最直观的就是各种语法着色,关键字如“int”,字符串如"ddd",注释如“com.bbe”。

      今天我们学习如何让你的编辑器支持语法着色。

·定义

      我们首先从思想上定义哪些输入串将被语法着色,以及它们的颜色和字体类型,我们有如下三种模式将被语法着色:

Ø       关键字

关键字包括SELECT, FROMWHERE

n         颜色:RGB(127, 0, 85)

n         styleSWT.BOLD

n         示例:CREATE

Ø       字符串

n         颜色:RGB(42, 0, 255)

n         style:默认

n         示例:"String"

Ø       注释

n         颜色:RGB(63, 95, 191)

n         style:默认

n         示例:/*Zero Bobo Resource Manager */

是的,正如你所见,我们使用的是Eclipse的默认语法颜色。

·分析

·3如何让编辑器着色

      想想,怎么才能让编辑器语法着色?

Ø       我们必须有一个语法(词法)扫描器(Scanner),它能够分解出输入中的单词(Token),并且根据某种模式判断出单词的类型,是关键字、字符串还是数字?在此前我们已经定义了各种Token类型对应的语法颜色和字体类型(如·2定义中描述)。 

Ø       AbstractDecoratedTextEditor上有一个SourceViewerSourceViewer属于JFace,它封装了StyledText。我们还必须为SourceViewer设置一个Configuration以支持对SourceViewer提供各种增加功能(add-ons),由它支持对SourceViewer进行语法着色。

·32 Eclipse的策略

针对我们上面的考虑,Eclipse中有对应的类实现它们:

 org.eclipse.jface.text.rules.RuleBasedScanner

为了支持语法着色功能,就必须使用某种扫描器对输入进行语法分析,将输入分解为一个个的记号(Token),同时还要确定这些Token属于什么类型,是关键字还是字符串。

定位于org.eclipse.jface.text.rules下的RuleBasedScanner类提供了扫描器的功能,该类可设置多个Rule(规则),对于输入按序执行这些rule,当某个Rule能够成功evaluate一个输入,就返回一个定义好的Token。如果一个rule返回了一个UN_DEFINETOKEN,就继续让下一个Rule来解析。如果没有Rule能够返回定义的token,则Scanner返回一个特定的Token,对该token调用isOther()将返回true。如果遇到了文件的结尾,则对Scanner返回的Token调用isEOF返回true

我们自己定义一个ZSqlScanner类继承RuleBasedScanner,并在构造中设置需要的rule

关于Rule主要有如下几种(Rule均实现IRule接口):

a)                 WordRule实现IRule:该规则可以发现一个完整的字,比如JavaSQL的关键字,他们的语法组成是固定的,int就是intlong就是long,通过这个规则可以发现这些关键字。WordRule需要一个IWordDetector接口的实例来辅助分析(实际上WordRule有点小问题,在后面介绍)。

b)                 WhitespaceRule实现IRule:顾名思义,发现输入中的空白字符。WhitespaceRule需要一个IWhitespaceDetector接口的实例来辅助分析。

c)                 SingleLineRule继承PatternRule:根据某种模式匹配规则,比如字符串由“”开始和结束。但SingleLineRule要求字符序列必须在单行上匹配模式。

d)                 MultiLineRuleSingleLineRule类似,不同在于MultiLineRule允许字符序列在多行上匹配模式(比如多行注释/*  */可用这种规则)。

e)                 EndOfLineRule继承自SingleLineRule,它开始于某种指定的模式,结束一定是一个换行符(line delimiter),比如单行注释“//abcd”就可使用这种规则。

 org.eclipse.jface.text.source.SourceViewerConfiguration

在前言中我们已经了解,SourceViewer通过SourceViewerConfiguration类来控制其各种增件配置,如代码着色,自动提示等。为了支持语法着色,我们必须提供自己的SourceViewerConfiguration类:ZSqlSourceViewerConfiguration,并且重写getPresentationReconciler方法。 

IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer)方法,返回一个IPresentationReconciler接口的实例,该实例上注册了了一个毁坏器(damager)和一个修复器(repairer)。

damager负责计算文档被修改的区域

repairer负责重新构建文档被修改区域的表现形式(着色)

·源代码

      通过分析,我们的思想已经有了,下面就来看源代码。由于篇幅关系,我们不在这里介绍所有的源代码,只介绍增加的和重要的代码。介绍的顺序按照执行的流程。

·4扩展父类的initializeEditor()方法,并如下实现:

       super.initializeEditor(); 

this.setSourceViewerConfiguration(new

ZSqlSourceViewerConfiguration()); 

    initializeEditor()方法会在ZSqlEditor的构造方法前执行,因为在AbstractDecoratedTextEditor类的构造中调用了initializeEditor()方法,此时ZSqlEditor的构造方法还没有执行(请参考我的另一篇文章,Java对象的构造顺序-让代码在构造方法前执行)。

你也许会问,此时我们的SourceViewer还没有创建,怎么能够设置Configuration,实际上AbstractTextEditor会为你保持Configuration对象,并在其createPartControl()方法中将其配置到SourceViewer上。ZSqlEditor.intializeEditor()在ZSqlEditor的构造方法之前执行(因为它在父类AbstractDecoratedTextEditor的构造方法中被调用)因此我们在这里设置Configuration。而在AbstractTextEditor.createPartControl()方法中,将调用createSourceViewer()方法创建SourceViewer的实例,并为SourceViewer配置Configuration(使用我们设置的configuration)。而一旦为SourceViewer设置了Configuration,就不能重新配置,否则会出现IllegalStateException异常(因此,你实际上可以在ZSqlEditor的initializeEditor(), constructor(), init()方法,包括createPartControl()方法(调用super.createPartControl()方法之前)调用setSourceViewerConfiguration()方法)。

·42 增加类ZSqlSourceViewerConfiguration

extends SourceViewerConfiguration

重写public IPresentationReconciler getPresentationReconciler(

  ISourceViewer sourceViewer)方法

·4增加类ZSqlScanner extends RuleBasedScanner

·4增加类ZSqlWhiteSpaceDetector, ZSqlWordDetector

这两个类均为Rule的辅助类,负责发现空白字符和关键字。

·45 增加接口ZISqlSyntax

    这个接口用来提供各种字符串数组,当前仅提供关键字字符串数组。ZSqlWordDetector根据这些来判断某个模式是否关键字。

·运行

      点击下载(http://www.sinadisk.com/pick.aspx?code=com.bbebfe.sql_source_highlight)源代码工程和插件Jar包。

      下载完成后你可以选择导入源代码工程或者直接将Jar包拷贝到Eclipseplugins目录下。通过File -> open file打开任意.sql后缀就可以激活编辑器。运行效果如下:

 

·总结

      在本章我们学习了如何让我们的编辑器支持语法着色,虽然我们只定义了最简单的几种模式,但你完全可以以此推导出其他的多种模式。不过目前编辑器在代码着色方面仍然有些小问题,将在下一章介绍并解决。

原文地址:https://www.cnblogs.com/eclipsetech/p/8627049.html