编辑器制作之代码折叠
代码折叠这个功能,我最早是在Dreamweaver里面看到的,具体哪个版本记不清了,好多年了。
当时DW的实现是当你选择文本的时候,在编辑器的左侧,有一个折叠的提示,提示你可以把选中的
文本折叠起来。那个时候觉得这个功能,毫无用处。不过自从VisualStudio2003以来,代码折叠
这个功能几乎成为了程序员的必备。
的确,在浏览代码的时候,代码折叠可以带来一些好处,让重点凸显在用户的面前,或者可以拉近两块
相隔很远的代码,实现比较。当然,这个也完全可以通过分割视图完成。
在众多的编辑器当中,我认为单纯就代码折叠而言,目前实现的最好的还是VisualStudio,它
可以根据语言上下文的关系,即语法,进行代码折叠,这是其它编辑器无法企及的。当然,它本身也是
一个重量级的IDE,超出了简单编辑器的范畴。
本文试图描述代码折叠最基本的思路,没有具体的代码。其实这个功能并不难实现,相反很简单。
难点在于要和编辑器本身很好的结合。
以下面的C语言为例。
1 #include <stdio.h>
2
3 int main(int argc, char *argv[])
4 {
5 printf("Hello, world\n");
6
7 return 0;
8 }
9
如果对上面的代码进行折叠,应该如何实现呢?聪明的读者,应该马上就会知道了代码折叠的思路了。
对,就是在{和},即两个大括号之间进行折叠。那么如何实现递归折叠呢?这个也很简单,我们只要标记
一个Level,不同的Level之间用不同的图标显示在编辑器左侧,点击的时候根据Level的前后大小关系,
判断是该折叠还是该展开。
比如下面的代码:
1 #include <stdio.h>
2
3 int main(int argc, char *argv[])
4 {
5 {
6 printf("Hello, world\n");
7
8 }
9 return 0;
10 }
在第4行和第5行的时候我们应该显示一个+,5, 6,7,8,9我们应该显示和上下文关联的"|"符号,那么代码
也就很好写了。如下,根据前一行的level设置本行的level:
int set_level( int prevLevel, const char* str, int len, void* others ){
int retLevel = prevLevel;
while( ! end of str ){
if( str has '{' )
retLevel++;
if( str has '}' )
retLevel--;
}
return retLevel;
}
分析完的level要保存在行信息里面.不然就无法绘制+或者-了。
瞧,如此简单的代码折叠就出来了。
其实大部分的简单编辑器都是这么多的,比如scintilla。这么做的好处是实现起来非常简单,高效,
而且基本上能满足大部分的需求。另外,上面的函数还有一个参数others,这个可以根据前文已经做过的词法分析,
再做进一步处理,从而实现过滤掉注释或者字符串里面的{和},并且还可以实现对注释的折叠。
很显然,这种方法也有缺点,就是只能实现类C的这种代码折叠。没有办法,每种语言都有自己的特色,
要想做更好的折叠只有这个办法。比如vb,我们可以在funtion和end function之间折叠,html我们可以在
<body>和</body>之间折叠。不可能写了一个就会万能的。
不过,可以有一种类似万能的效果,就是利用Tab或者空格来折叠。也就是Editplus现在做成的那样。
这个实现起来思路和上面是一模一样的,不再赘述。
ps:下一篇,编辑器之代码自动补全,敬请期待。
posted on 2009-03-07 16:07
megax 阅读(3887)
评论(13) 编辑 收藏 引用