QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 4722|回复: 2

程序员的编辑器——VIM(zz)

[复制链接]
发表于 2006-3-5 22:39:20 | 显示全部楼层 |阅读模式
发信人: Dieken (风催草低), 信区: VIM
标  题: 程序员的编辑器——VIM
发信站: 水木社区 (Sun Mar  5 00:16:38 2006), 站内

初稿,大家多提提意见,我准备投到CSDN去,有两节未完成,
另外插件推荐处大家帮我再想想,有没有很爽的智能完成的插件
(我一直都Ctrl-p/Ctrl-n的很满足,呵呵),还有资源链接
处我忘了王垠的主页了,刚才想去edyfox的主页找,结果发现
突然访问不了了,edyfox兄看到了帮我re出来啊,谢谢了!

还需要抓图,各位愿意的也帮我抓抓,最好多个功能抓到一张图
里。

// 不知道CSDN是否允许在出刊前在网上传播,所以各位还请
// 给个面子,先不要转贴,如要转贴请注明出处:-)

--

※ 来源:·水木社区 http://newsmth.net·[FROM: 221.122.47.*]


附件: vim-manuscript.txt (16805 字节)







程序员的编辑器——VIM
            dieken at newsmth dot net
            yubao.liu at gmail dot com

首先请注意标题,我在介绍的是编辑器,不是IDE,所以如果想将VIM跟Visual Studio、
Eclipse等等比较时,请跟他们的编辑器比较。

一、VIM的历史
(1)ed
    ed是UNIX上最古老最基本的编辑器,它最初是UNIX之父Ken Thompson编写的,
他第一次在ed中应用了正则表达式(regular expression),这个创举将RE理论带入了实践,
对UNIX界造成了深远的影响。 实际上ed是受来自加州伯克利大学的QED编辑器的影响,
Ken便是从所院校这里毕业的。
ed是一种行模式编辑器,下面是一个ed会话的例子:
$ ed greeting
0            # 因为新创建文件,所以读入了0个字节
a            # 进入编辑模式(append)
hello world, eveyone.    # 输入一行文本
            # 回到命令模式
1p            # 显示(print)第一行
hello world, eveyone.
1c            # 最后一个词写错了, 修改(change)第一行
hello world, everyone.
            # 回到命令模式
1p            # 重新显示第一行, 这回发现无误
hello world, everyone.
q            # 退出(quit)
?            # ?表示没有保存或者命令不认识
w            # 保存(write)
23            # 提示写了23个字节
q            # 退出
    也许大家觉得这个编辑器比较BT, 可是在70年代, 许多使用UNIX的人都是用廉价
的终端机通过电话线连到UNIX服务器上的, 因为传输速率慢, 所以这种简洁的行模式编辑
就很有意义, 现在虽然硬件有了长足的发展, ed编辑器很少有人用了, 但是它的很多理念
比如命令字符、正则表达式却在它的很多后辈身上体现出来。下面这个网址有一些ed的笑
话,从中我们或多或少能体会到那个时代人们的某种精神。
        http://www.gnu.org/fun/jokes/ed.msg.html

GNU ed:        http://www.gnu.org/software/ed/ed.html
Reference:    http://en.wikipedia.org/wiki/ed
        http://snap.nlc.dcccd.edu/learn/nlc/ed.html
        http://cm.bell-labs.com/cm/cs/who/dmr/qed.html
        http://www.answers.com/topic/ken-thompson

(2)ex
    ex是ed的扩展,实际上vi构建在ex之上, vi引入了现在我们所熟悉的全屏编辑模式。

(3)vi
    随着硬件的发展,UNIX上许多全屏模式编辑器被开发出来,pico, nano, joe, jed,
jove, 但是最为广泛使用的无疑就是VI(nvi, elvis, vim等)和Emacs(GNU Emacs, XEmacs等)。

    1976年左右Bill Joy开发了vi,他也是伯克利大学的毕业生,后来他跟其他人一起
成立了Sun Microsystems公司并成为了Sun的首席科学家。一开始Bill开发了ex, 尔后开
发了vi作为ex的visual interface, 也就是说vi允许一次能看到一屏的文本而非一行, vi
也因此得名。在当今的UNIX系统上,可能没有缺省安装Emacs,但是肯定会有vi,当然,ed
编辑器也必定存在:-)
Reference:    http://www.bellevuelinux.org/vi/history.html
        http://www.theregister.co.uk/2003/09/11/bill_joys_greatest_gift/

(4)VIM
    技术不断进步,需求也在不断提高,vi的各种变种也不断涌现,知名的有nvi, elvis,
VIM, vile, yzis, 其中移植性最好、特性最多、使用最广的当属VIM, VIM主要是Bram Moolenaar
创作的。下面是VIM的重要版本历史:
DATE        VERSION        Milestone
2005        Vim 7.0aa    Spell Checking, multi tabpage
2000 Jul 09    Vim 6.0a    Folding (and more)  
1998 Feb 19    Vim 5.0        Syntax coloring/highlighting  
1996 May 29    Vim 4.0        Graphical User Interface (Robert Webb).  
1994 Aug 12    Vim 3.0        Support for multiple buffers and windows.  
1992        Vim 1.22    Port to Unix. Vim now competes with Vi.
                This was when Vim became Vi IMproved.  
1991 Nov 2    Vim 1.14    First release (on Fred Fish disk #591).

Reference:    Learning the vi Editor, 6th Edition, O\'Reilly.
        http://www.mamiyami.com/document/oreilly/books/unix2/vi/index.htm
        (中国电力出版社有中译版)
        http://www.vmunix.com/vim/hist.html
        http://www.vmunix.com/vim/
        http://www.vim.org
        vim :help vi_diff.txt
            :help version4.txt
            :help version5.txt
            :help version6.txt

二、VI/VIM基础知识
    很多人应该都知道VI是个有模式的编辑器: 编辑模式和命令模式, 按ESC回到命令
模式, 用i或者a进入编辑模式, 由于区分了模式, 导致VI的命令非常简洁, 而无模式编辑
器比如Emacs, 所有的命令都需要加上控制键Ctrl或Alt, 所以有个笑话说Emacser们最希望
计算机备一个脚踏板, 这样就可以用脚踩Ctrl和Alt键了(编辑器圣战——在VI和Emacs之间
有很多口水战,自然也引出非常多的幽默),这里罗嗦一句VI vs. Emacs: VI继承了ed的
理念,另外也有历史原因,VI追求的是快捷——启动程序迅速,编辑文本高效,功能专注,
而Emacs追求的是功能的丰富强大以及集成带来的方便,在Emacs里头可以发邮件,上新闻组,
听mp3,浏览网页,玩游戏,几乎可以login->emacs->logout了:-), VI和Emacs都是程序员
的编辑器,相比而言, Emacs更是提供了一种程序员的生活氛围。
    闲话少说,这篇文档也不是一份VI/VIM教程,所以这一节我只会简单的提及VI/VIM的基
本知识。VIM引入了更多的模式, 在VIM里头:help mode可以看到VIM的所有模式, 主要有如下几种:
Normal mode        即通常所谓的命令模式, 在此模式使用a,i,A,I,o,I等进入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!    不保存并退出
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的命令大多都可以带一个数字前缀或者一个数字范围, 比如:
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_name and some_ugly_modifier (void)
如果光标放在第一个s上,想删除到\"(\"为止,则输入dt(就可以了,t(的作用是跳到下一个
\"(\"前.

dG可以从当前位置一直删除到文件末尾, 因为G的作用是跳到文件最后一行。

VI的命令可以非常快捷的做到一些复杂的编辑操作,下面是几个示例:
(a)
将\"(1), ...., (2), ...., (100)\"替换成\"(2), ...., (3), ...., (101)\"。
在文本中一处处找到并修改是很累的,在VIM下一条命令就可以搞定:
:%s/(\\(\\d+\\))/\\=\"(\".(submatch(1)+1).\")\"/g
命令解释如下:
%       全文(\"%\"是\"1,$\"范围的缩写)
s       替换
/       搜索字符串开始
(       左括号
\\(      开始记录匹配
\\d+     一个或多个数字
\\)      结束记录匹配
)       右括号
/       搜索字符串结束
\\=      把后面的表达式计算出来作为替换字符串
\"(\"     左括号
       字符串连接运算符
(submatch(1) + 1)       把第一个匹配的结果加一作为一个整体返回
\")\"    添上右括号
/g      替换字符串结束, g表示替换每一行的所有匹配结果。

(b)
这个问题是我曾经碰到的, 有一个log系统对于输出行长度有限制, 因此在
输出很长的log时需要断行, 在断行时以单行的\"-$-\"标记, 现在的需求是
把这些行连起来, 在VIM中也可以很方便的做到(edyfox at newsmth指点):
:%s/\\n-\\$-\\n//g
命令的含义就是把\"换行-$-换行\"替换成空, 另一个办法是:
:g/-\\$-/norm ddkJx
命令g/-\\$-/的含义就是找到所有的断行标记, 然后norm表示在找到的
每一个行上执行后面的命令,dd删除这个断行标记, k移动到上一行, J合并
当前行和下一行, 由于J合并后会留一个空格(只对于英文情况下), 所以x
来删除这个空格.

(c)在Fortran代码
integer,dimension(:,,allocatable ::  &
  short_var, &
  A_very_long_name_var, &
  other
中, 想把每行的&符号定位到固定的一列, 比如第78列, 手动对齐也是很麻烦的,
这个问题可以用VIM的Align插件(http://www.vim.org/scripts/script.php?script_id=294)
解决, 另外利用宏也可以:
:set ve=all    使得光标可以定位到屏幕任何位置(缺省下VIM的光标只能放在行内的字符上)
gg              到文件第一行
/\\s\\+&\\s*$      找以&结尾的行, &前至少一个空白字符, 后0或多个空白字符
qa              记录宏到寄存器a
D               删除到行尾
78|             定位到第78列
i&<ESC>         插入&并返回到命令模式
n               查找下一个&
q               停止记录宏
10000@a         执行一万遍寄存器a中保存的命令
:set ve=\"\"      恢复ve缺省值

(d)连续插入72个等号:
按ESC进入Normal mode, 输入72i=再按ESC即可.

(e)在多行开始插入//:
移动光标到需要注释掉的第一行开头, 然后按Ctrl-v(如果开启了VIM的mswin行为, 则
Ctrl-v表示粘贴, 这时需要用Ctrl-q代替)进入Visual blockwise模式, 这个模式是
Visual mode的一种, 相当于UltraEdit中的块选择. 然后按j选择上所有需要注释行的
行首(看起来效果是选择了第一列), 输入I//再按ESC就可以在每一行开头插入//了.

Reference:    http://newsmth.org    VIM board
        http://edyfox.codecarver.org/html/index.html

这些例子也许初看起来有点吓人, 可是在很多时候VIM这些强大的命令能省不少力,VIM
不愧是为“编辑”这个功能费尽心思:-)

三、编程辅助
既然是程序员的编辑器,自然要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还未正式发布。

Reference:    :help windows
        :help buffers
        :help tabpage

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

Reference:    :help syntax

(4) 自动缩进
在打开自动缩进选项后,VIM会自动的控制缩进,比如输入{自动向右缩进一个tab字符
(具体用什么缩进可以配置), 输入}自动回退缩进. 使用=命令可以对选择的程序块排版
缩进, 这对于整理代码非常有帮助. 另外对选择的块用>>和<<命令可以很方便的控制一个
程序块的缩进.
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比较可惜的地方。

Reference:    :help \'complete\'

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

Reference    :help fold

( 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

四、强大方便的帮助系统
    使用了那么多软件,只有VIM和Emacs的帮助系统给我方便快捷的感觉,大部分
软件的帮助往往是摆设而已,而VIM的帮助的确是考虑到了自己\"help\"的身份,利用它
能很方便容易的找到想要的东西。
    VIM的帮助是超链接形式的,它使用的就是tags,所以可以跟ctags功能
一样按Ctrl-]跳转到链接所指处,按Ctrl-o返回。
    :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
(这些信息都在:help打开的帮助首页上)
如果你记不清命令或者选项的全称, 那么可以利用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>指{a-zA-Z0-9\"}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
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编写插件,这些插件
极大的丰富了VIM的功能。

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

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

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

Reference:    :help sign

六、常用VIM插件
BufExplorer.vim(http://xxxxx)
Taglist.vim
TabBar.vim
minibufexpl.vim
c.vim
latex-suite
cppcomplete.vim
word_complete.vim
winmanager

sketch.vim
DrawIt.vim

MultipleSearch
Mark.vim

SearchComplete.vim

http://insenvim.sourceforge.net

自动完成的插件?


七、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
王垠的页面??

《学习vi编辑器(第六版)》机械工业出版社译, O\'Reilly

两个学习正则表达式的工具(from happyvim at newsmth)
http://weitz.de/regex-coach/        Regex Coach
http://jregexptester.sourceforge.net/    JRegexpTester

http://www.yzis.org/        yzis是一个新的VI变种, 它支持变宽字体, 目前功能还不够丰富。
http://ex-vi.sourceforge.net/    传统VI的源代码

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

九、一份vimrc配置文件

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


--

※ 来源:· 七日网络  http://qsuns.com·[FROM: 211.155.136.*]
发表于 2006-3-6 10:04:25 | 显示全部楼层
vim默认一次只能复制50行,怎样设定能复制多一些?
回复

使用道具 举报

发表于 2006-3-6 13:46:47 | 显示全部楼层
freebsd6.0和suse10.0里的VI怎么不能用退格键?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-5-7 14:45 , Processed in 0.096766 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表