一、VIM的历史
1976年左右Bill Joy开发了vi,他也是伯克利大学的毕业生,后来他跟其他人一起成立了Sun Microsystems公司并成为了Sun的首席科学家。一开始Bill开发了ex,尔后开发了vi作为ex的visual interface,也就是说vi允许一次能看到一屏的文本而非一行,vi也因此得名。
“早期,当键盘和视频终端成为最新的计算机交互手段时,人们开发了VI。那时候的键盘不具有目前熟悉的全部功能键,所以,VI就设计成只需要打字机的键盘加上退出键就能完成对文本的输入和修改(现在有的还接受一些其他的键输入方式,如光标控制键)。尽管看起来受了限制,不能充分利用现代键盘新增的许多键,可是‘祸中有福’,限制带来的好处是手指不离开打字区就能完成所有的编辑工作。”
技术不断进步,需求也在不断提高,VI的各种变种也不断涌现,知名的有nvi,elvis,VIM,vile,yzis,其中移植性最好、特性最多、使用最广的当属VIM,VIM主要是Bram Moolenaar开发的。最初Bram在Amiga计算机上改进一个叫Stevie的VI版本,他称之为“Vi IMitation”。随着功能的逐渐丰富,VIM的含义也就改成了“Vi IMproved”。相比原始的VI,VIM增加的一项最重要的功能便是多级撤销,VI只支持一级撤销。
[separator]
二、VI/VIM基础知识
很多人应该都知道VI是个有模式的编辑器:编辑模式和命令模式,按ESC回到命令模式,用i或者a进入编辑模式,由于区分了模式,导致VI的命令非常简洁,而无模式编辑器比如Emacs,所有的命令都需要加上控制键Ctrl或Alt。
VI继承了ed的理念,另外也有历史原因,VI追求的是快捷——启动程序迅速,编辑文本高效,功能专注,而Emacs追求的是功能的丰富强大以及集成带来的方便。
在VIM里头:help mode可以看到VIM的所有模式,主要有如下几种:
Normal mode 即通常所谓的命令模式,在此模式使用a、i、A、I、o、O等进入Insert mode
Insert mode 即通常所谓的编辑模式,在此模式使用ESC进入Normal mode或者Ctrl-o临时进入Normal mode。
Command-line mode 命令行模式,在Normal mode下按冒号进入,按ESC取消执行命令或者回车执行命令,然后回到Normal mode。(Visual Studio.Net也添加了命令行脚本功能,幸甚)
Visual mode 即选择模式(注意跟用鼠标选择不同),用v,V,C-v或C-q进入
Select mode 鼠标选择
Replace mode 在Normal mode下按R进入,按ESC返回Normal mode,相当于Windows下命令行中按Insert键进入的覆盖模式
从VI/VIM中退出:按ESC确认返回到Normal mode,然后
:wq 保存并退出
:q! 不保存并退出
:x 退出,如果文件更改则保存
ZZ 退出,如果文件更改则保存(按住Shift,再按两次z)
VI的命令是非常具有美感的,下面是几个例子:
i 在光标前插入 I 在行首插入
a 在光标后插入 A 在行末插入
o 在下一行插入 O 在上一行插入
x 删除当前字符 X 删除前一个字符
类似的还有b,B,ge,gE,w,W,e,E,f,F,t,T,这些命令都可以用:help cmdname查到帮助。
dd 删除一行 yy 拷贝一行
h j k l 左下上右移动光标
Ctrl-w h,Ctrl-w j,Ctrl-w k,Ctrl-w l 切换到左下上右窗口
类似ed,VI/VIM的命令大多都可以带一个数字前缀或者一个数字范围,比如:
5dd 从当前行开始删除5行
5yy 从当前行开始拷贝5行
1,3d 删除1至3行
1,3y 拷贝1至3行 (.代表当前行,$代表最后一行)
d,y,c,v分别代表删除/拷贝/修改/选择
命令指定的范围,比如
int main(void)
{
......;
}
将光标放在{处,然后输入v%就可以把大括号中内容选定,然后按=就可以按照C语言格式缩排(:help =可以看到=命令的描述),%命令的作用是跳到匹配处,比如括号之间,C的宏指令#if #else #endif之间。
int some_ugly_modifier and some_ugly_name (void)
如果光标放在第一个s上,想删除到“(”为止,则输入dt(就可以了,t(的作用是跳到下一个
"("前。
dG可以从当前位置一直删除到文件末尾,因为G的作用是跳到文件最后一行。
VIM的命令可以非常快捷的做到一些复杂的编辑操作。
命令解释如下:
% 全文(“%”是“1,$”范围的缩写)
s 替换
/ 搜索字符串开始
( 左括号
\) 开始记录匹配
\d+ 一个或多个数字
\) 结束记录匹配
) 右括号
/ 搜索字符串结束
\= 把后面的表达式计算出来作为替换字符串
"(" 左括号
. 字符串连接运算符
(submatch(1