Chinaunix首页 | 论坛 | 博客
  • 博客访问: 593536
  • 博文数量: 226
  • 博客积分: 10080
  • 博客等级: 上将
  • 技术积分: 1725
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-26 11:15
文章分类

全部博文(226)

文章存档

2011年(5)

2010年(64)

2009年(99)

2008年(37)

2007年(21)

我的朋友

分类: LINUX

2009-06-23 20:12:15

vi编辑器的学习使用(二十一)
我们在Vim编辑器的学习使用(五)中曾结讨论了一些基本的窗口使用命令.

这些命令可以使得我们在不同的窗口内进行编辑工作,从而使得我们编辑多个文件成为可能.而在这里我们将会讨论一些更多的与窗口相关的命令操作.


   当我们使用多个窗口进行文件编辑时,我们如何来进行窗口的切换操作呢?我们可以使用命令CTRL-Wj回到下一个窗口,而使用命令CTRL-Wk回到上一个窗口.

我们还可以使用下面的命令来进行窗口的切换操作:
CTRL-Wt        切换到顶部的窗口
CTRL-Wb        切换到底部的窗口
CTRL-Wp        切换到我们进行切换操作以前我们所在的窗口
countCTRL-Ww    向下切换一个窗口

.如果是在底部,则进行回环.如果指明了数字,则切换到数字所指定的窗口.
countCTRL-WW    向下切换一个窗口,

如果是在顶部,则进行回环,如果指蝗了数字,则切换到数字所指定的窗口
我们在使用多个窗口进行文本编辑的时候,我们还可以进行窗口的移动,命令CTRL-Wr命令可以使得窗口向下进行循环移动.


这个命令可以带一个数字作为参数,可以指明向下循环移动所执行的次数.与其相类似的命令是CTRL-WR命令,这个命令可以使得窗口向上循环移动.

命令CTRL-Wx可以使得我们将当前窗口与下一个窗口进行位置的对换.如果当前是一个底部,则没有下一个窗口,这时执行这个命令时是将当前窗口与上一个窗口进行位置对换.

当我们在用多窗口进行多文件的编辑时我们可以用命令对这些文件进行共同的操作.:write命令可以保存当前文件.我们可以用下面的命令来实现对所有已经修改过的文件,包括隐藏缓冲区中的文件,进行保存操作:
:wall
命令:quit可以退出当前文件.

如果这是一个文件的最后一个窗口,那么这个文件将会被关闭.如果我们同时打开了多个窗口进文本的编辑,我们可以用下面的命令来退出所有的文件:
:qall

如果在这些文件中有文件进行了修改但是没有保存,在执行这个命令时会给出警告信息,这样我们就可以保存那些我们没有保存的修改了,但是如果我们想要放弃我们所做修改工作而强行退出我们可以用下面的命令:
:qall!

我们还可以将这个两个命令进行组合来实现对所有文件的保存退出的命令:
:wqall
命令CTRL-Wo可以使得当前窗口成为屏幕上的唯一的一个窗口,而其他的窗口全部关闭.系统会认为我们在其他的每一个窗口中都执行了命令:quit.

如果我们通过命令:args file-list指定了一个文件列表或是在启动vim时指定了一个文件列表,那么:all命令就会为每一个文件打开一个窗口,这样我们就可以进行多文件的编辑工作了.

下面的命令由命令:all变化而来的,这个命令可以每一个隐藏的缓冲区打开一个窗口:
:unhide
这个命令还可以带一个参数,用来指明一次打开的窗口数.例如如果我们要打开所有的缓冲区但是在屏幕上显示不超过5个窗口,我们可以用下面的命令:
:unhide 5
我们还可以用CTRL-W CTRL-^命令来分裂窗口来编辑交替文件.这个命令是新打开一窗口,并在这个窗口中装入交替文本并进编辑.而命令CTRL-^则是通过切换窗口来编辑交替文件.
命令CTRL-W CTRL-I会分裂当前窗口,然在查找当前光标下的单词第一次出现的地方.这样的查找不不仅是在当前文件中查找,也会在由#i nclude所包含进来的文件中进行查找.
在Vim中还有许多缩写的命令可以来快的完成工作,如下面的一些命令:
:countsnext        :split与:countnext的组合
:countsprevious        :split与:countprevious的组合
:countsNext        :split与:countNext的组合
:srewind        :split与:rewind的组合
:slast            :split与:last的组合
:sargument        :split与:argument的组合
CTRL-WCTRL-D        :split与]CTRL-D的组合
CTRL-Wf            :split与:find的组合
CTRL-Wg]        :split与CTRL-]的组合
在这些命令一个算是优点的地方就是如果命令执行失败那么是不会打开一个新的窗口的.
我们在用Vim编辑器进行文件编辑的时候可以用不同的缓冲区装入不同的文件,我们可以在启动Vim时指定要编辑的文件列表,我们也可以在编辑的过程中用下面的命令新增一个缓冲区:
:badd filename
这样这个指定的文件就会被加到缓冲区的列表中.这个文件的编辑过程只有我们切换到那个缓冲区时才会开始.这个命令还可以带参数,来指明当我们为这个缓冲区打开窗口时,光标所处的位置:
:badd +lnum filename
我们可以用下面的命令来删除一个缓冲区:
:bdelete filename
或者是也可以用下面的命令:
:bdelete 3
:3 bdelete
我们还可以用下面的命令来删除指定范围的缓冲区:
:1,3 bdelete
如果我们使用了!选项,那么我们在缓冲区所有的所有的改动都会被放弃:
:bdelete! filename
命令:bunload会卸载一个缓冲区,这样这个缓冲区就会从内存中卸载,所有为这个缓冲区打开的窗口也会关闭.但是这个文件名文件名仍然会存在于这个缓冲区列表中.:bunload命令与:bdelete命令的用法相类似.
我们可以用下面的命令来为每一个缓冲区打开一个窗口:
:ball
我们可以用laststatus选项来控制最后一个窗口是否显示状态行,这个选项的值如下:
0     最后一个窗口从不显示状态行
1
如果在屏幕上只有一个窗口,那么不显示状态行.如果有两个或更多个,则要在最后一个窗口显示状态行.
2    在窗口上总是显示状态行,哪怕屏幕中只有一个窗口.
我们可以用winheight选项来控制一个窗口最小的行数.但是这个并没有一个硬性的限制,如果窗口显得太拥挤了,Vim会减少窗口的尺寸.
当我们打开equalalways选项后,Vim会以相同的尺寸来分裂窗口,而这也正是Vim编辑器默认的情况,但是如果我们设置了noeqaulalways选项后我们就可以用不同的尺寸来分裂一个窗口.
winheight选项用来控制当前窗口的最小高度.而winminheight选项则用来控制其他窗口显示的高度.
在通常的情况下,:split命令是在当前窗口的上方打开一个新窗口.

而splitbelow选项可以使得Vim在当前窗口的下方打开一新窗口.
假 如我们正在编辑一个很长的文件,而现在天已经晚了,我们想着退出工作并在第二天接着做.这时我们可以将我们正在编辑的文件信息存成一个文件,在我们要第二 天要接着编辑这个文件时只要读入这个文件就可以了.这样的一个文件包含了所有我们正在编辑的文件信息,例如文件列表,窗口,标记,寄存器以及其他的一些信 息等等.
我们可以用下面的命令来产生一个程序文件:
:mksession filename
例如我们存储的文件是:
:mksession vimbook.vim
如果我们要接着工作,想要装入这个程序文件时只要用下面的命令:
:source vimbook.vim
我们也可以在启动Vim时指明要读入的程序信息文件:
$ vim -c ":source vimbook.vim"
我们可以使用sessionoption选项来控制我们在这样的文件存入什么样的内容.他是由逗号分开的一系列的关键的字符串组成的.例如默认的设置是这样的:
:set sessionoptions=buffers,winsize,options,help,blank
可能的关键字的值如下:
buffers        保存所有的缓冲区.包括在屏幕上显示的以及隐藏的和卸载的缓冲区.
globals        保存全局变量.这些全局变量是由大写和至少一个小写字母组成的.
help        帮助窗口
blank        屏幕上的空窗口
options        所有的选项和键盘映射
winpos        GUI窗口的位置
resize        屏幕的尺寸
winsize        窗口的尺寸
slash        在文件名中用斜线来代替空格.
unix        用UNIX的行结尾格式来保存程序信息文件.

vi编辑器的学习使用(二十二)
我们在Vi编辑器的学习使用(六)学习了基本的可视化模式,这时我们可以执行简单的可视化命令.在这里我们将会讨论更多的与可视化相关的命令.这些命令中的许多只有很少的观众,如果我们可以看这一次的学习,也许这很少的观众中就会包括我们.
我 们在Vi编辑器的学习使用(四)知道了如何来用寄存器实现复制,粘贴和删除的工作.我们也可以在可视化模式中来实现这些操作.例如要删除一个文本我们可以 这样的来做:在可视化模式中高亮显示这些文本,然后执行d命令.如果要将这些文本删除后放入寄存器中,我们可以用下面的命令来实现:"register d.要复制文本到寄存器中我们可以使用y命令.而D和Y命令与其相对应的小写字母的命令相类似,只是他们作用在一整行,而d和y命令是作用于高亮显示的部 分.
在块可视化模式中,$命令可以使得选中的文本扩展到所有的选中行的结尾处.当我们上下移动光标时,可以使得选中的文本扩展到这一行的结尾处.如果新行要比当前行长得多,这样的扩展也是会发生的.
gv命令可以重复前一次可视化模式时选中的文本.如果我们已经在可视化模式状态下,执行这个命令时会选中前一次选中的文本.如果我们重复执gv命令,就会在当前选中的文本和前一次选中的文本之间进行切换.
在 Vim编辑器的可视化模式下的许多命令都是用来帮助我们高亮显示我们想要的文本的.例如命令aw高亮显示下一个单词.事实他不仅高亮显示这个单词,而且也 包括这个单词后的空格.在一开始也许我们会认为这个命令没有太大的用处.因为w命令可以向前移动一个单词,我们为什么不用这个命令呢?
这是因为当 我们执行选择文本的操作时,选中的是从老的光标所在处到新的光标所在处之间的文本.当我们使用命令w来移动文本时,结果是光标置于下一个单词的第一个字符 上.如果这时我们要执行删除操作,我们命令的执行是不仅删掉了我们要删掉的单词,也同时删除了下一个单词的第一个字符.
而aw命令是将光标放在下一个单词的第一个字符的前面.换句话说,我们选中的是下一个单词前面的单词以及空格,而不是选中的下一个单词.
而另外一个使用aw命令而不使用w命令的原因就是不论光标置于一个单词的哪一个字符上,aw命令都可以选中整个单词,而w命令只是选中当前光标处和这个单词结尾之间的字符.
如果我们仅仅是想选中一个单词我们可以使用iw命令.
我们还可以使用下面的命令来选择文本:
countaw        选中一个单词以及其后的空格.
countiw        仅仅是选中一个单词.
countaW        选中一个WORD以及其后的空格.
countiW        仅仅是选中一个WORD
countas        选中一个句子以及其后的空格.
countis        仅仅选中一个句子.
countap        选中一个段落以及后面的空格.
countip        仅仅是选中一个段落.
counta(        在括号所包括的文本内,选择直到括号的文本并包括括号.
counti(        与上面的命令相类似,只是不包括括号.
counta<        选择<>内的文本,包括<>
counti<        选择<>内的文本,不包括<>
counta[        选择[]内的文本,包括[]
counti[        选择[]内的文本,不包括[]
counta{        选择{}内的文本,包括{}
counti{        选择{}内的文本,不包括{}
在可视化模式下,当我们选中一些文本以后,我们可以用命令o来使用光标移动选中的文本的另一个结尾处.然后我们可能再次执行o命令,来使得光标移动选中文本的另一个结尾处,也就我们来的地方.
而O命令可以在块可视化模式下将光标移动选中文本的另一角.换句话说,O命令是将光标移动选中文本中的同一行的结尾处.
在可视化模式下选中的文本,我们可以用命令~来实现大小写的转换.而U命令是使得选中的文本变成大写的形式,而u命令是将选中的文本变为小写的形式.
我们可以在可视化模式下选中文本,然后用命令J将这些选中的行合并为一行,并用空格来分隔这些行.如果我们希望在合并以并没有空格来分隔,我们可以用命令gJ.
我们可以用命令gq来格式化可视化模式下选中的文本.
我们还可以用g?命令来加密高亮显示的文本,在这个命令中我们采用的是Vim中所采用的rot 13加密算法.如果我们对同一个文本进行两次加密操作,就相当我们进行了解密操作.
在可视化模式下我们还可以用命令:来对指定的范围进行命令行操作.例如我们要将文本块写入一个文件我们可以这样的来做:
在可视化模式下选中我们要写入文件的文本,然后执行下面的命令:
:write block.txt
这样就可以将指定的文本块写入文件了.
命令!是使用外部的命令来对我们所要编辑的文件中的文本进行操作.例如我们可以使用!sort来使用UNIX下的sort程序进行文本的排序.我们可以这样的来做:
在可视化模式下选中我们要进行操作的文本,然后执行下面的命令:
:!sort
这样就可以对这些我们选中的文本进行排序操作了.
选择模式是另一种的可视化模式,他可以允许我们对选中的文本进行的快速的删除作替换的操作.我们使用选择模式也是很简单的操作.我们可以高亮显示文本,然后用来删除这段文本.我们也可以高亮显示文本,然后用我们所输入的内容来替换这些文本.
那 么选择模式和可视化模式相比较又如何呢?在可视化模式下,我们可以高亮显示我们选中的文本,然后执行命令操作.换句话我们要用命令来结束可视化模式.而在 选择模式下,命令仅限于(用于操作删除操作)和可打印的字符(用于替换操作).这样就会使得我们的操作变得更为简单,因为我们不需要 来输入命令了,然而与可视化模式相比较他也有着太多的限制.
我们可以用下面命令来开始一种选择模式:
gh        进入字符选择模式
gH        进入行选择模式
gCTRL-H        进入块选择模式
在选择模式下移动光标比在正常模式下要显得困难一些.因为如果我们输入任何的可打印字符,Vim就会删掉我们选中的文本并进插入状态开始我们的输入.所以要选择文本我们只好使用小方向键,CTRL以及功能键.
如果我们进行了如下的设置我们还可以用鼠标来选择文本:
:set selectmode=mouse
(注:如果没有设置这个选项,可以在可视模式下执行鼠标操作而不可以在选择模式下执行鼠标操作)
在选择模式下,我们可以用命令或是CTRL-H来删除我们选中的文本.如果我们输入可打印的字符Vim编辑就会删除我们选中的文本然后进入插入模式.
我们可以用命令CTRL-O来从选择模式切换到可视化模式.如果我们要可视化模式和选择模式中进行切换,我们可以使用CTRL-G命令.
在 通常情况下,当我们选择文本后,这些文本仍会保持选中的状态.有时即使是我们在执行了命令以后,这些文本仍然保持选中的状态.gV命令可以选得选中的文本 在命令执行过后消失选中状态.这个在我们使用宏时显得更为有用.我们用他来一些工作,工作完成以后,我们就希望他能消失.

vi编辑器的学习使用(二十三))
Vim编辑器由一群需要一个好的文本编辑器的程序员们所写出来的.正因为是这样,Vim中包含了许多的命令,我们可以用这些命令来自定义并且使我们的程序编辑工作变得更为简单.
例 如如果我们现在正在编辑我们的程序文件.我们设置了autoindent选项,并且现在正处在第三层次的缩进上.而现在我们要加入一个注释块.这是一个很 大的注释块,我们希望能将这个注释块放在文本的第一列.这时我们就需要禁止所有的自动缩进形式.为了这样的目的,一种方法是可以输入几次CTRL-D命 令,或者是使用0CTRL-D命令.
命令0CTRL-D是在插入模式下移除所有的自动缩进的设置,并将光标放在第一列(在这里我们要注意的,当我 们输入0时,我们所输入的0会显示在屏幕上,这时Vim会认为我们要在文本中插入一个0,然后我们执行命令CTRL-D,这时Vim就会意识到我们要做的 是执行命令0CTRL-D,并且这时0会就会从屏幕上消失.
当我们使用0CTRL-D命令以后,光标会回到第一列,而且下一行也是从第一列开始的.
然后如果我们正在输入一个标签或是我们要输入#ifdef时我们只需要一行中的光标移动第一列就可以了.这时我们可以使用命令^CTRL-D.这个命令只会将当前行的光标放在第一列.当我们开始下一行时,这种缩进形式又会自动的执行.
CTRL- T命令与命令相类似,只是前者在文本中插入一个缩进,而这个缩进的大小由shiftwidth选项来控制的.如果我们设置了 shiftwidth选项的值为4,我们输入,光标会移动以后第八列处,这是因为缩进的大小是由 tabstop选项来控制的,而在默认的情况下这个值为8.但是如果我们输入了CTRL-T命令就会将光标移动以后的第四列处.这两个命令在一行的任何一 点都是可以正常工作的.所以我们可以输入一些文本然后执行CTRL-T命令将其缩进,然后用CTRL-D来取消这样的缩进形式.
在通常的情况下当 我们用命令CTRL-R来插入寄存器中的内容时,这些内容是自动缩进的.如果我们不希望这样的事情发生,我们可以用CTRL-RCTRL- Orgister命令.或者是如果我们要插入寄存器中的内容,并希望Vim编辑能正确的完成我们的要求我们可以用下面的命令CTRL-R CTRL-P register.这样的命令在我们的程序文件中进行剪切和复制时显得尤为有用,因为在这时的程序文件中一般是设置了自动缩进选项的,而如果我们剪切或是 复制后再粘贴时就会用两次的缩进操作,而这不是我们所希望的,这时我们就要用这些命令了.
在通常的情况下,命令"registerp命令是将指定寄存器中的文本插入到缓冲区中,而命令"register]p命令与此相类似的,所不同的是这个命令在插入时会有自动缩进的设置.而与此相类似的是命令"register]P与"registerP.
在 计算机产生以前的时代,存在着一个交流的工具被叫作打印机.打印机的一些模块可以执行tabs.但是很不幸的是这些tab的大小被设置成为八个空格.而在 计算机产后以后,他的第一个终端就是打印机.后来有一些更为现代的设备代替了打印机,但是古老的八个空格大小的tab被保留了下来,以保持与以前的相兼 容.
但是这样的设计为我们以后的程序设计工作带来无尽的麻烦.因为有研究可以显示最易读的程序是四个字符的缩进,而Tab是八个字符的缩进.我们如何来调合这样的事实.人们想出了许多解决的办法,如下:
1 在我们输入代码时结合使用空格和Tab.如果我们需要12个字符的缩进,我们可以使用一个Tab和四个空格.
2 告诉机器将Tab设为四个字符的大小,然后在任何的地方使用Tab.
3 放开我们的双手并且认为Tab是一个工作的魔鬼,而且我们总是使用空格.
幸运的是Vim编辑器支持以上的三种方法.
如果我们使用空格和Tab的组合,我们可以像正常一样的进行编辑.在默认的Vim设置情况下就可以很好的来工作.
但是我们可以通过设置softtabstop选项的值的来使我们的工作变得再简单一些.这个选项告诉Vim编辑使得Tab键看上去和感觉上是使用softtabstop选项贩值,但是实际上我们是使用Tab和空格的结合在做事情.
例如我们可以用下面的命令来使得以后每一次我们在按下Tab键时光标位于以后的第四列处::set softtabstop=4
当我们第一次按下Tab时,Vim会在文本中插入四个空格.当我们第二次按下Tab键时,Vim就会去掉刚才的四个空格,然后在文本中插入一个Tab.也就是说当有八个空格相当于一个Tab时,Vim就会用一个Tab来代替这八个空格.
另一个相关的选项就是smarttab选项.我们可以用下面的合谋来设置这个选项:
:set smarttab
当 我们设置了这个选项以后,插入一行开头的Tab就会被看作是软Tab.在这种情况下,Tab的大小所使用的值就是shiftwidth选项所设定的值.但 是在其他的地方插入的Tab就会像是正常的Tab一样的.在这里我们要注意的就是当我们要让这个选项来正常工作时,一定要使软Tab关掉(:set softtabstop=0).
精巧缩进(smart indent)是软Tab和正常Tab的组合.当我们执行下面的命令,Vim编辑器就会区别对待一行开头的Tab:
:set smarttab
例如如果我们有下面的设置:
:set shiftwidth=4
:set tabstop=8
:set smarttab
在这些设置中我们是设置Tab是八个空格而缩进是四个空格.当我们在一行的开始输入Tab时,光标就会移动一个缩进的大小,也就是四个空格.当我们输入两个Tab时,光标就会移动两个缩进的大小,也就是八个空格.
下面的内容则显示出了我们在一行的开始输入特定的内容时的显示:
            四个空格
        一个Tab
        一个Tab,四个空格
    两个Tab
但是当我们在一行的其他地方输入Tab时,就会显得像正常的一样.
我们可以用下面的命令来设置一个Tab为四个空格:
:set tabstop=4
事实上我们可以用这个命令来将Tab设置成任何我们想要的值.
如 果我们在我们的文件中含有Tab字符,我们可以通过设置expandtab选项来控制.当我们设置了这个选项,一个Tab键就会插入一系列的空格.在这里 我们要知道的就是expandtab选项并不会影响文章中的其他的Tab键值.换句说文档中的Tab值仍然会保持.如果我们要将Tab转换为空格,我们可 以使用:retab命令.
我们可以使用:retab命令来实现在文章中不同Tab设置之间的转换.我们可以用这个命令来使得文章中一系列的空格转 换为Tab,或者是将一个Tab转换为一系列的空格.例如现在我们有一个文件使用是四个空格的Tab设置.但是这并不是标准的设置,而我们希望将他转换为 八个空格的设置.我们希望这两个文件看起来是一样的,只是Tab的值不同.我们可以按照下面的方法来做:
:set tabstop=4
:%retab 8
这样以后我们的文件看起来就像是没有做过修改一样的,因为Vim将空白符与tabstop的新值相匹配.
再比如我们需要一个没有Tab的文件.首先我们执行命令设置expandtab选项.这样就会使得我们输入的新文本中的Tab成为空格.但是老文本中的Tab依然存在.要将这些Tab转换为空格,我们可以用下面的命令:
:%retab
因为我们没有指定一个新的Tab值,Vim就会使用现在的tabstop的值.但是因为我们又设置了expandtab这个选项,所以所有的Tab就会用空格来代替.
在 这些Tab设置中存在的问题就是会有不同的人用不同的习惯来使用Vim处理文件.所以说如果我们可以很好的处理三种不同类型的人写的文件,我们就可能容易 的确处理各种不同的Tab设置.这个问题的一个解决办法就是我们在写文件的时候在文件的开头或是文件的结尾下加上一个注释块,在其中标出我们所使用的 Tab设置.例如:
/*vim:tabstop=8:expandtab:shiftwidth=8*/
当我们知道这些以后我们可以建立 我们自己所喜欢的格式.但是Vim是一个精巧的编辑器,他可以理解类似这样的注释并且为我们配置这些设置.但是有一点是要严格执行,那就是注释必须是这种 形式的,而且是必须是在一个程序文件的前五行或是后五行才可以.这种类型的注释就叫做模式行(modeline).
假如我们设置了shiftwidth的值为四,而我们在一行的开始输入了三个空格.那么当我们执行命令>>时会是什么样呢?会在前面插入四个空格的缩进还是移动到最近的一个缩进处呢?答案取决于我们所设置的shiftround选项的值.
以通常的情况下,这个选项是没有设置的,所以会新增四个空格的缩进.但是如果我们执行了下面的命令,那么光标就会移动到最近的一个缩进处:
:set shiftround
当 我们执行命令=时我们可以使用通过equalprg选项所指定的程序来进行文件的格式化工作.如果没有设置这个选项或者是我们没有编辑一个Lisp程序, 那么Vim就会使用他自己的缩进程序来缩进C或者是C++的程序文件.如果我们想要使用GNU的缩进程序我们可以执行下面的命令:
:set euqalprg=/usr/local/bin/indent
我们还可以要求Vim来格式化注释而且他可以很好的来完成我们的要求:
例如我们有下面的一段注释:
/*
 *This is a test.
 *Of the text formatting.
 */
我们可以通过下面的命令来格式化这段注释:
1 将光标放在这段注释开始的地方.
2 用命令v进入可视化模式.
3 将光标移动到这段注释的结尾处.
4 用命令gq来格式化这段注释.
结果如下:
/*
 *This is a test.Of the text formatting.
 */
(没有达到预期的效果,想来应处理程序文件中才有用)
我们可以通过comments选项来定义哪些是注释而哪些不是.我们还可以用命令gq{motion}来完成注释的格式化工作.
我们可以使用comments选项来定义哪些文本是注释而哪些文本不是注释.这个选项由成对出现的标记:字符串格式组成(flag:string).
可以使用的标记(flags)如下:
b
后面必须跟上空格.这就是说如果一个字符后面跟上空格或是其他的空白符,那么这个字符开始了一个注释.
f    只有第一行有注释字符串.在下一行不要重复这个字符串,但是要保持缩进格式
l
当使用在三段注释的情况下,必须保证中间一行要与注释的开始和结束相对应.而且必须使用s或是e标记.
n    指明了嵌套注释
r    与l相类似,所不同的只是右对齐
x
告诉Vim在三段注释的情况下我们可以在下面的三种情况下仅输入最后一个字符就可以结束注注释:
1 我们已经在注释的开头输入了.
2 注释有中间部分.
3 结束字符串的第一个字符是这一行的第一个字符.
对于三段注释的情况,下面的一些标记适用:
s    开始三段注释
m    三段注释的中间部分
e    三段注释的结尾
number    在三段注释的中间部分的缩进中添加指定的空格
一个C程序的注释用/*开始,有中间部分*,以*/结尾.就像下面的一样:
/*
  * This is a comment
  */
这样的注释结果是由comments选项所指定的:
sl:/*,mb:*,ex:*/
在这个设置中sl表明这是一个三段注释的起始处并且在这个命令中的其他行需要缩进一个额外的空格.这个注释是以/*开始的.
这个注释的中间部分是由mb:*来定义的.m表明了一个中间部分,而b则是说在我们输入的任何内容后必须有一个空格.这段文本以*开始注释.
注释的结束是以ex:*/来指定的.e表明注释的结束,而x则是表明了我们只需要输入结束标记的最后一个字符来完成注释.而结束的定界符是*/.
那么我们如何来使这样的定义工作呢?首先我们要设置下面的选项:
:set formatoptions=qro
下面的一些选项在我们要格式化文本时会显得更为有用:
q    允许使用gq来格式化化注释
r    在我们输入回车后自动的加入注释的中间部分
o    我们用o或是O命令来开始一个注释行时自动的添加注释行的中间部分
下面让我们看一下这样的设置会如何的工作:
我 们要开始一段注释,我们在这一行输入注释的开始标记/*,然后我们打下回车,因为在格式选项中我们设置了r,所以在下一行中会自动的添加注释的中间部分并 且会在后面添加一个空格.当我们在再输入回来也会出现同样的情况,但是这时我们要结束我们的注释输入了,我们就如何结束呢?Vim是一个精巧的编辑器,当 我们在这种情况下只输入/时,光标就会向后移动一格插入/,这样就正确的结束我们的注释输入了.结果如下:
/*
* This is a test
*/
我们还可以使用各种不同的格式命令来格式化文本或是注释.
C程序文件的缩进过程是由下面的一些选项来控制的:
cinkeys        定义了引发缩进事件的关键字
cinoptions    定义了如何缩进
cinwords    定义了C和C++的关键字
cinkeys选项定义了哪些字符会引起缩进的变化.这个选项事实上是一对输入字符和关键字字符的组合(type-chars key-chars).
输入字符如下:
!    他后面的字符不会被插入.这在我们要定义一个字符来格式化一行使之重新缩进时会显得更为有用.在默认的情况下,CTRL-F就被定义为重新缩进.
*    这一行会在这个字符输入之前进行重新缩进.
0    如果这是一行中第一个输入的字符就会影响这一行的缩进发生变化.(这并不是说他是这一行的第一个字符,因为这一行会进行自动缩进.他只是指第一个输入的字符)
关键字符如下:
^X    控制字符CTRL-X
o    告诉Vim在我们用命令o开始一个新行时要缩进该行.
O    与o相同
e    当我们输入最后一个else中的e时重新缩进此行.
:    当我们在一个标签或是事件的描述后输入:时会重新缩进此行.
<^>,<<>,<>>,,,    在尖括号中的精确的字符
而cinkeys选项默认的值如下:
0{,0},:,0#,!^F,o,O,e   
cinoptions 选项来控制每一行缩进的大小.这个选项是由一系列的关键字和缩进(key indent)所组成的.这里子关键字是一个单一的字符,用来指明影响程序的哪一部分.而缩进(indent)则是告诉程序要用多大的缩进.这个缩进可以 是几个空格(如8个),或者是负数量的空格(如-8个).还可以是由s所指定的shiftwidth选项值的倍数.例如1s是指一个 shiftwidth,而0.5s是指半个shiftwidth,而-1s则没有缩进一个shiftwidth.
关键字    默认    描述
>    s    没有被其他字符所覆盖,正常缩进.
e    0    以花括号为结束标记的行后面的行的额外缩进.
n    0    在if,while后的没有在花括号内的单一行的额外缩进.
f    0    添加到函数体的额外缩进.包括定义函数的{}.
{    0    添加到开始{的空格
}    0    添加到结束}的空格
^    0    添加到开始于第一列的{}内的文本的空格.
:    s    在switch语句中的自动缩进
=    s    在case语句后的额外缩进
g    s    对于C++中的保护关键字(public,private,protected)的缩进
h    s    保护关键字语句后的语句的缩进
p    s    K&R风格的缩进
t    s    在单一行进行函数类型声明的缩进
+    s    连续行的缩进
c    3    多行注释中间部分的缩进(如果没有指定*)
(    2s    表达式中间部分一行的缩进,事实上是指一对括号内部的缩进.
u    2s    嵌套括号内的一行的缩进,与(相类似,只是这个要更深一层.
)    20    指定用来查找一对闭括号()的行数.
*    30    指定用来查找没有结束的注释的行数
选项cinwords用来定义哪一些单词可以使得下一个C语句在精巧缩进(smartindent mode)模式下和在C缩进模式下(Cindent mode)缩进一个层次.默认的选项值如下:
:set cinwords=if,else,while,do,for,switch
假如我们要用尽量少的编辑动作来比较两个文件的不同,那么我们要怎么样的来做呢?这时我们可以打开两个窗口,分别在两个窗口中进行编辑.然后我们在每一个窗口中执行下面的命令:
:set scrollbind
这样以后如果有一个窗口发生滚动,那么另一个窗口也就会有相同的动作.
就你是我们要在两个文件窗口中进行动作一样,也许有的时候我们会需要移动一个窗口而不要移动另一个窗口,这时我们可以我们要移动的窗口内执行下面的命令就可了:
:set noscrollbind
如果我们要同步滚动,我们可以执行下面的命令:
:set scrollbind
选项scrollopt可以用来控制scrollbind如何的来工作.我们可以将其设为如下的值:
ver    垂直同步滚动
hor    水平同步滚动
jump    当我们在两个窗口中进行切换时,一定要使用偏移(offset)为0
最后如果我们要使两个窗口同步,我们可以使用下面的命令:
:syncbind
假 如我们正在看一个文件的两个版本,我们需要在这两个文件中进行滚动查看.也许我们为了查看一些东西而关掉了scrollbind.这样这两个文件就会停在 不同的地方.而我们还希望他们可以再一次同步滚动.这时我们可以分别到这两个文件所在的窗口然后将他们移动相同的地方.而事实上我们可以叫Vim来完这样 的工作.在这样的情况下,我们可以分别在两个文件中设置scrollbind,然后执行下面的命令:
:syncbind
这样Vim就使得两个文件同步了.
假如我们正在看一个程序文件,但是却碰到一个我们并不理解的函数调用.我们可以用命令CTRL-]跳转到函数定义的地方.但是这样做却有一个问题,那就当前的文件被函数定义的内容所替代,我们也就不可以从屏幕上看到这个文件的内容了.
这个问题的一个解决办法就是我们使用被称为preview的特殊窗口.我们可以通过执行下面的命令来打开preview的特殊窗口,在这个窗口中显示函数定义的内容:
:ptag function
如果我们已经打开了一个preview窗口,那么他就会切换到当前正在查看的函数定义内容.如果我们要关闭这个窗口,我们可以执行下面的命令:
:pclose
命令CTRL-Wz和ZZ也可以有关闭这个窗口的作用.
在preview窗口中我们执行下面的命令来完成我们的工作:
:ppop        在这个窗口中执行一个:pop命令.
:ptselect identifier    打开一个新的preview窗口并执行:tselect命令
:ptjump identifier    打开一个新的preview窗口并执行:ptjump 命令
:count ptnext        在这个窗口中执行:count tnext命令
:count ptprevious    在这个窗口中执行:count ptprevious命令
:count ptrewind        在这个窗口中执行:count ptrewind命令
:ptlast            在这个窗口中执行:ptlast命令.
CTRL-W}            以当前光标下的内容执行一个:ptag命令
CTRL-Wg}        以当前光标下的内容执行一个:ptjump命令
matchpairs选项可以用来控制哪些字符可以用%命令来进行匹配.这个选项默认的值如下:
:set matchpairs=(:),{:},[:]
这就告诉Vim要匹配(),{},[]
匹配<>,我们可以用下面的命令:
:set matchpairs=<:>
这个命令在我们要编写HTML文件时会显得更为有用.
这个命令仅仅是匹配<>.如果我们要同时匹配其他的字符,我们可以用下面的命令:
:set matchpairs=(:),{:},[:],<:>
这样的命令显得似乎是有一些太长了,我们可以用+=命令来达到同样的目的.例如上面的命令我们可以用下面的命令来作到:
:set matchpairs+=<:>
如果我们希望我们在输入括号时,光标会跳转到与其匹配的地方进行显示,我们可以执行下面的命令来做到:
:set showmatch
通常情况下这个跳转持续的时间为0.5秒(半秒),我们可以用matchtime选项来控制这个时间.例如如果我们希望这个时间持续1.5秒,我们可以用下面的命令:
:set matchtime=15
在这里是以0.1秒为单位的.
我们在Vim编辑器还可以用命令来查找未匹配的括号.如[{查找前一个未匹配的{,]{查找后一个未匹配的{.[}查找前一个未匹配的},而]}查找后一个未匹配的}.
])查找后一个未匹配的),而[(查找前一个未匹配的(.[#查找前一个未匹配的#if或者是#else.而]#查找后一个未匹配的同类情况.
下面的命令可以移动一个Java方法的开头或结尾:
[m    向后查找一个方法的开头
[M    向后查找一个方法的结尾
]m    向前查找一个方法的开头
]M    向前查找一个方法的结尾
在Vim编辑器还提供了许多的移动命令来帮助程序人员在他们的程序文件中进行浏览.下面的一些命令可以找到位于第一列的{和}:
count[[        向后查找位于第一列的前一个{
count[]        向后查找位于第一列的前一个}
count]]        向前查找位于第一列的后一个{
count][        向前查找位于第一列的后一个}
命令[/和[*可向后移动他可以找到的第一个C注释的开始处,而]/和]*可以向前移动他可以找到下一个C注释的结束处.
随着一个程序文件变得越来越大,我们会将这个程序文件分在不同的目录中,这样就会大大的方便我们的管理.让我们来看一下一个小的工作,我们有一个包含有main.c和main.h的主目录,其余的目录就是含有lib.c和lib.h的lib目录(库文件).
我们从主目录中开始我们的编辑工作.第一件事就是告诉Vim关于是我们的新目录的情况.我们可以用:set ^=将这个目录放在查找路径的上部:
:set ^=../lib
假如我们正在编辑文件main.c,而这个文件的内容类似于下面的:
#i nclude "main.h"
#i nclude "lib.h"

int main(int argc,char*argv[])
现在我们要查看一下lib.h中一个子程序的声明.一个办法是我们可以执行下面的命令:
:vi ../lib/lib.h
这个命令是假定我们知道lib.h的位置所在.但是在这里我们会有一个更好的方法.首先我们将光标放在下面一行中的文件名上:
#i nclude "lib.h"
然后我们执行命令gf.这就告诉Vim编辑试着编辑以光标下的内容为文件名的文件.编辑器就会在path(路径)变量的每一个目录中进行查找.
假如我们要编辑文件lib.c,而这个文件名并没有出现在现在的文本内容,我们就没有办法来用gf命令,这时我们可以用下面的命令:
:find lib.c
这个命令类似于:vi命令,所不同的只是他要在路径中进行查找.下面的命令与其相类似,只是他是分裂当前窗口进行查找:
:sfind lib.c
gf命令与:find命令相类似,只是这个命令认为当前光标下的内容是我们要编辑的文件.如果在path中有不只一个文件与指定的文件相匹配,这时我们可以通过给定gf命令一个参数来选择我们要编辑的文件.
换句话说如果我们将光标放在param.h上然后执行命令2gf,Vim就会编辑通过path选项指定的路径目录中查找的文件列表中的第二个文件.
path选项用来告诉Vim在哪里查找被当前文件包含进来的文件,这个选项的格式如下:
:set path=directory,directory,...
在这里的directory是指我们要查找的目录,如:
:set path=/usr/include,/usr/X11R6/include
我们还可以在这个命令中使用通配符来进行匹配,如:
:set path=/usr/include,/usr/include/*
下面是一些特殊的目录:
**    匹配整个目录树,如:
    :set path=/usr/include/**
    这个命令查找目录/usr/include及其所有的子目录.下面的命令指定了在所有以/ho
me/oualline/progs开始以include结束的目录内的文件
    :set path=/home/oualline/progs/**/include
""    空字符串指当前目录
.    指我们正在编辑的文件所在的目录
例如下面的命令是告诉Vim查找的目录包括/usr/include及其所的子目录,我们正编辑的文件所在的目录(.)以及当前目录(,,):
:set path=/usr/include/**,.,,
如果我们想确定一下我们可以查找到所有的#i nclude文件,我们可以使用下面的命令:
:checkpath
这个命令的作用范围不仅仅是我们正在编辑的#i nclude目录,而且包括任何他们#i nclude的目录,结果就是要查看所有的#i nclude文件.
在这种情况下,有许多的文件要包含文件stddef.h和stdarg.h.但是Vim却不能找到这些文件.如果我们要告诉VimLinux特殊的include目录,我们要以执行下面的命令:
:set path+=/usr/include/linux
但是:checkpath命令只是列出所以不能找到的文件,如果我们要列出所以的#i nclude文件,我们可以用下面的命令:
:checkpath!
Vim编辑器知道C和C++的宏定义.但是如果是其他的语言又会怎么样呢?选项define包含了一个长规的表达式,Vim编辑器可以通过他来查找一个定义.例如如果我们要使Vim查找以字符串function开头的宏,我们可以使用下面的命令:
:set define=function
选 项include定义一个包含(include)的目录是什么样子的.这个选项可以用来为我们使用命令]CTRL-I,[CTRL-I,]d,[d在这些 我们所包含进来的文件中进行查找.这个选项也可以为命令:checkpath所用.正如define选项一样,这个选项的值也是一个长规的表达式.
命令[i用来查找光标下的内容第一次出现的地方.注释的文本会被忽略掉.
命令]j用来查找光标下的内容下一次出现的地方.注释的文本会被忽略掉.
命令[I会列出所有包含当前光标下的内容的句子,命令]I与其相类似,只是这个命令是从当前光标处开始.
:make命令会产生一个错误列表.Vim编辑器会记住我们前10次:make命令和:grep命令的执行结果.如果我们要到前一次的错误列表,我们可以用下面的命令:
:colder
如果我们要到一个新的错误列表,我们可以用下面的命令:
:cnewer
当我们执行:make命令时所要执行的程序名称是由makeprg选项来定义的.在通常的情况下会设为make,但是Visual C++的用户可以通过下面的命令将其设为nmake:
:set makeprg=nmake
:make命令会重定向Make的输出到一个错误文件.这个文件的名字是由makeef选项来控制的.如果这个选项包含有字符##,字符##就会被专一的数字所代替.这个选项默认的值取决于我们正在使用的操作系统.默认的值如下:
Amiga        t:vim##.Err
UNIX        /tmp/vim##.err
Windows        vim##.err
我们可以在命令中包含指定的Vim关键字.%字符可以扩展当前文件的名字,所以我们执行下面的命令:
:set makeprg=make\%
然后我们执行命令:
:make
他就会执行下面的命令:
$ make file.c
file.c就是我们正在编辑的文件的名字.这个并没有太大的用处,所以我们可以重新定义这个命令并使用:r(root)的权限:
:set makeprg=make\%:r.o
这样我们就会执行下面的命令:
$ make file.o
选项errorformat可以用来控制Vim如何来组织错误文件以使得他可以知道文件名以及错误发生的地方.这个选项的格式如下:
:set errorformat={string},{string},{string}
这里的字符是由特殊字符%所指出的典型的错误信息用来指明特殊的操作(与标准C函数scanf很相像).这些特殊的字符如下:
%f    文件名
%l    行号
%c    列号
%t    错误类型(单一字符)
%n    错误行号
%m    错误信息
%r    匹配一行中的剩余
%*{char}匹配并跳过由{char}所指定的scanf转换
%%    字符%
当我们在编译一个程序的时候,我们也许要在几个目录中进行遍历.GNU make程序会在当我们进入一个目录或是离开一个目录时打印出相应的信息.
如果要正确的得到文件名,Vim就要清楚的知道这些目录的变化.下面的一些错误格式用来在目录发生变化时告诉Vim一些相关的信息:
%D    当进入一个目录时打印出指定的信息.字符串的%f指明我们所进入的目录
%X    指定离开目录时的信息.字符串中的%f指明了make已用毕的目录.
一些编译器,例如GNU GCC编译器,会输入一些冗长的错误信息.如果我们正在使用默认的errorformat就会导致三种错误信息.这实在是够讨厌的.但是幸运的是Vim编辑器可以识别出不同的错误信息.处理不同信息的模式代码如下:
%A    开始多行信息
%E    开始多行错误信息
%W    开始多行警告信息
%C    连续多行信息
%Z    结束多行信息
%G    全局.只有在+或是-连接时才有用
%O    单行文件信息:重新读入匹配的部分
%P    单行文件信息:将%f文件压入栈
%Q    单行文件信息:将最后一个文件压出栈
+或是-可以放在任何字符的前面,从而组成下面的内容:
%-letter    不要包含输出中的匹配行
%+letter    包含%m错误字符串的整个匹配行
在 通常的情况下,我们执行:make命令并有错误发生,Vim会在当前的窗口中显示错误文件.如果我们通过设置switchbuf选项来进行窗口的分 裂,Vim就会在一个新的窗口来显示错误文件.:grep命令会运行由选项grepprg所指定的程序.这个选项包含了我们要用的命令行.#和%字符会扩 展到当前文件名和交替文件名.而字符串$*将会被:grep命令的参数所代替.
在这里我们要注意的就是在UNIX系统上,grepprg默认是指grep -n.在Windows系统上,默认是指findstr/s
:grep命令使用grepformat选项来告诉Vim如何来组织Grep的输出文件.
在通常的情况下,Vim是使用二分法进行查找指定的标记名字.如果一个标记文件是按序排列的,这样的方法可以是很快速的.否则的话我们可以使用线性查找的方法.如果要强制进行线性查找,我们可以用下面的命令;
:set notagbsearch
这个选项会在我们的标记文件不是有序的时有用.
有一些系统会限制我们在函数名中所使用的字符数.如果我们要在Vim中加入这样的限制,我们可以通过设置taglength选项来限制我们函数名的最大长度.
我们可以用tags选项来指定标记文件名.这个可以用来指其他目录中的文件.如:
:set tags+=/home/oualline/tools/vim/tags
但 是这会带来一些令人费解的地方.是我们在当前目录中启动并告诉ctags将标记文件放在目录/home/oualline/tools/vim还是我们在 当前的目录执行了ctags呢?现在的Vim编辑器已经用其他的选项来解决了这个问题了.如果我们进行下面的设置,所有的标记都会和含有标记文件的目录有 关系:
:set tagrelative
否则的话,他们会和当前目录有关系.
如果我们设置了tagstack选项,那么:tag命令和:tjump命令就会建立一个标记栈.否则是不会保持栈的.
Vim编辑器允许我们自定义用来进行语法高亮显示的颜色.Vim编辑器识别下面三种不同的终端:
term    平常的白色背景色,黑色前景色的终端(没有颜色)
cterm    彩色终端,例如xterm或者是Windows的DOS
gui    Gvim所产生的窗口
要改变通常的终端的高亮显示的颜色,我们可以用下面的命令:
:highlight group-name term=attribute
这里的group-name是我们要高亮显示的语法组.这是我们要设置的语法匹配的规则用来告诉Vim程序中的哪一部分要进行高亮显示.而attribute是终端的属性.对于平常的终端如下:
bold    underline    reverse    italic    standout
我们可以用逗号来组合这些属性,如:
:highlight Keyword term=reverse,bold
假如我们有一个不是通常代码的终端.我们可以通过start和stop高亮显示的选项来定义我们自己的属性.这些定义一个用来发送的字符串来开始一个颜色和结束一个颜色.例如:
:highlight Keyword start=X stop=Y
有了这样的定义,当Vim要显示关键字时,例如显示if就会显示为XifY
如果我们对UNIX的终端定义的文件较为熟悉,我们可以使用终端代码.us定义了开始下划线的代码,而ue则是退出下划线模式的字符串.要指定这种高亮显示的方法,我们可执行下面的命令:
:highlight Keyword start=t_us stop=t_ue
颜色是由cterm的设置来定义的.我们可以使用cterm=attribute的方式来进行我们的设置.
但 是对于一个彩色终端来说还有许多其他的选项.ctermfg=color-number可以用来设置前景色.ctermbg=color-number用 来设置后景色.Vim可以识别出颜色的名称.例如下面的命令可以告诉Vim在显示注释时后景色为蓝色,而前景色为红色,并且有下划线:
:highlight Comment cterm=underline ctermfg=red ctermbg=blue
GUI 终端可以使用选项gui=attribute的方式来在图形窗口下显示语法元素的属性.选项guifg和guibg定义了前景和后景的颜色.这些颜色是名 称来进行区别的.如果名称中包含空格,那么这个颜色的名称就要用单引号括起来.为了事物的可移动性,Vim建议我们只使用以下的颜色:Black    Blue    Brown    Cyan    DarkBlue    DarkCyan    DarkGray    DarkGreen    DarkMagenta    DarkRed    Gray    Green    LightBlue    LightCyan    LightGray    LightGreen    LightMagenta    LightRed    LightYellow    Magenta    Orange    Purple    Red    SeaGreen    SlateBlue    Violet    White    Yellow
我们可以使用X11的颜色数字来定义我们的颜色.这就可以在所有的系统上正确的显示,而不论是否使用X11系统.这种模式为#rrggbb,在这里rr是红色的数量,bb是蓝色的数量,gg是绿色的数量.
我们还可以在一个高亮显示行来定义几种终端的颜色,如:
:highlight Error term=reverse \ cterm=blod ctermfg=7 ctermbg=1
语法元素是由$VIMRUNTIME/syntax中的宏来定义的.然而为了使得事情变得更为简单,我们常会用下面的一些名字:
Boolean        Character    Comment        Conditional
Constant    Debug        Define        Delimiter
Error        Exception    Float        Function   
Identifier    Include        Keyword        Label
Macro        Number        Operator    PreCondit
PreProc        Repeat        Special        SpecialChar
Structure    Tag        Todo        Type
Typedef
除了这些语法元素,Vim还定义了下面的许多事物:
Cursor        光标下的字符
Directory    目录名称以及其他列出的特殊名称
ErrorMsg    在最底行显示出的错误信息
IncSearch    增长(Incremental)查找的查找结果
ModeMsg        在左下角显示的模式名称
MoreMsg        当Vim在显示一个很长的信息并且要显示更多的信息时的提示
NonText
Vim编辑器会在超出文件结尾时显示~.我们可以用@来表明一行不会在显示一屏上.这些语法元素可以用来定义用哪些颜色来显示语法元素
Question    当Vim询问问题时.
SpecialKey    命令:map列出键盘的映射.这个选项定义了用特殊键来进行高亮显示
StatusLine    当前窗口的状态行.
StatusLineNC    其他窗口的状态行
Title        命令:set all,:autocmd的输出标题
Visual        这个颜色用来高亮显示可文本块
syntax选项包含有用于当有语法高亮显示的语言.我们可以用下面的命令来关闭语法显示:
:set syntax=off
如果想要打开,我们就用下面的命令:
:set syntax=on
vi编辑器的学习使用(二十四)
在这一次的学习中我们会介绍一些更多的关于缩写和键盘映射的问题.
我们在编辑的过程中可以用:abbreviate命令来设置一个缩写,那么我们如何来移除一个缩写呢?我们可以用命令:unabbreviate来移除一个缩写.例如我们用下面的命令来设置一个缩写:
:abbreviate @a fresh
如果我们要移除这个缩写我们可以用下面的命令:
:unabbreviate fresh
如果我们要清除所有的缩写,我们可以用下面的命令:
:abclear
我们用上面的命令定义的缩写可以正常的工作在插入模式和命令行模式两种状态下.如果我们是在文本中输入@a,他就会扩展为fresh,而如果我们在:命令行中输入@a,他也可以扩展成为fresh.如果我们要定义一个只工作在插模式下的缩写,我们可以用这样的命令:
:iabbreviate @a fresh
这也就是说如果我们在命令行输入@a,那么他仅是@a,而不会扩展为fresh.如果要取消一个插入模式的缩定义,我们可以用下面的命令:
:iunabbreviate @a
同样的我们可以用下面的命令来清除所有的插入模式的缩写定义:
:iabclear
相类似的,如果我们要定义一个只在命令行模式下工作的缩写,我们可以用命令:cabbreviate来完成,而取消这个定义的命令为:cunabbreviate,如果要清除所有的缩写列表,我们可以用下面的命令:
:cabclear
如果我们要列出所有的缩定,我们可以用下面的命令:
:abbreviate
在这个命令的执行结果第一列显示出缩写的类型,标记如下:
c    命令行模式
i    插入模式
!    两种模式均可
CTRL-C命令可以使得Vim离开插模式.这个命令与命令的不同之处就在于在回到正常状态的过程中并不会检查一个缩写.
map命令可以使得我们将一定的模式与键盘对应起来.例如如果我们要使用F5来复制来选中的文本到寄存器v中,我们可以用下面的命令来定义:
:map "vy
这样的定义的F5在正常以及可视模式下都可以使用.但是也许我们真正希望的是只在可视模式下来使用这个命令,这时我们可以用下面的命令来进行定义:
:vmap "vy
这里的v是告诉Vim这样定义的命令是只在可视模式下使用.
如下面的列表:
Command    Normal    Visual    Operator Pending    Insert    Command Line
命令    正常    可视    运算符延伸        插入    命令行
:map    y    y    y   
:nmap    y   
:vmap        y
:omap            y
:map!                        y    y
:imap                        y
:cmap                            y
现在假如我们要定义以使得命令d可以删除C程序的文本块.与此相类似的,y可以将程序块复制到未命名寄存器中.所以我们要做就是要傅F7来选择当前的文本块.我们可以使用下面的命令:
:omap a{
这 个命令会使得在operator-pending模式下选择文本块.有了这样的映射,当我们输入d命令中的d 时,我们就进入了operator-pending模式.然后执行命令就可以地命令a{了,这样我就可以选择文本块了.因为我们执行 了d命令,所以这个文本块被删除了.
其他的一些映射命令如下:
:map lhs rhs
这个是将lsh映射到rhs,所以当我们按下lhs时我们实际上执行的是rhs
如下面的映射命令:
:map ^A dd
:map ^B ^A
执行了这样的命令以后,当我们输入CTRL-A时Vim会删除一行.而CTRL-B也会是同样的作用.当我们使用控制字符时,我们必须用CTRL-V来引用他.换句话说如果我们要达到:map ^A dd的目的,我们就可以用下面的命令来完成:
:map CTRL-VCTRL-A dd
(似乎这个命令这样的做是不成的)
如果我们要重新映射,我们可以使用命令:noremap,例如:
:noremap lhs rhs
如果我们要取消一个映射,可以使用:unmap命令,如:
:unmap lhs
如果我们取消所有的映射,我们可以使用命令:
:mapclear
但是我们在使用这个命令时要注意,因为这个命令也会移除所有我们自定的默认映射.
如果我们要列出所有的映射,我们可以用下面的命令:
:map
第一列的标记指明了这样的映射可以在哪一种模式下工作:
字符    模式
    正常,可视,运算符(operator-pending)
n    正常
v    可视
o    operator-pending
!    插入和命令模式
i    插入模式
c    命令模式
第二列指出各种lhs的任何映射.第三列是rhs的映射值.如果rhs是以*开头的,那么这个rhs是不可以重新映射的.
:map命令可以列出所有的映射,而:map!只列出插入和命令行模式的映射.而:imap,:vmap,:omap,:nmap命令只是列出指定模式的映射.在默认的情况下,Vim允许循环映射,要关掉这个特征,可以执行下面的命令:
:set noremap
如果我们执行下面的命令:
:abbreviate @a ad
:imap ad adder
这样当我们输入@a时,字符ad会被插入,然而ad又映射到插入模式的字符串adder,所以字符串adder会被插入到文本中.如果我们使用用命令:noreabbrev就可以避免这样的问题.

vi编辑器的学习使用(二十五)
虽然Vim编辑器在可视的情况下可以极好的完成我们的工作,但是有时我们是也需要使用命令行命令的.例如在脚本中命令行命令的使用会更容易,同时有许多特别的命令是只在命令模式下才可以实现的.
:delete命令可以删除一个范围内的文本行.例如我们要删除1到5行,我们可以用下面的命令来做:
:1,5 delete
:delete命令的一般格式如下:
:range delete register count
在 这个命令中的register是我们的删除的文本要放入的寄存器.这个可以是我们用a-z命名的寄存器中的一个.如果我们使用大写的字符做为寄存器的名 字,那么这些文本就会被添加到已经存在文本的寄存器中.如果没有指定这个参数,那么就会使用未命名的寄存器.而count则指出要删除的行数.range 则是指明要使用的行.
我们还可以使用命令来删除含有指定字符串的行.如我们可以用下面的命令来删除从第一个包含字符串hello到第一个包含字符串goodbye的行之间所有的行:
:/hello/,/goodbye/ delete
在 这里我们要注意的就是如果goodbye在hello之前出现,那么这个命令就不会正常的工作了.我们还可以使用偏移量(offset)来重新定义要查找 的字符串.例如/hello/+1是指含有hello字符串行的下一行,因而我们还可以使用下面的命令来进行删除的操作:
:/beach/+1,/seashore/-1 delete
我们还可以使用下面的一些简写的运算符:
\/    向前查找上一次使用的模式
\?    向后查找上一次使用的模式
\&    向前查找上一次使用的子模式
(注:这个地方不懂,也不晓如何来用)
我们还可以使用链式的模式,例如下面的命令在找到字符串first以后要查找second字符串:
/first//second
所以我们还可以使用下面这样的删除命令:
:/hello//goodbye/ delete
我们还可以指定行号,用来指明在第几行进行查找,如果我们要从第七行开始查找,我们可以使用下面的命令:
7/first/
如果我们只是执行一个:命令,那么Vim编辑器就会进行命令行模式然后允许我们指定一个要删除的范围.如果我们在这个命令之前指定了一个数字,例如5:,那么要删除的范围就是这个数字所指定的范围(包括当前行).事实上这样指定的范围如下:
:...+count-1
例如我们在一段文本中执行下面的命令:
3:delete
这实际上是执行下面的命令:
:...+2 delete
这个命令可以删除当前行以及当前行以下的两行,总计三行的文本.
删除命令的另一个形式如下:
:line delete count
在这种情况下,:delete命令回到line所指定的行(默认为当前行),然后删除count行文本(包括当前行).
:copy命令是将几行的文本从一个地方复制到另一个地方.这个命令的一般格式如下:
:range copy address
如果没有特别指定,range默认是指当前行.这个命令是拷贝range所指定的范围行的文本到address指定行的后面.
与:copy命令相类似的是:move命令,所不同的只是这个命令是移动而不复制.
假 如我们要在我们正编辑的文本中插入一些行,而由于某些原因,我们要使用命令行的方式来完成这样的工作.这时我们就要将光标移动我们希望新行出现的上一行. 换句话说,我们是希望将插入的文本出现在当前行的后面.然后我们可以执行命令:append来开始我们的插入过程,我们输入我们要插入的内容并用句号 (.)来结束一行的输入.例如我们在一个测试文本中执行下面的命令:
:1append
这个命令是要第一行的后面插入我们新的文本行.执行这个命令后,我们可以在Vi的底部输入我们要插入的内容.当我们要结束我们的输入时,只要在一新行输入.就可以了.这样我们输入的内容就会出在第一行的后面了.
:append命令的一般格式如下:
:line append
我们输入的新文本将会插入在line所指定的行后面.
:insert命令也可以插入文本,这个命令的一般形式如下:
:line insert
这个命令与:append命令相似,所不同的是后者是当前行的后面插入文本,而前者是在当前的前面插入文本.
我们不必打开number选项也可以实现在打印一行文本时打印此行的行号.命令:#与:print命令相类似,所不同的只是前者可以打印出行号.
例如在我们的测试文本中执行下面的命令:
:1 print
执行结果如下:
A UNIX sales lady,Lenore,
而我们执行下面的命令:
:1#
执行结果如下:
1 A UNIX sales lady,Lenore,
选项list可以使得不可见的字符成为可见字符.命令:list可以列出指定的行,而且这个命令全认为list选项已经打开.如下面的命令:
:1,5 list
这个命令就可以列出1-5行的内容.
这个命令与:print命令不同的地方只是这个命令也可以打印出回车,Tab等不可见的字符.
:z命令可以打印出一个范围内的文本行(默认情况下为当前行)以及这一行附近的行.例如我们执行下面的命令:
:100 z
这个命令会打印出从第100行开始的直到当前屏幕满屏的所有的文本行.
这个命令可以指定一个数字,用来表示除了打印指定的行以外要额外打印的行.例如下面的命令:
:100 z 3
这个就使得Vim除了打印第100行还要另打印额外的三行.
:z命令以后还可以再跟上一个代码用来表示要显示多少的文本.可用的代码如下:
代码    起始行        结束行        当前行
+    当前行        向前一个屏幕    向前一个屏幕的下一行
-    向后一个屏幕    当前行        当前行
^    向后两个屏幕    向后一个屏幕    向后一个屏幕
.    向后半屏    向前半屏    向前半屏
=    向后半屏    向前半屏    当前行
基本的substitute命令格式如下:
:range substitute /from/to/flags count
这里的定义符可以是除了字母,数字,反斜线,双引号或是竖线以外的任何字符.在Vim编辑器中Vim还使用一些特殊的字符来表示特殊的事物.例如*表示重复0次或是多次.如果我们设置了nomagic选项,那么这些字符的特殊意义就会被关掉了.
命令:smgic可以执行一个替换操作,但是这个命令要求我们设置了magic选项.
例如我们可以使用只有一行的文件来测试这些命令.我们可以用命令将整个文件打印出来:
:%print
Test aaa* aa* a*
然后我们设置了magic选项并且执行替换命令 .p标记告诉编辑器打印出他所改变的行:
:set magic
:1 substitute /a*/b/p
命令的执行结果如下:
bTest aaa* aa* a*
这 个命令只是改变了一行开始的部分.为什么会将Test变为b*Test而且并没有a呢?这就是因为*可以匹配0次或是多次,而Test正是以0个a开始 的.但是为什么只是替换了一次呢?这是因为:substitute命令中是改变第一个出现的地方.如果我们使用g标记就可以替换全部的匹配项了,我们撤销 刚才的命令并执行下面的命令:
:undo
:1 substitute /a*/b/pg
这个命令的执行结果如下:
bTest b*b b*b b*
现在我们在关闭magic选项的情况下再做一次:
:undo
:set nomagic
:1 substitute /a*/b/pg
这个命令的执行结果如下:
Test aab ab b
在没有设置magic的情况下,*仅是一个*.
而:smagic命令则是在执行替换命令时强制转换*以及其他一些字符的意义,例如我们执行下面的命令:
:undo
:smagic /a*/b/pg
这个命令的执行结果如下:
bTest b*b b*b b*
而相类似的是命令:snomagic选项强行关掉magic选项:
:undo
:snomagic /a*/b/pg
这个命令的执行结果如下:
Test aab ab b
&命令可以重复执行替换.这个命令可以保存旧的from和to的字符串,但是允许我们使用不同的范围(range)和标记(flags).这个命令的一般形式如下:
:range & flags count
例如我们执行下面的命令:
:1 substitute /a\+/b/p
这个命令的执行结果如下:
Test b* aa* a*
这个命令可以改变第一个出现from所指的字符的地方.但是我们希望是的整个一行都要发生相应的替换,这时我们可以重复这一次替换命令:
:&g
这一次在命令的执行过程中就不会打印执行结果,因为我们在这里指定的标记是g,而不是p.这个命令的执行结果如下:
Test b* b* b*
命令:&和命令:substitute在没有指定替换字符串的情况下作用相同,都可以执行上一次的替换命令.
在正常的命令状态下命令&可以重复上一次的:substitute命令.例如如果我们执行下面的命令就会将第五行中的字符manager变为idiot:
:5 substitute /manager/idiot/
这时如果在正常的命令模式下我们执行命令&,那么这一行中的下一个manager字符串也会发生变化.如果我们下移一行然后执行命令&,那么这一行也会发生相应的变化.如果我们在这个命令中指定了count,那么这个命令就可以作用多行.
:~命令与命令&g相类似,所不同的是前者使用的字符是上一次使用/或是?查找时使用的字符串,而不是上一次:substitute命令中的字符串.这个命令的一般格式如下:
:range~ flags count
在一般的情况下,:substitute命令只是改变一行中第一个出现指定的字符串处,除非我们使用了g标记.如果我们希望g标记能成为默认的设置,我们可以使用下面的命令:
:set gdefault
但是这里我们要注意的就是也许这样的设置会打断我们的一些脚本.
到了现在我们所说过的一些命令都是有一个限制的,那就是我们所要执行的命令只作用在相邻的行上.然而有时我们所希望是改变含有特定类型的行,这时我们就要用到:global命令了.这个命令的一般形式如下:
:range global /pattern/command
这个命令可以告诉Vim编辑器对在指定的范围内包含有指定的类型的所有行执地指定的命令.例如如果我们要打印出一个文件中所有包含单词Professor的行,我们可以使用下面的命令:
:%global /Professor/ print
而命令:global!将对所有的行执行指定的命令,但是却不匹配指定的类型.与其相类似的是:vglobal命令.
命令:ijump查找指定的类型,并且会跳转到指定的范围内第一个出现的单词处.这个命令不仅会在当前文件中进行查找,而且会在由#i nclude所包含进来的文件中进行查找.这个命令的一般格式如下:
:range ijump count [/]pattern[/]
如果我们在这个命令中指定了count,那么就会跳转到第count个类型出现处.这个类型会被看作是精确的文本,除非是由斜线括起来的.
例如下面的一个Hello.c的文件:
#i nclude
int main()
{
    printf("Hello World\n");
    return (0);
}
如果我们执行下面的命令就会跳转到第一个含有 define EOF的行处:
:ijump /define\s*EOF/
在我们目录的情况,他是在包含进来的文件stdio.h中
与这个命令相类似的是命令:ilist,所不同的只是这个命令是列出相应的行而不是跳转到相应的行.
命令:isearch与:ilist命令相类似,只是这个命令列出第一个出现指定内容的行.
最后命令:isplit是命令:ijump和命令:split的组合.
我们已经知道用命令[CTRL-D来跳转到当前光标下的宏定义处.下面的命令也可以起到同样的作用:
:djump name
例如我们要跳转到宏MAX处,我们可以用下面的命令:
:djump MAX
执行这个命令我们并不必需要知道我们定义的宏的全名,如果我们只是知道宏名的一部分,我们就可以使用由斜线括起来的常规表达式来进行相应的查找.如下面的命令:
:djump /MAX/
我们还可以指定参数来控制这个命令的查找范围,如下面的命令:
:50,100 djump /MAX/
这个命令只在第50到第100行内进行相应的查找.
如果我们希望查找到是第二个而不是第一个宏定义,我们可以通过指定count参数来做到.例如我们要查找第二个MAX的定义处,我们可以用下面的命令:
:djump 2 MAX
下面的命令会在一个新窗口内显示宏定义:
:range dsplit count [/]pattern[/]
这个命令是命令:split和命令:djump的组合.
命令:dlist与命令:dsplit相类似,只是前者并不会移动到一个宏的定义处,而是列出匹配的宏定义.
而命令:dsearch只是显示第一个匹配的宏定义.如果命令:ilist,ijump,:djump,:dlist,:dsearch带上!选项,那么在注释内的定义也可以进行查找.
如果我们要改变当前Vim的工作目录,我们可以用下面的命令:
:cd dir
这个命令与系统的cd命令相类似.如果没有指定目录,那么就会回到我们的用户主目录.
要查看当前Vim的工作在哪一个目录下,我们可以有用下面的命令:
:pwd
要回到前一个工作目录,我们可以用下面的命令:
:cd -
下面的命令可以打印出当前文件的名字以及一些相关的行信息:
:file
如果我们要改变当前文件的名字,我们可以使用下面的命令:
:file name
例如我们正在编辑的文件名为complete.txt,我们可以使用:write命令进行保存.现在我们要缩短文件并且存为summary.txt,我们可以执行下面的命令:
:file summary.txt
如果我们继续进行编辑,那么所的改动都会被存入文件summary.txt中.
与:file命令相似,命令:=可以打印出当前行的行号.
:write命令可以将缓冲区或是一个文件中指定范围内的文本存入.他还有一些其他的选项.例如下面的命令就可以将我们正编辑的文件内容追加到文件collect.txt中:
:write >> collect.txt
如果这个文件并不存在,那么这个命令就会给出错误信息.如果我们要强行追加,可以使用!选项:
:write!>>collect.txt
:write命令不仅可以保存文件,而且可以将文件导入其他的程序.在Linux系统中,我们可以用下面的命令将文件发送到打印机:
:write !lpr
(注::write! lpr与:write !lpr这两个命令的不同,前才是强行保存文件而后者则是将文件发送到打印机)
命令:uddate与命令:write相类似,所不同的只是如果缓冲区没有被修改,那么这个命令就不会起作用了.
:read命令将会读入一个文件.这个命令的一般格式如下:
:line read file
这个命令会将名为file的文件读入并且插入在line后面.如果没有指定文件,那么就会使用当前的文件,如果没有指定要插入的行,那么就会使用当前的行.
与:write命令相类似,:read命令可以使用一个命令而不是一个文件.如果要读入一个命令的输出并插入到当前行的后面,我们可以使用下面的命令:
:line read !command
我们在以前的学习曾学过如何在寄存器中录制宏.如果我们要在命令行中使用这些宏,我们可以用下面的命令来执行寄存器中的宏内容:
:line@register
这个命令会将光标移动到指定的行,然后执行寄存器中的内容.这就意味着下面的命令执行上一次的命令行:
:@:
如果要执行上一次的:@register命令,我们可以用下面的命令:
:line@@
命令:>使得文本右缩进,:<命令使文本向左缩进.例如下面的命令将会使第五行到第十行向右缩进:
:5,10>
:change命令与:delete命令相类似,所不同的只是他还同时执行:insert命令,也就是有我们可以同时输入我们要插入的文本.
命令:startinsert命令可以开始插入模式,就像是我们在正常模式下执行i命令一样.
如果我们要将几行合并为一行,我们可以使用命令:join,在这个命令的执行中将会使用空格来分隔这几行.如果我们不希望加入空格,我们可以用下面的命令来合并:
:join!
下面的命令可以将指定的行的文本复制到寄存器中:
:range yank register
如果没有指定寄存器,将会使用未命名寄存器.
:put命令会将寄存中的内容粘贴到指定的文本行的后面.例如要将寄存器中的内容粘贴到第五行的后面,我们可以用下面的命令:
:5put a
如果要将文本放在这一行的前面,我们可以用下面的命令:
:5put! a
:undo命令会撤销上一次的命令操作,与u命令相类似.而:redo命令会重做撤销的操作,与命令CTRL-R命令相类似.
如果要标记一行的开始,可以用下面的命令:
:mark {register}
如果指定了行,那么那一行将会被标记.命令:k将会起到同样的作用,只是我们不需要在寄存器名前加上一个空格.例如下面的命令:
:100 mark x
:100 ka
命令:preserve可以将整个文件写入swap文件.这就使得我们可以在没有原始文件的情况下来修复我们的编辑部分.
如果我们要执行单一的Shell命令,我们可以用下面的命令:
:!cmd
cmd就是我们要执行的系统命令.
例如要查看当前的日期,我们可以用下面的命令:
:!date
如果我们要重复上一次的Shell命令,我们可以用下面的命令来做:
:!!
最后下面的命令可以挂起Vim而进入命令提示行:
:shell
现在我们就可以执行各种的系统的命令了.在我们完成我们的工作以后,我们可以用exit命令回到Vim编辑器.
下面的一些选项可以控制命令的执行:
shell        我们要执行的命令名
shellcmdflag    跟在命令后的标记
shellquote    在命令中的引用字符
shellxquote    命令中的引用字符和重定向
shellpipe    使用管道的字符串
shellredir    重定向输出的字符串
shellslash    在文件名中使用向前的斜线(只在DOS中使用)
命令:history可以当前命令模式下的命令历史
Vim编辑器可以记录各种命令的历史,下面的标记指出所记录的历史类型;
c    cmd    :    命令行历史
s    search    /    查找字符串历史
e    expr    =    表达式寄存器历史
i    input    @    输入行历史
a    all        所有的历史
如果我们列出所有的历史,我们可以用下面的命令:
:history all
:history命令的一般格式如下:
:history code first,last
如果没有指定first和last,那么就会列出所有的命令.first参数默认是指历史第一个输入的,而last就是指最后一个.负数是指由历史的结束处向前的数的第几个.例如-2是指最后个命令的输入.
例如下面的命令列出第一个到第五个的命令行历史:
:history c 1,5
而下面的命令则是列出了上五次的查找历史:
:history s -5
history选项可以用来控制记录的历史命令数.例如我们要将记录的历史命令数增加为50,我们可以用下面的命令:
:set history=50
Vim编辑器可以记录上几次的错误以及在屏幕最后一行显示的信息.要查看这些信息,我们可以用下面的命令:
:messages
下面的命令可以使得信息的输出在显示在屏幕的同时会拷贝到一个文件中:
:redir > file
如果要停止拷贝,可以使用下面的命令:
:redir END
这个命令在保存调试信息时会显得更为有用.
我们还可以用:redir命令将输出追加到文件中:
:redir >> file
:normal命令可以使我们执行一个正常模式下的命令.例如下面的命令是将光标下的单词改为DONE:
:normal cwDONE
在行这些命令时要求命令必须是一个完整的命令.如果我们已经挂起Vim然后执行命令时,Vim显示全直到命令完全时也会发生变化.
下面的命令会将当前的文本写入文件,然后退出:
:exit
如果我们使用!选项,即时这个文件被标记为只读,那么Vim也会强行保存.
我们还可以在命令行指定一个文件名,那么当前的内容就会在退出以前写入我们所指定的文件,例如下面的命令:
:exit save.txt
如果我们只是想着将文件中的一部分保存到另一个文件,我们可以指定一个范围来保存.例如要保存100行,我们可以用下面的命令:
:1,100 exit save.txt
下面的命令与:exit命令相类似,不同的是这个命令总是会保存文件:
:range wq! file
而:exit命令只是在文件发生改变时才会保存.
阅读(755) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~