(转)编辑器_编辑器杂谈(转载)+点评

   简介摘要: 编辑器杂谈(转载)+点评 编辑器杂谈(转载)+点评点评:Scintilla: 目前Scintilla有一统江湖的趋势。只要是新开发的软件工具能够用到高级编辑器的地方基本上就会用它了。的确Scintilla为一些开发提供了便利,但是,是不是也阻碍了编辑器发展的进程啊?没人愿意开发了,还会有进步

编辑器[bian ji qi]杂谈(转载)+点评 编辑器[bian ji qi]杂谈(转载)+点评

点评:
Scintilla:     目前Scintilla有一统江湖的趋势。只要是新开发的软件[ruan jian]工具能够用到高级编辑器[bian ji qi]的地方基本上就会用它了。的确Scintilla为一些开发提供了便利,但是,是不是也阻碍了编辑器[bian ji qi]发展的进程[jin cheng]啊?没人愿意开发了,还会有进步嘛?所以说,有时候开源[yuan]并不一定是好事,你开源[yuan]开的不好就罢了,开的好了,就会挤掉很多优秀的共享软件[ruan jian][gong xiang ruan jian],以至于没人来做这项了。
另外Scintilla的出现导致同质化非常严重,个个都长的差不多,操作也差不多,体现不出特点,这个HuaHope的杂谈中有描述。如果一个编辑器[bian ji qi]要定位[ding wei]于一个专业文本[wen ben]编辑软件[ruan jian],比如现在的Editplus, UlrtaEdit那样,我觉得还是不要采用Scintilla的较好,当然如果像Code:Blocks定位[ding wei]于IDE,采用Scintilla就是更快更好的选择[xuan ze]了。坦白的说,开发高性能[xing neng][gao xing neng]多用途编辑器[bian ji qi]难度是很高的。

Style:    这个是我纠结很长时间的一个东西,在几年前,我一直是用的动态[dong tai]渲染本屏文本[wen ben]。因为一个屏幕[ping mu]上显示[xian shi]的非常少,所以效率不错。但是也带来一些不便。比如括号匹配时,就需要重新进行分析,否则你不知道该括号是在注释[zhu shi]中,还是在字符[zi fu]串[zi fu chuan]中,还是真正我们需要的括号。再比如,现在有些编辑器[bian ji qi]带的功能,当鼠标[shu biao]移动到Email,URL之类的时候,会出现动作,如果采用动态[dong tai]渲染,那么就会看到CPU明显的上升。当然,也可以再采用一些措施,只存储当前屏幕[ping mu]的Style。但是这会使得编辑器[bian ji qi]的架构非常的复杂、繁琐,以至于我最后都不想去做了。所以为每一个字符[zi fu]存储一个Style(CHAR),是最好的选择[xuan ze]。至此你会发现,世界清静了,代码漂亮了,但是内存[nei cun]也浪费了最多一倍(Unicode:0.5倍文本[wen ben], 其它:最多一倍).有了Style之后,很多事情都好办了,比如前文提到的括号匹配,鼠标[shu biao]动作等。不过Style应该是个可选功能,在不需要的时候我们可以对它关掉,关掉的时候,去掉其它高级功能支持[zhi chi],MegxEdit已实现。因为每个CHAR有8位,我拿出了6位存储Style,剩下2为用来标记[biao ji]特殊用途,所以可以组合[zu he]出很好的效果,和Scintilla差不多。

Lexer:     这也是一个难点,难点不在于写,而是在于如何和编辑器[bian ji qi]组合[zu he]。我最初采用的算法[suan fa]是渲染本屏的文本[wen ben],存储该行最后的状态[zhuang tai]。当用户[yong hu]滚动的时候,判断滚动时的可见行,从该行开始分析。猛一看,这么做太完美了,当我费了九年二虎之力做完之后,我发现我做了无用功。这么做只适合查看文本[wen ben],但不适合编辑器[bian ji qi]文本[wen ben],如果你编辑了文本[wen ben],在滚动的话,同时屏幕[ping mu]下方都未被分析过的话,就会有明显的延迟[yan chi]了。另外你也判断不出屏幕[ping mu]下方是否被分析过,所以最后抛弃。
   所以最后的策略:从用户[yong hu]输入[shu ru]点[ru dian],开始分析,直到下一行是状态[zhuang tai]和本行一致(仅限多行注释[zhu shi],多行字符[zi fu]串[zi fu chuan],子语言[zi yu yan][yu yan])。有人会说,每编辑一次都要这么做,岂不是很浪费CPU啊?不是这样的,我告诉你,Editplus, EMEditor, Scintilla都是这么做的。所以也就出现了HuaHope提到的那种情况[qing kuang]:如果一个C++文本[wen ben]很大,并且只是变量定义之类的,不含有任何多行注释[zhu shi],那么你在开头输入[shu ru]/*的话,现在市面上的编辑器[bian ji qi](EditPlus, EMEditor, UltraEdit)都会有延迟[yan chi]。在这一点上Editplus做的较好,MegaxEdit的性能[xing neng]在EditPlus,he EmEditor之间, EmEditor <= MegaxEdit <= EditPlus,其它不再点评,基本会假死。
   在现代的CPU+内存[nei cun]下,经过我测试,打开173万行c++文件[wen jian]进行括号匹配,插入字符[zi fu],Lex分析的话,用户[yong hu]基本不会察觉有明显延迟[yan chi]。

Unicode:     Editplus、EMEditor和其它的编辑器[bian ji qi]的内核[nei he]均是UTF16的,MegaxEdit也是。所以如果你打开一个1M的ANSII文本[wen ben]的话,那么实际最少使用2M文本[wen ben]+1MStyle=最少3M内存[nei cun]。是不是很浪费内存[nei cun]啊。且听我分析。UTF16内核[nei he]的显著优点是极大极大极大极大的简化了开发,而且完美支持[zhi chi]各种字体[zi ti],即使你现在的文件[wen jian]是CP932,你也可以输入[shu ru]日文韩文中文[zhong wen],而不会出现乱码。至于浪费内存[nei cun],在windows操作系统[xi tong][cao zuo xi tong]上,申请大块内存[nei cun]谈不上浪费不浪费。真正浪费内存[nei cun]的地方是UndoRedo数据[shu ju]结构[jie gou]和一些文本[wen ben]操作。另外还有一个内存[nei cun]消耗大户,那就是行信息[xin xi]。为了解决这些真正的,看似不起眼的内存[nei cun]消耗,MegaxEdit采用了一个非常精巧的MemPool,参考[can kao]自Loki,在一定程度上缓解了这些问题[wen ti]。不过即使如此,在1G的CPU上不建议编辑器[bian ji qi]超过200M的文本[wen ben]。
   如果不采用UTF16内核[nei he],还有一种不错的方案,也就是MBCS方案,这个我实现过,但是被我抛弃了。原因是代码丑陋。方案如下:文件[wen jian]的存储仍然采用该文件[wen jian]的物理形式,也就是直接读取[du qu]到内存[nei cun]上。在显示[xian shi]的时候动态[dong tai]转化成Unicode.相关的函数[han shu]有CharNext, CharPrev和MB2CS,CS2MB之类的。这么做的话几乎可以达到和UTF16一模一样的效果,只是插入文本[wen ben]的时候,同样要转换[zhuan huan],如果插入的文本[wen ben]非该文本[wen ben]的codepage,很显然会乱码。据我猜测, 日本的秀丸似乎是这么做的。秀丸虽然不支持[zhi chi]Unicode,但是可以强制Codepage,KeepContent来实现。
   关于UTF8,其实UTF8也可以看成MBCS。因为UTF8是不定长的,所以某些操作非常蹩脚,而且读取[du qu]文件[wen jian]的时候需要一定程度的转换[zhuan huan],非常的麻烦。
   从平均性能[xing neng]和操作简便性上来说,没有比UTF16更棒的了。但是UTF16有个很大的缺点,并不是内存[nei cun]占用。而是它无法原原本本反向操作。比如你用Editplus读取[du qu]一个EXE,指定codepage为932,不作修改[xiu gai],直接保存,那么保存后的文件[wen jian]和原来的EXE是肯定不一样的。因为涉及到字符[zi fu]映射[ying she]的问题[wen ti],这是硬伤,无解决方案。但是,我想不会有人用文本[wen ben]编辑器[bian ji qi][wen ben bian ji qi]编辑器[bian ji qi]非文本[wen ben]文件[wen jian]吧,所以也无伤大雅。另外,还有一个硬伤,现在有了UTF32了,到时候UTF16就不够用了,呵呵,也许只有UTF8变长字节能支持[zhi chi]了。

大文件[wen jian]支持[zhi chi]:    呵呵,这是个很有意思的问题[wen ti],关键是什么叫做大文件[wen jian]。在MegaxEdit上的定义是,文本[wen ben]的大小超过100M, 文件[wen jian]行数超过100万,叫可以叫做大文件[wen jian]了。注意这儿有个文件[wen jian]行数限制。如果一个文本[wen ben]除了换行[huan hang]什么都不含有的话,行数超过100万,就会让很多编辑器[bian ji qi]反映迟钝了。在此吹一下,MegaxEdit还是不错的,性能[xing neng]刚刚的。
    高性能[xing neng][gao xing neng]多用途的文本[wen ben]编辑器[bian ji qi][wen ben bian ji qi]要考虑的事情非常多,对于大文件[wen jian]是不可能支持[zhi chi]很完美的,甚至直接不支持[zhi chi]。所以纠结于大文件[wen jian]是否支持[zhi chi]的好,有点舍本逐末了。曾经我就在这点上浪费了很多青春。
   不过我仍然对大文件[wen jian]处理颇有心得。最投机取巧的方法[fang fa]就是EmEditor现在采用的那样,分段[fen duan]映射[ying she]。不管你多大,我每次只读[zhi du]取[du qu]一点。修改[xiu gai]的时候直接在原偏移处,插入修改[xiu gai]的代码即可。如果这么做的话,任何一个编辑器[bian ji qi]通过插件[cha jian]都可以实现。比较好的做法是采用Piece Table,在此不详述。

正则表达式[zheng ze biao da shi]:   说实话,本人自动机[zi dong ji]学的很烂。我能写出一个正则库,但是效率估计连我都不想用。我最初的目的是做成Lex的那样,一个正则式映射[ying she]一个状态[zhuang tai]。直接配置[pei zhi],实现语法[yu fa]加亮[jia liang]。可惜,最后因本人功力有限,放弃。最后采用了日本的鬼车c++ wrapper,最近更新成了5.9.2. 我以前看过它的日文Help,记得是不支持[zhi chi]嵌套[qian tao]的,多谢HuaHope提醒,回头好好研究研究。如果支持[zhi chi]嵌套[qian tao],那么HotText就支持[zhi chi]嵌套[qian tao]变量了。但是MegaxEdit仍然坚持变量要定义后使用,因为解析省事。
    在此提一下鬼车,这是一个很牛X的正则库,性能[xing neng]颇高,而且支持[zhi chi]各种Encoding,将来我的多文件[wen jian]正则查找[cha zhao]就靠它了。鬼车和Ruby结合比较紧密,支持[zhi chi]好几种mode,本人研究也不深,希望有志者仔细研究研究。这儿有个很不错的c++ wrapper: http://homepage3.nifty.com/k-takata/mysoft/bregonig.html

其它: 

>>不过文中有几处小错还是需要指出,估计Megax是不是没有苹果机器实际试用和深入研究过Textmate,所以不太清楚?

本人确实没有MAC,找了几个GIF图片还有E和intype试用了一下,看见它们都叫bundle,于是误以为这个在Textmate上也叫bundle. 

>>Megax在东京呆了这么多年,即便 英文的帮助没注意,日文的帮助也应该至少读一遍的。
你咋知道我在鬼子地方混过?这都能调查清楚。O(∩_∩)O哈哈~

>>另外需要提一个疑惑的是:既然使用了Oniguruma正则库,Oniguruma使用文本[wen ben]方式匹配时,其算法[suan fa]就是BM算法[suan fa],已然很快,实在没有必要再编 写BM算法[suan fa]了。那又为何在2008年8月之“MegaxEdit开发最新状况”中要自行开发BM或KMP算法[suan fa]呢?

本人比较懒,能不写就尽量不写,至于想要自行写BM算法[suan fa],主要是编辑器[bian ji qi]数据[shu ju]结构[jie gou]问题[wen ti]。不过现在这个问题[wen ti]已经不存在了,因为舍掉了多行匹配能力[neng li](即一段文本[wen ben](含有换行[huan hang]符)可以跨行匹配)。

非常感谢含金量如此高的评论。抛砖引玉,结果钓了块钻石。

================以下是转载========================
作者:HuaHope 
    Scintilla的相关项目很多,官方网站[wang zhan]的related中就列举了相当多的。只是恰如有次见到一个评论中说的,自从有了 Scintilla,几乎大多数的编辑器[bian ji qi]都很少自己编写“编辑器[bian ji qi]”了,完全是加个外壳[wai ke],当然编辑器[bian ji qi]控件SynEdit(delphi)、CodeMax等 也功不可没。 

    就Scite_ru、Scite Latex IDE而言,其实并不算是出众的Scintilla相关项目,而ScintillaLua虽然是这里看到了才知道新有了这个项目,也刚去下载[xia zai]了(可惜 zip的解压失败,就下载[xia zai]的tgz的),但只是看看配置[pei zhi]文件[wen jian]就知道了,其也只不过是Mitchell Foral的一个副产品,之前Mitchell Foral就有Scite Tools和Scite St,再加上后来的Textadept,这几个都是差不多的实现,除了补足SciTE的动态[dong tai]着色[se]之外,还有一个snippet功能,不过也许 ScintillaLua可能独立[du li]后实现的比以前更完善吧,没有看代码,但是lexer配置[pei zhi]倒是丰富了很多,终于几乎实现了Scintilla的所有支持[zhi chi] 语言[yu yan],另外一个最大的改进就是许可[xu ke]证终于换成了BSD,比Scite Tools的LGPL要更开放些,以至于SciTE_ru最新的版本就以及迫不及待地整合了ScintillaLua,实现了外部lexer的支持[zhi chi]。不过 从设计角度而言,Lexer采用外挂的lua脚本[jiao ben],处理能力[neng li]毕竟有限,虽然使用llpeg灵活性[ling huo xing]增强[zeng qiang]了,但是效能无疑更低了,即便是luajit,估计也 无法对付稍大一点的文件[wen jian]。Scintilla比较好的项目,Filerx算是不错,可惜很久就不更新了。其余的,就编辑器[bian ji qi]而言,都没能走出 Scintilla的限制,也自然更难超越Scintilla自身的光环。 

    其实国内基于Scintilla的项目也很多的,但真正自己写编辑器[bian ji qi]的也有,比如已经商业化的Aptedit,还有MegaxEdit 等,MegaxEdit的博客中讲了一些编辑器[bian ji qi]实现技术,比如折叠[zhe die]等,和Scintilla实现是类似的,只是很可惜,由于没有实物,所以无法评测其功能 和性能[xing neng],不过虽然上面说大多数编辑器[bian ji qi]完全拿来义不好,但是MegaxEdit完全自己写,甚至字符[zi fu]串[zi fu chuan]查找[cha zhao]KMP算法[suan fa]也自己实现,实在也太过于自力更生,看 日志[ri zhi]好像还自己实现了可配置[pei zhi]的状态[zhuang tai]机,距离正则库也差不远了,只不知道正则库是否也自己写完了:)Megax还曾经到FlexEdit网站[wang zhan]评论过,虽然指 出没有突出优势的缺点也不算错,但从其日志[ri zhi]上描述的技术思想中感觉块着色[se]算法[suan fa]虽然比Scintilla的要好,但是还是不够完善的,比如不允许循环[xun huan]嵌套[qian tao]语 言,其实这个限制并不应存在,除非刻意的构造,否则几乎所有的文件[wen jian]中语言[yu yan]再怎么嵌套[qian tao]都是有限的,也是可以分析着色[se]的。另至于嵌套[qian tao]只允许4个子语言[zi yu yan][yu yan],对于 html而言就未必够用,而且如果不独立[du li]线程[xian cheng],即便是块着色[se]速度对于10万行以上的大文件[wen jian]也依然很慢,不过Megax从09年2月就消失了,一直到这个月 才又冒出来更新日志[ri zhi],感觉依然对lex很纠结,估计还有一段路要走。当然还有MadEdit,也是很不错的,16进制和内码做得很好,只是大文件[wen jian]处理能力[neng li] 有限,界面[jie mian]也不够美观。至于国人的flexedit、notepad++等,也多半只是加个壳而已。没有太多需要说的,Notepad++的插件[cha jian]系统[xi tong]倒是 不错,现在的插件[cha jian]也非常的多,只是其中很多没有实现界面[jie mian]的插件[cha jian]并没有太多的必要,如果Notepad++实现ScitTE中的lua脚本[jiao ben]扩展[kuo zhan],编写脚本[jiao ben]即 可扩展[kuo zhan]类似的功能,实在没有必要做成dll,从一种扩展[kuo zhan]走向另一种封闭,只是没有深入研究过其插件[cha jian]系统[xi tong],感觉整体设计还是不错的,不过距离几乎完全插件[cha jian]化 的Eclipse估计还是有所差距。 

    而国外的自己写编辑器[bian ji qi]模块[mo kuai]的就要多一些,比如e texteditor,intype(早期是自己修改[xiu gai]的Scintilla,后来好像是觉得Scintilla不够好,重新实现了自己 的),sublime text editor等等,其实编辑器[bian ji qi]技术最难,也是最核心的就只是如何对内存[nei cun]进行Gap操作,如果完成了这个,效率足够,其余的真的很容 易,Codeproject上有一些相关的教程,但估计看完的并不多。至于Komodo、XmlSpy、LuaEdit、Autoit的编辑器[bian ji qi]、 Adobe的Creative Suite套件[tao jian]中的ExtendScript Toolkit等,由于产品定位[ding wei]不同,直接使用Scintilla的编辑器[bian ji qi]也无可厚非。何况Komodo、Adobe都曾对Scintilla社区有贡献 过代码,比如Scintilla中的Mac代码很多都是Adobe贡献的。 

     至于MacOs下的Textmate也是自行实现的编辑器[bian ji qi]模块[mo kuai],不过没有测试过大文件[wen jian]性能[xing neng],MacOs下的开发有个很好的优点,很多都是苹果内置 实现了,而且MacOs本身就与脚本[jiao ben]相当紧密,甚至自带了tcl、perl等,shell也很好用,所以MacOs下的编辑器[bian ji qi]都实现的比较好,比如 BBEditor等,xcode使用起来也非常方便,不过很奇怪的是,xcode的snippet、自动补全等在输入[shu ru]代码后会用灰色[se]字体[zi ti]将后续的补全,但 是如果用户[yong hu]不想要这个,又会自动清除[qing chu],重新补全,但实际使用中感觉文本[wen ben]晃动的不太舒服,尤其是多行补全时,也许有人喜欢这样的风格吧,不过也可能有设置[she zhi]可 以关掉吧。 

    当然提到编辑器[bian ji qi],不能不提的是Unix下的Vim和Emacs,两者各有千秋,不过也有各自的缺点,要不如果过于完美,凭近乎传奇的悠久历史,早 就一统江湖了,呵呵。目前两者在windows平台[ping tai]都还算小众,另外,两者设计也不是绝对完美的,比如vim的键盘[jian pan]映射[ying she],命令[ming ling]的内部代码全部是硬编码[bian ma],如 dd删除[shan chu]行,以及yy等就是判断是否d或y重复而实现的,虽然新命令[ming ling]可以做map,也依然可完全定制键盘[jian pan]序列,但是如果代码实现能够将键盘[jian pan]序列与对应功能 任意由用户[yong hu]绑定[bang ding],或者内部使用表来绑定[bang ding]键盘[jian pan]序列和其默认[mo ren]功能,即更灵活些就更好了,这样修改[xiu gai]起来也很容易就可以改进键盘[jian pan]绑定[bang ding],而不是现在功能处理分散在代 码的各个地方。UltraEdit没什么太多要说的,虽然不及Vim和Emacs悠久历史,但也再过几年就开发了二十年了,足够长的时间,也足够做很多改 进了,事实也是如此,现在的实在是太庞大了,一个编辑器[bian ji qi]要几十兆,不过就功能而言,除了大和全之外,16进制还可以,列模式[mo shi]虽然也不错,但对于东亚等复杂 文字[wen zi]处理还是不够完善,至于作为重要特性的大文件[wen jian]处理性[li xing]能其实也不好,用临时文件[lin shi wen jian][wen jian]时先要复制一个副本[fu ben]导致速度很慢,而且占用大量硬盘[ying pan],不用,就无法撤销编 辑,实在是两难。何况现代编辑器[bian ji qi]的许多理念,如自定义着色[se]Lexer、snippet等,也是很难见到。扩展[kuo zhan]性也不够好。而就体积而言,同样庞大的 Emacs就远比UltraEdit要强上非常多,可见UltraEdit之臃肿,至于提到的大文件[wen jian]和扩展[kuo zhan]性,EmEditor就很不 错,EmEditor通过基于内存[nei cun]映射[ying she]的框架[kuang jia]实现了一个很好的大文件[wen jian]编辑功能,不过EmEditor很多都依赖于插件[cha jian],未必是很好的设计。如果不像 Eclipse那样,有众多的拥蹙开发插件[cha jian]的话,而只靠开发者[kai fa zhe]本身开发的话,插件[cha jian]系统[xi tong]用处并不大。更何况虽然EmEditor的脚本[jiao ben]扩展[kuo zhan]做得不错,好像也 实现了com,但是多数插件[cha jian]仿佛并不是脚本[jiao ben]实现的,这和样就无形增加了第三方[di san fang]开发难处。开发Visual Assist可以make money,给EmEditor开发插件[cha jian],估计很少有用户[yong hu]这么做吧,幸好EmEditor还是卖出了不少钱的,开发者[kai fa zhe]一直相当积极的升级,一次版本都能发 几十个beta版,现在已经是版本9了吧,相对而言,EmEditor升级对于现代编辑器[bian ji qi]功能的关注还是不错的,9中就已经实现了snippet,比起 UltraEdit经过15个版本还停留在Templates模板功能上,每次的升级只是围绕着彩色[se]的tab页,界面[jie mian]配置[pei zhi]的角色[se]化,查找[cha zhao]窗口[chuang kou]中的单行编辑 框变成多行编辑框,应该算是比较上进的了,不是说UltraEdit做的改进不重要,只要是用户[yong hu]使用到的,都是最重要的功能点,但是核心功能的改进更不可 或缺,否则界面[jie mian]做得再好,编辑效率提不高,有什么用呢。说了这么多编辑器[bian ji qi],也提一下Editplus,虽然功能不算突出,但设计的很简洁,很中庸型的编辑 器。至于pspad,开发了很多的功能,甚至包[bao]括计算器[ji suan qi],颜色[se]拾取器等,确实很辛苦,但是依然不够稳定,而且比起同样是delphi编写的RJ TextEd来说,功能也并不算丰富,界面[jie mian]也逊色[se]些,其实delphi的界面[jie mian]库很好用,换肤功能也很强,虽然也许换肤对于编辑器[bian ji qi]而言过于花哨,但是只要是 会接触和使用到编辑器[bian ji qi],而不是只知道记事本和word的,编辑器[bian ji qi]多半是最最常用的工作或学习[xue xi]的不可或缺的工具。因此如果拥有一套美观的默认[mo ren]外观对于用户[yong hu]使 用也是很有用的,毕竟爱美之心人皆有之。

撇开其他非Scintilla的编辑器[bian ji qi]不谈,就Scintilla编辑器[bian ji qi]而言,最大的缺点,也是很奇怪的,就是几乎每个项目都很少会修改[xiu gai] Scintilla内部,Mitchell Foral的Scite Tools和Scite St、Textadept、Scintillalua算是少有的另类,其余的真的很难看到做较大功能改进的,也许为了升级更新编辑器[bian ji qi]模块[mo kuai]方便,甚至静态编 译的都很少,一律的动态[dong tai]链接[lian jie],几乎都是完全的拿来主义。说实话,如果编辑功能只是工程的一部分,那也符合重用的开发理念,但很多工程本身就是开发编辑器[bian ji qi], 也一味的用而不改进核心功能,不仅使自身无法提高层次,不利于Scintilla发展,更使得现在大多数Scintilla同质化非常严重,譬 如,Scintilla的列模式[mo shi]几乎每个项目都在期待,但是由于Neil一直很难决定如何很好的实现virtual space,所以所有的相关项目的列模式[mo shi]为人诟病已经很多年,直到2.0中实现了多选区编辑和virtual space功能才算是了却了几年来的心愿,而且就目前而言,列模式[mo shi]还实现得并不完善,比如列模式[mo shi]下的粘贴文本[wen ben]就无法像UltraEdit一样粘贴到每一 行。
不过1.76之后的代码就很少跟踪了,也没有去看这个新功能代码如何实现的,其实virtual space和列模式[mo shi]功能要实现很简单,只要在原先选区的Anchor和current基础上增加virtual Anchor和virtual current即可。另外每个项目都知道Scintilla内存[nei cun]消耗是文本[wen ben]自身的两倍,仅仅是为了实现style,Neil在实验项目中 SinkWorld虽然对此作出了改进,但是SinkWorld进展实在非常缓慢,类似于Scintilla与SciTE,展示SinkWorld的 Tentacle 也很久没有更新了。而且SinkWorld中的改进是针对于Scintilla中style的8个bit位128种style无法充分支[fen zhi]持html这种可 嵌入子语言[zi yu yan][yu yan]类型[lei xing]很多的扩展[kuo zhan]型语言[xing yu yan][yu yan]的,要实现的是动态[dong tai]长度的Style,这样必然会带来更严重的内存[nei cun]问题[wen ti],其实就内存[nei cun]而言,打开相同的文件[wen jian],Vim消耗的内 存是相对而言比较少的,基本上比实际文本[wen ben]多一些,而其他的编辑器[bian ji qi]大多也是内存[nei cun]消耗很多,甚至有三倍于文本[wen ben]自身的,但其实内存[nei cun]问题[wen ti]并不必要用现在的 style实现方式的,动态[dong tai]数组[shu zu]是一个更好的方式,不仅可以做到内存[nei cun]占用几乎与文本[wen ben]自身大小接近,而且对于识别[shi bie]同一style的起始结束和结束都是很有益 处的,复杂度甚至可以做到常量[chang liang],而不是现在的线性[xian xing],需要逐个byte的去比对搜索[sou suo],这点对于基于代码做分析,比如识别[shi bie]注释[zhu shi]、字符[zi fu]串[zi fu chuan]等块状文本[wen ben]有很重要的意 义。
当然,Scintilla目前最大的弱势还是在于正则库,Regex实在是一个过于简单的正则引擎,虽然Scintilla在1.77版本中就实现了 正则引擎的外接口[jie kou],相关项目,如Programmer's Notepad也已经实现了使用Pcre和Xpressive分别用于Scintilla内部和配置[pei zhi]的正则匹配,但是多半还是需要针对各个引擎库写迭代[die dai]器 的,这样就不免又造成了一定的门槛,使得现在大多数项目依然使用内置的功能很弱的正则库。而没有一个优秀的正则库作为支撑,就很难实现自由度很高的自动缩 进、函数[han shu]识别[shi bie]等,更重要的,Lexer就无法做成可配置[pei zhi]。用户[yong hu]自由的实现如vim、emacs、textmate那样编写lexer扩展[kuo zhan]就无法成为可能。 而缺少这些,对于现代的编辑器[bian ji qi]功能而言,不免是一个很大的遗憾和功能劣势。
除此以外,对于大文件[wen jian]的支持[zhi chi]也是Scintilla的弱势,由于内部的设计导致 的双倍内存[nei cun]问题[wen ti],使得大文件[wen jian]支持[zhi chi]更为捉衿见肘,相关的一些功能,比如括号对匹配高亮,以目前的SciTE内部实现是搜索[sou suo]全部文本[wen ben],这显然在大文件[wen jian]时会导致 界面[jie mian]假死,而Notepad++则弥补了这个缺陷[que xian],将搜索[sou suo]限定在上下搜索[sou suo]2000行而已,但这对于大文件[wen jian]又显然是不够的。诸如此类的功能,对于大文件[wen jian]而言 便不免会有所缺失,不过Neil很早就宣称,Scintilla并不是为大文件[wen jian]设计的,所以也无可厚非。何况大文件[wen jian]的需求[xu qiu]比较特殊,并不能完全做到统一, 也许Neil除了认为难以实现之外,还考虑到了大文件[wen jian]操作与系统[xi tong]是紧密相连的,比如windows的内存[nei cun]映射[ying she],其他平台[ping tai]的实现就不尽相同,因此严格意义 上,就Scintilla不与具体系统[xi tong]捆绑的设计目标[mu biao]来说,这并不是Scintilla遗漏的功能,实际上,从某种意义而言,Scintilla已经提供 了很好的框架[kuang jia],足以支撑外部项目使用系统[xi tong]函数[han shu]和算法[suan fa]更好的处理大文件[wen jian],不过所有的项目鲜有见到实现了大文件[wen jian]操作的,包[bao]括最流行的项目Notepad++。 当然大文件[wen jian]本身就是很难做处理的,即便是宣称大文件[wen jian]处理比较好的EmEditor,打开普通的非着色[se]文件[wen jian]还好,但一旦遇到着色[se]的如cpp文件[wen jian],也一样会很 痛苦,因为着色[se]是需要遍历[bian li]每一个字符[zi fu]并采集属性[shu xing]的,因无法见到EmEditor的Lexer代码,不知道如何实现的。但是要解决着色[se]问题[wen ti],前提[qian ti]必然是 Lexer线程[xian cheng]独立[du li],而非Scintilla现在的单线程[dan xian cheng][xian cheng],虽然Scintilla内部设计了一些位置[wei zhi]信息[xin xi],可以接续着色[se]等,但对于大文档[wen dang],依然会有明显 的延迟[yan chi]。Vim要好些,可惜也没有去研究过其Lexer代码。上文提到的Megax的分块着色[se]是一个好的解决方案,但是多线程[xian cheng][duo xian cheng]依然是最终解决的不可或缺 的,其实Scintilla Maillist中很早就几次提过多线程[xian cheng][duo xian cheng]着色[se],但是Neil认为难度很大,也没有人提出可行的方案,也就不了了之了。
与大文件[wen jian]类似的,缺失的还有全面支持[zhi chi] UTF8,和16进制,vim和Emacs等早已经实现了内部完整支持[zhi chi]Unicode,当然实际内码是UTF8,因为对于许多字符[zi fu]集而言,Utf8比 Utf16等编码[bian ma]方式要节省内存[nei cun],而Scintilla则由于扩展[kuo zhan]性,采取设置[she zhi]内码方式,虽然也可以支持[zhi chi]UTF8,但是兼容多内码的设计带来了很多的效率 问题[wen ti],比如查找[cha zhao]时,对于MBCS,就需要判断当前字符[zi fu]是否是leading字符[zi fu],这样很显然会非常慢,这从SciTE设置[she zhi]内码为CP936等代码页后的搜 索就可以很明显的看出与其他编辑器[bian ji qi]的速度差距,而且支持[zhi chi]单一的UTF8可以更好的识别[shi bie]文本[wen ben],比如中文[zhong wen]的书名号配对《》,这是多内码设计所无法实现的,因为 项目无法对每一种代码页都做分析,做出特定的表来识别[shi bie],不过这个错不完全在Scintilla,外部项目本身可以弥补这些缺陷[que xian],可惜从开源[yuan]的一些编辑器[bian ji qi]实 现上看,并没有编辑器[bian ji qi]如此做。
至于16进制,UltraEdit实现的比较好,虽然一些编辑器[bian ji qi]项目也实现了16进制,比如FlexEdit、 Notepad++、Scite_RU等,但是FlexEdit是另外写的16进制编辑模块[mo kuai],不是用的Scintilla,Notepad++也是一 样,HexEditor插件[cha jian]也是另外实现的基于树形列表[lie biao]Treelist的16进制编辑控件,而SciTE_Ru虽然是通过lua脚本[jiao ben]实现了原生的 Scintilla十六进制[shi liu jin zhi]编辑,但是类似于Dos时的小窗口[chuang kou]编辑实现的并不算好。很奇怪的是,1.78版本中实现的两个主要新特性之一的文本[wen ben]边栏 Text margin就完全可以很好的实现16进制编辑时的偏移量[pian yi liang]显示[xian shi],但是依然还是见不到有项目基于此自行实现的16进制编辑功能,也许一样要等到 Scintilla完全实现内置16进制编辑才会普及吧。至于1.78中添加的另一个新特性注释[zhu shi]行Annotation lines,很类似于xcode中设计的出错显示[xian shi],不过也许visual studio等windows开发环境[kai fa huan jing]习惯于将错误[cuo wu]输出[shu chu]到Output窗口[chuang kou],而只有要显示[xian shi]汇编[hui bian]时才混合代码和汇编[hui bian]一起显示[xian shi],所以Annotation lines也是应用[ying yong]寥寥,平心而论,Scintilla就编辑功能的覆盖[fu gai]广度已经做得比较完备了,许多功能并不弱于vim、Emacs等超级编辑器[bian ji qi],但是 问题[wen ti]在于各项目组合[zu he]基础功能之后的深度还不够,以至同质化严重的同时,各项目也功能平平,比如自动缩进[suo jin],vim实现了四种缩进[suo jin],auto、smart、 c、以及indentexpr,而emacs则实现了gnu、java、linux、python、user等多种成熟的缩进[suo jin]风格,提过组合[zu he],在vim和 emacs中几乎常见的缩进[suo jin]风格都很容易实现。而SciTE实现了简单的自动缩进[suo jin]后,大多数基本沿用,因此缩进[suo jin]都不够智能[zhi neng],而Notepad++的插件[cha jian] NppAutoIndent则从一定程度上改进了Notepad++的自动缩进[suo jin],可见自动缩进[suo jin]并非是Scintilla不能支持[zhi chi],而是大多数项目设计使用 不当。
当然SciTE还展示了lua脚本[jiao ben]扩展[kuo zhan],以及提过windows的消息[xiao xi]扩展[kuo zhan]等,如Filerx就是使用外部SendMessage来操作 SciTE,效果很好,可以录制和重放操作,对于文本[wen ben]编辑器[bian ji qi][wen ben bian ji qi]而言,lua脚本[jiao ben]使用SciTe的库函数[han shu]接口[jie kou]已经足够实现绝大多数文本[wen ben]功能扩展[kuo zhan]。但可惜的是, 大多数项目没能很好的继承[ji cheng]SciTE这种良好的扩展[kuo zhan]性,大多数项目没有实现类似的lua系统[xi tong],就是有扩展[kuo zhan]性也是另起炉灶,如Notepad++自行实现了 插件[cha jian]系统[xi tong],固然设计的还不错,但却失去了脚本[jiao ben]的灵活,而programmer's notepad等虽也自行实现了采用python等其他脚本[jiao ben]语言[yu yan]的脚本[jiao ben]扩展[kuo zhan],可惜自由度却还是不如SciTE。当然同样可惜的是,依然有些扩展[kuo zhan]是需要有界 面的,尤其是运行[yun hang]时需要引入参数[can shu]的,而单纯的lua无法扩展[kuo zhan]界面[jie mian],lua的几个界面[jie mian]库如iup,tckUI等也不能很好的担当大任,使得单纯的SciTE 中的lua扩展[kuo zhan]使用并不是特别方便,再加上SciTE本身非界面[jie mian]化的配置[pei zhi]不够友好,导致其用户[yong hu]并不是很多。至于lua和wxWidgets或者Qt虽然可 以较好的互动,但是前提[qian ti]是SciTE不是采用这些库开发的,而即便有项目以这些界面[jie mian]库开发,使用lua来控制[kong zhi],估计需要做的事情依然很多,不够轻量化[liang hua],也 不符合现在网络[wang luo]化的发展趋势。
至于比编辑器[bian ji qi]更复杂的IDE,情况[qing kuang]也差不多,大多数IDE现在都是Eclipse化了,另外由于Borland的黯然离开,除了微软[wei ruan]自家的Visual Studio,考虑到跨平台[ping tai],IDE多半用的不是java就是wxWidgets,如另一个与Eclipse齐名的NetBean也是java实现的。而 一些小型的IDE,如Code::Blocks、Komodo等,出于开发方便,最主要的核心组件[zu jian]之一也很少自行开发,直接使用了Scintilla,其 实,无论是从开发角度还是使用角度而言,编辑器[bian ji qi]不仅仅是IDE的基础,也同时已经具备了IDE的初步雏形,尤其是除了少数几个巨型IDE如微软[wei ruan]的 Visual Studio,Sun Java Studio,IBM Rational(基于Eclipse),以及一些CPU厂商,如Intel、Motorola的IDE等,可以有足够的实力考虑和实现包[bao]括编译[bian yi]器、调试[tiao shi] 器、编辑器[bian ji qi]、版本控制[kong zhi][ban ben kong zhi]器等各个组件[zu jian]的设计开发衔接以更好的整合之外,大多数的IDE基本都是外挂式的,比如挂上GCC,SVN等等,而这些,很多编辑器[bian ji qi]其 实也都可以做到,甚至包[bao]括外挂调试[tiao shi]器,只是相对而言,由于设计目标[mu biao]和定位[ding wei]不同,IDE实现和整合的功能更多,IDE的插件[cha jian]系统[xi tong]一般也更复杂也更完善,扩展[kuo zhan] 功能更容易,而这对于大多数单兵作战开发的编辑器[bian ji qi]就很少会充分的考虑到。当然类似的还有SlickEdit、UltraEdit Studio,以及以代码分析著称的Source Insight等第三方[di san fang]IDE,至于Emacs也可以算是IDE吧,对于此类IDE,优秀的编辑器[bian ji qi]都一样是其基础,不过就以Source Insight而言,其定位[ding wei]就是编辑代码文件[wen jian],因此大文件[wen jian]操作就很少考虑,否则,以Source Insight独特的不等行高的设计,大文件[wen jian]的整体行高计算和显示[xian shi]就会是一个棘手的问题[wen ti]。另外SlickEdit的Slick-C,和Emacs的 Lisp是比较独特的,几乎所有的功能都是用Slick-C,或者Lisp实现的,应该算是可扩展[kuo zhan]性[ke kuo zhan xing]最好的IDE设计之一。 

   只是Source Insight、SlickEdit、UltraEdit、Textmate、EmEditor、Visual Assist等都有商业赢利支撑,而Eclipse、NetBean等虽开源[yuan]免费,但背后也都有IBM、Sun等大型技术公司做支撑,相比较之下,开源[yuan]且 免费的Scintilla即便相关的项目众多,几乎占据了开源[yuan]编辑器[bian ji qi]项目的半壁江山,但如果所有的项目都只是提需求[xu qiu],缺陷[que xian],和等待[deng dai]使用,那么仅靠Neil 一个开发者[kai fa zhe]而言,虽然Scintilla已经做得足够好了,也因坚持了近十年的不断奋斗也让人由衷感慨和钦佩,但如果Scintilla想做得更好,实在 将是很艰难的前行。 
   很高兴没看到MegaxEdit没自行实现正则库,前段时间在MissDeer的博客中随手写的一篇“编辑器[bian ji qi]杂谈”中还提到了这个,开发应有所为有所不 为,什么都自行实现且不论是否可以写得更好,也实在没有必要,当然例如Emacs的Richard Stallman样样精通的超级大牛除外。“编辑器[bian ji qi]杂谈”主要是针对Scintilla系编辑器[bian ji qi]写的,也评论了点现有知名编辑器[bian ji qi],随附在后,希望一点心得 有点小用。 

    不过文中有几处小错还是需要指出,估计Megax是不是没有苹果机器实际试用和深入研究过Textmate,所以不太清楚? 

其一,Textmate的这个功能不是Bundle,而是Snippet,Bundle功能比这个要重要和强劲的多,Bundle构建了脚本[jiao ben]与编 辑器以及系统[xi tong]的关联,类似于脚本[jiao ben]宏,MacOs上脚本[jiao ben]体系比Windows要好很多,自带的脚本[jiao ben]也远比Windows的JavaScript、 vbScript要丰富,当然Windows的Com也异常[yi chang]强大,不过苹果在脚本[jiao ben]体系的人机交互[ren ji jiao hu][jiao hu]上远比Windows要好上很多。而Snippet则基本 上就是文本[wen ben]段落辅助完成,其实Visual Studio里面就有Snippet功能,不过估计使用和研究的人更少,毕竟不是很明显的功能。Vim和Emacs也早有插件[cha jian],或多或少也实现了较完整的 Snippet。 

其二,Oniguruma正则库,也就是鬼车是支持[zhi chi]循环[xun huan]嵌套[qian tao]的,其自带的帮助中写得很清楚,而且还举了实例,Megax在东京呆了这么多年,即便 英文的帮助没注意,日文的帮助也应该至少读一遍的。应该说,最近流行的正则库大多数都已经实现了嵌套[qian tao]匹配,如脚本[jiao ben]语言[yu yan]Perl、PHP、开发平 台.Net、Java的正则库,以及正则库Greta等都是支持[zhi chi]嵌套[qian tao]的,这个在O'Reilly《精通正则表达式[zheng ze biao da shi]》一书中有详细的描述。当然1.9.0版 本之后采用Oniguruma的Ruby自然也支持[zhi chi]嵌套[qian tao]正则。不过也正由于Oniguruma合入了Ruby,因此现在Oniguruma的最新代码已基 本合并入Ruby开发,可惜的是,Ruby加了很多专有的定义进去,使得剥离一个最新的Oniguruma已经很难了。最容易为第三方[di san fang]集成[ji cheng]使用的 Oniguruma也许永远都定格在5.9.1了吧。 

其三,正因为Oniguruma支持[zhi chi]嵌套[qian tao]正则,所以TextMate支持[zhi chi]Snippet嵌套[qian tao]变量也就不足为奇了,因为TextMate的正则库正 是Oniguruma的Cocoa移植[yi zhi]版本,也许是OgreKit。当然由于Textmate商业软件[ruan jian]的源[yuan]码不可见,也不排除TextMate直接使用字 符串函数[han shu]进行解析,因为Snippet本身并不复杂,纯字符[zi fu]串[zi fu chuan]解析也很容易。目前Snippet做的比较完善的除了TextMate,还有Intype一 样的支持[zhi chi]嵌套[qian tao]变量,但是e TextEditor就只能支持[zhi chi]简单的文本[wen ben]了。 

其四,写伪码时最好也要注意语法[yu fa],strFind.Format( "\$\{%d:(.*?)\}", i ); 肯定编不出正则的,Escape转义[zhuan yi]字符[zi fu]应该写\\,而不是\,要不然引号就先使用\转义[zhuan yi]了,再往下就自然出错。这不是TCL,TCL可以使用{}来规 避,而C则不行。 

不过总得来说,基本上Snippet的实现就是这样了,不过依然有两点需要改进,一是变量的顺序,其实没有必要规定顺序。当然,如果按一次处理一 个序号自然会引入顺序问题[wen ti],但是如果一遍先将所有编号区域[qu yu]全部找出存储,并记录位置[wei zhi]信息[xin xi],再行一次性替换[ti huan],就可以解决顺序问题[wen ti]了。其二,Tab键并不是一 个完美的键,无论是TextMate,还是Intype等,都只可以用Tab前进,而无法后退,这是因为Tab本是就是缩进[suo jin]键,此处挪作Snippet 用,从而导致一个键二次定义,从用户[yong hu]角度上而言是不可取的,使得用户[yong hu]在Snippet过程中无法缩进[suo jin],例如复杂点的段落,自动缩进[suo jin]不完美的情景下,用户[yong hu]就 只能退出[tui chu]Snippet再行修改[xiu gai]了。因此目前TextMate等多半是在编写Snippet时就预设好缩进[suo jin],在Snippet时仅仅依据上一行进行整体缩 进,从而一定程度上避免了这个问题[wen ti]。但是也因为很难做完善,所以Shift-Tab并没有用来实现Snippet的回跳,依然还是定义为减少缩进[suo jin]。这个问 题在 Mitchell Foral 的Scite-Tools中有提及,因此Scite-Tools在Scite的基础上使用Ruby实现了Snippet时,并没有使用Tab键,而是 Ctrl的组合[zu he]键,这样就轻松的完成了前进和后退,如果TextMate等跳出Tab的圈子,自然一样可以轻松后退,不过如果决定权交到用户[yong hu]手中也许会更 好。Mitchell Foral 基于Scite的后来的最新Mod作品,如TextAdept等,Snippet又用lua重新编写了。由于Snippet自身就是Ruby或Lua脚本[jiao ben] 的便利性,Mitchell的Snippet从某种意义而言应该是比TextMate更为强大,因为此时Snippet已经是具有完备功能的脚本[jiao ben]段,有点 类似于Bundle,而不再仅仅是一段字符[zi fu]串[zi fu chuan]了。 

    Snippet作为一个非常便捷的编码[bian ma]辅助功能,也依然在不断发展,自解释[jie shi]应是目前的最新阶段,其代表就是Zen Coding,作为快速开发的典范,类CSS的语法[yu fa],使得编写Html等网页[wang ye]语言[yu yan]非常迅捷,可惜,其作用[zuo yong]域由于语法[yu fa]特殊性,估计也很难走出Html的编程[bian cheng] 范围[fan wei]了。

一时感慨,写得多了,希望对于关注或采用Scintilla的项目,以及致力于自行编写编辑器[bian ji qi]的能有所用。

posted

转自: http://www.aowe.net/n1910c6.aspx

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值