碎碎念

2007, July 29

Vim的潜能

Filed under: vim, vi, 编辑器, Python

Vim潜能

虽然独特的屏幕编辑指令与方便使用的正则接口才是Vi类编辑器最重要的特点;虽然大部分用户只需要用10-20%的Vi功能;虽然Vim的定位是一个普通文本编辑器。但是大家还是想知道除了常规的编辑功能外,这个编辑器到底还可以做什么?

下面这些都是Vim扩展功能的重要手段:

  • 宏(包括了q命令,:map命令和:ab命令)
  • Vim Script(升级版的Ex命令)
  • 外部程序

宏与Vim Script能实现复杂的功能但局限于Vim提供的命令/函数中。使用外部程序的灵活性要差一点,通常只用来过滤编辑区的文本。这就是Vim的全部本事吗?当然不是。Vim还有两大武器——开放源码与编程语言接口。

1 开放源码

Vim是开放源码软件,所以像所有开放源码软件一样,你可以对它做任意的改动。Vim-ShellVimGdb是较为人所知的例子,它们使得在Vim中使用shell及在Vim中进行集成调试成为可能。

得益于开放源码,c程序员们可以在源码级别为Vim“添砖加瓦”。这是扩充Vim的功能最强大的途径——开放源码意味着可能性。一直以来,Bram Moolenaar都声称不会在Vim中集成shell或加入控制调试器的功能1。但由于Vim源码开放,用户还是有机会在Vim中使用Shell及调试程序——虽然它们没能成为Vim的正式发布的一部分,但这些补丁的存在至少让“源码上的无限可能性”不至于成为流于虚无的口号。

Bram认为Vim应该成为一个开发框架的一部分(编辑器部分)而不是成为开发框架本身。而他也身体力行,于是就有了Agide。我想正是由于他对Vim的清晰定位,Vim才不至于成为另一个自带编辑器的操作系统。但小小私心的说,在Vim中加入Shell应该还是符合Vim的自身特点的(因为有行模式的存在),也有利于Vim与其他程序的交互操作。而且只是作为Shell的表现层,不至于增加许多代码。

只是从源码上改进Vim终究是麻烦了一点——需要编译部署的周期。2于是有人为Vim增加了一些接口目的是能在Vim中使用通用脚本语言,重要的是这还成了正式发布的一部分。于是我们就有了perl和Python接口!当然,通过这些接口你还是无法改变Vim的运行机制,无法像c一样无所不能。但这样做还是换来了多方面的好处:首先,你不用为了增加一个绿豆大的功能,而在Vim源码海里打转。其次,你的开发周期中少了编译及重新部署Vim的过程。第三,现今流行的大多数脚本语言都是高级的语言,可以大幅减少开发时间。最后,你还可以选择不加入这些接口——如果你不需要的话,也没有人会强迫你安装一个你不需要用的60MB的脚本引擎。

2 Vim的编程语言接口

现在仍有许多Vim用户对Vim的程序语言接口不了解,。Vim中除了有自带的脚本引擎外还支持多种脚本语言,其中perl和python自Vim 5开始就成为了正式发布的一部分。现在可以使用的有五种脚本语言Perl, Python, Ruby, TCL和MzScheme。据不一定可靠消息称Java和Lua的接口也在开发中。

记住:只有在编译时加入了相应的选项才能使用这些程序语言接口。

??:在Vim脚本中使用这些脚本言与通过!命令使用这些脚本语言有什么不同?外部命令/程序只能修改buffer的内容,而这些接口允许在脚本语言中访问Vim的所有功能。与开发一个更强的Vim脚本引擎相比这样做有什么优势?这些脚本语言都是成熟的通用编程语言,功能上无赘言;多种脚本语言支持也为用户提供更多的选择,用户可以使用自己熟悉的语言。当然,它们都符合Unix工具箱哲学——工具专注于各自的领域,并可以组合使用。

各个脚本语言能直接访问的Vim对象不完全一样。总的来说可以直接在这些程序语言中使用的对象还不多,但Vim提供了访问Vim Script的接口确保所有的Vim功能都可以通过这些脚本语言访问。举例而言,你可以在perl中修改buffer的内容,但没法直接指定某一段文字所使用的语法高亮颜色。然而,你可以通过VIM::DoCommand()调用Vim Script设置高亮。

那利用Vim的程序语言接口到底能做些什么呢?通常使用的分工模式是由Vim负责输入输出,而处理逻辑部分由脚本负责。因为这几个都是通用编程语言,所以负责处理逻辑的脚本实际上可以完成任何编程语言能完成的工作。不过记住不要滥用Vim了!如果你只是打开Vim,运行脚本,然后关闭Vim,说明你可能不需要用到Vim而可以直接用该脚本语言完成同样的工作。想一下能否在Vim中实现下面描述的功能?

  1. 按一个功能键(比如<F2>)就自动从网上抓取最新的Vim Tips,并在一个分割窗口中显示。
  2. 将当前编辑文本发布到twitter。
  3. 按<F2>将当前编辑文本导出为Word格式,并自动进行适当的格式编排。
  4. 与GTalk用户聊天。
  5. 以MySQL(或其他数据库)做为万能补全的匹配源
  6. 写一个机器人应答程序。
  7. 一个音乐播放器。

没错,所有这些功能都可以实现。

  • 解析XML对主流脚本语言来说都只是小菜一碟,你唯一需要确定是在Vim中的显示格式。
  • 发送POST请求同样不是问题。可参考:Twitter Wiki,这里是现成的Vim script(Twitter)
  • 导出为Word格式需要机子上预先安装有Word,脚本语言可以使用自己的com接口来访问Word对象(Word.Application)。将解析过的文本传递给Word的com对象,并根据解析的结果添加适当的样式(控制Word对象或添加Word的样式比较简单,根据文本判断选择样式则相对复杂一点。因为涉及到文本的解析。)见使用Python來控制MS_Word
  • Perl、Python、Ruby都有现成的库XMPP可以与GTalk通信,为Vim添加这个功能并不困难。参考:XMPP Perl Library
  • 通过脚本的SQL接口访问数据库返回自动补全的匹配源。这当然也没问题。
  • 如果你需要的只是不断回答Yes的机器人的话,使用Vim Script足矣。如果你要写一个更智能的机器人话你就需要这些更强大的脚本语言。如果你想用现成的那就看这里,这是Python实现
  • 音乐播放器?没错,还是可以。只是在这个应用中其实不需要Vim。

如果你觉得这不像是Vim能做到什么,而更像是这些接口能做些什么的话——没错,实现“责任和义务的转移”这正是这些接口的意义所在。有了这些通用开发语言加持,Vim能做什么就看你的创意了——你唯一需要确定的是实现这些功能需不需要用到Vim

用这些接口开发Vim扩展的一个局限是,你可以同Vim交互的手段相当有限(比如没办法开一个监听Vim事件的守护进程)而且Vim没有图形方面的接口。只是当你遇到这方面的限制时,说明你很可能已经越界了——你正用Vim来做一些跟编辑/显示文本无关的事。

3 最后

c语言无疑是最强大的武器,但用c扩展Vim功能的开发成本相对较高。如果你会前面说的这几门脚本语言中的任何一种,你就可以用少量的开发成本为Vim增加非常多的可能性。啰嗦一句——如果你不会,你还是可以让Vim助你提高工作效率,要知道在这些接口出现前Vi类编辑器就已经是最受欢迎的编辑器了。

我听到很多人不用Vim的原因竟是因为他们用不了这么多功能-__-!,我写这篇文章时用到的最高级的的Vim指令是搜索,但已经足够提高编辑效率了(类似的话我这几天大概说了200次,只是效果不彰XD)。Vim有很多的高级应用,那演示的是Vim的可能性,但大多数人的大多数操作都只用到几十个最常用的Vi(m)指令及指令组合——而这几个指令才是Vi(m)最有价值的功能。

作为一个Vim的用户,应该要清楚这两点,首先,Vim的目标之一是可以方便地与其他工具协作而不是取代其他工具;其次,Vim的定位是通用文本编辑器。因此使用Vim的脚本接口扩展功能前,你应该先问一下自己:有没有现成的更好/更方便的工具?为什么这个应用中需要用到Vim?

Appendix A Vim开发原则

相信大家选择编辑器无外乎就是在功能、体积、速度、外观(还有操作方式,只是在用Vi之前大家可能没意识到编辑器是可以有不同的操作方式的)中做一个权衡。没有一个编辑器能满足所有要求。对功能,外观上的要求越高,就要牺牲点体积和速度;反之亦然。Vim试图同时满足功能、体积和速度方面的要求——这不是一个容易达成的目标。Bram Moolenaar为此定了一些Vim开发的原则。可以通过以下命令查看:

:h develop.txt

这些既是Vim的开发原则,也解释了Vim之所以成为现在的Vim。通过这些原则我们可以一窥Vim背后的理念。为了减少大家在浏览器与Vim中切换的次数,这里列出一部分:

  • Vim的目标是成为一个更好的Vi而不是一个全新的编辑器。
  • 尽可能地使用键盘,因为大数人没有第三只手握鼠标。
  • 减少使用控制键的使用,因为按控制键不方便。
  • 要能支持多种不同的终端、平台、多种编译器和库。尽可能的在多平台间保持外观和功能上的一致。除非确实是很酷的功能否则不要开发某平台独有的功能。
  • 新的功能都要带有完整的文档。
  • 体积要小,速度要快。确保Vim只用少量的系统资源,让旧的机子也能用Vim。
  • 有些用户使用低带宽的网络连接,要减少网络通讯量。
  • 用户拥有定制的自由,包括可以选择去除那些带来体积增加却又不是大多数人用得上的功能。
  • Vim的目标是方便高效地与其他程序协作,而不是代替所有其他程序。Vim的定位是系统的组件之一,而不是一个包罗所有功能的巨大程序。
  • Vim不是一个shell(交互式命令行解释器/控制台/命令提示符)也不是一个操作系统。所以你没法在Vim中开一个shell或用Vim去控制debugger。按Vim的设计理念,应该是将Vim作为其他shell或IDE中的编辑部件(而不是成为shell或IDE本身)。
  • Vim不会为了更华美的外观而牺牲其外观在不同平台的一致性。
  • 原则上欢迎添加任意功能(除非与其他原则相抵触XD)。

Bram在这篇文章里面对Vim的发展有类似的阐述:工具应专注于各自的领域,并且可以通过组合产生1+1>2的效果,而不是成为一个无所不能的臃肿程序。Vim功能上的增强会被限制在文本编辑方面。它的目标是成为最好的编辑器并且可以与方便地其他工具相配合。3




Footnotes

[1] :h desing-not

[2] 而且考虑到Unix/Linux上大把的开源软件,“可以从源码上扩展功能”这一点实在不是特别吸引人的特性。

[3] 听起来有点耳熟?就是前面提到的Unix的工具箱哲学。关于这段话可以在原文中搜索”World domination”。事实上Bram Moolenaar曾多次提及这些原则,google一下“高效文本编辑的七个习惯”。


vim_chatbot

Get free blog up and running in minutes with Blogsome
Theme designed by Jay of onefinejay.com