日历

November 2011
M T W T F S S
« Jul   Dec »
 123456
78910111213
14151617181920
21222324252627
282930  

VIM之魅(上)

 

VIM之魅(上)

前言

本月,著名的文本编辑器 Vim 迎来了它的 二十大寿 。 凑巧本人最近正在折腾Vim的配置和插件,心头正痒之时逢此佳际,便再也按捺不住写博的冲动。 其实,为Vim撰文的念头早已有之,只是于今为烈。

Vim的全称Vi IMproved(早期名为Vi IMitation),顾名思义是Unix上流行编辑器 Vi 的模仿和改进版。 毫不夸张地说,自从接触计算机以来,见识过无数的应用软件,深得吾心者唯Vim一款而已。 有时用到兴处,不免心生感慨:这才是软件中的极品呢,识之而不荐之简直就是一种罪过啊。 想起Vim还是慈善软件(careware或charityware),而自己从未给可怜的乌干达孩子们捐过一分钱, 更觉有些羞惭。为了心中的负疚感,我也早该为它写点什么了。

谈及Vim的优点,开源、免费、小巧、成熟、跨平台、文档丰富、社区活跃等等固是不假, 但相较其真正的妙处,以上皆不足道。 事实上,这些因素直接影响的主要是软件的使用成本,而非使用价值。 真正卓越的软件,会让深谙其道的用户不惜代价地拥有,因为它最终将带来远超成本的回报。 TextMate (恰好也是一种文本编辑器)便是一例, 虽收费不菲,且仅能运行于Mac, 但仍然吸引了大量的用户。 不少人甚至为了能用上它而专门购买Mac机,正如其开发者所号召的那样: Buy a Mac, get TextMate!

用户对Vim向来毁誉不一:初见者往往嫌其平凡甚或简陋,初试者往往觉其古怪难用, 而熟用者则食髓知味(词虽暧昧,却极准确)并奉为极致。 为何同一产品的评价如此两极分化?Vim究竟有何魅力值得大书特书? 下面就此谈谈个人的一些见解,并分享一些心得。不当之处敬请指正,不足之处欢迎补充。

关于Vim的误解

首先澄清一些对Vim的常见误解。

  1. Vim太古老,与现代编辑器相比早已过时

的确,计算机领域日新月异,一个年届二十的软件算得上是高龄者了。 何况Vim的大部分精华传承自Vi,而后者已三十有五,更是垂垂老矣。 然从另一个角度看,一个软件在漫长时间的洗礼和无数后辈的冲击之下能够屹立不倒, 不正彰显出它的伟大吗?更令人称奇的是:时至今日,Vi/Vim的许多理念不仅没有落后, 反依旧保持领先。关于这一点,容我稍后再述。 此外,Vim本身也在不断地发展,就在一年前还发布了最新稳定版(7.3)。

  1. Vim是程序员(或geek)的玩意,一般人用不上

虽然Vim在程序员手中更能发挥威力,但编程绝非其唯一的用武之地。 除了IT人士,学生、教师、科研工作者、记者、文字工作者等等,凡常需文字编辑者均可考虑使用。

  1. Vim难学又难用,犯不着为区区一个编辑器而为难自己

相比一般的编辑器,Vim的学习曲线无疑陡峭得多,其用法更是异乎寻常。 但从长远来看,对于一个频繁处理文字的人来说,这点投资绝对是值得的。 “磨刀不误砍柴工”的道理谁都明白,可生活中愿意磨刀的人还真不多。 一个常见的例子是,许多经常打字的人宁肯用“二指禅”,也不愿练习盲打。 放着一本万利的事不做,偏去干无本微利的活,与其说是惰性太大,不如说是理性太少。 再说,Vim虽然命令丰富、功能强大,却并不因此而显得复杂(这当然得益于精巧和谐的设计)。 根据本人经验,十分钟便能入门,一周内即可基本熟练。 此时虽距精通尚远,但效率已远超一般编辑器了。 总的说来, 学用Vim最大的障碍并不在于其本身,而在于固有观念和习惯对人的束缚

  1. Vim只能用于编辑纯文本格式的文件,适用范围太窄

首先为纯文本格式正名。不得不说,人们实在太过倚重二进制格式了。 就拿最常用的Word来说,用户不妨自问一下: 有多少次是习惯性地打开Word编辑文档而实际上只用到了记事本(Notepad)的功能? 又有多少次只用到了写字板(WordPad)的功能? 即便用到了Word的某些高级功能,是否又为各种排版问题而大费周章? 第一种情况说明纯文本格式足矣,后两种情况可考虑用 标记语言Markup Language )代替。 所谓标记语言,即是在文本中规定一些特殊的语法标记,从而将普通文本结构化。 最常见的标记语言是广泛用于互联网的HTML和XML(Word 2003也开始支持XML)。 此外,广泛运用于学术报告和科技论文的 LaTeX 也是一种标记语言,在处理排版、图表、文献等方面远胜Word,当然学习门槛也远比后者为高。 近年来, TextileMarkDownreStructuredText轻量级标记语言Lightweight Markup Language ) 开始流行。比起XML,它们更简洁、更直观,因而也更方便用纯文本编辑器生成。 本网站的以前博文是由基于XML的 DocBook 生成的, 从本文开始则采用reStructuredText。 之所以不用Word, 是因为它价格不菲(盗版也要花良心、安全、时间等成本)、 平台单一(主要运行于Windows,Mac版较难用)、格式封闭、体积较大、速度较慢、 不够安全(可能中毒)、欠缺稳定(有时崩溃)、难以用Vim编写(二进制格式)等等。 此外,Word的一大优点是“ 所见即所得 ”(WYSIWYG),但相应的缺点是“ 所得仅所见 ”。 由于内容与形式混成一体,既不利于维护,也不利于扩展。 作为对比,DocBook、LaTeX、reStructuredText等标记文本将内容与形式分离, 同一内容不仅可生成多种文件格式(如HTML、XML、PDF、ODF、RTF等),还能生成不同的样式风格; 反过来,同一样式可应用于不同的内容(Word也有模版,但弗如远甚)。

不仅类似Word的字处理器可以采用文本格式替代,类似Excel的电子表格同样如此。 (注:按说应用软件与文件格式本不应混为一谈,但由于二者关系紧密,为行文简洁本文暂不区分) 用XML结合XSLT技术,或者用CSV结合Vim插件,不仅可制作表格,还能统计数据。 如果需要轻量级数据库,不一定要用Access、SQLite或者MySQL,XML或 YAML 也许已经足够。 图形文件也不是非二进制格式不可的,不妨考虑 SVG 矢量图 或者 DOT语言 , 还可试试有趣的 ASCII Art 。 甚至声音文件也有文本形式的 ABC记谱法

相比二进制格式,文本格式的好处有很多:格式公开透明,适用各种平台和工具; 方便人工编辑、查看和搜索;利于脚本处理和版本控制; 不会因部分数据毁损而出现打不开文件的情形,等等。 这当然不是在劝说大家放弃使用以二进制文件为基础的应用软件, 毕竟后者更加易学、易用,界面也更美观,功能通常也更完备, 而是旨在说明:文本格式绝不是低级、原始或狭窄的代名词。 无论是私人的记事本、邮件、日记,还是网络的博客、论坛、维基, 或者报刊文章、论文书籍,文本格式皆可充任主力军。

醉翁之意不在酒,以上列举了纯文本的诸般优点,自然是为了给Vim更多一展身手的机会。 不过Vim对非文本文件也不是完全束手无策的。 例如,它能直接编辑zip、gzip、tar、bzip2等格式的压缩文件。 以前我一直用 KeePass 统一管理密码, 但总觉有些不便,在得知最新Vim已支持在线编辑加密文件(Blowfish算法)后, 开始有了改用Vim的打算。其实何止是压缩和加密文件,理论上对于一切已知算法的文件, Vim皆可在打开、编辑、保存之后保持原有的二进制格式。另外,假如用户熟悉某种二进制格式,在设定 “:set binary“ 后,也可直接编辑原始的二进制文件(如JPG文件)。

Vim的理念

冗长的铺垫之后,终于迎来了本文的正题:Vim到底好在哪里? 这个问题的答案既是一言难尽,也可一字道尽,那就是—— 。 手指随心而蹈之时,如奔雷闪电,快得无与伦比,快到不可理喻。 Vim何以如此之快?以在下之见,诀窍在于它秉承的理念: 减少使用鼠标、减少敲击键盘、减少手指移动、减少目光移动。

1. 减少使用鼠标

不可否认,鼠标是一项伟大的发明,直观、灵活、简便、易用。 但如同对二进制格式一样,人们对鼠标(或其他定点设备)也是过度依赖了。 大多时候,鼠标的方便是以降低效率为代价的。 在Windows下,一个常见的使用场景是:鼠标点击“开始”菜单,滑动 到某个应用后点开应用程序,在程序中继续使用鼠标操作各种菜单或工具栏。 很少人会这么做:通过键盘(Win+R)打开运行对话框,然后键入命令从而启动程序。 更少人愿意花功夫为常用的程序绑定自设的快捷键,并学习和使用程序自带的快捷键功能。 究竟有多少人不会使用除Ctrl-C(复制)和Ctrl-V(粘贴)以外的热键不得而知, 不过前不久Google的一位专家有一个惊人的发现, 九成美国互联网用户不知Ctrl-F有何功用

常识告诉我们,在使用电脑时,只有在眼、手、心三者合一的情况下才能达到最高效率, 而在频繁使用鼠标的过程中,用户的眼光在菜单、工具栏、按钮、弹出窗口与程序主版之间来回地切换, 手指在键盘和鼠标之间不断地移动,注意力不时被分散,效率因此大打折扣。比较几个最常见的操作场景:是点击“确定”或“取消”按钮快,还是用回车键或Esc键快?是把鼠标移到小叉处关闭窗口快,还是按Alt+F4、Ctrl-W或Cmd-W快?是在键盘输入时切换到鼠标以点击邻近输入框快,还是用Tab或Shift-Tab快?在切换程序时,是用鼠标在任务栏点击快,还是用Alt-Tab或Cmd-Tab快? 在文本编辑中,鼠标的弊端愈加明显。以一个简单情形为例: 光标在某行的中间,用户希望把该行与下行对调。若用鼠标,则须先将其移至行头, 选定整行,然后拖放到下一行(碰上Notepad这类不支持拖放的编辑器就更费事了)。 鼠标稍有不灵,或眼神不济,或手指不稳,都可能导致操作失误。费眼、费手、费时、费神。 换成Vim用户,在正常模式下闭目输入 ddp 三字符即可,此时前者恐怕才刚刚摸到鼠标呢。 如果把任务换成:将当前行移至最末行,请非Vim用户再用鼠标拖放试试? 他只能祈祷最末行不要距离太远,尤其不要在滚动窗口之外。 Vim用户遇此则毫无难色,一套连环四击( ddGp )便完事大吉。

Vim注重键盘的基因来自Vi,作为Unix下的一个典型应用,后者完全不支持鼠标。 这可以看成一种历史局限,但也正是这种局限迫使设计者把键盘利用到极致。 请看下图——

http://blog.zhenghui.org/img/vi-vim-cheat-sheet.gif

图中的键盘(包括上下)总共95种按键,仅1种(“\”键)未被征用,利用率高达99%。 即便如此,也远未穷尽Vim的命令。 另一参考图 更详尽些,依然只是冰山一角。

2. 减少敲击键盘

在Word下,前述交换两行文字的任务也可不用鼠标完成:先按Home键,再依次按Shift键、 End键、Ctrl-X、下方向键、Ctrl-V。只是共计八键,比Vim多了一倍有余。 论起精减Vim(Vi)键击次数的功臣,当首推其独树一帜的 多模式(multi-mode) 特征。 据我所知,编辑器中除号称Windows下TextMate的 E Text Editor 支持multi-edit模式外, 其他皆无明确的模式概念。 关于模式,常有两种误解。 一是以为Vim只有两种或三种模式,而实际上它有六种基本模式和六种衍生模式。 二是以为其他编辑器是单模式。其实,任何编辑器至少有两种模式:一种是 插入模式(insert mode),一种是命令模式(nd mode)。 每当用户按住如Ctrl、Alt、Fn、Win、d等修饰键(modifier key)时, 实际是进入了命令模式,一旦松开修饰键,便回到插入模式。由于此过程转瞬即逝, 用户往往并无模式的观念,故有人称之为 准模式(quasimode) 。 Vim也有准模式,只是并非主流。 因此, Vim与非Vi类编辑器之间的区别不在于有无模式,而在于模式能否持续 。 模式不能持续带来的一个问题是,一旦需要对文本进行连续调整时,会频繁求助修饰键 (用鼠标只会更慢)。Vim则不然,一旦通过Esc键切换到命令模式后便一直保持, 直到用户主动退出。其间所有命令不再需要多余的修饰键,自然节省了键击次数。 这颇为类似Caps Lock键的功用,即一旦开启便转为大写字母模式,不再需要Shift键的修饰。另外,一些键盘的Insert键也能从默认的插入模式转至改写模式(overtype mode)—— 相当于Vim中的替换模式(replace mode)——输入的字符将覆盖原有的字符。

修饰键的另一局限是,每键只能修饰一个普通键,这为命令的设计和使用带来了困难。 与Vim齐名的编辑器Emacs同样以功能强大、命令繁多而闻名,但由于没有显式模式, 键盘上的普通字符根本不够用,只好经常采用多个修饰键组合的命令,以致于有人戏称Emacs是 ” E sc- M eta- A lt- C trl- S hift”的缩写。 模式让Vim摆脱了修饰键的羁绊,大大扩展了命令的设计空间, 这也是Vim的命令虽多却简洁易记的根本原因。

模式是Vim初学者碰到的最早也是最大的障碍,一次次的哔哔声更令人或茫然、或沮丧。 很多人因此知难而退,殊不知翻过此山后,前面将是一马平川,任君驰骋 (参见趣味的 学习曲线图 )。 一切特别的别扭之后通常都隐藏着某种特别的自然,要克服模式的障碍,除了勤加练习外, 更重要的是理解其设计理念。模式的奥妙不用外寻,尽在其名之中。此话何解? 前面提到命令模式,那是为了方便Vim与其他编辑器对比,其实Vim相应的术语是 普通模式(normal mode)。“普通”二字可不普通,这意味着对编辑器的彻底颠覆——

在一般编辑器中,插入模式是“普通”的,命令模式是“特殊”的;
在Vi类编辑器中,命令模式是“普通”的,插入模式是“特殊”的。

这启示我们,使用Vi类编辑器的一个诀窍是: 让普通模式成为常态,让插入模式成为暂态 。 具体地说,打开Vim便默认进入普通模式,需要添加文字时才切换到插入模式, 一旦完成立刻返回普通模式(通常不正是这么用替换模式的吗?)。这就避免了用户时常错判当前模式的问题—— 当他在把脑中的思想转化为文字时,应当是插入模式; 当他正在酝酿思考、修改文字或跳转页面时,应当是普通模式。 养成习惯后自然成为下意识,不必从光标、状态栏或哔哔声来判断当前模式, 这才是更高效的用法。

进一步考察Vi的模式哲学,会发现它具有天然的合理性。除了打字员,一般人 在编辑文档时大部分时间都是用于思考、修改、浏览的,只有少部分时间在 输入全新的内容。这点对程序员而言尤其正确,设计代码、修改代码、 浏览代码的时间总是大大多于编写代码的时间。 对文字创作者而言同样成立,世上有多少人能做到文思泉涌、下笔千言、 倚马可待且一字不易呢?再天才的作家不也讲究反复推敲吗? 对那些文字“借鉴”者来说就更重要了, Ctrl-C Ctrl-V 之后, 剩下的不都是些拼拼凑凑、改头换面的活儿吗?

光有模式哲学是不够的,还得靠强大的命令体系支撑。如果在普通模式下 不能高效地完成各种任务,那么让其成为常态也是没多大意义的。 好在Vim的命令丰富而不失简洁、强大而不失灵活,常人凡能想到的编辑浏览动作, Vim都有相应的命令,并且通常不止一种。

除模式之外,避免重复动作是Vim节省按键次数的另一大法宝。 最基本的拷贝粘贴自不必说,Vim还能自动将一些改动的文字保存在寄存器 (register,相当于剪贴板)中,以供日后粘贴之用, 更可让用户将复制内容放入指定的寄存器中。

在进行文字搜索时, ; 可重复上次行内(字符)搜索, , 可反向重复上次行内搜索, n 可重复上次全局(字串)搜索, N 可反向重复上次全局搜索。在命令行模式(command-line mode)中进行文本替换时, & 可重复上次替换。 使用可视化模式(visual mode)时, gv 可恢复上次进入该模式时选定的区域。

还有更多:键入 . (小数点),便能重复上次在普通模式下的编辑命令,何其方便; 键入 @: , 便能重复上次在命令行模式下的编辑命令,何其自然 ( 注:Vim中 @ 代表回放, : 是命令行模式的切换键); 用 q 命令启动宏(macro),更能录制一系列按键动作,可随时无限次重放,何其强大。

Vim不仅能帮用户重复一次操作,还可重复多次。 在普通模式下,数字前缀可指定命令的重复次数。 如 dd 代表删除1行文字, 10dd 则将删除10行。 在命令行模式下,可对指定范围和匹配模式的行进行统一处理。 如 20,100g/the/d 表示删除第20行到第100行之间包含 the 字串的所有行。 在可视化模式下,也能对所选区域进行统一操作。 如 Vr* 将当前行的所有字符全部变成星号。

若对Vim进行适当配置,节约键击的方式更是五花八门。 比如,按Tab键便能在插入模式、命令行模式下自动完成单词, 参考的范围有当前打开的所有文件、指定的字库、程序的关键词、函数库、文件的路径等等。 利用 map 功能可以建立各种模式下的键盘映射,定义自认为更合理、更简洁的命令和缩写。 如果经常把 the 写成 teh , 可设置 abbreviate 进行自动纠正。 如此等等,不胜枚举。

狂热的Vimer都以少敲按键为荣,正如 vimgolf.com 上所说:Real Vim ninjas count every keystroke(真正的Vim忍者会数每个按键)。 普通用户倒也不必如此,不过一定要明白一件事:当你经常重复某些编辑动作的时候, 很可能一个的美妙命令正擦肩而过。假如当真无此命令,Vim也授予了你自创的权力。 每当我在Vim下的指法开始凌乱,甚至忍不住去碰鼠标的时候, 或者频繁在插入模式下修改内容的时候,总会感到Vim之神在一旁坏笑: shame on you!(译成时兴的中文网语是:你弱爆了!)

3. 减少手指移动

Vim不仅提倡少用鼠标、少敲键盘,还提倡少动手指。 显而易见,在按键次数相同的情况下,手指的移动距离越小,效率自然越高。

模式的存在使得Vim的命令不太依赖修饰键,多由字母键组成。 用户的手指无疑更青睐后者,不仅更熟悉,移动距离和扭动角度也更小。 反观Emacs,用户频繁用小指按修饰键,会产生所谓的 Emacs小指问题 , 以致于有人恨不能用脚踏板来代替修饰键(别说, 还真有 ),以解救受苦受难的小指。

除模式之外,最令Vim初学者感到不习惯的恐怕要数方向键的用法了。 在Vim的正常模式下,一般不用方向键来移动光标,取而代之的是 H(左)、J(下)、K(上)、L(右)键。 事出有因,Bill Joy当年开发Vi时所用的ADM3A键盘 ( 见图 ) 没有专门的方向键,而与H、J、K、L诸键合一。 这似乎又是历史局限带来的福利,事实证明这是Vi类编辑器高效的又一大要素。 由于四键分布在右手主键(即J键)附近,远比按方向键方便。考虑到方向键的使用频率, 如此设计大大减少了手指的移动距离。Vi这一标志性的风格,也为一些应用软件 (如mutt、Nethack)和一些网站(如Gmail、Greader)所借鉴。

Vim初学者另一个抱怨是,用来切换到普通模式的Esc键地处偏远,与Emacs用户同病相怜。 这似乎有违前面所说的原则。不过如果仔细看看ADM3A键盘就能理解了:上面 的Esc键在现代键盘的Tab键处。解决的办法有很多,我的做法是修改系统设置, 将Esc键与Caps Lock键对换(后者于我全无用处,还占到风水宝地)。

Vim有不少叠字母命令,如 ccddggyyzzZZ<<>>``''[[]]@@ 等等。 很明显,同样键入两个字母,当二者相同时手指的移动距离最小,也最省心。

4. 减少目光移动

要提高编辑效率,不仅要经济用手,还要经济用眼。 目光频繁地搜寻或切换不仅本身消耗时间,更对思路的连贯性造成干扰,导致工作效率降低。 Vim针对用户频繁的编辑或浏览的需求,提供了周到的服务,能最大限度地 减少目光搜寻时间和目光转移次数。

同样由于历史原因,Vi当初是用于终端执行的程序,没有多窗口,虽可用 Ctrl-Z 或 命令 :stop 切换到其他程序,但终究不便。因此,设计者千方百计地减少用户 离开当前窗口的机会,从而减少用户的目光和注意力的转移。

避免离开编辑窗口最自然的一个方法是,在编辑环境下完成尽可能多的任务。 例如,为了减少到终端的切换,Vim除了能编辑本地文件外,还能通过FTP、RCP、SCP、HTTP 等协议直接编辑远程文件。 又如,Vim本身的命令虽然不少,但主要是编辑方面的功能。 为弥补这一不足,Vim提供了外部命令的接口,如可通过设置 makeprg 变量来指定make程序,设置 grepprg 变量来指定grep程序,设置 helpprgkeywordprg 变量来指定帮助程序,等等。Vim更能直接执行shell命令,必要时还可读取外部命令的输出结果。 如果安装 Conque Shell 插件,甚至可以在Vim中直接运行(模拟)终端本身。

顺带提一下,虽然有人认为Vim算不得真正意义上的IDE(集成开发环境),在这方面不如 Emacs那般强大,但开发人员所需要的多文件浏览、全局搜索、代码大纲(outline)、 语法高亮、自动补全(autocomplete)、代码片段(snippet)、自动格式化、语法检验、 文本比较、编译、运行、调试、单元测试、与SCM等工具集成等功能,在Vim内部均可完成。 考虑到它无敌的编辑效率、灵活的配置、强大的脚本支持 (包括原生的Vimscript以及外来的Perl、Python、Ruby等)以及相比 一般IDE在启动速度、内存占用等方面的优势,完全称得上是开发神器。

不少人对Vim朴素得近乎寒碜的界面耿耿于心,殊不知那些花哨的界面、时髦的效果都是吸引目光、分散注意力的元凶。以前对Mac电脑印象最深的就是桌面底部那些华丽而生动的应用程序图标,可待我真正拥有以后,很遗憾地发现它们的风采完全没有展示的机会。因为最常见的应用皆有快捷键绑定,次常见的应用也可通过Quicksilver或Alfred来唤出。

在我的个人配置中,Vim是全屏显示的,且既无菜单,也无工具条,更无按钮,连滚动条都禁用,几乎称得上是零界面了。 窃以为这才是最好的界面,所有的服务都默默藏于幕后,不占用一寸屏幕资源, 不消耗一丝目光,却能在所需之时应键而出。在能自动识别人类意念的软件被发明之前, 实在很难找到比这更好的人机交互方式了。

为减少目光的移动,Vim在Vi之上新增了折叠(fold)功能,可把次要或暂不关心的文本 隐藏起来。根据实际需求,用户可选择具体的折叠方式,可手动折叠,也可按缩进、 语法、标记或比较(diff)来折叠,还可按自定义的表达式来折叠。

不少人都说Vim难学,但他们很可能忽略了一件事:Vim的在线帮助极为详尽且极为便利。 vimtutor为初学者提供了半小时的入门教程,此后用户对于任何有疑问的命令或主题,键入 :h <关键词> 即可,其中关键词部分支持 通配符。如果连命令或主题都不清楚,可试试 :helpgrep 命令。假如连帮助本身 也不会用,那就敲 :help help 吧。 总之,用户完全不必在使用Vim时查找其他的参考书籍或电子文档, 他们的目光又少了一个离开的理由。

(未完待续)

 

Share
 请您评分1星(很差)2星(不行)3星(一般)4星(不错)5星(很棒) (已有1人评分,平均分为:5.00 / 5)

27 comments to VIM之魅(上)

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

  

  

  

This blog is kept spam free by WP-SpamFree.