程序员的编辑器VIM.docx
《程序员的编辑器VIM.docx》由会员分享,可在线阅读,更多相关《程序员的编辑器VIM.docx(20页珍藏版)》请在冰豆网上搜索。
程序员的编辑器VIM
程序员的编辑器——VIM
一、VIM的历史
1976年左右BillJoy开发了vi,他也是伯克利大学的毕业生,后来他跟其他人一起成立了SunMicrosystems公司并成为了Sun的首席科学家。
一开始Bill开发了ex,尔后开发了vi作为ex的visualinterface,也就是说vi允许一次能看到一屏的文本而非一行,vi也因此得名。
“早期,当键盘和视频终端成为最新的计算机交互手段时,人们开发了VI。
那时候的键盘不具有目前熟悉的全部功能键,所以,VI就设计成只需要打字机的键盘加上退出键就能完成对文本的输入和修改(现在有的还接受一些其他的键输入方式,如光标控制键)。
尽管看起来受了限制,不能充分利用现代键盘新增的许多键,可是‘祸中有福’,限制带来的好处是手指不离开打字区就能完成所有的编辑工作。
”
技术不断进步,需求也在不断提高,VI的各种变种也不断涌现,知名的有nvi,elvis,VIM,vile,yzis,其中移植性最好、特性最多、使用最广的当属VIM,VIM主要是BramMoolenaar开发的。
最初Bram在Amiga计算机上改进一个叫Stevie的VI版本,他称之为“ViIMitation”。
随着功能的逐渐丰富,VIM的含义也就改成了“ViIMproved”。
相比原始的VI,VIM增加的一项最重要的功能便是多级撤销,VI只支持一级撤销。
[separator]
二、VI/VIM基础知识
很多人应该都知道VI是个有模式的编辑器:
编辑模式和命令模式,按ESC回到命令模式,用i或者a进入编辑模式,由于区分了模式,导致VI的命令非常简洁,而无模式编辑器比如Emacs,所有的命令都需要加上控制键Ctrl或Alt。
VI继承了ed的理念,另外也有历史原因,VI追求的是快捷——启动程序迅速,编辑文本高效,功能专注,而Emacs追求的是功能的丰富强大以及集成带来的方便。
在VIM里头:
helpmode可以看到VIM的所有模式,主要有如下几种:
?
Normalmode即通常所谓的命令模式,在此模式使用a、i、A、I、o、O等进入Insertmode
?
Insertmode即通常所谓的编辑模式,在此模式使用ESC进入Normalmode或者Ctrl-o临时进入Normalmode。
?
Command-linemode命令行模式,在Normalmode下按冒号进入,按ESC取消执行命令或者回车执行命令,然后回到Normalmode。
(VisualStudio.Net也添加了命令行脚本功能,幸甚)
?
Visualmode即选择模式(注意跟用鼠标选择不同),用v,V,C-v或C-q进入
?
Selectmode鼠标选择
?
Replacemode在Normalmode下按R进入,按ESC返回Normalmode,相当于Windows下命令行中按Insert键进入的覆盖模式
从VI/VIM中退出:
按ESC确认返回到Normalmode,然后
?
:
wq保存并退出
?
:
q!
不保存并退出
?
退出,如果文件更改则保存
?
ZZ退出,如果文件更改则保存(按住Shift,再按两次z)
VI的命令是非常具有美感的,下面是几个例子:
?
i在光标前插入I在行首插入
?
a在光标后插入A在行末插入
?
o在下一行插入O在上一行插入
?
x删除当前字符X删除前一个字符
类似的还有b,B,ge,gE,w,W,e,E,f,F,t,T,这些命令都可以用:
helpcmdname查到帮助。
?
dd删除一行yy拷贝一行
?
hjkl左下上右移动光标
?
Ctrl-wh,Ctrl-wj,Ctrl-wk,Ctrl-wl切换到左下上右窗口
类似ed,VI/VIM的命令大多都可以带一个数字前缀或者一个数字范围,比如:
?
5dd从当前行开始删除5行
?
5yy从当前行开始拷贝5行
?
1,3d删除1至3行
?
1,3y拷贝1至3行(.代表当前行,$代表最后一行)
d,y,c,v分别代表删除/拷贝/修改/选择
命令指定的范围,比如
intmain(void)
{
……;
}
将光标放在{处,然后输入v%就可以把大括号中内容选定,然后按=就可以按照C语言格式缩排(:
help=可以看到=命令的描述),%命令的作用是跳到匹配处,比如括号之间,C的宏指令#if#else#endif之间。
intsome_ugly_modifierandsome_ugly_name(void)
如果光标放在第一个s上,想删除到“(”为止,则输入dt(就可以了,t(的作用是跳到下一个
“(“前。
dG可以从当前位置一直删除到文件末尾,因为G的作用是跳到文件最后一行。
VIM的命令可以非常快捷的做到一些复杂的编辑操作。
命令解释如下:
?
%全文(“%”是“1,$”范围的缩写)
?
s替换
?
/搜索字符串开始
?
(左括号
?
\)开始记录匹配
?
\d+一个或多个数字
?
\)结束记录匹配
?
)右括号
?
/搜索字符串结束
?
\=把后面的表达式计算出来作为替换字符串
?
“(“左括号
?
.字符串连接运算符
?
(submatch
(1)+1)把第一个匹配的结果加一作为一个整体返回
?
.”)”添上右括号
?
/g替换字符串结束,g表示替换每一行的所有匹配结果。
?
:
setve=all使得光标可以定位到屏幕任何位置(缺省下VIM的光标只能放在行内的字符上)
?
gg到文件第一行
?
/\s\+&\s*$找以&结尾的行,&前至少一个空白字符,后0或多个空白字符
?
qa记录宏到寄存器a
?
D删除到行尾
?
78|定位到第78列
?
i&插入&并返回到命令模式
?
n查找下一个&
?
q停止记录宏
?
10000@a执行一万遍寄存器a中保存的命令
?
:
setve=”"恢复ve缺省值
三、编程辅助
既然是程序员的编辑器,自然要show一下它的编程辅助功能。
(1)ctags,cscope
现在的IDE都提供了类、函数的索引功能,可以方便的找到某个类或者函数的在哪里定义的,VIM这方面可以利用ctags、cscope做到,Exuberantctags支持的语言种类非常多,UltraEdit的tags功能也是利用的ctags。
cscope只支持C,它能实现SourceInsight的一些功能,比如查找某个函数调用了哪些函数,某个函数被哪些函数调用。
VIM对这两个工具集成的非常好,利用它们就可以在源文件中方便的跳转搜索类和函数了。
Reference:
?
Exuberantctags
?
http:
//iamphet.nm.ru/cscope/cscopeforWin32
?
:
helpctags
?
:
helpcscope
(2)multiwindow,multibuffer,multitabpage
一个buffer对应一个文件,它可以对应多个window,这样可以方便的对照编辑一个文件的不同部分,tabpage跟现在许多编辑器上常见的标签页意义并不一样,可以将tabpage理解为一个windows的容器,这样如果想新建一个窗口编辑文件但又不想打乱现在的多窗口布局,那么就可以新开一个tabpage,把新窗口放到这个新的tabpage里头。
tabpage是VIM7.0不久前新增的特性,目前VIM7.0还未正式发布。
(此文发表至PConline时,已经正式发布。
)
?
Reference:
?
:
helpwindows
?
:
helpbuffers
?
:
helptabpage
(3)语法高亮
VIM发行版里带了450多种语言的语法高亮,在其主页vim.org上还可以找到更多。
?
Reference:
?
:
helpsyntax
(4)自动缩进
在打开自动缩进选项后,VIM会自动的控制缩进,比如输入{自动向右缩进一个tab字符(具体用什么缩进可以配置),输入}自动回退缩进。
使用=命令可以对选择的程序块排版缩进,这对于整理代码非常有帮助。
另外对选择的块用>>和<<命令可以很方便的控制一个程序块的缩进。
?
Reference:
?
:
helpcindent
?
:
helpautoindent
?
:
helpsmartindent
(5)类和函数列表
taglist等插件可以提供很方便的类和函数列表功能。
(6)自动完成
VIM在Insertmode下输入一个单词的前几个字符,然后用Ctrl-p或者Ctrl-n就可以列出以这些字符开头的单词,特别在配置了ctags后也能列出头文件中的符号,特别方便,除此外VIM还有行自动完成、文件名自动完成等,这点即使是现在强大的IDE也未免不足。
如果设置了如下选项:
?
:
setwildmode=list:
full
?
:
setwildmenu
则在命令行打开文件或者输入命令时按Tab(以输入字符为前缀补全)或者Ctrl-d(列出包含输入字符的所有匹配项目)自动补全,这一功能大大降低了VIM的使用难度。
另外有许多插件可以实现许多IDE中的自动完成类成员的功能,当然,这个功能还比不上Eclispe、VisualStudio等IDE中的强大,这一点是VIM比较可惜的地方。
VIM7.0引入了OmniCompletion,可以自定义匹配完成函数,也许可以弥补这个缺陷。
?
Reference:
:
help‘complete’
?
:
helpomni-completion
(7)folding
VIM支持折叠代码,还可以根据文件中特殊的标记对文件中的行折叠,可以实现Outline视图,这可以极大的方便编辑很大的文件。
Reference:
:
helpfold
(8)quickfix
许多人对于UNIX开发的印象都是“编辑代码,退出编辑器,编译,发现错误,记录出错信息,遍辑代码,退出编辑器,编译,用gdb调试,再编辑代码……”,这是古老的VI时代的事情了,有了VIM的quickfix特性,可以在VIM里编译然后直接跳到编译出错的行,这个反复的过程无需退出编辑器,而且VIM的quickfix特性可以经配置后支持不同的编译器以及不同的语言:
只要编译器在出错信息里包含文件名和行号。
不过比较遗憾的是VIM对于集成调试支持还不好,有些项目尝试集成GDB到VIM,比如http:
//skawina.eu.org/mikolaj/vimgdb/和http:
//www.volny.cz/zellerin/gdbvim/,在http:
//www.vim.org/search.php中的scripts处搜索gdb也可以找到一些插件.这方面Emacs的GUD(GrandUnifiedDebugger)调试界面要更强大,毕竟GCC/GDB/Emacs是一家。
Reference:
:
helpquickfix
(9)autocommand
VIM可以在某些事件发生时比如打开文件、保存文件、切换窗口时自动执行一些VIM命令,VIM的许多插件都利用了这个功能。
常用的一种情况是把某种文件后缀指定到一种文件格式上,比如*.jv指定到Java文件格式,这样在每次打开.jv类型的文件时自动使用Java的语法高亮:
:
autocmdBufNewFile,BufRead*.jv:
setft=Java
Reference:
:
helpautocmd.txt
(10)modeline
在编辑文件时常常指定一些选项,比如缩进量、是否将制表符转换成空格等,每次手动指定这些选项很麻烦,写到vimrc中却又成了全局选项,而且换了一份VIM,原有的设置就丢失了。
VIM可以识别文件中的特殊行,自动设置一些选项,下面是写在C源文件开头的一个modeline示例:
?
/*vi:
settw=0ts=8sw=8noetnowrapft=cfdm=syntax:
*/
?
/*
?
*File:
xxxx.c
?
*Author:
xxx
?
*/
四、强大方便的帮助系统
使用了那么多软件,只有VIM和Emacs的帮助系统给笔者方便快捷的感觉,大部分软件的帮助往往是摆设而已,而VIM的帮助的确是考虑到了自己“help”的身份,利用它能很方便容易的找到想要的东西。
VIM的帮助是超链接形式的,它使用的就是tags,所以可以跟ctags功能一样按Ctrl-]跳转到链接所指处,按Ctrl-t返回。
?
:
help打开帮助首页,这个首页分类非常清楚
?
:
helpcmd查找normalmode命令,比如:
helpdd
?
:
helpi_cmd查找insertmode命令,比如:
helpi_Ctrl-y
?
:
help:
cmd查找command-line命令,比如:
help:
s
?
:
help‘option查找选项,比如:
help‘tabstop
如果你记不清命令或者选项的全称,那么可以利用Tab或者Ctrl-d的自动补全功能。
:
helpoptions可以找到所有的选项说明
查看某一个选项的值(实际上选项是VIM中的一种变量,类似SHELL的变量以$符号引用,VIM的选项以&引用,另外VIM的寄存器以@引用):
:
echo&tabstop
五、其它高级功能
(1)寄存器
VIM里面的寄存器可以用来保存拷贝的文本、记录的宏、设置的书签等等,一般的编辑器都只有一个剪切板(MSOffice加入了多个剪切板),而VIM和Emacs编辑器中的多寄存器可以实现多个剪切板的功能。
VIM中有九类寄存器:
?
无名寄存器”最近一次删除/修改/替换操作的文本都会放入这个寄存器
?
10个数字寄存器0-9拷贝或者删除的文本存入这些寄存器,这些寄存器是循环使用的,在每次存入内容到寄存器1时,原有的内容会依次存入到后一个寄存器中。
?
小删除寄存器–删除内容少于一行时放入这个寄存器。
?
26个命名寄存器a-zA-Z大小写无关。
这些寄存器可以在拷贝或者删除等操作中指定使用。
?
四个只读寄存器:
.%#特殊用途。
?
表达式寄存器=特殊用途。
?
选择和拖放寄存器*+~用于与系统剪切板交互,以及接收拖放操作的内容。
?
黑洞寄存器_放到这里面的内容都被丢弃,这样可以删除或拷贝时不影响其它寄存器。
?
最后一次搜索模式寄存器/保存最后一次搜索的正则表达式。
使用:
reg命令可以看到所有寄存器中的内容,使用”+y或者”*y可以将visualmode下选择
的内容拷贝到系统剪切板,使用”+p或者”*p可以将剪切板中的内容粘贴到VIM中,如果打开了
mswin特性的话则在insertmode下使用Ctrl-x,Ctrl-v,Ctrl-c了。
Reference:
:
helpregisters
(2)宏
Normalmode下按q,指{a-zA-Z0-9″}37个寄存器中的一个,然后可以进行任何操作,包括在模式间切换,最后在Normal模式下按q可以结束宏录制,用@命令可以应用这个宏,命令前可以带数字前缀表示执行多少次这个宏。
Reference:
:
helpq
(3)书签
Normalmode下按m作书签,指26个命名寄存器中的一个,然后可以用’或者`跳到书签处。
Reference:
:
helpm
(4)映射
VI/VIM可以将某个按键序列映射到一个命令序列上,比如在配置文件.vimrc(Windows下是_vimrc)中写入
mapi=strftime(”%Y-%m-%d”)
即可以在Normalmode下插入当前日期。
Reference:
:
help:
map
(5)缩写
VI/VIM支持用一个缩写字符串代替一个长的字符串,比如
:
abhwhelloworld
然后在Insertmode下输入“hw”(不包括引号)后VIM就自动替换成了“helloworld”。
这里展示一个Emacs下abbrev功能的动画(没错,是Emacs的):
http:
//www.bloomington.in.us/~brutt/msf-abbrev.html
http:
//www.bloomington.in.us/~brutt/msf-abbrev-demo.gif
Reference:
:
help:
ab
(6):
s//和:
g//,:
!
g//
这两个命名加上正则表达式,常常能完成非常复杂的编辑任务,可以毫不夸张地说是VIM的两柄瑞士军刀。
:
s是替换操作,:
g是查找匹配模式的行,:
!
g是查找不匹配模式的行。
http:
//www.vim.org/tips/tip.php?
tip_id=1063这个tip可以把:
g找到的行拷贝到一个新的缓冲区中,非常有用。
?
Reference:
:
help:
s
?
:
help:
g
(7)插件
VIM自己有脚本语言,另外也支持用Perl/Python/Tcl/Ruby/Scheme编写插件,这些插件极大的丰富了VIM的功能。
(8)colorscheme
VIM有许多配色方案,下面这个链接有许多配色方案效果的图样:
http:
//www.cs.cmu.edu/~maverick/VimColorSchemeTest/
(9)二进制编辑
VIM可以利用xxd实现二进制编辑,不过这项功能还是不够好用。
(10)sign
sign指在编辑窗口的最左列显示一个标记,利用这个功能能实现很多IDE中的书签标记或者断点标记。
Reference:
:
helpsign
六、VIMScripts
VIMscript包含几大类:
?
colorscheme配色方案
?
ftpluginFiletype插件,特定语言语法的设置,比如如何识别注释
?
syntax语法高亮的配色
?
plugin提供额外功能的插件,比如智能完成、缓冲区管理。
VIM的script安装非常简单,下载的script文件或者压缩包里头都有安装说明,在VIM的安装目录(比如C:
\VIM64)下面有一个vimfiles目录,把script放到vimfiles目录下即可。
对于多用户系统,可以在HOME目录(一般是c:
\DocumentsandSettings\)下面建立一个vimfiles目录,把script放置到这里。
下面是一些好用的VIM插件,具体使用办法请参考各自。
vim文件头部的注释。
BufExplorer.vim*****
http:
//www.vim.org/scripts/script.php?
script_id=42
这个插件可以使编辑多文件更加方便,装完插件后Normalmode下输入\be即可打开缓冲区列表,光标放置在某一个文件上按回车即可打开这个文件,而缓冲区列表自动关闭。
Taglist.vim*****
http:
//www.vim.org/scripts/script.php?
script_id=273
这个插件可以实现类或者函数列表功能,支持C/C++,java,perl,python,tcl,sql,php等语言,它可以在VIM中创建一个窗口,列出编辑的源文件中的类、函数、变量定义列表,而且更方便的是这个列表也插入在了右键菜单中,分类存放,访问非常方便。
TabBar.vim***
http:
//www.vim.org/scripts/script.php?
script_id=1338
这个插件实现了类似UltraEdit中的标签页的功能,而且能通过Alt-来切换,代表1-9。
minibufexpl.vim***
http:
//www.vim.org/scripts/script.php?
script_id=159
实现了类似UltraEdit中的标签也功能。
c.vim***
http:
//www.vim.org/scripts/script.php?
script_id=213
提供了很多便于C/C++编程的功能,比如文件头模版,代码片断等。
CRefVim**
http:
//www.vim.org/scripts/script.php?
script_id=614
为VIM定制的C参考手册,这样对于语法或者函数不清楚的地方可以方便的查找了。
latex-suite*****
http:
//www.vim.org/scripts/script.php?
script_id=475
http:
//vim-
提供了很多便于编辑TeX/LaTeX文件的功能,比如在VIM里面编译或者预览、自动插入TeX标记等。
word_complete.vim***
http:
//www.vim.org/scripts/script.php?
script_id=73
Insert模式下在输入的时候自动补全单词,如果补全正确可以按Tab键接受,否则可以不管它继续输入或者按Ctrl-n,Ctrl-p切换补全。
注意是输入三个字符后才开始补全。
VimJDE
http:
//www.vim.org/scripts/script.php?
script_id=1213
支持C/C++等的自动完成(需要VIM7.0,编译时打开+ruby特性).
cppcomplete.vim**
http:
//www.vim.org/scripts/script.php?
script_id=527
能自动完成C/C++/Java的结构或类成员,注意它的快捷键是Alt-l(字母L)不是Alt-i。
TheNEADCommenter**
http:
//www.vim.org/scripts/script.php?
script_id=1218
在许多类型的文件中方便的加上注释或者取消注释。
winmanager
http:
//www.vim.org/scripts/script.php?
script_id=95
把标准的FileExplorer以及BufferExplorer插件集成在一起,提供现代编辑器中常见的文件列表和缓冲区列表功能。
sket