编辑器杂谈之一 Scintilla(上)
HuaHope
Scintilla的相关项目很多,的related中就列举了相当多的。只是恰如有次见到一个评论中说的,自从有了Scintilla,几乎大多数的编辑器都很少自己编写“编辑器”了,完全是加个外壳,当然编辑器控件SynEdit(delphi)、CodeMax等也功不可没。
就Scite_ru、Scite Latex IDE而言,其实并不算是出众的Scintilla相关项目,而ScintillaLua虽然是这里看到了才知道新有了这个项目,也刚去下载了(可惜zip的解压失败,就下载的tgz的),但只是看看配置文件就知道了,其也只不过是Mitchell Foral的一个副产品,之前Mitchell Foral就有Scite Tools和Scite St,再加上后来的Textadept,这几个都是差不多的实现,除了补足SciTE的动态着之外,还有一个snippet功能,不过也许ScintillaLua可能独立后实现的比以前更完善吧,没有看代码,但是lexer配置倒是丰富了很多,终于几乎实现了Scintilla的所有支持语言,另外一个最大的改进就是许可证终于换成了BSD,比Scite Tools的LGPL要更开放些,以至于SciTE_ru最新的版本就以及迫不及待地整合了ScintillaLua,实现了外部lexer的支持。不过从设计角度而言,Lexer采用外挂的lua脚本,处理能力毕竟有限,虽然使用llpeg灵活性增强了,但是效能无疑更低了,即便是luajit,估计也无法对付稍大一点的文件。Scintilla比较好的项目,Filerx算是不错,可惜很久就不更新了。其余的,就编辑器而言,都没能走出Scintilla的限制,也自然更难超越Scintilla自身的光环。
其实国内基于Scintilla的项目也很多的,但真正自己写编辑器的也有,比如已经商业化的Aptedit,还有MegaxEdit等,MegaxEdit的博客中讲了一些编辑器实现技术,比如折叠等,和Scintilla实现是类似的,只是很可惜,由于没有实物,所以无法评测其功能和性能,不过虽然上面说大多数编辑器完全拿来义不好,但是MegaxEdit完全自己写,甚至字符串查KMP算法也自己实现,实在也太过于自力更生,看日志好像还自己实现了可配置的状态机,距离正则库也差不远了,只不知道正则库是否也自己写完了:)Megax还曾经到FlexEdit网站评论过,虽然指出没有突出优势的缺点也不算错,但从其日志上描述的技术思想中感觉块着算法虽然比Scintilla的要好,但是还是不够完善的,比如不允许循环嵌套语言,其实这个限制并不应存在,除非刻意的构造,否则几乎所有的文件中语言再怎么嵌套都是有限的,也是可以分析着的。另至于嵌套只允许4个子语言,对于html而言就未必够用,而且如果不独立线程,即便是块着速度对于10万行以上的大文件也依然很慢,不过Megax从09年2月就消失了,一
直到这个月才又冒出来更新日志,感觉依然对lex很纠结,估计还有一段路要走。当然还有MadEdit,也是很不错的,16进制和内码做得很好,只是大文件处理能力有限,界面也不够美观。至于国人的flexedit、notepad++等,也多半只是加个壳而已。没有太多需要说的,Notepad++的插件系统倒是不错,现在的插件也非常的多,只是其中很多没有实现界面的插件并没有太多的必要,如果Notepad++实现ScitTE中的lua脚本扩展,编写脚本即可扩展类似的功能,实在没有必要做成dll,从一种扩展走向另一种封闭,只是没有深入研究过其插件系统,感觉整体设计还是不错的,不过距离几乎完全插件化的Eclipse估计还是有所差距。
而国外的自己写编辑器模块的就要多一些,比如e texteditor,intype(早期是自己修改的Scintilla,后来好像是觉得Scintilla不够好,重新实现了自己的),sublime text editor等等,其实编辑器技术最难,也是最核心的就只是如何对内存进行Gap操作,如果完成了这个,效率足够,其余的真的很容易,Codeproject上有一些相关的教程,但估计看完的并不多。至于Komodo、XmlSpy、LuaEdit、Autoit的编辑器、Adobe的Creative Suite套件中的ExtendScript Toolkit等,由于产品定位不同,直接使用Scintilla的编辑器也无可厚非。何况Komodo、Adobe都曾对Scintilla社区有贡献过代码,比如Scintilla中的Mac代码很多都是Adobe贡献的。
至于MacOs下的Textmate也是自行实现的编辑器模块,不过没有测试过大文件性能,MacOs下的开发有个很好的优点,很多都是苹果内置实现了,而且MacOs本身就与脚本相当紧密,甚至自带了tcl、perl等,shell也很好用,所以MacOs下的编辑器都实现的比较好,比如BBEditor等,xcode使用起来也非常方便,不过很奇怪的是,xcode的snippet、自动补全等在输入代码后会用灰字体将后续的补全,但是如果用户不想要这个,又会自动清除,重新补全,但实际使用中感觉文本晃动的不太舒服,尤其是多行补全时,也许有人喜欢这样的风格吧,不过也可能有设置可以关掉吧。
当然提到编辑器,不能不提的是Unix下的Vim和Emacs,两者各有千秋,不过也有各自的缺点,要不如果过于完美,凭近乎传奇的悠久历史,早就一统江湖了,呵呵。目前两者在windows平台都还算小众,另外,两者设计也不是绝对完美的,比如vim的键盘映射,命令的内部代码全部是硬编码,如dd删除行,
以及yy等就是判断是否d或y重复而实现的,虽然新命令可以做map,也依然可完全定制键盘序列,但是如果代码实现能够将键盘序列与对应功能任意由用户绑定,或者内部使用表来绑定键盘序列和其默认功能,即更灵活些就更好了,这
样修改起来也很容易就可以改进键盘绑定,而不是现在功能处理分散在代码的各个地方。UltraEdit没什么太多要说的,虽然不及Vim和Emacs悠久历史,但也再过几年就开发了二十年了,足够长的时间,也足够做很多改进了,事实也是如此,现在的实在是太庞大了,一个编辑器要几十兆,不过就功能而言,除了大和全之外,16进制还可以,列模式虽然也不错,但对于东亚等复杂文字处理还是不够完善,至于作为重要特性的大文件处理性能其实也不好,用临时文件时先要复制一个副本导致速度很慢,而且占用大量硬盘,不用,就无法撤销编辑,实在是两难。何况现代编辑器的许多理念,如自定义着Lexer、snippet等,也是很难见到。扩展性也不够好。而就体积而言,同样庞大的Emacs就远比UltraEdit要强上非常多,可见UltraEdit之臃肿,至于提到的大文件和扩展性,EmEditor就很不错,EmEditor通过基于内存映射的框架实现了一个很好的大文件编辑功能,不过EmEditor很多都依赖于插件,未必是很好的设计。如果不像Eclipse那样,有众多的拥蹙开发插件的话,而只靠开发者本身开发的话,插件系统用处并不大。更何况虽然EmEditor的脚本扩展做得不错,好像也实现了com,但是多数插件仿佛并不是脚本实现的,这和样就无形增加了第三方开发难处。开发Visual Assist可以make money,给EmEditor开发插件,估计很少有用户这么做吧,幸好EmEditor还是卖出了不少钱的,开发者一直相当积极的升级,一次
版本都能发几十个beta版,现在已经是版本9了吧,相对而言,EmEditor升级对于现代编辑器功能的关注还是不错的,9中就已经实现了snippet,比起UltraEdit经过15个版本还停留在Templates模板功能上,每次的升级只是围绕着彩的tab页,界面配置的角化,查窗口中的单行编辑框变成多行编辑框,应该算是比较上进的了,不是说UltraEdit做的改进不重要,只要是用户使用到的,都是最重要的功能点,但是核心功能的改进更不可或缺,否则界面做得再好,编辑效率提不高,有什么用呢。说了这么多编辑器,也提一下Editplus,虽然功能不算突出,但设计的很简洁,很中庸型的编辑器。至于pspad,开发了很多的功能,甚至包括计算器,颜拾取器等,确实很辛苦,但是依然不够稳定,而且比起同样是delphi编写的RJ TextEd来说,功能也并不算丰富,界面也逊些,其实delphi的界面库很好用,换肤功能也很强,虽然也许换肤对于编辑器而言过于花哨,但是只要是会接触和使用到编辑器,而不是只知道记事本和word的,编辑器多半是最最常用的工作或学习的不可或缺的工具。因此如果拥有一套美观的默认外观对autoit
于用户使用也是很有用的,毕竟爱美之心人皆有之。
编辑器杂谈之一 Scintilla(中)
HuaHope
撇开其他非Scintilla的编辑器不谈,就Scintilla编辑器而言,最大的缺点,也是很奇怪的,就是几乎每个
项目都很少会修改Scintilla内部,Mitchell Foral的Scite Tools和Scite St、Textadept、Scintillalua算是少有的另类,其余的真的很难看到做较大功能改进的,也许为了升级更新编辑器模块方便,甚至静态编译的都很少,一律的动态链接,几乎都是完全的拿来主义。说实话,如果编辑功能只是工程的一部分,那也符合重用的开发理念,但很多工程本身就是开发编辑器,也一味的用而不改进核心功能,不仅使自身无法提高层次,不利于Scintilla发展,更使得现在大多数Scintilla同质化非常严重,譬如,Scintilla的列模式几乎每个项目都在期待,但是由于Neil一直很难决定如何很好的实现virtual space,所以所有的相关项目的列模式为人诟病已经很多年,直到2.0中实现了多选区编辑和virtual space功能才算是了却了几年来的心愿,而且就目前而言,列模式还实现得并不完善,比如列模式下的粘贴文本就无法像UltraEdit一样粘贴到每一行。不过1.76之后的代码就很少跟踪了,也没有去看这个新功能代码如何实现的,其实virtual space和列模式功能要实现很简单,只要在原先选区的Anchor和current基础上增加virtual Anchor和virtual current即可。另外每个项目都知道Scintilla内存消耗是文本自身的两倍,仅仅是为了实现style,Neil在实验项目中SinkWorld虽然对此作出了改进,但是SinkWorld进展实在非常缓慢,类似于Scintilla与SciTE,展示SinkWorld的Tentacle 也很久没有更新了。而且SinkWorld中的改进是针对于Scintilla中style的8个bit位128种style无法充分支持html这种可嵌入子语言类型很多的扩展型语言的,要实现的是动态长度的Style,这样必然会带来更严重的内存问题,其实就内存而言,打开相同的文件,Vim消耗的内存是相对而言比较少的,基本上比实际文本多一些,而其他的编辑器大多也是内存消耗很多,甚至有三倍于文本自身的,但其实内存问题并不必要用现在的style实现方式的,动态数组是一个更
好的方式,不仅可以做到内存占用几乎与文本自身大小接近,而且对于识别同一style的起始结束和结束都是很有益处的,复杂度甚至可以做到常量,而不是现在的线性,需要逐个byte的去比对搜索,这点对于基于代码做分析,比如识别注释、字符串等块状文本有很重要的意义。当然,Scintilla目前最大的弱势还是在于正则库,Regex实在是一个过于简单的正则引擎,虽然Scintilla在1.77版本中就实现了正则引擎的外接口,相关项目,如Pr
ogrammer's Notepad也已经实现了使用Pcre和Xpressive分别用于Scintilla内部和配置的正则匹配,但是多半还是需要针对各个引擎库写迭代器的,这样就不免又造成了一定的门槛,使得现在大多数项目依然使用内置的功能很弱的正则库。而没有一个优秀的正则库作为支撑,就很难实现自由度很高的自动缩进、函数识别等,更重要的,Lexer就无法做成可配置。用户自由的实现如vim、emacs、textmate那样编写lexer扩展就无法成为可能。而缺少这些,对于现代的编辑器功能而言,不免是一个很大的遗憾和功能劣势。除此以外,对于大文件的支持也是Scintilla的弱势,由于内部的设计导致的双倍内存问题,使得大文件支持更为捉衿见肘,相关的一些功能,比如括号对匹配高亮,以目前的SciTE内部实现是搜索全部文本,这显然在大文件时会导致界面假死,而Notepad++则弥补了这个缺陷,将搜索限定在上下搜索2000行而已,但这对于大文件又显然是不够的。诸如此类的功能,对于大文件而言便不免会有所缺失,不过Neil很早就宣称,Scintilla并不是为大文件设计的,所以也无可厚非。何况大文件的需求比较特殊,并不能完全做到统一,也许Neil除了认为难以实现之外,还考虑到了大文件操作与系统是紧密相连的,
比如windows的内存映射,其他平台的实现就不尽相同,因此严格意义上,就Scintilla不与具体系统捆绑的设计目标来说,这并不是Scintilla遗漏的功能,实际上,从某种意义而言,Scintilla已经提供了很好的框架,足以支撑外部项目使用系统函数和算法更好的处理大文件,不过所有的项目鲜有见到实现了大文件操作的,包括最流行的项目Notepad++。当然大文件本身就是很难做处理的,即便是宣称大文件处理比较好的EmEditor,打开普通的非着文件还好,但一旦遇到着的如cpp文件,也一样会很痛苦,因为着是需要遍历每一个字符并采集属性的,因无法见到EmEditor的Lexer代码,不知道如何实现的。但是要解决着问题,前提必然是Lexer线程独立,而非Scintilla现在的单线程,虽然Scintilla内部设计了一些位置信息,可以接续着等,但对于大文档,依然会有明显的延迟。Vim要好些,可惜也没有去研究过其Lexer代码。上文提到的Megax的分块着是一个好的解决方案,但是多线程依然是最终解决的不可或缺的,其实Scintilla Maillist中很早就几次提过多线程着,但是Neil认为难度很大,也没有人提出可行的方案,也就不了了之了。与大文件类似的,缺失的还有全面支持UTF8,和16进制,vim和Emacs等早已经实现了内部完整支持Unicode,当然实际内码是UTF8,因为对于许多字符集而言,Utf8比Utf16等编码

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。