用Vi也有段历史了吧,总是记不住那些命令。但最近在客户这边不知道是怎么了,Vi熟练度暴涨,现在整天玩macro不亦乐乎。大概缘由还是找了个比较全的reference card,双面儿打印好,就放跟前儿,想干什么一定忍住别换别的编辑器,逼着自己用Vi。几个回合下来,我现在在Eclipse里都直按hjkl。。。
说笑。但是现在真是离不开Vi了。在北京的时候分析日志文件就很头痛。有的时候我们过于放任服务器上的应用,结果端下来的日志有几百兆。。。很多编辑器看见这个就趴下了。。。UE倒是还行但毕竟是盗版,不爽。而且我上学的时候就用出过UE的bug,从此基本敬而远之。Eclipse的编辑器也不错,但是要把文件搞到workspace里又嫌麻烦,即使是通过链接的方式。再说Eclipse还是太重了点。剩下能开大文件的也就是基于Scintilla的Scite和Notepad++了。Notepad++的搞笑默认字体我不太能忍。Scite倒是不错但功能又过于简单了。。。
好吧,我知道我事儿多。这不还有Vi呢么。原来不理解为什么,到底为什么要用hjkl这种诡异的方式来移动光标。其实Vi的哲学是把指令用一个字符序列来表示,并且指令可以互相组合。哎?你有没有觉得这个像什么?
我觉得像Lisp:
1. 指令(代码)即字符(数据),字符(数据)即指令(代码)。
2. 至于互相组合的指令,就像高阶函数那样,是一种过程抽象。
这样的好处是什么呢?第一点简单来说,就是由于指令本身也是数据,因此可以被编辑也便于记录;另外由于数据可以被映射为指令,你可以使用创建和操纵数据的方式去创建和操纵指令。第二点稍微高深一些,就是Vi指令体现了一种抽象的思想,其功能是作用在某个抽象层次上。
有点元编程的味道吧?我先解释第二点。想想看,在Notepad++里,假设你要对一些文件做一组相同的操作,比如你要去掉一些log文件的头部,这个操作要删掉每个文件的前39行,那你就要开始录制macro,用鼠标划上39行,或者用shift+end再加down arrow39行,然后点delete。往好了说,你有个删除当前行的快捷键ctrl+d(Eclipse里就是),那你也得按39次!
Vi呢?四个字符:39dd。什么叫抽象?这就叫抽象!原来我有一朋友讲过一事儿,她回学校看老师,到办公室看见n个老师,挨个叫:黄老师好,张老师好,王老师好。。。然后教数学的老师发话了:教你那点儿数学都忘光了吧?合并同类项:老师们好!
其实就是这么回事儿。Vi之所以神奇就因为它有个normal mode。这种模式下你按键盘输入的不是字符,而是指令。如果说删39行还体现不出差别,那么删1000行呢??用过普通编辑器的人可以想想,要删1000行怎么办:你不得不用鼠标拉滚动条,看看1000到了没有,还要小心不要划多了或者划少了。Vi的指令是可以互相组合的,像39就好像是一个高阶函数一样:39dd是删39行,39iILOVEYOU<Esc>是写39遍我爱你。。。关键是它把39这个特征抽象出来了!
接下来解释第一点。所有这些指令,包括组合指令,都可以表示为字符序列。你可以把这些指令存起来,比如存在Vi的register里,然后想用的时候拿出来用。你还可以根据需要随意修改它们。想想看在Notepad++里你一样可以录macro,但你能修改这个macro么?我相信Notepad++一定有某种内部方式,某种数据结构记录macro,可能很简单也可能很复杂,但whatever你是看不到的你也改不了。这样假设你费了挺大劲录了个删39行的macro,发现下一拨要处理的log文件都要删40行,你咋办?
Vi就方便了。你可以找到存macro的那个register - 你会发现它只存了一个字符序列 - 39dd。然后你把它改成40dd,就行了。
我举的例子简单。如果这个操作除了删几行之外再包括很多其他操作,Vi的优势会更大。用Vi的高手老是说Vi有“禅”(Zen)在里面,呵呵。我不想说那么玄,说白一点,和Lisp一样,Vi就是以极大的灵活性,应对变化。程序,软件,项目,莫不过如此。