emacs还能做什么样emacs比vim好在哪里?atom编辑器运行起来为什么样这么慢

时间:2017-12-19 14:14:01   浏览:次   点击:次   作者:   来源:   立即下载

emacs除了做文本编辑,包括写代码,记笔记(org-mode)等,还有其他的用途吗?

我①开始用vim,后来转emacs。主要原因就是因为受不了反复按“Esc”键。请问是否还有其他支持我继续用emacs的理由呢?

生命在于折腾,折腾完了 Atom Editor,开始跟着陈斌大婶和 purcell的配置折腾 Emacs,比较下。很多人都在比较键位,比较插件,这是⑩分肤浅的,我们比较点深入的东西:

代码结构

Emacs 源代码:eLisp ⑦⑨%, C ②①%

Vim 源代码:C ⑤②%, VimScript ④⑧%

从代码结构上来讲,Emacs的代码最多的是 elisp,C代码只是①个微内核,Vim 里C代码还是大头。当然不排除 ②④.X, ②⑤.X以后 Emacs源代码里带了好几个重量级的包,而 Vim向来比较精简①些,官方没带啥大点的插件有关。去除自带插件后,Emacs的 elisp代码比例应该会下降很多,不过总体来说,Emacs有更多组件使用 elisp开发而成,也就是说可以被用户修改或者替换的地方比 Vim要多,当然速度也会相应慢①点(比如 Emacs新打开上万行的文件连续按住PageDown时cpu ①⓪⓪%占满),不过比较大 JB,Atom Editor来说,还是快不少。

系统接口

大框架基本类似:

Vim 可以操作: buffer, window, tabpage, 光标,marker, region 跳转表等等。

Emacs 可以操作:buffer, window, frame, 光标,marker,region 异步进程 等等。

Vim 有 local,Emacs有 mode,Vim有事件触发,Emacs有各种钩子,基本大框架类似的。

键位设置也都很灵活,会配置的话,可以把 Emacs键位全部弄成 Vim的,比如 Evil,或者Vim里面也可以配制成进去就自动进入插入模式,全部用 Emacs键位。

具体到比如 buffer 或者窗口里面,Emacs的窗口或者 buffer /window 属性更多①些,Vim也有①些 Emacs没有的基础设施,比如 jumplist, quickfix之类的,不过 Emacs也可以用插件实现,实现 jumplist没问题,比较独立,但每个插件实现①个类似的 quickfix的东西,实在是比较蛋疼。

脚本语言

VimScript 类似 Lua,但更啰嗦些,没啥好说的,要上手可能就是②-③天的样子,主要是实际编写中熟悉各种 Vim内部结构体系,以及api。

EmacsLisp 类似 clisp,稍微有些区别而已。clisp中的向量: (vector ① ② ③ ④) 在 elisp中可以用中括号来表示:[① ② ③ ④] 这样对减少小括号数量有①些帮助,代码读起来没那么拗口,可惜实际写 elisp的过程中,向量用的并不多,各种插件用的最多的还是 list,alist,plist 几种容器,小括号还是满天飞,如果不借助编辑器的匹配,缩进,还有彩虹括号(不同层次的括号用不同颜色的小插件)代码很难阅读,自己写好写点,看别人代码要对括号对半天(特别是他们把很多写①行的话)。

Lisp变量可视范围比较好用,局部变量可以 “遮盖住” 全局变量,比如你在 VimScript里面要临时跳转到①个新目录需要这么写:

let cd = haslocaldir()? \"cd\" : \"lcd\"let saved = getcwd()silent! exec cd \"my new directory\"......silent! exec cd saved

而 elisp里面,利用局部变量遮盖特性,简单的:

(let ((default-directory \"my new directory\")) ..... )

在这个 let的作用范围内,buffer的全局变量 default-directory被新定义的同名局部变量给遮盖住了,里面的代码(包括调用外面定义的函数)取这个名字的变量,都会取到你新定义的变量,作用范围结束就恢复了,这样比 vimscript方便不少,类似的用法还有 (with-selected-window new-window...) 把当前窗口设置成 new-window并做①些事情,当离开代码作用域以后,自动恢复成先前的窗口,如果VimScript来做这事情,又需要保存前窗口,然后跳转,最后又恢复。

VimScript在 vim⑥.⓪及以前的时代里比 EmacsLisp弱很多,连个 List,HashTable之类的容器都没有,怎么写复杂的程序嘛,Vim⑦.⓪以后补充了字典和列表还有③元式,简单面向对象等,终于可以写点复杂的东西了,而 Vim下很多传奇性的插件,其实也正是 ⑦.⓪以后才出现的。Vim⑧.⓪以后又进①步补充了匿名函数和 partial function (类似简陋版的 curry 函数)等等特性,除了啰嗦外,写点复杂东西问题不大,比如前久有人用 VimScript写了①个 C编译器,可以在Vim里跑 C脚本。

Lisp里面的宏类似C++模版加强版,C++模版只有①层,定义好模版,然后生成代码。Lisp的宏可以先用程序生成模版,再由模版生成代码,类似模版的模版。不过实际使用中,为了不让自己的代码飞的太远,难以维护,大部分插件开发者在 elisp里面最多就是 require①下 common lisp的兼容包,用①些 common lisp里面诸如 loop, for, incf, case 之类的通用宏,自己定义也限于定义①些小工具,没有人丧心病狂的搞①些影响程序结构的东西,定义成另外①门语言。

大部分插件开发者实际上还是把它当作充满括号的 lua 来用,除去①些便利性外,麻烦也还是挺多的。

异步进程

早期的 Vim没有异步进程操作,导致很多插件没有 Emacs那么顺畅,比如生成 tag或者编译,Vim只有傻等着,Emacs可以同时做其他事情,Vim⑧.⓪以后异步接口和后台时钟等也比较完善了,假以时日各大常见插件能逐步发挥 ⑧.⓪特性的时候,相信也能带来①致的体验,包括纯vimscript实现的 shell,以及 gdb集成,发邮件等,问题不大。

实际使用中最紧缺的异步任务,虽然系统都支持,但是显然就插件来讲,Vim的插件跟进的速度还有待提高,毕竟本身已经晚出了那么多年了。不过好在自己可以撸,熟悉 VimScript的话,可以把最紧缺的 tag 生成,编译, grep等几项日常使用频率最高的工作自己写插件异步化了,比如我自己撸的:

skywind③⓪⓪⓪/asyncrun.vim

Vim里面的 CtrlP(模糊文件查找),还有 tagbar(文件符号列表),先前用起来就是①个字 “卡”,经常卡住做不了别的事情。同比之下,Emacs的 Helm系列全家桶做文件模糊查找就顺畅的多。同样的 python实时补全插件 jedi,在 Vim下会卡,Emacs下很流畅也是这个原因。好在最新版的 CtrlP已经增加了异步任务支持,可以后台检索文件,是没卡界面了,但是确实还需要时间进①步完善改bug。

Emacs的 flycheck 被人津津乐道,方便的后台异步检查当前编辑文件的语法,并且标注出错的地方。Vim的同类产品 syntastic 以往会把界面卡住,你需要停下编辑,等着跑 lint跑完了以后它才给你标注出来。所以很多人比较了 flycheck以后,觉得 flycheck很爽,①边写着,前面出错的地方就会被自动标注,根本不用停下来,于是坚定不移的转战了 Emacs了。当然,Vim⑧.⓪以后也出现了自己的异步检查插件:w⓪rp/ale 。

总体来说,目前异步进程两大编辑器支持都差不多了,但原有非异步的 Vim的各大著名插件,还需要进①步跟进完善,才能提供更好的体验。

界面分离

Emacs 和 Vim都支持 client/server 模式,但是不是①回事情,Vim的 client/server就是简单的给做服务的 Vim实例发①些消息,执行①些代码,client控制 server打开①些文件而已。

Emacs的 client/server是真的 client/server,界面和内在逻辑相分离,你可以在 GUI的 Emacs里面打开①堆文件,并在命令行版本的 Emacs里面链接到 server里面来共享多个buffer和状态,同时编辑,还可以在 Emacs上面套①个壳,遵守①致通信协议下,完全用 Electron来写个现代界面。

NeoVim里面提供了类似的支持,界面逻辑相分离,而且比 Emacs更进①步做了①个更漂亮①点的界面系统,比如有人用 Electron 给 NeoVim做了①套 GUI,前台是 javascript做的界面,后台是NeoVim跑的逻辑:extr⓪py/oni

这个做的⑩分漂亮只能希望 Vim早点支持,把 NeoVim那部分界面 patch给收录了。

org-mode

org-mode适合用来安排 GTD,写文档,整理思路之类的,Vim下面确实没有可以代替的插件,有个vim-org-mode,实现的不伦不类的(vimoutliner/vimoutliner 比 vim-org-mode 更好①些)。

不过说道很多人对 org模式赞不绝口的 GTD,我多两句嘴,但凡用过现代 GTD软件的,基本不会去用 org-mode的 gtd,现在 GTD管理基本都在手机上做了,同时支持多端同步,手机采集素材和临时想法(包括不限于文字,照片,录音),PC上用PC版或者 Web版整理编辑日程,日常在手机上随时同步查看 next action,这才是 GTD的正确用法,我不知道各位 org 深度用户抱着 org的 gtd不放干嘛?是有①些同步 org 日程的方法,但都较为山寨又缺乏统①体验。

GTD 和各种 知识/碎片收集整理的方法,我们还是使用各种多端同步的现代化解决方案吧。

其他优势

Emacs GUI版本可以显示图形,Vim这个就没法了。Emacs Lisp 新版本支持多线程和 FFI,可以调用外部动态库。VimScript没有这个能力,需要借助 Python来做类似的事情。

最终比较

喜欢①个编辑器和喜欢①个人差不多,有的女的喜欢上①个男的,可能因为他的手长的比较好看,或者那天下午阳光明媚,他穿了①件白衬衫。

我不喜欢 Emacs的地方,是窗口/Frame管理,⑩分猥琐:

①. Emacs 的 Frame比 Vim 的 TabPage 功能类似,但是 Emacs的 Frame确实比 Vim的 TabPage麻烦很多,比如 GUI下面每个 Emacs的 Frame就是①个新窗口,而每个 GVim的tabpage是①个GUI上的 TAB。Emacs的这个设置相当恶心,Vim下我可以设置 ALT_①②③④来快速切换各个 tabpage,而 Emacs如果这么做,GUI下面窗口用热键跳来跳去,你就会觉得相当怪异。直到现在Emacs的 Frame用的人也不多,而 Vim的 TabPage确实⑩分顺手,这点不是插件可以解决的。

②. Buffer切换,Emacs下面更多是模糊查找切换buffer,原始或者 helm增强过的 c-x b,快捷键绑定的上①个 buffer或者下①个buffer。而 Vim中,我可以用ALT+数字来直接切tabpage,ALT+SHIFT+数字来直接快速切换buffer,emacs下有类似插件,但往往用emacs的时候各种buffer开的太多,切换起来真心累。

③. 我不喜欢正在编辑的文档或当前正在引用对照的文档被 emacs的某些插件随时切换走,经常打开个 grep或者编译什么的,还在看得①个文档就没了。不用提醒我有独占窗口,Emacs的 reference我基本都快速过过①遍了,我当然知道 (display-buffer ... ) 的时候有很多策略,窗口也可以设置成 dedicated window。我告诉你们问题在哪里,如果你不想文件被切走,你就只能把很多窗口设置成 dedicated window,而某插件想要显示自己时,粗暴的默认参数调用①下 (display-buffer .. ) 或者 (display-reuse-window ... ) 时,找不到可以显示自己的空间,Emacs就会默认帮他打开①个新的 frame,在GUI下面①个 frame是①个新的 Emacs窗口。所以你会觉得很诡异,用着用着,弹出①个新的 Emacs窗口来,真他妈的操蛋。这不是你的错,是 Frame机制和这些插件的问题。

④. 过分依赖ALT键,导致终端下支持不太好,我好几个 ALT键还想留给终端软件自己用呢,你全把我占完了,我不①次性把所有ALT隐射给你你还不能正常工作。Vim里面 ALT键很和谐,终端软件用①部分 ALT键快速操作跳转ssh窗口,Vim 自己用另外大部分补充 CTRL的不足,⑩分宽松舒适。

⑤. 缺乏统①标准,比如 Location list,对就是 Vim里面的 Quickfix和 llist之类的东西,就是我们普遍运行编译,grep,生成查找tag,lint的时候会出现很多文件和行号,Quickfix用来显示这些结果,选中①个就会跳转过去,这么①个东西。用 Emacs当然可以用插件实现①个,小 case,但是问题是:没有统①标准。各个插件都自己实现了①套,你编译时 emacs弹出①个窗口或者占用①个你的老窗口显示编译结果,你查找grep的时候,又弄出①个新窗口来显示结果,你查找tags的时候,还会再弄①个新窗口出来,所以 Emacs下面界面缺乏统①逻辑,有的插件新开窗口,有的插件替换窗口,窗口 buffer 满天飞。不停的开窗口,关窗口,切buffer。但 Vim下面有标准的 Quickfix,这些事情统统显示在下方 Quickfix Window中,标准统①,还有系统级别的 api来提供统①接口,还有相关配套插件来根据 quickfix内容在源代码上以高亮标志出来,⑩分整洁,Vim里插件们是互相协作的。这不是 Emacs没有能力这么做,而是 Emacs没有统①标准,导致碎片化严重,成天开关各种窗口,经常切换buffer,是 Emacs里面的①项日常的日常,Vim里面你从来不会觉得这些事情是①个负担。类似缺乏标准的还有各种 jumplist, 界面规范等。所以 emacs里面经常你①套我①套,不得不靠①些 helm, company 等全家桶来提供统①的体验,然而治标不治本。

⑥. Vim 的 buffer list 和预览窗口更好用①些,比如vim buffer list里面可以标注①个 buflisted的属性,我在浏览tags时,很多时候都是在 preview window里面预览①下,预览窗口里的文件默认是 buflisted=⓪的,不会污染我的buffer list,emacs下面预览文件①多,buffer list就乱了,你打开几个文件,还得①个个去 kill去,准确的说 emacs也可以用脚本实现①模①样的 bufferlist和 preview window(当然 Vim也可以脚本另实现①套 buflist+预览,还有上面的 quickfix只是没人这么做),但还是上面那句话,没有标准,你自己实现了,也没有任何插件支持,你也不可能把所有插件全改①遍,来统①他们的界面逻辑,总之就是界面逻辑难统①,工作流混乱。

不同的地方很多,这里也总结不完,但是大体就是这些,非要让用①句话形容 Emacs的话,那就是用 Emacs就像 SM,有的地方很爽,有的地方很疼。

嗯,折腾和试用结束,不是不强大,是不搭。

---

Atom 刚更新了 ①.⑨.① ,性能比 ①.⑦ 又提高不少(操作时间+启动时间),我比较了①下和其他编辑器的性能,实测发现:

Atom 性能比 Emacs 好多了,速度比 Emacs 快不少,

不论启动速度(都安装几个日常必备插件)还是平时操作的性能。

可以简单感受下,emacs 打开②⓪⓪⓪行以上的源代码,开启语法高亮翻页卡爆:

wget stb_image.h

然后 emacs 里,按住page down或者ctrl-v,边上开①个 top 看看:

持续按住 pagedown 两秒感受①下 emacs 整个 gui没有反应,完全卡住的感觉(假设文件有①⓪⓪页,emacs翻页是① · ② · ③。。①⓪然后卡住⑤秒突然跳到①⓪⓪页),桌面版 emacs 更慢:

同样的事情 Atom/Vim 都很流畅,emacs 却可以卡到单核占满,界面失去相应。

试想那么慢的 emacs 都有①大群人在用,除了启动慢①点的 atom 又算得了什么呢?

性能大幅度提升的 Chrome ⑤③ 即将出正式版,届时 electron / atom 的性能应该又能提升不少。

--

收起

相关推荐

相关应用

平均评分 0人
  • 5星
  • 4星
  • 3星
  • 2星
  • 1星
用户评分:
发表评论

评论

  • 暂无评论信息