Vim Vs Emacs

Vim编辑器使用了大概有三年的时间,emacs呢则是最近几天才尝试的,之所以会尝试emacs,第一点是因为看了不少书籍和博客都在说lisp如何如何好;第二点则是因为近期出现了广受好评的spacemacs项目,这个项目可以说开箱即用,而且使用了最接近vim的evil包,据说这个包还原了百分之80以上的vim功能,是所有的试图模拟vim模式的尝试中做得最好。

这就很明显,spacemacs这个项目会拉拢一部分Vim用户,的确,它成功地吸引了我的注意力,我早就想试下这个“操作系统”是如何牛逼。

下面我单纯的从用户的角度来比较两者,对比非常浅。

包管理

对于一直用惯了vim简陋的包管理的我,一看到emacs的包管理,的确有点惊艳到我。

在emacs中,只需要点击菜单的Options->Manage Emacs Packages,既能打开emacs的包管理器,打开包管理器之后,可以搜索,可以安装,可以访问主页,多么友好的用户体验,跟Vim真是天差地别。

emacs包管理器

安装窗口

由于各种原因,在天朝下载可能很慢,但用户可以更换镜像源,就像linux上apt,yum和macOS上的HomeBrew一样,有个官方的服务器专门存放这些包,而且世界各地也有志愿同步官方的镜像源。

以上只是新用户的我的体验而已,然而通过阅读一些资料之后,我们发现其实emacs也是长期没有自带的包管理器的,在emacs 23的时代出现了一个非官方的包管理:packages.el。后来到了emacs 24才被集成到里面去。

另外还要说下这货的更新其实非常麻烦,首先要进入package-list-packages然后在需要更新的包标记为需要更新,问题在于Package-list-packages是列出所有的包,包括了没有安装的,意味着你要标记其实非常麻烦…

现在来看vim的包管理,实际上vim根本没有包管理,我们来谈下vim的包管理发展史。

  • 最开始的时候,用户必须把每个插件不同文件手动放在指定的目录上

  • 后来出现一种压缩格式,用户只需要在vim中执行:so xxx.sz就可以自动将包释放到对应的目录,

  • tpope大神横空创造出了vim-pathogen,这个时候用户再也不需要将一个包里面不同文件放在不同文件夹里面了,一个包就是一个文件夹,结合github和git-submodule,我们就可以在线下载更新了,但是一开始github还没火,绝大部分开发者将包提交到Vim官网上而非github上,后来出现了一个用户vim-scripts将官网大部分插件上传到github上,从此开始,pathogen才真正活起来,同时随着github的流行,越来越多作者将插件放到github上来管理,到现在vim-scripts已经功成身退了。

  • Vundle,用户不在需要通过git-submodule来在线更新了,只需要在配置文件加入简单命令即可窗口化管理插件。很多小白用户都是从这个插件开始的。

  • vim-plug,可以说目前最受欢迎的包管理器除了实现Vundle的功能之外,还有两个个杀手级别的功能就是lazzy load和多线程异步更新,特别是前者的出现让vim的包管理一段时间内超过emacs的,用户可以根据文件类型,动作命令来选择什么时候加载,用户可以决定下载包之后的动作是什么,还可以指定git仓库的tab和分支。

  • 其它。dein.vim和vim-plug不相上下,甚至更好。neobundle.vim同样是由Shougo大神写的,同样优秀不过是他写的上一代产品,还是推荐dein.vim。

emacs默认的包管理的话,还有一个有点,就是自动解决依赖,这对vim来说是不太可能的,因为vim的插件是散户自己弄的,没有官方的组织,只能靠用户自己注意依赖问题,好在vim的依赖很少,emacs的自带的包管理有个缺点就是无法lazzy load而且需要用户自己写脚本维护自己的插件列表已经安装和更新,只要你把包安装了除非你包删除掉否则无法不加载,后来出现use-Packages才解决了这个问题。

总结:vim由于先天原因找包比较困难,但是找到之后维护起来比emacs简单得多。

补全

编辑器中所有功能中大概大家最关心的就是这个功能吧,emacs有一个company包以及相关的补全包,但就company包来说就挺不错的,能补全路径打开buffer中的单词以及elip的函数变量等等,要是开发elip就这个包就够了,可惜,号称操作系统的emacs仍然无法很好解决高级编程语言的补全问题,以前的emacs也和vim一样使用ctags和cscope来进行补全跳转,后来谷歌大神Valloric为vim创造出惊天插件youcompleteme,真正意义做到语义级别的补全,后来大神将这个插件的服务端ycmd统一接口,让更多的编辑器可以使用ycm,所以你现在去搜如果要做到语义级别的补全,会得到和vim一样的结果,那就是使用ycm。

vim的话,如果使用了ycm的话,vim script本身的补全反而找不到较好的方案呢,各位知道怎么弄?

shell或者终端模拟器

我现在的vim的配置是:vim+vimshell,而neovim则是用自带的终端模拟器,neovim的终端模拟器丝滑般好用。

emacs的有自带的用elisp写的eshell,类似vimshell的地位,说实话,这个eshell难配置,难用,而且慢,经常卡,使用体验输给vimshell。

emacs当然也有终端模拟器,可惜打开之后尽是乱码,当然这可能和我使用zsh+oh-my-zsh有关。

在这一点上vim获胜了。

搜索定位

补全那一小节有一些没说,似乎用emacs的人不喜欢fuzzy complete或者fuzzy search,我用company的补全真的很难习惯。什么是fuzzy请看下面的动图:

ycm

在搜索方面,vim最著名的插件就是ctrlp.vim,也就是Fuzzy file, buffer, mru, tag, etc finder,配合the_siliver_searcher搜索速度真是无人能敌,在搜索linux源码的时候也是秒开,最重要的是fuzzy这个特性在茫茫的文件中,这是找到文件最佳途径,而那些emacser貌似很少用这些特性。

另外的ctrlp的一个扩展也非常牛逼,那就是ctrlp-funky,就是用ctrlp的接口列出当前文件的函数,然后用户可以fuzzy定位到该位置,有了这个插件之后,我基本就不用tagbar之类的插件了。

emacs也有一个imenu,但是支持的语言类型太少和ctrlp-funky没得比,后者支持三十多种语言。

当然,emacs在文本搜索中有一个优势就是实时显示,这一点貌似还么有vim插件实现过。

其它优秀插件

vim-multiple-curosr这个功能是在st编辑器首先出现,出现不久之后就有vim插件了,而且做得非常不错而且可以结合全局搜索插件进行替换,非常方便,可以看我的这篇文章vim重构插件PK

emacs也有当却和evil不能和谐共处,至今没有找到体验和上面的vim-multiple-curosr一致的包。

vim-multiple-curosr

vim-easymotion,超级强大的光标定位插件,甚至可以在多窗口中定位,evil系列中也实现了一个可惜功能上和用户体验差太多了,比如它没有行模式,不可以多窗口。

vim-easymotion

magit & vim-fugitive

emacs上的magit包体验真的很不错,涵盖了大部分git命令,git有很多命令很难记住,但magit的帮助非常给力,通常是两个字母的组合按键,按下前一个字母之后出现窗口提示下一步能做什么。

相比之下,vim-fugitive就相对简陋些不过够用,一个git status窗口下也能完成很多操作。

lisp

第一次认识lisp,是从它的数学表达式开始,然后它竟然是逆波兰式的,果然名副其实的古老编程语言,瞬间好感提升。

然后写lisp需要写大量的括号,所以好像因此出现一种paredit的编辑模式,减少因为括号太多导致的错误,看了视频介绍觉得很好用,特别适合lisp和html这样的语言。

当然我对lisp的认识只建立在一两个视频上,所以不敢多少。

org-mode

好吧,我还没有尝试过这货,因为我看的那视频那位大神说他弄了几个月才熟悉。但我大概知道他的作用:todo list & gtd & note ;

这样的工具非常多了,我不觉得在编辑上面弄这些是个好的选择。

所谓的操作系统

  • 听歌什么的
  • 收发邮件
  • twitter & 微博

只要命令行可以做到的,都可以集成到vim & neovim上,实际的确有。

浮云。

总结

程序员的编辑器的要求就是:

  • 快速编辑
  • 文件定位
  • 补全跳转
  • 搜索替换

除此之外都是浮云,在编辑器方面emacs永远输给vim。