我们可以通过执行命令CTRL-K character1 character2来插入一个特殊字符.我们也可以用下面的命令为定义们的自己的特殊字符:
:digraphs character1 character2 number
这就是告诉Vim编辑器当我们输入CTRL-K character1 character2命令以后要插入数字表示为number的字符.
如果我们的工作要我们插入很多的特殊字符,我们可以用下面的命令打开digraph选项:
:set digraph
关闭这个选项的命令为:
:set nodigraph
(注:这部分内容部是看不明白,也做不出结果)
命令~可以改变字母的大小写.~命令的执行结果是由选项tildeop的值来控制的.如果我们没有设置这个选项,那个这个命令就像正常一样的动作:
:set notildeop
但是如果我们设置了tildeop选项,那么这个命令的语法就变成了~motion的形式:
:set tildeop
例如下面的句子:
this is a test
如果我们没设置这个选项,那么在我们执行命令时就会实单个字符的大小转换.但是在我们设置了这个选项以后,我们将光标放在第一t上并执行~ft的结果则为
THIS IS A Test
这个命令会使得当前光标以后第一t和光标间的字符全部转换为大写.如果在这个句子中还有小写的字符,那么这个命令还可以执行第二次.直到句子中的字符全部为大写为止.
这时的命令还可以指定字符转换的个数和方向.例如命令3~l是从当前字符开始向右3个字符进行大小写的转换.与这个命令方式相类似的是g~motion格式的命令,所不同的仅是后者不依赖于tildeop选项的设置.命令g~g~或是g~~是进行整个一行的转换.
其他的一些大小写转换的命令还有:
gUmotion命令是使得当前光标处到motino所指处的字符全部变为大写.而gUU或是gUgU则是作用在整个行上.如果指定了参数count则所指定的行都会发生变化.而gumotion,guu,gugu则是和上面所说的命令相类似,所不同的只是他们是将字符变为小写.
我们在用Vim进行编辑的时候可以进行多次的撤销命令,这个次数是由选项undolevels来指定的.如果我们要将这个值设为5000,那么我们可以用下面命令来做到:
:set undolevels=5000
命令ZQ是命令:q!的另一种说法.这个会放弃我们所做更改然后退出.
命令:write则是保存文件.命令:quit是退出Vim.我们可以使用一个缩写来达到保存退出的目的::wq
这个命令可以用参数来指定保存退出时使用的文件名,如:
:wq filename
如果这个文件存在且是一个只读文件时我们会得到一些错误信息,当然了我们可以强制执行这个命令:
:wq! filename
我们还可以将指定的行进行保存:
:1,10 wq filename
与命令:wq相类似的命令是:xit
vi编辑器的学习使用(十九)
Vim编辑器强大的搜索引擎可以使得我们快速的执行各种类型的查找,从而大的方便了我们的编辑工作,使得我们的编辑工作更加快速和高效.
我们在进行查找的过程中可以打开高亮显示选项,这样在我们找到我们想要的字符后,Vim就会将字符串进行高亮显示,我们也可以很方便的知道我们要找的字符串在哪里.我们可以使用下面的命令来打开高亮显示选项:
:set hlsearch
关闭这个选项的命令为:
:set nohlsearch
在默认的情况下Vim编辑器是很敏感的,也就是Vim编辑器可以很好的来区分一个单词的大小写,从而可以准确的查找得到我们想要的字符串.例如如果一个文件中有这样的几个字符串:
include,INCLUDE,Include.当我们使用命令/include来查找字符串时只有include字符会被高亮显示.
但是如果我们打开ignorecase选项后再执行这个命令结果就不一了,这时所有的类似的字符都会被高亮显示.打开这个选项的命令为:
:set ignorecase
但是这样的查找结果并不是我们想要的,也不是我们所希望发生的,因而我们常用下面的命令选项设置:
:set noignorecase
这样Vim就可以正确的查找我们想要的字符串.
如果我们设置了ignorecase选项后,我们想要查找字符串word,而匹配的则可能是word,Word,WORD.如果我们要查找字符串WORD,匹配的结里也是一样的.但是如果我们设置了以下的两项后的执行结果就会变得不一样了:
;set ignorecase
:set smartcase
经过这样的设置以后,如果我们输入的是小写字符,那么Vim就会匹配各种可能的组合,这时与设置了ignorecase的情况相同,但是如果我们在输入中有一个大写字符,那么这时的查找就变成了精确查找了,与设置了noignorecase的情况相同.
在默认的情下,我们输入要查找的字符串,vim是从当前光标处向前查找,直到文件的结尾,如果没有打到,那么就会从文件的开头开始查找,直到光标所处的位置.我们可以通过设置选项nowrapscan来禁止这种循环查找的方式,这个命令如下:
:set nowrapscan
这样以后如果已经查找到文件的底部时就会在Vim底部显示出一条错误信息.如果我们想要回到正常的状态,我们可以使用下面的命令;
:set wrapscan
如果我们正处在一个很长的查找过短中而我们想要停止这一查找开始我们新的工作,这时我们可以使用CTRL-C命令,如果是在Windows系统上则要使用CTRL-BREAK命令.
我们在编辑文件的过程中还可以使用立时查找的命令.如果我们想快速查找当前光标下的字符串,我们可以使用命令*,这个命令可以向前查找与当前光标下的单词精确匹配的字符串.而命令#则向前查找与当前光标下的字符精确匹配的字符串.换句话说如果当前光标下的字符串为word,在执行*命令查找时并不会与Word相匹配.与这个立时查找命令相类似的就是g*命令.这也是一个立时查找的命令,只不过他不会进行严格的整字匹配,如果用这个命令来查找word那么就有可能和Word相匹配.而g#命令与其相同,只不过他是向相反的方向进行查找匹配.
在默认的情况下,在查找时Vim会将光标放在第一个匹配的结果的开始处.我们也可以指定查找结束后光标所处的位置.对于向前查找的命令我们可以斜线后用数字来指明光标所处的位置,如下面的命令:
/set/2
这个命令会在查找结束后将光标入在第一个set字符串后第二行的开始处.
在这个命令中这个数字可以是正数也可以是负数.如果仅是一个简单的数字,光标会被放在第一个匹配字符串处后或是前的数字所指定的行的开始处.正是向后,负数是向前.如果斜线后是b和数字的,那么在查找结束后,光标将会被置于第一个匹配字符串的开始处,然后向左或是右移动n个字符,这里的n即为数字所指定的数.如果为正数则是向右移动,如果是负数,则是向左移动.如下面的命令:
/set/b2
这个命令会使用Vim在查找结束后将光标放在第一个匹配字符的开始处,然后向右移动两个字符,也就是说最后光标会位于第一个匹配字符串中的t的位置.将b改为s也是一样的效果.
与参数b或是s相类似是e参数,这个参数会使得光标放在第一个匹配字符串的结尾处.同样我们也可以指定数来指是向右还是向左移动光标以及移动的字符数.如下面的命令:
/set/e
这个命令会使光标放在第一个匹配字符处的结尾处,在没有指定数字时是这个样子的.而下面命令:
/set/e2
这个命令是会将光标放在第一个匹配字符串的结尾处,然后向右移动2个字符.这里的数字如果是正数则向右移,如果为负数,则向左移.
例如下面的命令:
/set/e+2
这个命令是告诉Vim在查找set字符串结束后将光标放在第一个匹配字符串的结尾处,然后向右移动两个字符.在这里我们将这个数字称为偏移量.如果我们要重复上一次的查找但是需要不同的偏移量我们可以用下面的命令:
//5
不使用偏移量时我们可以指明一个空的偏移量,如:
//
例如下面的一些例子:
/set/e+2
向前搜索字符串2,并将光标放在第一个匹配字符串的结尾处,然后向右移动2个字符
/    重复前一次的查找,使用相同的偏移量.
//    重复前一次的查找,但是不使用偏移量.
我们还可以使用查找命令?来进行类似的查找,例如:
?set?b5
这个命令是告诉Vimu将光标放在最后一个匹配字符串的开头部分,然后向右移动5个字符
??-2命令则继续前一次的查找命令,但是使用新的偏移量.
??命令是继续前一次的查找命令,但是不使用偏移量.
但是有一件事我们要清楚的就是我们在用偏移量进行光标定位时的查找是从当前光标所在处开始的,这会给我们带来一些麻烦.例如我们在执行命令/set/-2时Vim会将光标放在第一匹配的字符串处,然后上移两行.当我们用n命令来重复上一次的查找时,我们会找到我们刚才找到过的那个字符串,然后再向上偏移两行.这个结果就是不论我们输入了多少的次n命令,我们仍是在原地踏步的,哪里也去不了.
Vim使用通用的表达式(regular expressions)来进行逻辑查找.我们在以前讨论过用简单的字符串进行查找,但是这里我们将要看到的通用字符串查找要简单字符查找的功能强大得多.通过在我们的命令中使用通用表达式,我们可以查找任何一种字符类型,例如我们可以查找以t开头而以ing结尾的字尾串(通用表达式为\<t[^]*ing\>).然而这种强大的功能也是要付出一定的代价的.通用表达式是神秘的和简洁的.也许我们要花上很上的一段时间才会习惯这种查找方式,然后才能掌握这个强大的查找工具.
在学习这些通用表达式的查找的过程中我们最好将高亮显示这个选项打开,这样就可以使Vim高亮显示最后一次查找的匹配结果.打开高亮显示的命令为:
:set hlsearch
一个通用表达式是由一些元素组成的.这些元素是通用表达式中最小的匹配单位.一个元素可以是一个字符,例如a,与字符a相匹配,或者是一个特殊字符,例如$,匹配一行的结束.还可以是其他的字符,例如\<,是指一个单词的开始.
在通用表达式中,我们用\<来匹配一个单词的开始,用\>来匹配一个单词的结束.也就是说要将我们想要查找的字符串放在这两个中间.这样我们就可以精确的来查找我们想要查找的字符串,而不会有其他的一些匹配情况.而如果我们用简单字符串形式来查找,我们就会得到许多的匹配情况,甚至在一个单词中的组成部分也可以成为匹配情况.例如在文件中有Californian,Unfortunately.如果用命令/for来查找,那么就会找到这两个单词.而如果我们用通用表达式\<for\>来进行查找,则只会精确的查找到for,而不会用其他的匹配情况.这时的命令形式如下:
/\<for\>
我们在进行查找的时候还可以使用一些修饰符来进行表达式的组合.例如修饰符*就可以表示一个字符可以匹配0次或是多次.换句话说,Vim编辑器会进行尽可能多的匹配.所以通用表达式te*可以匹配te,tee,teee等等.基于还可以匹配t,为什么呢?因为在这里e可以匹配0次,所以就可以匹配t.而修饰符\+则表明这个字符可以匹配一次或是多次.所以表达式te\+可以匹配te,tee,teee等等.但是这一次这个表达式不可以再匹配t了,因为这里e最少要匹配一次.
最后一个修饰符\=表示一个字符匹配0次或是一次.这就是说表达te\=可以匹配t,te,但是不可以是tee,虽然这个命令会匹配tee的前两个字符.
还有一些特殊的字符可以来匹配一定范围的字符.如\a匹配一个字符,而\d匹配任何数字.所以表达式\a\a\a可以匹配任意三个字符.例如下面的命令可以查找任意四个数字:
/\d\d\d\d
我们还可以用下面的命令来查找任意后带一个下划线的三个字符:
/\a\a\a_
\a可以匹配所有的字符(小写的或是大写的).但是假如我们现在只要匹配元音字符又该如何来做呢?这时我们可以使用范围作用符[].范围作用符可以匹配一系字符中的一个.例如[aeiou]只匹配一个小写元音字符.所以表达式t[aeiou]n可以匹配tan,ten,tin,ton,tun.
我们还可以通过短横线来在括号内指明字符的范围.例如[0-9]可以匹配0到9中的任一字符.
我们还可以组合其他的字符.例如[0-9aeiou]可以匹配任意一个数字或是小写的元音字符.
而修饰符^可以指代除本身以外的所有字符.
下面列出一些匹配的情况:
表达式        匹配结果
one[\-]way    one-way
2\^4        2^4
2[\^*]4        2^4,2*4
如果我们要指找所有的大写字符又应如何来做呢?一个办法就是使用表达式[A-Z].还有一个办法就是我们可以使用预先定义的字符类.[:upper:]可以匹配大写字符.所以我们要指找大写字符也可以这样的来写:[[:upper:]].我们可以使用字符类来写出所有的字符:
[[:upper:][:lower:]].
在Vim中还有许多不同的字符类定义
我们还可以通过表达来指出一个字符重复的次数.这个的一般格式如下:
\{minimum,maximum}
例如表达式a\{3,5}可以匹配3到5个a.在默认的情况下Vim将会尽可能多的进行匹配.所以表达a\{3,5}最多可以匹配到5个a.
在这个命令格式中最小次数可以省略,Vim默认的情况下最小次数为0.所以表达式a\{,5}可以匹配0到5个a.最大次数也可以省略,在这种情况下Vim默认匹配无穷大.所以表达式a\{3,}最少可以匹配3个a,最多是尽可能的多.
如果我们只指定一个数字,那么Vim就会精确的匹配相应的次数.例如a\{5}只会精确的匹配5次.
如果我们在数字前加了一个负号(-),那么Vim在查找时就会尽可能少的进行匹配.
例如a\{-3,5}匹配3到5个a,但是会尽可能少的进行匹配.事实上这个表达式仅会匹配3个a,哪怕是我们的文件中用aaaaa,Vim也只会尽可能少的进行匹配.
表达式a\{-3,}匹配三个或是更多个a,并且尽可以少地的进行匹配.而表达式a\{-,5}可以匹配0到五个字符.表达式a\{-}可以匹配0到无穷大个字符.在通常情况下这个表达式匹配0个符,除非在他的后面还有字符或是表达式.例如[a-z]\{-}x将会匹配.cxcx中的cx.而表达式[a-z]*x将会匹配整个cxcx.最后表达式a\{-5}将会精确的匹配5个字符.
我们还可以使用运算符\(和\)定义一个组.例如表达式a*b可以匹配b,ab,aab,aaab等等.而表达式a\(XY\)*b可以匹配ab,aXYb,aXYXYb,aXYXYXYb等等.
我们还可以用或运算运符\|来查找两个或是多个可能的匹配.例如通用表达式foo\|bar可以查找foo或是bar.
现在我们知道了这样多的表达式的表示方法,那么我们如何来应用他们呢?例如我们现在要查的内容为1MGU103.这个字符串是由1个数字,3个大写字符,3个数字组成的.可以有几种方法来表示:
一是先表示前面的一个数字:[0-9],然后加入大写字符后就成为了:[0-9][A-Z].因为有三个大写字符我们可以加入精确匹配的数字:[0-9][A-Z]\{3}.最后我们再加入最后面的三个数字.所以最后的结果就成了:[0-9][A-Z]\{3}[0-9]\{3}
另一种利用\d指任何的数字,而\u指任何的大写字符.所以用这样的方法写成的表达示就为:
\d\u\{3}\d{3}.
从这里我们可以看到用这样的方式来查找要比第一种方法快得多.如果我们编辑的文件在采用这两种方法进行查找时会看出差别,那么我们的文件也许就是太大了.
我们还可以用这样的表达示:\d\u\u\u\d\d\d,这个也可以找到我们想要的内容.
最后我们还可以用字符类来写出我们的表达式:
[[:digit:]][[:upper:]]\{3}[[:digit:]]\{3}
这四种方法都可以很好的来完成我们的工作,我们只要记住一种我们容易记住的就可以了.毕竟我们可以记住的简单的方法要比我们不能记住的精妙的方法快得多啊.
到现在我们所有的讨论和方法都是在认为我们已经打开magic选项的基础上来做的.如果这个选项被关闭了,那么我们在通用表达式中的许多的特殊字符就失去了他们神奇的魔力,我们只有通过字符转义才可以正常的来使用.
关闭magic的选项命令为:
:set nomagic
这时*,.,[,]就都被认为只是平常的字符了.如果我们还想用*来指0次或是更多次就要用到转义:\*.
所以我们应保证magic选项是打开的,这样我们也才可以使用Vim强大的搜索能力,而这也正是Vim默认情况下所做的.
一些常用的偏移(Offset)定义:
+[num]        光标置于第一个匹配字符下第num行的开始处.
-[num]        光标置于第一个匹配字符上第num行的开始处.
e        匹配字符串的结尾处.
e[num]
光标置于第一个匹配字符串的结尾处,然后移动num个字符,如果为正,向右移,为负,向左移.
b s        第一个匹配字符串的开始处.
b[num]
s[num]
光标置于第一个匹配字符串的开始处,然后移动num个字符,如果为正,向右移,为负,向左移.
常用的通用表达式如下:(认为magic选项打开)
简单的元素:
x    字符x   
^    一行的开始处
$    一行的结尾处.
.    单一的字符
\<    查找字符串的开始标记
\>    查找字符串的结束标记.
范围运算符:
[abc]        匹配a,b或是c
[^abc]        匹配除abc以处的字符
[a-z]        匹配从a到z的所有小写字符
[a-zA-Z]    匹配所有字符,包括大小写.
字符类:
[:alnum:]    匹配所有的字符和数字
[:alpha:]    匹配所有的字符
[:ascii:]    匹配所有的ASCII字符
[:backspace:]    匹配退格符<BS>
[:blank:]    匹配空格和Tab
[:cntrl:]    匹配所有的控制字符
[:digit:]    匹配所有的数字
[:escape:]    匹配Esc
[:graph:]    匹配所打印的字符,不包括空格
[:lower:]    匹配所有的小写字符
[:print:]    匹配所有的要打印字符,包括空格
[:return:]    匹配所有的行末符号(包括<Enter>,<CR>,<NL>).
[:punct:]    匹配所有的功能符号
[:space:]    匹配所有的空白符
[:tab:]        匹配Tab
[:upper:]    匹配所有的大写字符
[:xdigit:]    匹配十六进制数字.
类型:
\(pattern\)    标记一个类型以后使用
\1        与第一个在\(\)中的子表达式匹配的字符串匹配相同的字符串
例如表达式\([a-z]\)\1可以匹配aa,bb或是类似的.
\2        与\1相类似,但是是使用第二个子表达式
\9        与\1相类似,但是是使用第九个子表达式
特殊字符:
\a    大小写字母字符
\A    除了a-zA-Z以外的字母字符
\b    <BS>
\d    数字字符
\D    非数字字符
\e    <ESC>
\f    由isfname选项定义的文件名字符
\F    文件名字符,但是不包含数字
\h    单词的头字符(A-Za-z)
\H    不是单词的头字符(A-Za-z)
\i    由isdent选项定义的字符
\I    定义的字符,但是不包括数字
\k    由iskeyword选项定义的关键字字符
\K    关键字字符,但是不包括数字
\l    小字字符(a-z)
\L    非小写字符(除了a-z以外的字符)
\o    八进制数字
\O    非八进制数字
\p    由isprint选项定义的可打印字符
\P    可打印字符,但是不包括数字
\r    <CR>
\s    空白符<Space>和<Tab>
\S    非空白符
\t    <Tab>
\u    大写字母字符(A-Z)
\U    非大写字母字符
\w    单词字符(0-9A-Za-z)
\W    非单词字符
\x    十六进制数字
\X    非十六进制数字
\~    匹配最后指定的字符串
修饰符:
*    匹配0次或是多次,尽可能多的匹配
\+    匹配1次或是多次,尽可能多的匹配
\=    匹配0次或是1次
\{}    匹配0次或是多次
\{n}
\{-n}    匹配n次
\{n,m}    匹配n次到m次
\{n,}    匹配n次到多次
\{,m}    匹配0次到m次
\{-n,m}    匹配n次到m次,尽可能少的进行匹配
\{-n,}    至少匹配n次,尽可能少的进行匹配
\{-,m}    匹配到m次,尽可能少的进行匹配
\{-}    匹配0次到多次,尽可能少的进行匹配
str1\|str2    匹配str1或是str2
vi编辑器的学习使用(二十)
Vim编辑器有不同的方法来处理各类事物.我们在Vim编辑器的学习使用(四)已经讨论过文本块和多文件的处理方法.有了这些命令,我们就可以很好的来完成我们的工作.在这一次的学习中我们会讨论一些更多的内容.从而使得我们的Vim编辑工作来得更完美一些.
当我们插入文本行的时候可以使用p命令或是P命令.所不同的是p命令是在当前行的下一行进行插入,插入后光标移动到新行的开头处,而P命令是在当前的上一行进行插入,插入后光标移到新行的下一行的开头处.而我们还可以使用gp或是gP命令.不同的是gp命令是将光标移动到新行的结尾处,也就是新行的下一行的开头处.gP命令与此相类似,是在当前的上一行进行插入,插入后,光标移动新行的结尾处,也就是下一行的开头处.
在Vim编辑器中还有一些特殊的标记符,如单引号'是指光标上一次的位置,但是这个位置不包括由方向键移动的位置.其他的一些特殊的标记包括:
]    上一次插入的文本的开头
[    上一次插入的文本的结尾
"    当我们离开文件时光标所处的位置
(注:这个地方看书是这样写的,但是自己做时却只可以是',[,],而且是要按两次键才行,不解:().
到现在为止我们所做的所有的复制和删除文本时我们并没有指明我们要使用哪一个寄存器.如果我们没有指明要用哪一个寄存器,Vim就会使用默认的没有命名的寄存器.用来指明这个寄存器的标记符是两个双引号("").在这里前一个双引号用来指示一个寄存器,而后一个双引号则是这个寄存器的名字.这样"a就是指我们使用a寄存器.
我们可以在我们的复制文本或是删除文本这前来指明我们的所复制或是删除的文本要放在哪一个寄存器中,指明寄存器的命令格式如下:
"register
在这里register是一个小写字母,是我们所指定的寄存器的名字,这样我们就可以有26个寄存器可以使用.
在通常的情况下我们使用yy所复制的文本是被放在没有命名的那个寄存器中,我们可以使用命令"ayy将我们所复制的文本放在指定的寄存器中.当然如果我们使用这样的命令,我们所复制的文本也会被放入未命名的寄存中的.
如果我们想知道寄存中都包含有哪些内容,我们可以使用下面的命令:
:registers
一般我们复制或是粘贴的文本会被入以字母命名的寄存器中,当然我们也可以使用一些特殊的寄存器.
我们可以通过给命令:registers一个参数,我们可以来查看特定寄存器中的内容,例如我们可以用下面的命令来查看寄存器a和x中的内容:
:registers ax
当我们使用命令"ayy我们是将当前文本行的内容放入寄存器中,而当我们再使用相应的大写字母来指定寄存器时,如"Ayy我们是将当前行内容追加到寄存器"a中,这时候在这个寄存器中就存两行文本,在寄存器中^J是指一行的结束.
在Vim中还有一些特殊的寄存器,第一个就是我们已经知道的未命名寄存器,他的名字是一个双引号".其他的还有1到9寄存器,寄存器1中含有我们上一次删除的文本,依次类推.
在古老时代的Vi中,Vi只可以撤销三次.如果我们将dd命令执行了三次,也许我们就没有太多的好运来使用u命令将我们删掉的文本再恢复过来.但是幸运的是这三个文本被分别存放在寄存器1,2,3中.我们可以通过命令"1P,"2P,"3P将这些文本再粘贴回来,或者是我们可以使用下面的命令来达到同样的结果:
""P..
其他的一些特殊的寄存器:
寄存器        描述            可复写
0        上一次复制的文本    是   
-        上一次删除的文本    否
.        上一次插入的文本    否
%        当前文件的名字        否
#        交替文件的名字        否
/        上一次查找的字符串    否
:        上一次":"命令        否
_        黑洞(black hole)    是
=        表达式            否
*        由鼠标选中的文本    是
黑洞寄存器(_)(The Black Hole Register)
黑洞寄存器是一个特殊的寄存器,我们放入其中的任何文本都不复存在.当然我们也可以使用p命令来粘贴这个寄存器中的文本,但是这样做是没有意义的,因为在这个寄存器中根本就不存在任何内容.这样的寄存器也有着相当重要的作用.如果我们想永久删除某一文本而不是将他放入1-9中某个寄存中,我们可以使用这个寄存器.例如命令dd删除一行文本并将这一行文本存在寄存器1中,而我们用命令"_dd则是将这行文本放入黑洞寄存器中,这些文本也就会永久地消失了,而寄存器1中的文本会保持不变.
表达式寄存器(=)(The Expression Register)
我们可以使用表达式寄存器来在文本中输入表达式.当我们输入表达式寄存器开始的命令时,就会在Vim的下部显示一个提示行,这就是给我们一个机会,我们就可以在这里来输入我们的表达式了.然后我们可以使用命令p将表达式的结果粘贴到文本.
例如我们要在文本中插入38*56的值,我们可以这样来做:
进入命令模式,输入表达式寄存器开始的命令"=,这时就会在Vim的下端显示出=来等待我们的输入,我们可以输入38*56,回车,然后输入命令p,这样就可以将我们的计算结果插入文本中了.
在表达式寄存器中我们不仅可以使用通常的算术运算符,还可以使用Vim特定的函数和运算符.如果我们不仅仅是用常用的算术运算符来完成我们的工作,也许我们就需要来查阅表达式文档了.例如我们可以通过表达式寄存器来得到环境变量的值.如果我们输入"=$HOME我们就可以得到HOME变量的值了.
剪切板寄存器(*)(The Clipboard Register)
剪切板寄存器可以使得我们通过系统的剪切板来读写数据.如果是在UNIX系统上,这个要在图形界面下使用.这样我们就可以通过剪切板寄存器来在不同的Vim编辑器或者是其他的程序包之间进行文本的剪切和复制.
我们在UNIX或是Linux系统中可以使用Vim编辑器和grep命令处理包含某一个指定词的所有文件.这对于我们有着极大有用处,因为我们可以用这个组合来查看或是处理包含某一个变量的程序文件.例如现在我们要编辑包含有变量frame_counter的C程序文件.这时我们就可以使用下面的命令:
$ vim `grep -l 'frame_counter' *.c`
(注:在这里最外面的是反外号,即数字键1旁边的,而里面的是单引号)
在这个命令中,grep命令在一系列文件查找包含有指定单词的文件.在这里我们指定-l选项,这样这个命令就会列出包含有这个单词的文件,而不会打印找到的字符串.在这里我们要查找的字符串frame_counter,我们可以使用这个命令来查找其他的字符串或是表达式.而整个的命令由反引号包括起来.这就可以告诉UNIX Shell来运行这个命令,并假定认为这个命令的执行已由命令打印输出.所以这个命令的执行结果就是运行grep命令并产生一个文件的列表,这些文件名放在Vim的命令行中,这样Vim就可以来编辑这些文件了.
也许有的人会说为什么要在这里展现这个命令呢?这是UNIX Shell的特征而不是Vim作品的一部分.而这正是使得Vim更加完美.
我们可以用下面的命令来设置参数列表:
:arg `grep -l 'frame_counter' *.c`
在这个参数列表中我们可以用命令来指定我们想要编辑的文件,例如如果我们要编辑第三个文件我们可以用下面的命令:
:argument 3
这个命令可以使得我们用文件在参数列表中的位置来编辑这个文件.如果我们是用下面的命令来启动Vim的:
$ gvim one.c two.c three.c four.c five.c
这时如果我们要编辑第四个文件我们可以用下面的命令:
:argument 4
当我们在命令行中用命令来指定一系列文件时,我们完成文件列表的初始化工作.但是我们可以用命令:args来指定新的文件列表.例如下面的命令:
:args alpha.c beta.c gamma.c
执行完毕这个命令以后我们开始编辑文件alpha.c,然后是文件beta.c.
有时我们在编辑文件时希望文件在打开后光标能定位我们希望在的行,这我们该如何来做到呢?例如我们要第12行开始编辑文件,我们可以用命令打开这个文件,然后执行命令12G来使得光标到指定的行.我们也可以在vim启动时在命令后面加上行号来指明光标要到的地方.如下面的命令:
$ gvim +12 file.c
我们还可以用这样的命令形式+/string来使得文件在装入以后光标放在指定的字符串.例如我们希望文件在打开后光标放在第一个包含字符#i nclude处,我们可以用下面这样的命令:
$ gvim +/#i nclude file.c
当然我们可以在+后面放上任何命令模式的命令.
我们可以用多种多样的命令来指明+cmd的参数.通常:vi命令格式如下:
:vi [+cmd] {file}
下面的这些命令也可以带上+cmd的形式:
:next [+cmd]
:wnext [+cmd]
:previous[+cmd]
:wprevious [+cmd]
:Next[+cmd]
:wNext[+cmd]
:rewind[+cmd]
:last[+cmd]
标记符a-z只是当前文件的标记.换句话说,我们可以在一个文件标记a,也可以在另外一个文件中标记a.如果我们执行命令'a我们就可以跳转到当前文件中的a标记处.而大写字母(A-Z)的标记符则就不一样了.他不仅标记了当前文件中的某一行而且也标记当前文件.例如我们正在编辑文件one.c而且在其中用A做了一处标记.然后当我们在编辑文件two.c时我们就可以执行命令'A,这样就可以跳转到one.c文件中的标记处
当我们用插入模式进入文本时我们也可以执行种不同的命令.例如<BS><BackSpace>可以清除光标前面的字符,而CTRL-U会清除整个一行或者至少是你刚输入的内容,CTRL-W会清除光标前面的字符.当我们在插入模式时我们也可以来移动光标,这时我们不可以再用传统的h,j,k,l,但是这时我们可以使用小方向键来移动光标.<HOME>可以移动到一行的开头,<END>可以移动到一行结尾.<PageUp>可以向上翻屏,<PageDown>可以向下翻屏.
在插入模式下如果我们输入CTRL-A,Vim编辑器就会插入我们上一次在Vim插入状态时所输入的文本.例如如果我们在文件中一行里输入#i nclude,然后我们用命令j向下移动一行并插入新的一行,这时如果我们想输入#i nclude,可以用命令CTRL-A来完成.CTRL-@命令与其相类似,所不同的只是在执行完这个命令后会退出插入模式.我们还可以用命令CTRL-V来引用下一个字符,换句话说任何有着特殊意义的字符他都将被忽略掉.例如如果我们输入CTRL-V<Esc>会在文本中插入空白符.我们也可以用命令CTRL-Vdigits来插入这个数字所指的字符,例如如果我们输入CTRL-V64就会在文本中插入@.在默认的情况下CTRL-V是使用十进制的数字,但是我们也可以插入十六进制的数字.
CTRL-Y命令可以输入光标上面的字会,当我们想要重复上一行时这个命令就会显得尤为有用.
与CTRL-Y命令相似的是CTRL-E命令,不同的是这个命令可能重复光标下面的字符.
命令CTRL-Rregister可以使得我们寄存器中的内容插入文本中.如果寄存器的内容含有类似于<BS>这样的特殊字符时,这些特殊会被重样解释,就像我们从键盘中输入这些字符一样.如果我们想这样,只是想着将这些字符作为普通字符业对待,我们可以用这样的命令:CTRL-R
CTRL-R register
例如我们输入下面的文本:
This is a test.
然后我们用命令"ayy将这些文本复制到寄存器a中,完成以后我们进入插入模式,输入命令CTRL-Ra,我们就会刚才我们复制的内容就会出现在文本行了.
如果我们不希望特殊字符被重新解释我们可以用命令CTRL-R CTRL-R register.
命令CTRL-\CTRL-N可以离开插入模式而回到正常模式下.换句话这个命令与<ESC>相类似,但这个命令可以在任何模式下使用,就这一点而似乎是要比<ESC>命令强大一些啊.
最后要介绍的就是CTRL-O命令,这个命令可以回到命令模式执行Vim命令在执行完以后又回到了插入模式.例如我们执行命令CTRL-Odw,Vim就会回到命令模式执行命令dw,在执行完毕后又回到了插入模式.
我们在使用全局标记时遇到的一个问题就是当我们退出Vim以后我们所设定的那些全局变量就不在存在.而我们希望能将这些保存下来.文件viminfo就是设计成为一个用保存标记信息以及下面的一些信息的文件:
命令行历史
查找历史
输入历史
寄存器
标记
缓冲区列表
全局变量
保存某一项的办法是我们要打开这个保存的选项,我们可以下面的命令来做到:
:set viminfo=string
这里的string表明了我们要保存的内容.
这里的string的语法是一个选项字符跟上一个参数.中间用逗号来分隔.首先'option用来表明我们要为少文件保存局部标记,我们可以选一个合适的数字,例如我们要选1000,那么这时的命令形式如下:
:set viminfo-'1000
而f选项则用来控制是否要保存全局标记.如果这个选项的值为0,则不保存,如果值为1或是我们没有指明f选项,那么vim都会保存这些全局标记.如果我们要用这一特征,我们可以用下面的命令:
:set viminfo='1000,f1
选项r会告诉Vim一些关于可移动介质的情况.在Vim中为可移动介质上的文件所做标记是不会被保存的,原因就是我们在Vim中要跳转到软盘文件的标记处是一个很难的操作.我们多次来表明r选项.如果我们在Windows系统上就可以用下面的命令来告诉Vim磁盘A和B是可移动介质:
:set viminfo='1000,f1,rA:,rB:
在UNIX系统并没有标准的软盘名称.在一般的情况下我们总是将软盘挂载在/mnt/floppy文件下,所以我们可以用下面的命令:
:set viminfo='1000,f1,r/mnt/floppy
\"选项用来控制每一个寄存器可以保存多少行.在默认的情况下,所有的行都会被保存.如果是0就不会保存.一般情况默认的设置已经可以很好的来满足我们的要求了,所以我们可以不必加入我们自己的设置.
:选项可以用来控制:历史行的记录.我想100应是可以满足我们的要求了吧:-):
:set viminfo='1000,f1,r/mnt/floppy,:100
/选项可以用来定义查找历史记录的大小,100也已是很充足的了:
:set viminfo='1000,f1,r/mnt/floppy,:100,/100
(注:Vim不会保存那些超过他的记录能力的内容,这是在选项history中设置的)
通常,当我们启动Vim以后如果我们已经设置了hlsearch选项,编辑器就会高亮显示上一次查找的内容.要关闭这个选项,我们可以viminfo的选项列表中加入h标记,或者是我们在Vim启动后执行命令:nohlsearch来关闭这个选项.
@选项用来控制输入历史记录的行数.输入历史会记住我们输入的所有内容.
如果我们设置了%选项,我们就可以保存缓冲区列表记录.如果我们没有在命令行指定一个文件来编辑,缓冲区列表就会被重新保存:
:set viminfo='1000,f1,r/mnt/floppy,:100,/100,%
!选项用保存全局变量,这些全局是名字全部为大写字母的变量:
:set viminfo='1000,f1,r/mnt/floppy,:100,/100,%,!
最后n选项用来指明viminfo的文件名.在UNIX系统中默认的为$HOME/.viminfo
我们可以将这些命令以及一些其他的初始化命令放在初始文件vimrc中.这样viminfo文件就会在Vim退出时自动保存,启动时来读取初始化.
如果我们要更清楚一些的来保存和读取这个文件,我们可以用下面的命令来以另外的文件名保存:
:wviminfo[file]
这样我们的这一些设置信息就会被写入这个文件中了.
我们可以用下面的命令来读取这个文件:
:rviminfo [file]
这样就会从这个文件中读入设置信息.如果这些信息与当前的设置有冲突,那么我们的这些设置信息就不再起作用了.我们可以用下面的命令来强制这些设置信息起作用:
:rviminfo![file]
有时我们会编辑一些文件中一行的宽度要超过屏幕的宽度.当行宽超过屏幕的宽度会发生什么事情呢?这时vim会将这一行进行回折以适应屏幕的宽度.如果我们设置了nowrap选项,则Vim会用单行来处理文件的第一行文本.这时超出屏幕的部分就会不再出现,从而从屏幕消失.
在默认的情况下,Vim并不会显示水平滚动条,我们可以用下面的命令来使得Gvim显示小平滚动条:
:set guioptions+=b
这样Gvim就可以水平滚动了.
当我们设置了nowrap选项后,命令^将光标移动当前行的第一个非空字符处.g^命令可以将光标移动到当前屏幕的第一个非空字符处.在执行这们执行这样的命令时如果在窗口的其他部分有文本,那么这一部分的文本将会被忽略.类似的一些命令如下:
命令        命令        含义
^        g^        向左移动当前屏幕的第一个非空字符处
<Home>        g<Home>
0        g0        向左移动当前屏幕的第一个字符处
<End>        g<End>
$        g$        向右移动当前屏幕的结尾处
        gm        移动到屏幕的中间
命令count|可将光标移动屏幕中指定的列.
命令countzh可以向左移动屏幕,移动的量度为count个字符.而命令countzl与其相类似,只是这个命令是向右移动屏幕.
命令zH可以向左移动个屏幕,而命令zL可以向右移到半个屏幕.命令j或是<Down>可以下移一行.在这里我们要知道的就是如果我们设置了wrap选项,那么下移一行在屏幕上显示也许就会是几行,这时我们要清楚,此时的几行正是设置了nowrap时的一行.
当我们设置了wrap选项,一个很长的一行Vim就会折成几行显示在屏幕上,这时我们可以用命令gj或是g<Down>来下移屏幕屏幕中显示的一行,这时也许我们移动的并非是真正的一行.而命令gk或是g<Up>命令与其相类似.
在默认的情况下,Vim编辑时会折回很长的一行,这时他首先是尽可能多的在屏幕的第一行放置文本,如果这一行的文本超出了屏幕的范围,Vim就会将其打断,然后在屏幕中的下一行显示其余的部分.我们也可以通过下面的命令来并闭这个选项:
:set nowrap
这时一个很长的句子超出屏幕的部分就在从屏幕上消失.我们可以通过沿着这个句子来移动光标,这样屏幕就会进行水平滚动,我们就可以看到这一行的其余部分了.
当然了我们也可以来自定义我们自己的句子回折形式:
首先我们可以告诉Vim在合适的地方来打断一个句子.我们可以用下面的命令来实现:
:set linebreak
那么又如何来定义一个合适的地方呢?这个是由breakat选项中的字符来确定的.在默认的情况下这些默认的字符是^I!@*-+_;:,./?如果我们不希望在下划线_处打断句子,我们可以用下面的命令来将_从这个列表移除就可以了:
:set breakat-=_
在通常的情况下,如果一个句子被打断Vim是不会在句子的连接的地方显示任何内容的.我们可以通过设置showbreak选项来显示我们所希望显示的内容信息:
:set showbreak="->"
我们最后要讨论的一个问题就当我们要在屏幕的结尾处打断一个句子我们应如何来做呢?这时我们可以用两个选择:一是我们可以不显示半行.这时Vim编辑器会在屏幕的底部来显示@以表时这是一个长句子,我们不能把他全部放在屏幕内.二是我们可以显示半行.
Vim默认的是采用第一种方法.如果我们要采用第二种方法我们可以用下面的命令来实现:
:set display=lastline