Hyperlink
Hyperlink(超链接)在 Java 编辑器中用来进行快速的代码定位,当你按住 Ctrl 键并把鼠标指向一个函数名的时候,函数名会显示为超链接,点击之后代码会跳转到函数的声明处。这个功能使得 Eclipse 浏览代码很方便,这次我就来介绍如何在自己的编辑器中添加超链接功能。
超链接的定位
编辑器不会知道哪块区域应该显示为超链接,这是通过 IHyperlinkDetector 接口实现的。这里牵涉到语义方面的内容,因为你必须要能知道鼠标下面到底是个什么。在解析器那一层需要实现这样的支持。
超链接的渲染
JTF 是如何显示超链接的?可能你会想到标注,缺省的实现不是这样。这里要介绍另外一个接口:IHyperlinkPresenter。JTF 缺省的时候是用 StyledText 的 StyleRange 实现的,其实就是把超链接的那块文字置为蓝色且带下划线。但是因为有了这么一个接口,你可以把超链接弄成任何样子。
实现超链接
本文要实现的超链接功能是:点击某个变量名,编辑器会选中声明该变量的那条语句。
底层支持
底层需要支持两个功能:判断某个位置是一个变量,以及得到变量声明的语句范围。由于我的例子很简单,判断是不是变量也非常简单,只要符号类型是一个 ID 类型就行了。得到变量声明的语句范围需要检查语法树,因为变量声明的子树以等号为根节点,所以找到对应的根节点就行了。然后从等号开始得到子树的最左和最右节点,从而计算出整个子树的字符范围。这些代码已经添加到了 TreeHelper 中,具体请参看 getVariableDeclaration 和 getTreeRange 方法。
实现 IHyperlink
我实现了一个 VariableHyperlink 来封装超链接信息,它最重要的方法是 open(),因为它会在你点击超链接后被调用:
清单1. VariableHyperlink 的 open 方法
public void open() {
// get doc
IDocument doc = viewer.getDocument();
// get tree
Tree tree = TreeManager.getTree(doc);
// get variable declaration range
Point range = TreeHelper.getVariableDeclaration(tree, variable);
// select text
if(range != null) {
viewer.setSelectedRange(range.x, range.y);
viewer.revealRange(range.x, range.y);
}
}
我用到了刚才提到的 TreeHelper 中的方法来得到声明语句的范围,剩下的事情就比较直接了,选择这个范围并让确保其在编辑器中可见。