程序员的编辑器——VIM

程序员的编辑器——VIM

一、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<motion>,y<motion>,c<motion>,v<motion>分别代表删除/拷贝/修改/选择<motion>

  命令指定的范围,比如
  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) + 1) 把第一个匹配的结果加一作为一个整体返回 
.")" 添上右括号 
/g 替换字符串结束,g表示替换每一行的所有匹配结果。 
:set ve=all 使得光标可以定位到屏幕任何位置(缺省下VIM的光标只能放在行内的字符上) 
gg 到文件第一行 
/\s\+&\s*$ 找以&结尾的行,&前至少一个空白字符,后0或多个空白字符 
qa 记录宏到寄存器a 
D 删除到行尾 
78| 定位到第78列 
i&<ESC> 插入&并返回到命令模式 
n 查找下一个& 
q 停止记录宏 
10000@a 执行一万遍寄存器a中保存的命令 
:set ve="" 恢复ve缺省值 


三、编程辅助

  既然是程序员的编辑器,自然要show一下它的编程辅助功能。

  (1) ctags,cscope

   现在的IDE都提供了类、函数的索引功能,可以方便的找到某个类或者函数的在哪里定义的,VIM这方面可以利用ctags、cscope做到, Exuberant ctags支持的语言种类非常多,UltraEdit的tags功能也是利用的ctags。cscope只支持C,它能实现Source Insight的一些功能,比如查找某个函数调用了哪些函数,某个函数被哪些函数调用。VIM对这两个工具集成的非常好,利用它们就可以在源文件中方便的 跳转搜索类和函数了。

  Reference:

  http://ctags.sourceforge.net Exuberant ctags 
  http://iamphet.nm.ru/cscope/ cscope for Win32 
  :help ctags 
  :help cscope 
  (2)multi window,multi buffer,multi tab page

   一个buffer对应一个文件,它可以对应多个window,这样可以方便的对照编辑一个文件的不同部分,tab page跟现在许多编辑器上常见的标签页意义并不一样,可以将tab page理解为一个windows的容器,这样如果想新建一个窗口编辑文件但又不想打乱现在的多窗口布局,那么就可以新开一个tab page,把新窗口放到这个新的tab page里头。tab page是VIM 7.0不久前新增的特性,目前VIM 7.0还未正式发布。(此文发表至PConline时,已经正式发布。)

  Reference: 
  :help windows 
  :help buffers 
  :help tabpage 
  (3) 语法高亮

  VIM发行版里带了450多种语言的语法高亮,在其主页vim.org上还可以找到更多。

  Reference: 
  :help syntax 
  (4) 自动缩进

  在打开自动缩进选项后,VIM会自动的控制缩进,比如输入自动回退缩进。使用=命令可以对选择的程序块排版缩进,这对于整理代码非常有帮助。另外对选择的块用>>和<<命令可以很方便的控制一个程序块的缩进。

  Reference: 
  :help cindent 
  :help autoindent 
  :help smartindent 
  (5) 类和函数列表

  taglist等插件可以提供很方便的类和函数列表功能。

  (6) 自动完成

   VIM在Insert mode下输入一个单词的前几个字符,然后用Ctrl-p或者Ctrl-n就可以列出以这些字符开头的单词,特别在配置了ctags后也能列出头文件中的 符号,特别方便,除此外VIM还有行自动完成、文件名自动完成等,这点即使是现在强大的IDE也未免不足。

  如果设置了如下选项:

  :set wildmode=list:full 
  :set wildmenu 
  则在命令行打开文件或者输入命令时按Tab(以输入字符为前缀补全)或者Ctrl-d(列出包含输入字符的所有匹配项目)自动补全,这一功能大大降低了VIM的使用难度。

   另外有许多插件可以实现许多IDE中的自动完成类成员的功能,当然,这个功能还比不上Eclispe、Visual Studio等IDE中的强大,这一点是VIM比较可惜的地方。VIM 7.0引入了Omni Completion,可以自定义匹配完成函数,也许可以弥补这个缺陷。

  Reference: :help 'complete' 
  :help omni-completion 
  (7) folding

  VIM支持折叠代码,还可以根据文件中特殊的标记对文件中的行折叠,可以实现Outline视图,这可以极大的方便编辑很大的文件。

  Reference: :help fold

  (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(Grand Unified Debugger)调试界面要更强大,毕竟GCC/GDB/Emacs是一家。

  Reference: :help quickfix

  (9)auto command

   VIM可以在某些事件发生时比如打开文件、保存文件、切换窗口时自动执行一些VIM命令,VIM的许多插件都利用了这个功能。常用的一种情况是把某种文 件后缀指定到一种文件格式上,比如*.jv指定到Java文件格式,这样在每次打开.jv类型的文件时自动使用Java的语法高亮:

  :autocmd BufNewFile, BufRead *.jv :set ft=Java

  Reference: :help autocmd.txt

  (10)mode line

   在编辑文件时常常指定一些选项,比如缩进量、是否将制表符转换成空格等,每次手动指定这些选项很麻烦,写到vimrc中却又成了全局选项,而且换了一份 VIM,原有的设置就丢失了。VIM可以识别文件中的特殊行,自动设置一些选项,下面是写在C源文件开头的一个mode line示例:

/* vi:set tw=0 ts=8 sw=8 noet nowrap ft=c fdm=syntax: */ 
/* 
* File: xxxx.c 
* Author: xxx 
*/ 




四、强大方便的帮助系统

  使用了那么多软件,只有VIM和Emacs的帮助系统给笔者方便快捷的感觉,大部分软件的帮助往往是摆设而已,而VIM的帮助的确是考虑到了自己“help”的身份,利用它能很方便容易的找到想要的东西。

  VIM的帮助是超链接形式的,它使用的就是tags,所以可以跟ctags功能一样按Ctrl-]跳转到链接所指处,按Ctrl-t返回。

:help 打开帮助首页,这个首页分类非常清楚 
:help cmd 查找normal mode命令,比如:help dd 
:help i_cmd 查找insert mode命令,比如:help i_Ctrl-y 
:help :cmd 查找command-line命令,比如:help :s 
:help 'option 查找选项,比如:help 'tabstop 
如果你记不清命令或者选项的全称,那么可以利用Tab或者Ctrl-d的自动补全功能。 
  :help options 可以找到所有的选项说明

  查看某一个选项的值(实际上选项是VIM中的一种变量,类似SHELL的变量以$符号引用,VIM的选项以&引用,另外VIM的寄存器以@引用):

  :echo &tabstop

五、其它高级功能

  (1)寄存器

  VIM里面的寄存器可以用来保存拷贝的文本、记录的宏、设置的书签等等,一般的编辑器都只有一个剪切板(MS Office加入了多个剪切板),而VIM和Emacs编辑器中的多寄存器可以实现多个剪切板的功能。VIM中有九类寄存器:

无名寄存器 " 最近一次删除/修改/替换操作的文本都会放入这个寄存器 
10个数字寄存器 0-9 拷贝或者删除的文本存入这些寄存器,这些寄存器是循环使用的,在每次存入内容到寄存器1时,原有的内容会依次存入到后一个寄存器中。 
小删除寄存器 - 删除内容少于一行时放入这个寄存器。 
26个命名寄存器 a-zA-Z 大小写无关。这些寄存器可以在拷贝或者删除等操作中指定使用。 
四个只读寄存器 :.%# 特殊用途。 
表达式寄存器 = 特殊用途。 
选择和拖放寄存器 *+~ 用于与系统剪切板交互,以及接收拖放操作的内容。 
黑洞寄存器 _ 放到这里面的内容都被丢弃,这样可以删除或拷贝时不影响其它寄存器。 
最后一次搜索模式寄存器 / 保存最后一次搜索的正则表达式。 
  使用:reg命令可以看到所有寄存器中的内容,使用"+y或者"*y可以将visual mode下选择
  的内容拷贝到系统剪切板,使用"+p或者"*p可以将剪切板中的内容粘贴到VIM中,如果打开了
  mswin特性的话则在insert mode下使用Ctrl-x,Ctrl-v,Ctrl-c了。

  Reference: :help registers

  (2) 宏
   Normal mode下按q<reg>,<reg>指37个寄存器中的一个,然后可以进行任何操作,包括在模式间切换,最后在Normal模 式下按q可以结束宏录制,用@<reg>命令可以应用这个宏,命令前可以带数字前缀表示执行多少次这个宏。

  Reference: :help q

  (3) 书签

  Normal mode下按m<reg>作书签,<reg>指26个命名寄存器中的一个,然后可以用'<reg>或者`<reg>跳到书签处。

  Reference: :help m

  (4) 映射

  VI/VIM可以将某个按键序列映射到一个命令序列上,比如在配置文件.vimrc(Windows下是_vimrc)中写入

map <F6> <ESC>i<C-R>=strftime("%Y-%m-%d")<ESC><ESC>

  即可以在Normal mode下插入当前日期。

  Reference: :help :map

  (5) 缩写

  VI/VIM支持用一个缩写字符串代替一个长的字符串,比如

  :ab hw hello world

  然后在Insert mode下输入“hw ”(不包括引号)后VIM就自动替换成了“hello world”。这里展示一个Emacs下abbrev功能的动画(没错,是Emacs的):

  http://www.bloomington.in.us/~brutt/msf-abbrev.html
  

  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) color scheme

  VIM有许多配色方案,下面这个链接有许多配色方案效果的图样:http://www.cs.cmu.edu/~maverick/VimColorSchemeTest/

  (9) 二进制编辑

  VIM可以利用xxd实现二进制编辑,不过这项功能还是不够好用。

  (10) sign

  sign指在编辑窗口的最左列显示一个标记,利用这个功能能实现很多IDE中的书签标记或者断点标记。

  Reference: :help sign

六、VIM Scripts

  VIM script包含几大类:

  color scheme 配色方案 
  ftplugin File type插件,特定语言语法的设置,比如如何识别注释 
  syntax 语法高亮的配色 
  plugin 提供额外功能的插件,比如智能完成、缓冲区管理。 
   VIM的script安装非常简单,下载的script文件或者压缩包里头都有安装说明,在VIM的安装目录(比如C:\VIM64)下面有一个 vimfiles目录,把script放到vimfiles目录下即可。对于多用户系统,可以在HOME目录(一般是c:\Documents and Settings<USER_NAME>\)下面建立一个vimfiles目录,把script放置到这里。

  下面是一些好用的VIM插件,具体使用办法请参考各自。vim文件头部的注释。

  BufExplorer.vim *****
  http://www.vim.org/scripts/script.php?script_id=42
  这个插件可以使编辑多文件更加方便,装完插件后Normal mode下输入\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-<n>来切换,<n>代表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-latex.sf.net/
  提供了很多便于编辑TeX/LaTeX文件的功能,比如在VIM里面编译或者预览、自动插入TeX标记等。

  word_complete.vim ***
  http://www.vim.org/scripts/script.php?script_id=73
  Insert模式下在输入的时候自动补全单词,如果补全正确可以按Tab键接受,否则可以不管它继续输入或者按Ctrl-n,Ctrl-p切换补全。注意是输入三个字符后才开始补全。

  Vim JDE
  http://www.vim.org/scripts/script.php?script_id=1213
  支持C/C++等的自动完成(需要VIM 7.0,编译时打开+ruby特性).

  cppcomplete.vim **
  http://www.vim.org/scripts/script.php?script_id=527
  能自动完成C/C++/Java的结构或类成员,注意它的快捷键是Alt-l(字母L)不是Alt-i。

  The NEAD Commenter **
  http://www.vim.org/scripts/script.php?script_id=1218
  在许多类型的文件中方便的加上注释或者取消注释。

  winmanager
  http://www.vim.org/scripts/script.php?script_id=95
  把标准的File Explorer以及Buffer Explorer插件集成在一起,提供现代编辑器中常见的文件列表和缓冲区列表功能。

  sketch.vim ***
  http://www.vim.org/scripts/script.php?script_id=705
  Draw with mouse: boxes, arrows, lines, fills. Transparent/opaque drag and drop.照着它的教程做一遍,你就会震撼于它的创意了。

  DrawIt.vim **
  http://www.vim.org/scripts/script.php?script_id=40
  可以方便的画连线图。

  MultipleSearch ***
  http://www.vim.org/scripts/script.php?script_id=479
  MultipleSearch2.vim ***
  http://www.vim.org/scripts/script.php?script_id=1183
  Mark.vim ***
  http://www.vim.org/scripts/script.php?script_id=1238
  otf.vim **
  http://www.vim.org/scripts/script.php?script_id=634
  这些插件可以同时高亮显示多次搜索结果,这个特性非常有利于显示代码中某些变量或函数的调用位置。

  SearchComplete.vim *
  http://www.vim.org/scripts/script.php?script_id=474
  可以用/搜索时按Tab补全要搜索的单词。

  Vim Intellisense
  http://insenvim.sourceforge.net
  顾名思义,此插件用于给VIM提供智能完成功能,支持C++,C#,Java,JSP,HTML,SQL,XML,笔者安装后一直懒得配置,也就没用上。

  project
  http://www.vim.org/scripts/script.php?script_id=69
  提供一些IDE功能,看介绍似乎很不错。

  JavaBrower
  http://www.vim.org/scripts/script.php?script_id=588
  提供文件中Java类的树状列表。

  vimspell
  http://www.vim.org/scripts/script.php?script_id=465
  ispell or aspell based spell checker with fly-spelling。

  cream
  http://cream.sourceforge.net/
  一套配置文件,可以把VIM的界面改成CUA(Common User Access)模型,降低VIM的学习难度,个人不推荐这种做法,不过其中有些高级配置值得学习(有意思的是Emacs也有类似的项目: Easymacs,EmacsW32)。

  IComplete
  http://icomplete.sf.net
  搭配VIM 7.0的Omni Complete,可以做到C/C++的智能完成功能.

七、VIM资源

  http://www.vim.org VIM主页,有许多scripts和tips,查找插件的第一去处 
  http://newsmth.net 新水木BBS的VIM版,有很多VIM爱好者可以讨论 
  http://vimdoc.sf.net VIM文档工程 
  http://vcd.gro.clinux.org/ VIM中文文档 
  http://tnerual.eriogerg.free.fr/vim.html VIM Quick Reference Card 
  http://edyfox.codecarver.org/ newsmth VIM版版主的wiki 
  http://learn.tsinghua.edu.cn:8080/2001315450/ 王垠的个人主页 
  《学习vi编辑器(第六版)》机械工业出版社译,O'Reilly 
  几个学习正则表达式的工具(from happyvim at newsmth)

  http://weitz.de/regex-coach/ Regex Coach 
  http://jregexptester.sourceforge.net/ JRegexp Tester 
  http://www.regexbuddy.com/ Regex Buddy 
  http://www.yzis.org/ yzis是一个新的VI变种,它支持变宽字体,目前功能还不够丰富。

  http://ex-vi.sourceforge.net/ 传统VI的源代码

八、编译安装最新CVS版的VIM

  1. 获取源代码

  cvs -z3 -d:pserver:anonymous@cvs.sf.net:/cvsroot/vim co vim7

  源代码位于当前目录的vim7目录下面,假设安装目标在d:\work\program\Vim\vim70b

  2.编译

  注意重新编译前最好clean一下,确保“*obj*”目录被删除了,否则可能出现莫名其妙的问题,比如链接时找不到一些函数。下面是一个批处理脚本:

  rem --------------------------------------------->
  @echo off
  set path=c:\winnt;c:\winnt\system32
  vcvars32.bat
  cd vim7\src
  rem .sh文件跟其它程序有关联,避免运行VC的link时执行了link.sh
  ren link.sh link.sh.old
  @echo clean...
  rem clean时加入这些选项是因为$(OUTDIR)和$(OBJDIR)根据这些标志合成的,
  rem 如果不加这些标志, 在rmdir /s /q时会找不到目录, 从而没有删除掉。
   nmake -f Make_mvc.mak clean FEATURES=HUGE GUI=yes OLE=yes MBYTE=yes IME=yes GDYNAMIC_IME=yes GIME=yes PERL=d:\work\program\Perl DYNAMIC_PERL=yes PERL_VER=58 PYTHON=d:\work\program\Python24 DYNAMIC_PYTHON=yes PYTHON_VER=24 SNIFF=yes CSCOPE=yes CPUNU=i586 DEBUG=yes MAP=lines
  @echo build big debug version...
  nmake -f Make_mvc.mak all FEATURES=HUGE GUI=yes OLE=yes MBYTE=yes IME=yes GDYNAMIC_IME=yes GIME=yes PERL=d:\work\program\Perl DYNAMIC_PERL=yes PERL_VER=58 PYTHON=d:\work\program\Python24 DYNAMIC_PYTHON=yes PYTHON_VER=24 SNIFF=yes CSCOPE=yes CPUNU=i586 DEBUG=yes MAP=lines
  ren link.sh.old link.sh
  @echo done.
  pause
  @echo on
  rem <-----------------------------------------------


  对于MinGW,

  @echo off
  @echo clean...
  make -f Make_ming.mak clean DEBUG=yes
  @echo make...
   make -f Make_ming.mak all GUI=yes OLE=yes MBYTE=yes IME=yes GDYNAMIC_IME=yes GIME=yes PERL=d:/work/program/Perl DYNAMIC_PERL=yes PERL_VER=58 PYTHON=d:/work/program/Python24 DYNAMIC_PYTHON=yes PYTHON_VER=24 CSCOPE=yes CPUNU=i586 DEBUG=yes MAP=lines
  @echo done.
  pause
  @echo on

  如果发现MinGW编译出来的gvimd.exe非常大(约4~5MB),可以用MinGW自带的strip处理一下。

  3. 安装

   如果你的系统先前有一份不同版本的VIM,那么需要先卸载掉(运行vim\vimXX\uninstal.exe,或者在拷贝完文件后运行新版VIM的 install.exe,它也会提示卸载旧版本),最近的VIM 7 CVS代码安装目录也从vim70aa转变到vim70b,也需要卸载原先的vim70aa,这一步主要是删除一些注册表项。

  如果你从CVS上更新代码后,install要求的安装目录名字没有改变(也就是说VIM版本没变),那么不需要卸载原先的版本,直接拷贝文件覆盖即可,如果你想更改目录安装的话也需要卸载。

  cd vim7
  dir /s/b *.exe
  dir /s/b *.dll
  xcopy vim7\runtime d:\work\program\vim\vim70b (vim70b是一个目录)
  copy vim7\src\*.exe d:\work\program\Vim\vim70b
  copy vim7\src\xxd\xxd.exe d:\work\program\Vim\vim70b
  copy vim7\src\vimtbar.dll d:\work\program\Vim\vim70b
  copy vim7\src\GvimExt\gvimext.dll d:\work\program\Vim\vim70b
  copy vim7\src\VisVim\Visvim.dll d:\work\program\Vim\vim70b

   然后进入vim70b目录运行install.exe,如果发现一个DOS窗口一闪而逝,那么很可能是建立的vim70b目录名不对,比如笔者前几天升 级后使用的仍然是vim70aa目录名,在DOS窗口中运行install.exe它就提示需要在vim70b目录下运行,将vim70aa改名即可。 install.exe的源代码是vim7\src\dosinst.c,这里面修改了注册表,并拷贝一些文件到WINDOWS目录下等等。

  4.善后

  视情况你需要更新PATH环境变量、文件关联、_vimrc中的路径名等,并将diff.exe,ctags.exe,cscope.exe拷贝到vim70b下面。

  最后运行gvimd.exe,键入:ver开始享受VIM吧。

九、一份vimrc配置文件(注:原文如此,不太清楚作者所要表达的信息)

十、VIM的不足

   前面已经提到,VIM在自动完成和集成调试方面还比不上现代的许多IDE,另外VIM对二进制编辑还没有UltraEdit强大,对于现在流行的重构, VIM也支持不力,但是作为一个文本编辑器而言,堪比的只有Emacs,另外Visual SlickEdit也很强大,不过它是商业软件。VIM也可以嵌入到Visual Studio中作为编辑器,另外Code Forge,Eclipse,NetBeans,Sun Visual Workshop等也提供了一定的VIM支持或者键绑定。

  Reference: 
  :help workshop 
  :help netbeans 
  :help debugger 
十一、工作中使用VI的问题

:w保存后,:q退出时,提示“E138: 不能写入 .viminfo 文件”。 
解决办法:将.viminfo.tmp临时文件删除掉即可。

其他信息:
vim有三种模式-普通(可视命令)模式,命令行模式,编辑模式。启动vim后在任何模式下按Esc键进入到普通模式。普通模式下输入 : 回车进入命令行模式,此时vim最窗口最下面一行为 : 后面可以输入命令行命令.在执行任何命令前要确保在相应的模式下。
1.启动与退出 
1)vi filename (启动vim)
2)命令行模式下 :wq=> 保存并退出,:q!=>强行退出,:e!=>放弃修改文件内容,重新载入该文件,:x =>退出,文件更改并保存,ZZ =>同:x命令 (退出vim) 

2.基本设置-命令行模式下 


:set nu 显示行号 
:syn on 显示语法高亮 
:set shiftwidth=4 设置自动缩进 4 个空格, 当然要设自动缩进先. 
:set sts=4 即设置 softtabstop 为 4. 输入 tab 后就跳了 4 格. 
:set tabstop=4 实际的 tab 即为 4 个空格, 而不是缺省的 8 个. 
:set expandtab 在输入 tab 后, vim 用恰当的空格来填充这个 tab. 
:set suffixes=.bak,~,.o,.h,.info,.swp,.aux,.bbl,.blg,.dvi,.lof,.log,.lot,.ps,.toc 
在vim中打开文件时, 按 tab 键补齐文件名时它会忽略上述文件. 
:set enc=utf-8 设置文字编码 
设置配置文件:
:scriptnames  列出配置文件.vimrc所在的目录
:version 用户所用的配置文件.vimrc的位置 

3.光标定位(普通模式、可视模式)




--------------------------------------------------------------------------------
$ 当前行的末尾
0 当前行的开头
^ 当前行第一个字母
gg 文件头
G 文件尾
`` 回到光标跳转前的位置
H 跳到屏幕上的第一行
M 跳到屏幕的中间行
L 跳到屏幕上的最后一行
w: 光标以单词向前移动至单词第一个字母
b: 与w相反,向后移动至单词的第一个字母
e: 光标以单词向前移动至单词最后一字母
ge: 与e相反,向后移动至单词的最后一字母
%: 移动到与制匹配的括号上去(),{},[],<>等
CTRL+G 得到当前光标在文件中的位置
向下翻页(page down): CTRL+f
向上翻页(page up): CTRL+b
向下移动半屏:CTRL+d
向上移动半屏:CTRL+u

补记:
. 光标定位(普通模式、可视模式)$ 当前行的末尾0 当前行的开头^ 当前行第一个字母gg 文件头G 文件尾`` 回到光标跳转前的位置H 跳到屏幕上的第一行M 跳到屏幕的中间行L 跳到屏幕上的最后一行w: 光标以单词向前移动至单词第一个字母b: 与w相反,向后移动至单词的第一个字母e: 光标以单词向前移动至单词最后一字母ge: 与e相反,向后移动至单词的最后一字母%: 移动到与制匹配的括号上去()...

光标定位技巧的补充:
'' 同`` -- 此命令相当有用, 它移动光标到上一个标记处, 比如用 gd, * 等查
找到某个单词后, 再输入此命令则回到上次停留的位置.

'. -- 此命令相当好使, 它移动光标到上一次的修改行.

`. -- 此命令相当强大, 它移动光标到上一次的修改点.

补记:

行号+G 跳转到指定行

fx 向右跳到本行字符x处(x可以是任何字符)
Fx 向左跳到本行字符x处(x可以是任何字符)
tx 和fx相同,区别是跳到字符x前
Tx 和Fx相同,区别是跳到字符x后

4.删除和复制(普通模式、可视模式)




--------------------------------------------------------------------------------
删除:

dd: 删除一行 
dw: 删除一个单词,需将光标移到单词的第一个字母。 
d$: 删除当前光标到该行的行尾的字母 
daw: 删除一个单词,光标在单词任意位置 
dnw: 删除N个单词 
dnj: 向下删除n行 
dnk: 向上删除n行 
J: 删除换行符,将光标移到改行,按shift+j删除行尾的换行符,下一行接上来了。 
复制:

yy: 复制一行 
yw: 复制一个单词,需将光标移到单词的第一个字母。 
yaw: 复制一个单词,光标在单词任意位置 
ynw: 复制N个单词 
ynj: 向下复制n行 
ynk: 向上复制n行 
修改:

cl: 更改当前字符 
cw: 修改当前单词到结尾 
cc: 修改当前行 
粘贴:p,粘贴用x、d、y操作的文本

可视模式下的方式:

可视模式下,选中要编辑的文字,可执行d、y,操作。

寄存器下的操作:
在复制前可以先指定一个寄存器,方法是在双引号后跟一个字母,例如"a指定了寄存器a,"B指定了寄存器B。所以,"ayy把当前行放进了寄存器a,以后就可以用"ap来粘贴寄存器a里的内容了。如果不确定寄存器里放了什么内容,可以使用:reg来查看。
Vim提供了一个很有用的特殊寄存器"+,它的内容就是系统剪贴板的内容。可以在Vim里用"+p粘贴出来。 

5.多文件操作



--------------------------------------------------------------------------------

:ls (:buffers) 显示buffer列表
:bn 转到下一个buffer
:bp 转到上一个buffer
:b 3 转到编号为 3 的buffer
:b index.html 转到名为index.html的buffer
:sav 另存为……
:set hidden 切换buffer时不给出保存当前buffer的提示
CTRL-G 查看当前buffer状态信息,如文件名、总行数、修改后未保存等。 
:sp(:vsp) 文件名 vim 将分割出一个横(纵)向窗口, 并在该窗口中打开新文件.从 vim6.0 开始, 文件名可以是一个目录的名称,把该目录打开并显示文件列表, 在文件名上按回车则在本窗口打 开该文件, 若输入O 则在新窗口中打开该文件, 输入 ? 可以看 到帮助信息 。 
:e 文件名 vim 将在原窗口中打开新的文件, 若旧文件编辑过, 会要求保存. 
c-w-w(即 ctrl 键与 w 键一同按下) vim 割了好几个窗口怎么办? 输入此命令可以将光标循环定位到各个窗口之中.c-w-h光标到左窗口,c-w-j下窗口,c-w-k上窗口,c-w-l右窗口。 
ls 此命令查看本 vim 程序已经打开了多少个文件, 在屏幕的最下方
会显示出如下数据:
1 %a "usevim.html" 行 162
2 # "xxxxxx.html" 行 0 其中:
1 表示打开的文件序号, 这个序号很有用处.
%a 表示文件代号, % 表示当前编辑的文件,
# 表示上次编辑的文件
"usevim.html" 表示文件名.
行 162 表示光标位置.:b 序号(代号) 此命令将指定序号(代号)的文件在本窗口打开, 其中的序号(代号)
就是用 :ls 命令看到的. 
:set diff 此命令用于比较两个文件, 可以用
:vsp filename
命令打开另一个文件, 然后在每个文件窗口中输入此命令,就能看
到效果了.


6. 查找/替换




--------------------------------------------------------------------------------
查找:
/xxx(?xxx) 表示在整篇文档中搜索匹配xxx的字符串, / 表示向下查找, ? 表示
向上查找.其中xxx可以是正规表达式,关于正规式就不多说了.
一般来说是区分大小写的, 要想不区分大小写, 那得先输入
:set ignorecase
查找到以后, 再输入 n 查找下一个匹配处, 输入 N 反方向查找.

*(#) 当光标停留在某个单词上时, 输入这条命令表示查找与该单词匹配的
下(上)一个单词. 同样, 再输入 n 查找下一个匹配处, 输入 N 反方
向查找.

g*(g#) 此命令与上条命令相似, 只不过它不完全匹配光标所在处的单词, 而
是匹配包含该单词的所有字符串.

gd 本命令查找与光标所在单词相匹配的单词, 并将光标停留在文档的非
注释段中第一次出现这个单词的地方.

% 本命令查找与光标所在处相匹配的反括号, 包括 () [] {}

f(F)x 本命令表示在光标所在行进行查找, 查找光标右(左)方第一个x字符.
找到后:
输入 ; 表示继续往下找
输入 , 表示反方向查找

替换:
替换是 vi 的强项, 因为可以用正规表达式来匹配字符串.以下提供几个例子.

:s/aa/bb/g 将光标所在行出现的所有包含 aa 的字符串中的 aa 替换为 bb
:s/\<aa\>/bb/g 将光标所在行出现的所有 aa 替换为 bb, 仅替换 aa 这个单词
:%s/aa/bb/g 将文档中出现的所有包含 aa 的字符串中的 aa 替换为 bb
:12,23s/aa/bb/g 将从12行到23行中出现的所有包含 aa 的字符串中的 aa 替换为 bb
:12,23s/^/#/ 将从12行到23行的行首加入 # 字符
:%s= *$== 将所有行尾多余的空格删除
:g/^\s*$/d 将所有不包含字符(空格也不包含)的空行删除.
例:将“(1), ...., (2), ....,(100)”替换成“(2), ...., (3), ...., (101)”。
在文本中一处处找到并修改是很累的,在VIM下一条命令就可以搞定: 
  :%s/(\(\d+\))/\="(".(submatch(1)+1).")"/g

  命令解释如下:

% 全文(“%”是“1,$”范围的缩写)
s 替换
/ 搜索字符串开始
( 左括号
\) 开始记录匹配
\d+ 一个或多个数字
\) 结束记录匹配
) 右括号
/ 搜索字符串结束
\= 把后面的表达式计算出来作为替换字符串
"(" 左括号
. 字符串连接运算符
(submatch(1) + 1) 把第一个匹配的结果加一作为一个整体返回
.")" 添上右括号
/g 替换字符串结束,g表示替换每一行的所有匹配结果。

宏替换
vi 不仅可以用 abbr 来替换文字, 也可以进行命令的宏定义. 有些命令输起来很费劲,
因此我把它们定义到 <F1>-<F12> 上, 这样就很方便了.这些配置可以预先写到 ~/.vimrc
(windows 下为 $VIM/_vimrc) 中, 写进去的时候不用写前面的冒号.

:nmap <F2> :nohls<cr> 取消被搜索字串的高亮
:nmap <F9> <C-W>w 命令模式下转移光标到不同窗口
:imap <F9> <ESC><F9> 输入模式下运行<F9>
:nmap <F12> :%s= *$==<cr> 删除所有行尾多余的空格.
:imap <F12> <ESC><F12> 同上

:java 中: (注, 这里为什么说 java 中, 因为以下定义对其他文件格式不起作用, 下文
会说到如何实现这一点)
:nmap <F3> :comp javac<CR>:mak -d . %<CR>
此命令用 javac 编译 java 文件, 它会自动将光标定位到出错点. 不过这需要定
义一个 javac.vim 文件在 $VIM/compiler 下, 在 javac.vim 里面只有两行字:
setlocal makeprg=javac
setlocal errorformat=%A%f:%l:\ %m,%-Z%p^,%-C%.%#

:nmap <F4> :comp ant<CR>:mak<CR>
此命令用 ant 编译 java 文件, 它会自动将光标定位到出错点. 一般来说, 安装
vim 后已经有了compiler/ant.vim文件, 因此这个命令可以直接使用. 但是需要
在当前目录下有 build.xml 文件, 当然还必须安装 ant 才行.

:nmap <F5> :cl<CR> 此命令用于查看所有的编译错误.
:imap <F5> <ESC><F5>

:nmap <F6> :cc<CR> 此命令用于查看当前的编译错误.
:imap <F6> <ESC><F6>

:nmap <F7> :cn<CR> 此命令用于跳到下一个出错位置.
:imap <F7> <ESC><F7>

:nmap <F8> :cp<CR> 此命令用于跳到上一个出错位置.
:imap <F8> <ESC><F8>

:nmap <F11> :JavaBrowser<cr>
此命令用于在窗口左部分割出一个新窗口, 里面的内容是 java 的资源树, 包括
本文件中出现的类, 类的成员变量及成员方法, 就好像 JCreator 表现的那样.
在这个窗口中输入 ? 会看到帮助. 嘿嘿, 很好用, 不过需要 ctags 支持.
:imap <F11> <ESC><F11> 

TAB AND autocmd




--------------------------------------------------------------------------------

TAB 就是制表符, 单独拿出来做一节是因为这个东西确实很有用.

<< 输入此命令则光标所在行向左移动一个 tab.
>> 输入此命令则光标所在行向右移动一个 tab.
5>> 输入此命令则光标后 5 行向右移动一个 tab.
:12,24> 此命令将12行到14行的数据都向右移动一个 tab.
:12,24>> 此命令将12行到14行的数据都向右移动两个 tab.

那么如何定义 tab 的大小呢? 有人愿意使用 8 个空格位, 有人用4个, 有的用2个.
有的人希望 tab 完全用空格代替, 也有的人希望 tab 就是 tab. 没关系, vim 能
帮助你.以下的设置一般也都先写入配置文件中, 免得老敲.

:set shiftwidth=4 设置自动缩进 4 个空格, 当然要设自动缩进先.
:set sts=4 即设置 softtabstop 为 4. 输入 tab 后就跳了 4 格.
:set tabstop=4 实际的 tab 即为 4 个空格, 而不是缺省的 8 个.
:set expandtab 在输入 tab 后, vim 用恰当的空格来填充这个 tab.

autocmd
这个命令十分的强大, 可以用这个命令实现对不同的文件格式应用不同的配置; 可以
在新建文件时自动添加上版权声明等等. 这些命令一般定义在 ~/.vimrc 这样的配置文件
里面. 由于他很强大, 所以我不能给出很具体的说明, 只能举几个例子, 详细的请看帮助.

:autocmd! 删除所有之前的自动命令.
autocmd FileType java source ~/.vim/files/java.vim
autocmd FileType java source ~/.vim/files/jcommenter.vim
以上两条命令让我在打开 java 文件时才应用后面提到的两个配置文件.
autocmd BufNewFile *.java 0r ~/.vim/files/skeletons/java.skel
以上这条命令让我在新建 java 文件时自动加入 java.skel 文件的内容.
autocmd BufNewFile *.java normal gnp
以上这条命令让我在新建 java 文件时自动运行 gnp 命令, 这个命令进行一些特殊化
处理, 比如将新 java 文件中的 __date__ 替换成今天的日期什么的. 

常用脚本和常用配置




--------------------------------------------------------------------------------

常用脚本
在 vim.sf.net 你可以发现很多脚本(script), 这些脚本常常有让你意想不到的作用.
我常用的有:

jcommenter.vim 自动加入 javadoc 风格的注释.
JBrowser.vim 类资源浏览. C, C++ 等可以用 Tlist

还有许多有用的, 比如 checkstyle.vim 可以检验你的编程风格, jad.vim 可以直接
反编译 .class 文件等等.
常用配置
在~/.vimrc 配置文件中你常常需要一些个性化配置. 比如上面写的一些宏定义, 一些
autocmd 定义等等. 比如:

set suffixes=.bak,~,.o,.h,.info,.swp,.aux,.bbl,.blg,.dvi,.lof,.log,.lot,.ps,.toc
这样在vim中打开文件时, 按 tab 键补齐文件名时它会忽略上述文件.

set nu 显示行号
set ai 设置自动缩进
map Y y$ 让 Y 和 D 一样, 要不然 Y 的本意和 yy 一样

posted @ 2012-08-15 11:51  欢喜王子  阅读(518)  评论(0编辑  收藏  举报