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命令与<Tab>命令相类似,只是前者在文本中插入一个缩进,而这个缩进的大小由shiftwidth选项来控制的.如果我们设置了shiftwidth选项的值为4,我们输入<Tab>,光标会移动以后第八列处,这是因为<Tab>缩进的大小是由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><Tab><Tab>        一个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时重新缩进此行.
:    当我们在一个标签或是事件的描述后输入:时会重新缩进此行.
<^>,<<>,<>>,<o>,<e>,<O>    在尖括号中的精确的字符
而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,而这个文件的内容类似于下面的:
#include "main.h"
#include "lib.h"

int main(int argc,char*argv[])
现在我们要查看一下lib.h中一个子程序的声明.一个办法是我们可以执行下面的命令:
:vi ../lib/lib.h
这个命令是假定我们知道lib.h的位置所在.但是在这里我们会有一个更好的方法.首先我们将光标放在下面一行中的文件名上:
#include "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/**,.,,
如果我们想确定一下我们可以查找到所有的#include文件,我们可以使用下面的命令:
:checkpath
这个命令的作用范围不仅仅是我们正在编辑的#include目录,而且包括任何他们#include的目录,结果就是要查看所有的#include文件.
在这种情况下,有许多的文件要包含文件stddef.h和stdarg.h.但是Vim却不能找到这些文件.如果我们要告诉VimLinux特殊的include目录,我们要以执行下面的命令:
:set path+=/usr/include/linux
但是:checkpath命令只是列出所以不能找到的文件,如果我们要列出所以的#include文件,我们可以用下面的命令:
: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=<Esc>X stop=<Esc>Y
有了这样的定义,当Vim要显示关键字时,例如显示if就会显示为<Esc>Xif<Esc>Y
如果我们对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

posted @ 2005-08-07 09:36  jlins  阅读(439)  评论(0编辑  收藏  举报