VIM技巧大全

来源:互联网 发布:360软件检测 编辑:程序博客网 时间:2024/06/07 20:20

vim使用大全[]

vi/vim 基本使用方法
本文介绍了vi (vim)的基本使用方法,但对于普通用户来说基本上够了!

vi
编辑器是所有UnixLinux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令。由于对UnixLinux系统的任何版本,vi编辑器是完全相同的,因此您可以在其他任何介绍vi的地方进一步了解它。Vi也是Linux中最基本的文本编辑器,学会它后,您将在Linux的世界里畅行无阻。

1
vi的基本概念
  基本上vi可以分为三种状态,分别是命令模式(commandmode)、插入模式(Insert mode)和底行模式(last linemode),各模式的功能区分如下:

1)
命令行模式command mode

  控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last linemode

2)
插入模式(Insert mode

  只有在Insert mode下,才可以做文字输入,按「ESC」键可回到命令行模式。

3)
底行模式(last line mode

  将文件保存或退出vi,也可以设置编辑环境,如寻找字符串、列出行号……等。

不过一般我们在使用时把vi简化成两个模式,就是将底行模式(lastline mode)也算入命令行模式command mode)。

2
vi的基本操作
a)
进入vi

  在系统提示符号输入vi及文件名称后,就进入vi全屏幕编辑画面:

$ vi myfile


  不过有一点要特别注意,就是您进入vi之后,是处于「命令行模式(commandmode)」,您要切换到「插入模式(Insert mode)」才能够输入文字。初次使用vi的人都会想先用上下左右键移动光标,结果电脑一直哔哔叫,把自己气个半死,所以进入vi后,先不要乱动,转换到「插入模式(Insertmode)」再说吧!

b)
切换至插入模式(Insert mode)编辑文件

  在「命令行模式(command mode)」下按一下字母「i」就可以进入「插入模式(Insert mode)」,这时候你就可以开始输入文字了。

c) Insert
的切换

  您目前处于「插入模式(Insert mode)」,您就只能一直输入文字,如果您发现输错了字!想用光标键往回移动,将该字删除,就要先按一下「ESC」键转到「命令行模式(commandmode)」再删除文字。

d)
退出vi及保存文件

  在「命令行模式(command mode)」下,按一下「:」冒号键进入「Lastline mode」,例如:

: w filename
(输入w filename」将文章以指定的文件名filename保存)

: wq (
输入「wq」,存盘并退出vi)

: q! (
输入q!不存盘强制退出vi)


3
、命令行模式(command mode)功能键
1
. 插入模式

  按「i」切换进入插入模式「insertmode」,按“i”进入插入模式后是从光标当前位置开始输入文件;
      
[ s ]进入插入模式后,是删除光标所在字符后再开始插入
  按「a」进入插入模式后,是从目前光标所在位置的下一个位置开始输入文字;

  按「o」进入插入模式后,是插入新的一行,从行首开始输入文字。

2
. 从插入模式切换为命令行模式

  按「ESC」键。

3
. 移动光标

vi可以直接用键盘上的光标来上下左右移动,但正规的vi是用小写英文字母「h」、「j」、「k」、「l」,分别控制光标左、下、上、右移一格。

  按「ctrl+b」:屏幕往移动一页。

  按「ctrl+f」:屏幕往移动一页。

  按「ctrl+u」:屏幕往移动半页。

  按「ctrl+d」:屏幕往移动半页。

  按数字「0」:移到文章的开头。

  按「G」:移动到文章的最后。

  按「$」:移动到光标所在行的行尾

  按「^」:移动到光标所在行的行首

  按「w」:光标跳到下个字的开头

  按「e」:光标跳到下个字的字尾

  按「b」:光标回到上个字的开头

  按「#l」:光标移到该行的第#个位置,如:5l,56l

4
. 删除文字

  「x」:每按一次,删除光标所在位置的后面一个字符。

  「#x」:例如,「6x」表示删除光标所在位置的后面”6个字符。

  「X」:大写的X,每按一次,删除光标所在位置的前面一个字符。

  「#X」:例如,「20X」表示删除光标所在位置的前面”20个字符。

  「dd」:删除光标所在行。

  「#dd」:从光标所在行开始删除#

5
. 复制

  「yw」:将光标所在之处到字尾的字符复制到缓冲区中。

  「#yw」:复制#个字到缓冲区

  「yy」:复制光标所在行到缓冲区。

  「#yy」:例如,「6yy」表示拷贝从光标所在的该行往下数”6行文字。

  「p」:将缓冲区内的字符贴到光标所在位置。注意:所有与“y”有关的复制命令都必须与“p”配合才能完成复制与粘贴功能。

6
. 替换

  「r」:替换光标所在处的字符。

  「R」:替换光标所到之处的字符,直到按下「ESC」键为止。

7
. 回复上一次操作

  「u」:如果您误执行一个命令,可以马上按下「u」,回到上一个操作。按多次“u”可以执行多次回复。

8
. 更改

  「cw」:更改光标所在处的字到字尾处

  「c#w」:例如,「c3w」表示更改3个字

9
. 跳至指定的行

  「ctrl+g」列出光标所在行的行号。

  「#G」:例如,「15G」,表示移动光标至文章的第15行行首。

4
Last line mode下命令简介
  在使用「last line mode」之前,请记住先按「ESC」键确定您已经处于「command mode」下后,再按「:」冒号即可进入「lastline mode」。

A)
列出行号

 set nu」:输入「set nu」后,会在文件中的每一行前面列出行号。

B)
跳到文件中的某一行

 「#」:「#」号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行了,如输入数字15,再回车,就会跳到文章的第15行。

C)
查找字符

 「/关键字」:先按「/」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往后寻找到您要的关键字为止。

 「?关键字」:先按「?」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往前寻找到您要的关键字为止。

D)
保存文件

 「w」:在冒号输入字母「w」就可以将文件保存起来。

E)
离开vi

 「q」:按「q」就是退出,如果无法离开vi,可以在「q」后跟一个「!」强制离开vi

 「qw」:一般建议离开时,搭配「w」一起使用,这样在退出的时候还可以保存文件。

5
vi命令列表
1
、下表列出命令模式下的一些键的功能:

h
左移光标一个字符

l
右移光标一个字符

k
光标上移一行

j
光标下移一行

^
光标移动至行首

0
数字“0”,光标移至文章的开头

G
光标移至文章的最后

$
光标移动至行尾

Ctrl+f
向前翻屏

Ctrl+b
向后翻屏

Ctrl+d
向前翻半屏

Ctrl+u
向后翻半屏

i
在光标位置前插入字符

a
在光标所在位置的后一个字符开始增加

o
插入新的一行,从行首开始输入

ESC
从输入状态退至命令状态

x
删除光标后面的字符

#x
删除光标后的#个字符

X
(
大写X),删除光标前面的字符

#X
删除光标前面的#个字符

dd
删除光标所在的行

#dd
删除从光标所在行数的#

yw
复制光标所在位置的一个字

#yw
复制光标所在位置的#个字

yy
复制光标所在位置的一行

#yy
复制从光标所在行数的#

p
粘贴

u
取消操作

cw
更改光标所在位置的一个字

#cw
更改光标所在位置的#个字


2
、下表列出行命令模式下的一些指令
w filename
储存正在编辑的文件为filename

wq filename
储存正在编辑的文件为filename,并退出vi

q!
放弃所有修改,退出vi

set nu
显示行号

/
?
查找,在/后输入要查找的内容

n
/?一起使用,如果查找的内容不是想要找的关键字,按n或向后(与/联用)或向前(与?联用)继续查找,直到找到为止。


对于第一次用vi,有几点注意要提醒一下:
1
、用vi打开文件,是处于「命令行模式(command

我再添加一些 呵呵
1、(motion)
  fx 向后 移动到搜索字母上,x 可以是任意一个字母
  tx 向后 移到搜索字母的左边 (这真的很有用)
  Fx 向前 移到搜索字母上
Tx 向前 移到搜索字母的左边
; 重复上面四种命令 ,也是重复命令 不过方向取反
. 重复上一个操作
 以上命令都是在本行移动
,. 当前行 ,%当前文件
gd to definition of the current word

  w:上一个词。  b:下一个词。(以nonword的特殊字符作为word的边界,如.,-等
W 上一个词 B 下一个词 (以空格作为word的边界)又称长单词
e: 下个词的最后一个字母 ge 上个词的最后一个字母
  0:移动光标到当前行首。
gm 移动到行正中
$:移动光标到行尾。
2$ 下一行行尾
  ^:移动光标到当前行的第一个字母位置。
  ) ( 移动光标到上/下一个句子。
{ } pre/next paragraph
 [{ ]} begin/end of block
 [[ ][ 代码块的开头和结尾假设{和}位于第一列的情况下成立
[( ]) 括号范围内前后移动
gD 跳转到局部变量的定义处

+ - 下一行的开始 上一行的开始(非空)
% matching parenthesis

  5、在整个文件里面有效移动光标
  gg:到文件首 G:到文件尾
  numG:移动光标到指定的行(num)。(比如 10G 就是到第 10 行)
  H:移动光标到屏幕上面  M:移动光标到屏幕中间  L:移动光标到屏幕下面 当前屏幕的操作
nH 光标到当前屏幕的第n行
nL 光标到当前屏幕的倒数第n行
zt scroll to top
 zz scroll to middle 有用 把当前编辑行置于屏幕中间
zb scroll to bottom
 ctr+B/b ctr+F/f pre/next page
 ctr+U/u ctr+D/d pre/next half page
 ctr+e ctr+y 上/下滚一行
  *:读取光标处的单词,并且移动光标到它再次出现的地方。
  #:读取光标处的单词,并且移动光标到它上次出现的地方。
g* 它不完全匹配光标所在处的单词,而是匹配包含该单词的所有字符串
  g# 它不完全匹配光标所在处的单词,而是匹配包含该单词的所有字符串

/text:从当前光标处开始搜索字符串text,并且到达 text 出现的地方。必须使用回车来开始这个搜索命令。如果想重复上次的搜索的话,按n
  ?text:和上面类似,但是是反方向。
/\<text\> 搜索完整的text单词
/ab\{3,5} 对b匹配3-5次
\{0,1}匹配0或1次跟\=一样
\{0,} 匹配0次或多次 跟\*一样
\{1,} 匹配1次或多次 跟\+一样
\{3} 匹配3次
/ab\{-1,3} 将会匹配abbb中的ab 意思是尽可能的避免重复
/a.\{-}b 其中{-}匹配前面的项一次或0次 尽可能地少 一般这个模式本身只可能匹配到0次
 因此这个命令 只会匹配到axbxb中的axb
 /a.*b 则会尽可能多的匹配因而对于axbxb 会匹配整个的axbxb
 /the\nword 匹配以the结束而且下一行以word开始的行
\_s 匹配空格或断行
/the\_sword the 与word 之间有空格或断行
/\d\u{3}\d\{3} 匹配一个数字 三个大写字母单个数字

/joe/s-2 所查找之处往前两个字符

 搜索完按n重复上次查找 N逆向上次查找
3n 向下搜索第三个
  
ma `a mark/jumpto a 'a 转到标记所在的行头(行头)
  `.:到你上次编辑文件的修改点。这个命令很有用,而且你不用自己去标记它
'. 到上次修改的行
`` 在上次编辑的地方与本次的地方来回跳转(仅限使用命令的跳转)
`0 上次编辑的地方
ctr+O ctr+I 往前或往后跳 编辑的地方

:s/old/new 将当前行中old替换为new 只替换一次
:s/old/new/n search and replace n times
 :s/old/new/g 将当前行中的old替换为new,全部替换
:.,$ s/old/new/g 将当前行至文件末尾中的old替换为new,全部替换
:.,$ s/old/new 将当前行中至文件末尾中的old替换为new,每行至替换一次
:1,$ s/old/new 或 :% s/old/new将文件所有行中的old替换为new,每行只替换一次
:1,$ s/old/new/g 或 :%s/old/new/g 将文件中的所有行的old替换为new,全部替换
%是目前编辑的文章 #是前一次编辑的文章
:?^chapter?-1,/^chapter/+2 s=grey=gray=g 将上个chapter与下一个chapter之间的所有的grey替换为gray,用=替换/ 来避免过多的/
 :g/foobar/s/bar/baz/g 搜索foobar 然后替换为foorbaz 不会影响到jailbars
 :g/\(foo\)\(bar\)/s/\2/\1baz/g
特殊的序列 & 所有查找时匹配到的东西
\[1-9] 1到9号用\(\)括起来的东西
\u 下一个字符被变成大写
\U 以后 所有的字符都变成大写 知道遇到\e
 \l 下一个字符变成小写
\L 以后的字符都变成小写


:.,.+4 从当前行到下面第四行
:`t,`b 从上一个标记t到下一个标记b
 ~ 改变当前字母的大小写类型
ggguG : 将当前编辑文件内容全部转换成小写
g~m 切换大小写 动作m跨越的行
guw 变小写
gUw 变大写
xp 当前字母和后一个字母的位置进行替换
ddp 两行互换位置


 回复 引用 查看 

#7楼2011-03-24 13:53|BI

2.高效的输入
  1、使用关键词自动完成
  输入一个长词的一部分,按住 Ctrl,再按 N或n)如果 VIM 会一直循环它找到的匹配的字符串。
  2、聪明的进入插入模式
  i:在当前字符的左边插入   I:在当前行首(第一个非空字符)插入
gI 在第一列插入文本
  a:在当前字符的右边插入   A:在当前行尾插入
  o:在当前行下面插入一个新行   O:在当前行上面插入一个新行
R ENTER REPLACE MODE 替换
S 替换掉光标所在行 再进入编辑模式
:> 本行缩进
:< 取消本行缩进
<< >> 左移或右移当前段落一个移动宽度(shiftwidth)
:>n 缩进连本行在内的n行
:<n 取消连本行在内的n行的缩进
  c{motion}:删除 motion 命令跨过的字符,并且进入插入模式。比如:c$,这将会删除从光标位置到行尾的字符并且进入插入模式。ct!,这会删除从光标位置到下一个叹号(但不包括),然后进入插入模式。被删除的字符被存在了剪贴板里面,并且可以再粘贴出来。
  d{motion}:和上面差不多,但是不进入插入模式。
  3、有效的移动大段的文本
 模式:
  v:按字符选择。经常使用的模式,所以亲自尝试一下它。
  V:按行选择。这在RGB(0x20,0x6a,0x4f)多行的文本的时候特别有用。
  CTR+v:按块选择。采用xbeta的_Vimrc文件时
ctr+q 按块选择。
  4、在可视选择模式下剪切和拷贝
  一旦你高亮了选区,你或许想进行一些操作:
  d:剪贴选择的内容到剪贴板。
  y:拷贝选择的内容到剪贴板。
  c:剪贴选择的内容到剪贴板并且进入插入模式。
  在非可视选择模式下剪切和拷贝
  如果你很清楚的知道你想拷贝或者剪切什么,那你根本就不需要进入可视选择模式。这样也会节省时间:
  d{motion}:剪切 motion 命令跨过的字符到剪贴板。比如,dw 会剪切一个词而 dfS 会将从当前光标到下一个 S 之间的字符剪切至剪贴板。
  y{motion}:和上面类似,不过是拷贝。
y2fa 表示拷贝从当前光标到光标后面的第二个a 字符之间的内容。
:12,y 表示拷贝第12 行到光标所在行之间的内容。
:,24y 表示拷贝光标所在行到第24 行之间的内容。
  c{motion}:和 d{motion} 类似,不过最后进入插入模式。 cw 改变一个词
cc change line d$ 删除从现在光标所在位置 (包括)至行尾
cw change word cw 与 dw 由区别 前者不去最后的一个空格后者去
rc 将光标下的字符替换为c
 R replace beginning at cursor
  dd:剪切当前行。 yw 复制的内容包括word之后的空白字符
ndd delete n lines
 ndw delete n words
 dw delete a word
  yy拷贝当前行。
Y 拷贝当前行。
Vyp 复制一行
  cc 剪切当前行并且进入插入模式。
  D 代表 d$ 删除到行尾的内容
  C 代表 d$ 修改到到行尾的内容。
  x 代表dl 删除当前光标下的字符
X 代表dh 删除当前光标左边的字符
daw 删除一个单词 (包括其后的空格
cis 删除一个句子
cas 删除一个句子 (包括后面的空白
diw 删除光标上的单词
daw 删除光标上的单词 (包括空白字符
 用d或x删除时 同时被删除的内容被保存起来
  s 代表cl 修改当前光标下的字符
S 代表cc 修改当行
J jion two lines
 r 替换之后不进入插入模式
gum gUm 小写/大写 动作m跨越的文本
<m >m 左移/右移 动作m跨越的行
n<< n>> 将n行左移或右移一个缩进位
  5、粘贴
   p 粘贴到光标后
 大写P 粘贴到光标前
  6、使用多重剪贴板
  很多编辑器都只提供了一个剪贴板。VIM 有很多。剪贴板在 VIM 里面被称为寄存器(Registers)。你可以列出当前定义的所有寄存器名和它们的内容,命令为“:reg”。最好使用小写字母来作为寄存器的名称,因为大写的有些被 VIM 占用了。
  使用寄存器的命令为双引号“。
  比如:我们要拷贝当前行到寄存器 k。你应该按 “kyy。(你也可以使用 V”ky。为什么这样也可以呢?)现在当前行应该已经存在了寄存器 k 里面直到你又拷贝了一些东西进入寄存器 k。现在你可以使用命令 “kp 来粘贴寄存器 k 里面的内容到你想要的位置。
  7、避免重复
. (小数点符号), 需要在normal下去执行 将会重复上一个修改命令。
u 撤销上次操作
U 撤销一行的操作 不管几次
ctr+R 恢复撤销
CTR+Y 重做

 回复 引用 查看 

#8楼2011-03-24 13:55|BI

@BI
8、使用数字
  3j 将会把光标向下移动三行。
  10dd 将会删除十行。
  y3″ 将会拷贝从当前光标到第三个出现的引号之间的内容到剪贴板。
:w save(:wq save and quit) ZZ保存后退出
:q quit(:q! quit anyway)
:only 关闭除当前窗口外的其它窗口
:qall 关闭所有的窗口 如果有为保存的文件则自动跳到为保存的文件
:wall 全部保存
:e x edit file x
:e x 放弃修改重新载入当前的文件x
:n new window
:h vim help
:xx jump to line #xx
ctr+N CTR+P auto-complete next/prev keyword 插入模式下的单词自动完成
ctr+x+l 自动补全整行内容
ctr+x+f auto-complete file name 搜索可匹配的文件名并完成
缩写:
:abbr sprt system.out.println
在编辑状态下输入sprt后再输入其他非字母符号会自动扩展
ctr+W 在多个窗口间切换
:set nu 或 :set number 显示行号
:set nonu 或 :setnonumber 消除行号
:set ruler 设置vim在右下角显示光标的位置
:set incsearch 自动匹配
:set hlsearch 搜索时自动匹配
:set nohlsearch
:set ignorecase 忽略大小写
:set wrapscan 设置循环搜索
:set textwidth=30 设置自动换行 并将 最大长度设为30
:set background=dark
:set background=light
:set patchmode=.org 编辑data.txt 时 保存原始文件为data.txt.org
:reg 查看剪切板中的内容
gf 打开光标处的文件名
pwd 获取当前工作目录
多窗口:
:vsp :sp vertically/horizontally split 纵向或横向分屏
:ctrl+w-w 切换窗口
:close 关闭窗口 可以阻止关闭最后一个VIM窗口
:only 关闭除了当前窗口之外的所有的窗口
ctrl+w++ 增加当前窗口的高度
:diffs split and diff 分屏比较
ctr+W p to last accessed window 移动到上个屏幕
ctr+W w to next window
:12 go to 12th line
:r file append file into vim/vi
:f file change current filename to file
:w save changes and stay in file
:q quit and ignore changes
:q! force quit and ignore changes `
:wq quit and save
:nw file write file to the nth lines
:e filename edit new file
:r filename insert the new file to the position of the current cursor
:0r filename 将文件filename的内容插入到文件的开头
:.,$w filename 将当前正在编辑的文件中的当前行至最后一行写到新的文件filename中
:.,$w >>filename 将当前正在编辑的文件中的当前行至最后一行写到追加到已有的文件filename中
z redraw the screen
zz put the cursor to middle
zt 光标到所在行到屏幕顶端
zb 光标所在行到屏幕下端
qm 录制宏到寄存器m
@m 执行寄存器中的宏
一些设置
:set go=
隐藏菜单
:set shiftwidth=4 一次移动4个单位 用于<和>命令 移动的宽度
5>> 光标后5行向右移动一个tab
 :12,24> 将12至24行的数据都向右移动一个tab
 :12,24>> 将12至24行的数据都向右移动两个tab
 <% or >% 来将({[等括号之间的文本都左移一个tab单位
shiftwidth(缩进的空格数,设置自动缩进时 会自动缩进4空格
tabstop(制表符的宽度)tab的宽度
expandtab(是否在缩进和遇到Tab键时使用空格替代;使用noexpandtab取消设置);
softtabstop(软制表符宽度,设置为非零数值后使用Tab键和Backspace时光标移动的格数等于该数值,
 但实际插入的字符仍受tabstop和expandtab控制);
autoindent(自动缩进,即每行的缩进值与上一行相等;使用noautoindent取消设置);
shiftwidth=4 tabstop=4:很多Windows出身的程序员会习惯这样的设置,让缩进等于制表符宽度。
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
模式行有好几种形式。本文只介绍上面的这种形式(其它形式类似,请自行参考“:help
modeline”):行首的“/*”和尾部的“*/”告诉C 编译器这是一行注释,不是代码的一部分;而
Vim可通过后面的“vim:”识别出模式行的开始(必须出现在行首或前面有一个空白字符);后面则是
“set”和空格间隔开的一串Vim选项;“:”表示模式行结束。

:set softtabstop=4 使得在第一列按下一个制表符光标就会向前移动4个空格 再次按下时
 会增加一个制表符总共8列
:set expandtab 只使用空格 制表符会被相应宽度的空格代替
:colo evening 背景变黑
语法高亮:
:syntax keyword xType int long char 将int long char定义为组xType
 :highlight link xType Type 将xType与Type联系起来 使得他们有相同的语法高亮
定义自己的映射键
在normal下: 用:map <F2> ggVG
在insert下: 用:imap <F2> ggVG

 回复 引用 查看 

#9楼2011-03-24 13:57|BI

@BI
组合命令:
:%s/ /^M/g 将所有的空格替换为换行
ggVG 全选
:%s/$/!/g 所有行末尾加!
:%s/old/\r&/gc 表示将old替换为前面加换行在加old
:s/fred/<c-r>a/g : 将fred 替换为寄存器a 里的内容,<c-r>为按下Ctrl与r,
 然后输入a 后,寄存器a 的内容会出现在命令行
:s/fred/<c-r>asome_text<c-r>s/g
:s/fred/\=@a/g : 与第一条的作用相同,但是更优雅一些,
 因为不会在命令行显示寄存器的内容
:%/为../&\r 将”为**“ 替换为 ”为**“加回车
编辑命令时:<left>代表向左一个字符
<right>代表向左一个字符
<shift+left>代表向左一个单词
<shift+right>代表向右一个单词
home 至命令行首
end 至命令行尾
ctrl+w 删除光标前的整个单词
ctrl+u 删除光标之前的所有内容
tab键自动补齐所输入的较长的单词或者文件路径
1. 去掉所有的行尾空格:“:%s/\s\+$//”。
“%”表示在整个文件范围内进行替换,
“\s”表示空白字符(空格和制表符),
“\+”对前面的字符匹配一次或多次(越多越好),
“$”匹配行尾(使用“\$”表示单纯的“$”字符);
 被替换的内容为空;由于一行最多只需替换一次,不需要特殊标志。这个还是比较简单的。
2.去掉所有的空白行:“:%s/\(\s*\n\)\+/\r/”。
 这回多了“\(”、“\)”、“\n”、“\r”和“*”。
“*”代表对前面的字符(此处为“\s”)匹配零次或多次(越多越好;使用“\*”表示单纯的“*”字符),
“\n”代表换行符,“\r”代表回车符,“\(”和“\)”对表达式进行分组,使其被视作一个不可分割的整体。因此,这个表达式的完整意义是,把连续的换行符
(包含换行符前面可能有的连续空白字符)替换成为一个单个的换行符。唯一很特殊的地方是,
在模式中使用的是“\n”,而被替换的内容中却不能使用“\n”,而只能使用“\r”。原因是
历史造成的,详情如果有兴趣的话可以查看“:help NL-used-for-Nul”。
3. 去掉所有的“//”注释:“:%s!\s*//.*!!”。首先可以注意到,这儿分隔符改用了“!”,原
因是在模式或字符串部分使用了“/”字符,不换用其他分隔符的话就得在每次使用“/”字符
本身时写成“\/”,上面的命令得写成“:%s/\s*\/\/.*//”,可读性较低。命令本身倒是相
当简单,用过正则表达式的人估计都知道“.”匹配表示除换行符之外的任何字符吧。
4.去掉所有的“/* */”注释:“:%s!\s*/\*\_.\{-}\*/\s*! !g”。这个略有点复杂了,用到
了几个不太常用的Vim正则表达式特性。“\_.”匹配包含换行在内的所有字符;“\{-}”表示
前一个字符可出现零次或多次,但在整个正则表达式可以匹配成功的前提下,匹配的字符数越
少越好;标志“g”表示一行里可以匹配和替换多次。替换的结果是个空格的目的是保证像
“int/* space not necessary around comments */main()”这样的表达式在替换之后
仍然是合法的。
5、:g/./,/^$/join
 :g/./ 一个全局命令, 查找那些至少有一个字符的行.
 ,/^$/ 指定一个范围, 从当前行开始(非空行)直到一个空行.
join ":join"命令把指定范围内的行连为一行.
6.对多个文件进行改动 例如把所有的c文件中的x_cnt变量替换为x_counter变量
 先将所要修改的文件放到参数列表上 :args *.c
再执行命令 :argdo%s/\<x_cnt\>/x_counter/ge |update
解释::argdo 命令已另一个命令为参数
g是对每行中的所有的x_cnt进行替换
e是避免某些 文件中没有一个x_cnt可供替换 那就不进行下面的替换的情况
| 用来分隔两个命令 后面的update 命令会在文件有所改变时保存 没改变的则不进行操作
 类似于argdo 命令:windo 会对所有的窗口都执行同样的操作
:buffer 则是对所有的缓冲区进行操作
:ls 可以查看缓冲区情况
:args 显示目前打开的文件
% 当前编辑文件
# 上次编辑文件
:previous 编辑上一个文件
:next 编辑下一个文件
:wprevious 保存并编辑上一个文件
:last 编辑最后一个文件
:first 编辑第一个文件
:lcd%:p:h 更改到当前文件所在的目录
lcd是仅仅改变当前窗口的工作路径%表示当前文件的文件名
 加上:p扩展为全名(带路径) 加上 :h 析出路径

 回复 引用 查看 

#10楼2011-03-24 14:00|BI

@BI
8. :g/^\s*$/d 删除所有空行
恢复机制:
 正在编辑一个文件help.txt时死机 则下次启用vim时用 :vim -r help.txt 来恢复
 然后先存储在另一个文件:write help.txt.recovered 再比较这两个文件
 如果正在编辑的文件没有名字则用 :vim -r "" 来恢复所有可能的文件
:echo 3+8*9 会计算出值
一些组合命令:
:g/^/m 0 依此将每行移动到第0行的下一行 实现倒序功能
:g/^/+1 d 删除偶数行
:s/\n\n\@!// \n\n\@!是查找后面不跟回车的回车 然后替换为空格
:g/./,/^$/j /./标记非空行 /^$/查找后面的行直到出现空行 然后对二者进行合并
:v/ccc\|ddd/s/aaa/bbb/g 将aaa替换成bbb 条件是行中有ccc但不能有ddd
:g/ccc/if getline('.')!~'ddd'|s/aaa/bbb/g 首先标记匹配的ccc行 然后执行if命令 getline函数
 则取得当前行然后判断是否匹配ddd
如果不匹配(!~的求值为true)则执行替换
:g/^/,+2 d|,+6 m -1 每十行删除前后三行
:g/^/,+6 m -1|+1,+3d 每十行删除前后三行
:g/if/+1,/elsif\|else/-1 t $ 将if与elsif或else之间的内容复制到末尾
:g/^/put_ : 双倍行宽 (pu =put)
:g/^/m0 : 颠倒文件 (m =move)
:'a,'bg/^/m'b : 颠倒选中的 a 到 b
:g/^/t. : 重复行
:g/fred/t$ : 拷贝行从fred 到结尾
:g/stage/t'a : 拷贝行从stage 到 marker a(a 为标记的位置)
隔行替换
:g/^/ if line('.')%2|s/^/zz /
查找标记a 与b 间所有包含"somestr"的行,并全部复制到第一个包含"otherstr"的行后
:'a,'bg/somestr/co/otherstr/ 其中 co(py) or mo(ve)
用文件中的内容替换字符串,-d表示删除上面的一行
:g/^MARK$/r tmp.ex | -d
:g/<pattern>/z#.5 : 带有上下文一并显示
:g/<pattern>/z#.5|echo "==========" : 优雅地显示
将g//和普通模式下的命令结合起来
:g/|/norm 2f|r* : 将第二个|替换为*号
全局命令和替换命令联姻 (强大的编辑能力)
:'a,'bg/fred/s/joe/susan/gic : 可以使用反向引用来匹配
:g/fred/,/joe/s/fred/joe/gic : 非行模式
:/fred/;/joe/-2,/sid/+3s/sally/alley/gIC 先找fred,然后找joe
:g/^/exe ".w ".line(".").".txt"
为每一行生成一个文件,文件名从1.txt 开始,依次为1.txt,2.txt,3,txt
xy\{2,}表示x后接至少两个y 相当于xyy\+或xyyy*
"ayy 将当前行复制到a缓冲区 "的作用是注释,以免当成插入
"ap 粘贴刚才复制的行
缓冲区在wim中的术语是registers 具体可以看:h registers
d,c,s,x,y等指令改变或删除的内容都是放在registers中的
:reg 命令可以查看缓冲区的内容 然后可以根据前面的标记加p复制需要的内容
冒号命令支持tab键补全功能
. 重复上一次的编辑动作(移动游标和冒号命令除外)、
:marks 可以得到所有的标签列表
vim+ 档案名 可以打开档案并且游标会落在最后一行的行尾
vim+n 档案名 游标会落在第n行的行首
vim+/string 档案名 进入档案后游标会进入第一个要找到的string上 按n可以继续寻找
多当编辑有两种形式:
argument list 进入vim前所用的参数就是多档
buffer list 进入vim后另外再开其它的档
:n 编辑下一个档案
:2n 编辑下二个档案
:N 编辑前一个档案 适用于argument list
:sp(:vsp) filename 分割出一个窗口并打开文件filename
:rew 回到首文件
:e 档案名 在不离开vim的情形下再开其它档案 只要要编辑的档案在目前的目录下即可
:e# 或CTR+^ 编辑前一个档案 用于两档互相编辑时相当好用 #表示前一次编辑的档案
:ls 会列出目前buffer中的所有档案
 编号后边有#的代表是前一个文件,可以通过:e#来进入,
%a 的代表是当前文件,
 什么也没有的可以通过:bn 来进入,这里的n 代表文件编号。
:b 文件名或编号移至该文件。
:args 查看当前打开的所有的文件
:h pattern 可以查看regexp内容
:changes 列出改变列表 :hchangelist 查看‘改变表转跳帮助’
:ju(mps) 列出跳转轨迹
:history 列出历史记录
:his c 命令行历史
:his s 搜索历史
"ayy@a : 把当前行作为命令执行
yy@" : 上面的匿名寄存器
u@. : 只执行键入的命令

 回复 引用 查看 

#11楼2011-03-24 14:05|BI

@BI
使用外部sort 排序
:%!sort -u : 用sort 排序整个文件(结果覆盖整个文件)
:'a,'b!sort -u : 从mark a 到mark b 之间的内容进行排序
!1} sort -u : 排序一个段落
:g/^$/;,/^$/-1!sort : 将每个块排序(注意这个关键的;)
:badd file.c : 添加file.c 到buffer 列表
:b 3 : 前往第三个 buffer
:b main : 前往含有main的buffer 中 比如说 main.c
:sav php.html : 把当前文件存为php.html并打开
:sav! %<.bak : 换一个后缀名保存 (旧方法)
:sav! %:r.cfm : 同上
:sav %:s/fred/joe/ : 替换文件名
:sav %:s/fred/joe/:r.bak2 : 替换文件和后缀
:!mv % %:r.bak : 重命名当前文件
:e! : 打开未修改之前的文件
:w c:/aaa/% : 存储文件到指定位置
:e # : 编辑标记为#的文件在buffer 中
:rew : 返回到第一个可编辑的文件
:brew : 回到第一个buffer
:sp fred.txt : 分割窗口打开fred.txt
:sball,:sb : 把所有的 buffers 分割显示在一个窗口中 (超有用)
:scrollbind : 让每个分离的窗口,同步滚动
:map <F5> :ls<CR>:e # : 按F5 显示所有buffer, 并显示行号
:set hidden : 允许不保存当前buffer 而进行切换
V : 进入可视化行选择模式
gv : 重新选择
:s/.\{,69\};\s*\|.\{,69\}\s\+/&\r/g 在70 列的时候换行
vim -c "%s/ABC/DEF/ge | update" file1.c 在打开一个文件时执行多条命令
vim -c "argdo %s/ABC/DEF/ge | update" *.c 在一组文件上执行多条命令
vim -c "argdo /begin/+1,/end/-1g/^/d| update" *.c 从一系列文件中删除一块区域
在文件中插入行号
:g/^/exec "s/^/".strpart(line(".")." ", 0, 4)
:%s/^/\=strpart(line(".")." ", 0, 5)
:%s/^/\=line('.'). ' '
命令使用于多个文件
:argdo %s/foo/bar/e : 在所有文件上操做 :args
:bufdo %s/foo/bar/e
:windo %s/foo/bar/e
:argdo exe '%!sort'|w! : 包含外部命令
REGEXP:
 * 0次以及多次
+ 一次以及以上
= 0或1次
| or的意思
:%s/\([a-z]\)\1/test/g 将aa,bb,cc,……zz替换为test
 :%s/[a-z][a-z]/test/g 不是一个意思 会将aa,ab,ac,等都替换为test
mastering regular expressions(o'reilly&asscociate) 书里详细介绍了正则表达式
\{m,n\} 前面部分的从m次至n次出现
\{m\} 精确m次出现
\{m,\} 大于等于m次出现
/\(foo\|bar\)\+ 匹配 foo foobarfoofoo barfoobar
/.*fred\&.*joe 搜索同时包括fred 跟joe的行
/\<\d\d\d\d\> 搜索独立的4位数字
/\D\d\d\d\d\D 搜索恰好4位的数字
/<\zs[^>]*\ze> 匹配<与>所包含的内容 但不包含<>
/<\@<=[^>]*>\@= 查找<与>所包含的内容
/<\@<=\_[^>]*>\@= 多行匹配<与>所包含的内容
/<!--\_p\{-}--> 匹配<与>所包含的所有内容 {-}是非贪婪匹配
:%s/^\n\+/\r/ 压缩空行,多个替换为一个
/<\zs[^>]*\ze> 匹配<>之间的内容
/<\@<=[^>]*>\@= search for tag contents, ignoring chevrons 匹配<>标签中的内容,而忽略<和>本身
/<\@<=\_[^>]*>\@= search for tags across possible multiple lines
:%s/\r//g delete dos returns ?M
:%s/\r/\r/g turn dos returns ?M into real returns (fixes joined lines)
在一个模式中的“或”操作符是\| 例如 /foo\|bar 他匹配到foo 或着是bar
 /\(foo\|bar\)\+ 它匹配到foo foofoo foobvar barfoobar
 /end\(if\|while\|for\) 匹配的是endif endwhile endfor
 /forever\&... 只会匹配到forever中的for 而不会匹配到fortuin的for
 /[a-z]可以匹配a到z中的一个字母
/[0123456789abc] 可以匹配0123456789abc中的任意一个字母
/[0-9a-c] 与上面等价
/[^a] 匹配除a之外的任意字符
/"[^"]*" 其中[^"]表示除双引号之外的任意一个字符总的命令将会匹配到“foo”或“3!x”
\d 数字 等价于[0-9]
 \D 非数字等价于[^0-9]
 \s 空白字符等价于[ ]包含<tab><space>
 \S 非空白字符等价于[^ ]
 \l 小写字母等价于[a-z]
 \L 非小写字母等价于[^a-z]
 \u 大写字母等价于[A-Z]
 \U 非大写字母等价于[^A-Z]
 \i 匹配标识符字符[a-zA-Z0-9]
 \I 匹配[a-zA-Z]
 \w 匹配一个字母、数字、或下划线[a-zA-Z0-9_]
\_s* 任何空白字符包括换行
\_.* 任何字符包括换行

 回复 引用 查看 

#12楼2011-03-24 14:08|BI

@BI
高级正则表达式
1./\s*\<\(return\|else\)\@!\w\+\s\+\w\+\s*([^)]*)\s*;\@!\s*$ 查找多由c语言中的函数
\< 零长度匹配,表示单词的开始
\@! 零长度匹配 表示要求他前面的内容不存在
2.要求是将
<par type="I" flags="RO">
</par>
<par type="I" flags="RO,H">
</par>
变成
<par type="I" flags="RO" id="0">
</par>
<par type="I" flags="RO,H" id="1">
</par>
方法一:
第一步,增加id="":
:g/^<par type/s/>$/ id="">/g
第二步,增加数字:
:let i=0 | g/^<par type/s/id="\zs\ze">$/\=i/| let i=i+1
这是用|号(逻辑或的符号,不是字母)连接的三个语句,
前后两个就是给i赋初值和递增,
id="\zs\ze">$ \zs 和\ze 是"零长度匹配",在这两个中间的才作为匹配内容,
这个语句就是只匹配双引号中间的内容,
这样不会把其他有用的地方替换掉了
\=i \=是把后面的字符串当成表达式来对待,在这里就是i 的值
方法二:
这是用一步解决的方法:
:let i=0 | g/^<par type/s/>$/\=substitute(" id =\"0\">", "0", i,"")/| let i = i+1
和上面的方法基本相同,就是替换右尖括号,不过这次是替换为substitute(" id =\"0\">", "0", i,"")
这是一个替换函数,就是在id=0中查找第一个0,并替换为i 的值,最后一个参数是{flag},一般为空.
08.08.19 我自己也写了一个,和上面的基本一样,就是不用substitute函数而已
:let i = 1 | g/^<par type=/s/>$/\=" id = " . i .">"/ | let i += 1
其中\=表示后面是个表达式,小数点用以连接字符串的几个部分,中间用了i 的值
3. 每行前面加上行号
法一:
:g/^/exec "s/^/".strpart(line(".")." ", 0, 4)
法二:
:%s/^/\=strpart(line(".")." ", 0, 4)/g
 line()返回一个行数,特别的,
line(".")返回当前光标所在行的行数,其他的参数见:hline()
 g/^/exec是对所有行执行一个或多个命令,具体可以:h exec 来查看,
每个命令必须用字符串,也就是要放在双引号里面,多个命令间用空格分割.
在上面的例子中,后面只有一个命令,但是这个命令是用小数点连起来的一个字符串
4.如下的赋值
firstline=1 //comment line 1
secondline=2 /*comment block 1*/
thirdline = 3//comment line 2
forthline= 4/*comment block 2*/
fifthline =5
希望整理成
firstline = 1 //comment line 1
secondline = 2 /*comment block 1*/
thirdline = 3 //comment line 2
forthline = 4 /*comment block 2*/
fifthline = 5
下面是我写的语句,比较长,应该还有更好的写法,以后有改进再补充
:g/=/s#\v(.*)\=\s*(((//|/\*)@!.)*)\ze(//|/\*)?#\=strpart(submatch(1) . "",0,13) . "= " .
strpart(submatch(2) . " ",0,10)# | s/\s*$//
前面紫色部分,查找所有包含等号的行,然后执行后面两个命令,
第一个命令是橘黄色的部分,第二个命令是蓝绿色部分,
第二个命令就是去掉行末的空格,这个不需要多解释,重点解释第一个命令
s#a#b#是一个替换的命令,这里用#做分隔符,是因为后面的表达式中有斜杆/,
如果用斜杆作为分隔符,则表达式中的斜杆需要转义,稍显累赘
\v表示后面的正则表达式中,除了字母和数字和下划线和斜杆,其他的都作为特殊字符对待,
有这个设置的好处,是后面可以省掉好几个用来转义的反斜杆,
像\(\)\+这些都可以简写成()+
\= 匹配一个等号
\s* 匹配0个或0个以上的空白符
加粗的部分是一个比较重要的地方,一共三层括号,最外层括号使这个括号内部的内容成为一个子匹配,
在后文中的submatch(2)就是指的这一部分,
后面的一个*号,表示第二个括号内的内容可以匹配0 次或0 次以上.
第二个括号内部,@!是个"零长度匹配",表示前面第三层括号内的内容不能出现,
小数点匹配除了换行符外的任意字符,
第三层括号里面,就是c语言注释的两种形式,//和/*,中间用|连接,表示"或"的关系.
整个粗体部分的意思就是,匹配尽量长的,且不是C语言注释的内容.
\ze 匹配结束,后面的所有内容只是作为限制条件,
在替换的时候,只会替换\ze之前的内容后面的括号和粗体部分的第三层括号内容是一样的,
后面的问号表示匹配0次或1次,因为不是所有的行都有注释的后面就是替换成的内容了,
strpart 函数相当于VB 中的mid 函数,就是取字符串从某个位置开始的一段内容,
这里用了一个小技巧(虽然写起来挺长的,但是想法简单),
就是比如要把一个字符串处理成13个字符的长度,不足的位置补空格,
我们就先在这个字符串后面加上13个空格,然后截取整段内容的前13个字符,
这样就满足要求了,还有其他的方法,比如用
另外一个函数submatch()表示的是前面用查找的时候的子匹配,也就是在括号中的内容,
submatch(0)对应这个匹配的内容,submatch(1)对应(.*)的内容,
submatch(2)对应粗体部分的内容
剩下的需要注意的地方,就是这里的小数点相当于VB中的&,是作为字符串的连接符号.

 回复 引用 查看 

#13楼2011-03-24 14:09|BI

@BI
这第一个命令的作用,就是找到等号,将等号前面的部分,用空格补齐到13个字符,
然后在等号后面空两格,等号后面原有的空格无论多少都去掉,然后把后面的内容,
到注释符号前面都整理成10个字符(不足补空格),最后才是注释
这样第一个命令执行后,对于没有注释的行,会多出来10个空格,不太好看,
所有就加了第二条命令,去掉行末的空白

5.使用vim匹配两个特殊字符之间的内容并替换
举例如下:
fileA:
Mark
..............
Mark
......
Mark
..............
Mark
......
Mark
..............
Mark
如果要把Mark之间的内容替换成:ABCD.
那么应该使用正则表达式:g/Mark\_.\{-}Mark/s//ABCD/g
如果要匹配第一个Mark到最后一个Mark,并替换成ABCD,
那么应该使用正则表达式:g/Mark\_.*Mark/s//ABCD/g

6.
这里以编写C语言程序为例, 假设,我们最终想完成的代码如下:
#define BIT_MASK_1 (1 << 0)
#define BIT_MASK_2 (1 << 1)
#define BIT_MASK_3 (1 << 2)
#define BIT_MASK_4 (1 << 3)
#define BIT_MASK_5 (1 << 4)
#define BIT_MASK_6 (1 << 5)
#define BIT_MASK_7 (1 << 6)
#define BIT_MASK_8 (1 << 7)
#define BIT_MASK_9 (1 << 8)
#define BIT_MASK_10 (1 << 9)
#define BIT_MASK_11 (1 << 10)
#define BIT_MASK_12 (1 << 11)
#define BIT_MASK_13 (1 << 12)

只需要先写好第一行,如下:
#define BIT_MASK_1 (1 << 0)
然后,我们回到Normal模式,在这一行上输入“Y12p",拷贝此行,然后粘贴12次。这样,我们得到总
共13行上面的内容。
现在使用"V12j"命令选中这13行,然后使用两次替换命令:
:'<,'>s/BIT_MASK_\zs\d*\ze/\=line(".") -line("'<") + 1
:'<,'>s/\zs\d*\ze)$/\=line(".")-line("'<")
其中'<,'> 为我们所选中的区域 (:help '<,:help '> )
 line(".") 当前光标所在行的行号 (:help line() )
 line("'<") 我们所选区域中第一行的行号 (:help line() )


7.
UniqueID2 = lview.focusedItem.subItems.opIndex(0).text;
Parent = lview.focusedItem.subItems.opIndex(0).text;
Children = lview.focusedItem.subItems.opIndex(0).text;
login = lview.focusedItem.subItems.opIndex(1).text;
txtCust.text = lview.focusedItem.subItems.opIndex(2).text;
txtProj.text = lview.focusedItem.subItems.opIndex(3).text;
替换为
UniqueID2 = lview.focusedItem.subItems.opIndex(0).text;
Parent = lview.focusedItem.subItems.opIndex(1).text;
Children = lview.focusedItem.subItems.opIndex(2).text;
……


:let n=0 | g/opIndex(\zs\d\+/s//\=n/|let n+=1
其中: | 用来分隔不同的命令 (:help :bar )

8.
g/pattern1/;/pattern2/-1d pattern1与pattern2之间的内容删除,包括pattern1所在的行但是不包括pattern2所在的行
g/pattern1/;/pattern2/-1move $ 将pattern1(包括此行)至pattern2所在行之间的内容移动到文章末



:g/firstcatalog/ 显示所有的fistcatalog
:g/firstcatalog/nu 显示所有fistcatalog以及所在的行号
:g/firstcatalog/z#=4 显示所有firstcatalog以及附近的4行 可以用 :h :z 看到详细说明)
:g!/firstcatalog/ 显示不包含firstcatalog的行






/bugs\(\_.\)*bunny 匹配所有bugs到bunny的字符串
/fred\_s*joe/i 匹配fred 开始到joe,之间一定得是空白字符
/bugs\(\_.\)*bunny 匹配所有bugs到bunny的字符串
:%s/^\n\{3}// ;: 删除连续3个空行
:%s/^\n\+/\r/ ;: 压缩空行,多个替换为一个
:%s,\(all/.*\)\@<=/,_,g ;: 用 _ 替换"all/"之后的 /
:'a,'bg/fred/s/dick/joe/igc 非常有用 'a,'b指定一个范围:marka ~mark b
:g/fred/,/joe/d : 删除所有的从fred 到joe

:%s/[.!?]\_s\+\a/\U&\E/g 大写所有句子的第一个字母



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





/joe/e : 设置光标到匹配"joe"的末尾
/joe/e+1 : 设置光标到匹配"joe"的末尾再后移一位
/joe/s-2 : 设置光标到匹配"joe“的开头再前移两位
/joe/-2 : 设置光标到匹配"joe“的行再向上移两行的开头



在一行里写多种命令:
:%s/\f\+\.gif\>/\r&\r/g | v/\.gif$/d | %s/gif/jpg/ :
将所有带有.gif的行,前后均加入一个空行;
 将不带有.gif 字样的行全部删除;
 将所有行中的gif换成jpg;
 注意三条语句,一旦某一条失败,则不执行下面的语句

 回复 引用 查看 

#14楼2011-03-24 14:10|BI

:%s/a/but/gie|:update|:next :
首先,将当前文件中的所有a 变为but;
 然后保存文件;
 最后进入下一个文件缓存区。如果有多个文件需要如此处理,

使用函数
:s/__date__/\=strftime("%c")/ : 将__date__替换成当前日期,使用strftime
函数。注意\=表示后面是表达式,结果可能是2008-1-3 17:59:46

\=submatch(0) 匹配每行第一组数字
替换一个特定字符串为数字
:let i=10 | 'a,'bg/Abc/s/yy/\=i/ |let i=i+1 # 将yy转换成10,11,12 等等
比上面的更精确
:let i=10 | 'a,'bg/Abc/s/xx\zsyy\ze/\=i/ |let i=i+1 # 将xxyy 转换成 xx11(第
一行),xx12(第二行),xx13(第三行)

:%s:\(\(\w\+\s\+\)\{2}\)str1:\1str2:
处理字段,替换所有在第三个字段中的str1 为str2

交换两个单词
:%s/\<\(on\|off\)\>/\=strpart("offon", 3 * ("off" ==submatch(0)), 3)/g

:%s/?\(.*\)\n\1$/\1/ delete duplicate lines




vim实现多文件查找和替换
对于多文件中的查找来说,比较容易,vimgrep是vim自带的一个工具,类似于
linux下的grep的用法就可以实现。比如要在当前目录查找word,
使用如下:
:vimgrep word *
如果想要递归查找所有下级目录里面,那么就用
:vimgrep word **
另外,如果想要在使用是快捷查找当前光标下的字母,则只需要在vimrc中添加如下代码:
“对搜索的设置
map ft :call Search_Word()<CR>:copen<CR>
function Search_Word()
let w = expand(”<cword>”) ” 在当前光标位置抓词
execute “vimgrep ” w ” *”
endfunction

第二,多文件替换。
实际上只要如下两个命令即可(假设要将当前目录下所有扩展名为.txt的文件中的hate
替换成love):
:args *.txt
:argdo %s/hate/love/gc | update
就可以完成啦。解释如下,
:args *.txt
这样写会扫描当前目录下的.txt文件,并加入到参数列表。但是这样写只会扫描当前目录,

如果想要递归扫描所有下级目录的话,用:args **/*.txt
而:argdo%s/hate/love/gc | update
是将参数列表中的所有文件的hate提换成love,并写入硬盘(如果没有|update,就不
会写入,但相应的替换也会被中断)
最后强调一点,使用替换命令的时候,一定记得备份,因为替换是直接写入硬盘滴哦……



专题:
1.模式行
:help modeline
:help 'modeline'
:help 'modelines'

模式一
// vim:ft=cpp tabstop=4
模式二
vim:set tw=78 ts=8 ft=helpnorl:sdfasdfasdgs

第一种形式中最后一设置项后的冒号或空格是可有可无的。
而第二种形式中最后一设置项后一定要有冒号——不管冒号后有没有文字。
在设置项中如果要使用空格、制表符或冒号可以在前面加上转义符-`\‘。
其他需要转义符的情况见`:helpoption-backslash‘。
2.折叠
:help folding
:help foldmethod
:help fold-methods
:help
:set foldmethod=manual
:3,8fo
折叠方式:
1)`manual‘ 手工规则
手工规则下,折叠层级由折叠区域的嵌套关系计算。当我们手工指定一个折叠的区域后,Vim
对这个区域的开始行和结束行做记号,多个区域的开始行和结束行形成了嵌套关系。如果一
个折叠区域不包含在其他区域之中,则其折叠层级为1;当这个区域直接包含于另一个区域
时则其为折叠层级为另一个区域的层级加1;依些类推。
2)`marker‘ 标记规则
当使用标记规则折叠时,层级的计算跟手工规则相似。除了它是根据文件中的标记来划分一
个折叠区域而不是手工指定。然后根据这些区域间的嵌套关系计算折叠层级。具体使用的标
记通过`foldmarker‘设置。默认是使用'{{{,}}}'。

手工和标记类似
:set foldmethod=manual
:3,8fo 或着高亮选择第三至8行 后 输入指令zf

使用manual一般是临时性的折叠。如果每次编辑特定文件都需要做同样折叠时时建议结合modeline使用其他折叠
规则。如果不得不使用manual方式时,你可以用:mksession保存包括折叠在内的一切当前编辑设置或者
用:mkview保存当前窗口

3)`indent‘ 缩进规则
行的缩进宽度除以`shiftwidth‘,并向下取整得到每一行的折叠层级。同一折叠层级及更高折
叠层级的连续行形成折叠。而其中的更高折叠层级的行——如果有的话,形成嵌套的折叠。

4)`syntax‘ 语法规则
跟`marker‘差不多,只是所用的标记是在语法文件中定义的,而不是通过`foldmarker‘设置。
5)`diff‘ 差异规则
除了差异行及其前 后三行1外,其余行折叠(层级为1)。
6)`expr‘ 表达式规则
由用户指定折叠层级的计算方式。方法是对`foldexpr‘进行设置。具体用法稍后说明。
:set foldmethod=expr
:set foldexpr=1
所有的行都被折叠foldexpr将每行的折叠层级设置为1
v:lnum>=8&&v:lnum<=20?1:0
v:lnum>=8\ &&\ v:lnum<=20\ ?\ 1:0

 回复 引用 查看 

#15楼2011-03-24 14:11|BI

@BI最后一些了 呵呵以后大家多多补充哦
三个在折叠的表达式比较常用几点:
v:lnum 内置变量,表示是“当前行的行号”。:help v:var 查看更多内置变量。
getline() 函数用以返回指定行的内容。
?: 三元条件语句。见:helpexpr1

v:lnum>=8&&v:lnum<=20?1:0
v:lnum>=8\ &&\ v:lnum<=20\ ?\ 1:0

:set foldexpr=(v:lnum>=8&&v:lnum<=20?1:0)

如果一行以@samp{#}开始,折叠。
:set foldexpr=getline(v:lnum)=~/^#/?1:0

以每5行为一组折叠
set v:lnum%5-1?1:'>1'

用正则表达式@samp{.}判断当前行是否含有文字。
set foldexpr=getline(v:lnum)=~'.'?1:0

在文章的末尾加入
vim: ro: fdm=expr: fde=getline(v\:lnum)=~'.'?1\:0:
foldtext=foldtext().v\:folddashes.getline(v\:folds
tart+1): foldcolumn=2
则每次打开文件会折叠(方式是空行之间的折叠在一起)

导出折叠的部分到笔记.txt
:folddoclosed .w! >>笔记.txt
如果folddoclosed只对当前关闭的折叠有效,要导出所有的折叠先使用指令zR
删除所有的marker用 :g/{{{/norm zD

在'.vimrc'(windows中是'_vimrc')中加入,下面的内容:
" 根据邮件的后缀名进行相关的设置。如果打开的文件后缀名是
'.eml',则当成邮件处理。
autocmd! BufReadPre *.eml se fdm=expr
fde=v:lnum==1?1:getline(v:lnum)=~'^$'?0:'='
fdt=Mailfdt(v:foldstart,v:foldend) ft=mail | syn on
" 定义函数,用来返回折叠的标题。
" 以折叠的第一和最后一行的行号为参数
func! Mailfdt(fst,fen)
let fst=a:fst
" 保存邮件的标题和发信人
let hfrom=''
let hsub=''
let tline=''
while a:fen!=fst
let tline=getline(fst)
" 判断当前行是否是我们感兴趣的行
" 如果是则保存
if tline=~'^From: '
let hfrom=tline
elseif tline=~'^Subject: '
let hsub=tline
endif
let fst=fst+1
endwhile
" 返回相关信息
if strlen(hfrom) || strlen(hsub)
return hsub . "\t\t\t" . hfrom
else
return getline(a:fst)
endif
endfunc
在加入上面的内容后,我们现在用Vim打开邮件(实际是以.eml作后缀名的文件)
看看,是不是清爽多了!

这是比较不常用但又可能比较有用的内容。使用:help查看相关信息。
v:foldstart 内置变量只读变量记录只前所在折叠的起始行号
v:foldend 内置变量结束行号,其余同上
foldlevel() 函数返回指定行的折叠层级
'foldlevel' 设置项只有高于这个值的折叠层级才会进行折叠
'foldnestmax' 设置项指定最深的嵌套数
'foldignore' 设置项在 indent规则中以这个值开始的行的将根据前后行的值来设定折叠层级
:folddoclose 命令 对当前闭合的行运行命令
:folddoopen 命令 对未折叠的行或定义了折叠但未闭合的行运行命令

更多内容参考`:helpvim-script‘
:help :folddoopen
:help :folddoclosed
3.
高效
1.移动速度
set hlsearch
 *
 使用fold 先全部关闭 移动到制定fold后再打开
2.Don't type it twice
使用CTR+n 自动填充 如果不对 则 CTR+p 回到起点 敲入新的字符 再 CTR+n时

3.Fix it when it's wrong
:iabbrev teh the
:syntax keyword WordError teh
4.A file seldom comes alone
:!ctags -R .
:tag init
:tnext
:grep “\<K_HOME\>” **/*.h
:cnext
:make
gf goto file



语法高亮帮助文档
:help syntax.txt
:help 'tags'
:help tags-file-format
:help tags-and-searches

:tag 关键字(跳转到与“关键字”匹配的标记处)
:tselect [关键字](显示与“关键字”匹配的标记列表,输入数字跳转到指定的标记)
:tjump [关键字](类似于“:tselect”,但当匹配项只有一个时直接跳转至标记处而不再显
示列表)
:tn(跳转到下一个匹配的标记处)
:tp(跳转到上一个匹配的标记处)
Ctrl-](跳转到与光标下的关键字匹配的标记处;除“关键字”直接从光标位置自动获得外,功
能与“:tags”相同)
g](与“Ctrl-]”功能类似,但使用的命令是“:tselect”)
g Ctrl-](与“Ctrl-]”功能类似,但使用的命令是“:tjump”)
Ctrl-T(跳转回上次使用以上命令跳转前的位置)


 

 

 

 

 

 

 

 

 

 

定制vim

3.1. Vim 脚本基础

在 .vimrc 文件中,和在第二章提到的插件和语法文件中,使用的语言就是 Vim 脚本语言。这种脚本语言语法有点像 BASIC,表达式有点像 C,还是比较容易理解的。本章中并不打算对其作很系统的介绍(要完整了解的话,请参见“:help usr_41.txt”),而只是介绍一些基本知识,特别是,了解定制 .vimrc 所需要的基本知识。

Vim 脚本相当于可直接在命令模式下执行的命令,只是不需要输入前面的冒号(如果用了冒号也不会出错)。因此,像设置选项、创建键盘映射这样的命令是直接可用的。当然,作为一种脚本语言,除了普通键盘上会输入的命令外,我们还需要一些更复杂的功能,特别是:变量,表达式,条件和循环语句,函数。

3.1.1. 变量

Vim 中使用如下的语法对变量进行赋值(创建变量):

let 变量名 = 数值

 

 

变量类型有两种,整数和字符串,在第一次赋值之前都不能使用。变量名除了可使用常规的字母、下划线和数字外,还可以使用几种特殊的前缀:

·        “b:”——只对当前缓冲区(buffer)有效的变量;

·        “w:”——只对当前编辑窗口(window)有效的变量。

·        “g:”——全局变量(在函数中访问全局变量必须使用该前缀,不加前缀的话则认为是函数内的局部变量);

·        “s:”——变量名只在当前脚本中有效;

·        “a:”——函数的参数;

·        “v:”——Vim内部预定义的特殊变量(参见“:help vim-variable”)。

下面三个前缀用来访问特殊的数值,由于行为和变量较为相似(可以读取和修改),也放在这儿一起讲:

·        “$”——访问环境变量;

·        “&”——访问 Vim 选项;

·        “@”——访问寄存器。

当变量不再使用时,可以使用“unlet变量名”删除变量。

3.1.2. 表达式

和 C 非常类似,可以使用变量和常量,可以使用括号,可以调用函数(“函数名(...)”),支持加法(“+”)、减法(“-”)、乘法(“*”)、除法(“/”)和取模(“%”),支持逻辑操作(“&&”、“||”和“!”),支持三元条件表达式(“a? b : c”)。字符串操作方面当然比 C 要强,可以使用“.”进行字符串拼接;可使用“==”、“<=”等进行字符串大小比较,可使用“=~”和“!~”进行正则表达式匹配,而且可以在比较操作符后面添加“#”或“?”来强制进行大小写敏感或不敏感的比较(缺省受 Vim 选项ignorecase 影响)。显示一个表达式的结果,可以使用“:echo 表达式”显示到状态栏上,或者在插入模式下使用“Ctrl-R=表达式”插入到缓冲区的文本中。

和其它很多在 Unix 下成长起来的语言一样,Vim 的字符串常量有双引号和单引号两种方式。使用单引号的话,单引号间的任何字符都是字符串的一部分,其中不能再包含单引号。使用双引号的话,则可以使用“\”产生换码序列(具体可参考“:helpexpr-quote”),如“\n”代表换行符,“\"”代表双引号,“\\”代表反斜杠本身,等等。

需要注意的话,双引号除了可以表示字符串常量外,还可以表示注释。行首的“"”,以及表达式中出现的成单的“"”,都表示“"”后面的部分全部是注释。

3.1.3. 条件和循环语句

条件语句形式如下:

 

if 表达式

  语句

endif

 

 

 

if 表达式

  语句

else

  语句

endif

 

 

 

if 表达式

  语句

elseif 表达式

  语句

endif

 

 

循环语句形式如下:

 

while 表达式

  语句

endwhile

 

 

条件和循环语句都可以嵌套。这些比较简单,就不多加说明了。

3.1.4. 函数

在表达式中使用函数时,就跟C 里面的方式类似,直接使用函数名加括号,括号里写上参数(可选)。在不需要返回值的情况下调用函数时,稍稍有些不同,要使用“call”命令,后面跟函数名和括号(括号里面写上可能有的参数)。

定义函数使用下面的语法:

 

function 函数名称(参数列表)

  语句

endfunction

 

 

如果已有同名函数存在,Vim会报错,除非在“function”后面加上一个“!”。

如果参数中不包含“...”,那么参数的数量是固定的,函数的调用者必须提供跟定义同样多的参数(在函数定义中使用参数名之前加上“a:”进行访问)。如果参数中包含“...”,那么参数的数量不固定,除了可以使用参数名称访问传递过来的参数外,还可以使用“a:0”知道额外传递的参数数量,使用“a:1”、“a:2”等访问这些额外传递的参数。

要在函数的中间返回,或者要返回数值的话,可以使用“return”语句。

Vim 内部定义了一百多个函数,详细列表请参见“:help function-list”。

回页首

3.2. 我的 .vimrc

作为一个 Vim 脚本的一个具体示例,我将讲解一下最实用的情况,我的 .vimrc 文件。文件.vimrc.html (请下载到本地打开) 是我的 .vimrc 文件通过以下步骤生成的HTML 文件:

1. 在 Vim 中打开 .vimrc 文件;

2. 执行命令“:colorscheme koehler”(缺省配色可能在浏览器中效果不佳)

3. 执行命令“:%!nl -w4 -s' '”(1.11 节)

4. 执行命令“:TOhtml”(1.13 节)

5. 执行命令“:w”

可以把浏览器中的文本内容粘贴到 Vim 中,然后使用下面这个替换命令“:%s/^ \+[0-9]\+ //”删除前面的行号,来恢复出最初的 .vimrc 文件。

下面逐行进行讲解,并包含理解其内容所需的资料的链接。建议大家直接阅读 .vimrc 文件的内容,并在有疑问时查阅下面的解释。

第 1 行:注释(3.1.2 节末段),其中包含一个模式行(1.4 节和 1.5 节)。

第 2 行:首先判断系统是否具有“自动命令”(autocmd)的支持,有的话才执行第3到第六行的内容(1.1 节、“:helphas”和“:help feature-list”)。

第 3 行:纯注释(后面我将跳过注释行不再说明)。

第 4 行:清除所有的自动命令(“:help autocmd-remove”),以方便调试,可以使用“source~/.vimrc”查看一些修改后的效果(“:help source”)。

第 6 行:对于后缀为“.asm”的文件,认为其是微软的 Macro Assembler 格式(“:help masm-syntax”)。

第 7 行:与第 2 行的 if 语句配对。

第 8-10 行:当使用了图形界面时(“:help feature-list”),确保所有的文件类型会在菜单“语法”(“Syntax”)下出现,而不是出现一个菜单项“Show filetypes in menu”。缺省行为可以让 Vim启动得更快一点点。

第 11-13 行:当使用了图形界面,并且环境变量 LANG 中不含“.”(即没有规定编码)时,把Vim 的内部编码设为 UTF-8。

第 14 行:不需要保持和 vi 非常兼容(“:help 'compatible'”)。

第 15 行:执行 Vim 缺省提供的 .vimrc 文件的示例,包含了打开语法加亮显示等最常用的功能。

第 16 行:打开自动缩进(1.4 节)。

第 17 行:缺省不产生备份文件(“:help 'backup'”)。

第 18 行:在输入括号时光标会短暂地跳到与之相匹配的括号处,不影响输入(“:help 'showmatch'”)。

第 19 行:正确地处理中文字符的折行和拼接(1.12 节)。

第 20 行:可自动识别的文件类型为带 BOM 字符的 Unicode 文件、UTF-8 编码的文件和 GBK 编码的文件。

第 21 行:设置状态行,使其能额外显示文件的编码信息,如图 2 中的“gbk”和“big5”(“:help 'statusline'”)。


图 2

第 22-24 行:如果该 Vim 支持鼠标,则启用鼠标支持(1.3 节)。

第 25-29 行:判断 Vim 是否包含多字节语言支持(multi_byte 特性),并且版本号(“:helpv:version”)大于 6.1(包含ambiwidth 选项)。

第 26-28 行:如果 Vim 的语言(“:help v:lang”;受环境变量 LANG 影响)是中文(zh)、日文(ja)或韩文(ko)的话,将模糊宽度的 Unicode 字符的宽度(ambiwidth选项,1.2 节)设为双宽度(double)。

第 31-36 行:改变上、下方向键行为方式:通常情况下这些键的作用范围是逻辑行,所以如果行很长的话光标的移动可能会不太方便;这些键盘映射把这些键的作用范围改成屏幕行(“help gk”),还为习惯使用“j”、“k”的人增加了映射“Ctrl-j”和“Ctrl-k”作用于屏幕行。前面四个映射使用的命令是“noremap”,作用于正常模式、可视模式和命令执行时;后面两个映射使用的命令是“inoremap”,仅作用于插入模式,其中使用“Ctrl-O”临时执行一个普通模式的命令(“:help i_CTRL-O”)。

第 38-41 行:在 Vim 中的插入模式中可以使用“Ctrl-R =”计算整数表达式的数值,但Vim 本身没有计算浮点表达式的能力。这四个映射提供了浮点表达式的计算能力:使用“\ma”(假设 Leader 字符为缺省的“\”,参见“:help <Leader>”)可将计算的结果放到下一行上(待计算的表达式为当前行或在可视模式选中的内容),使用“\mr”则用计算的结果替换待计算的表达式(同样为当前行或在可视模式选中的内容)。这些映射假设有一个命令“calcu”可用来计算一个表达式的内容。该命令可用下面的 shell 脚本简单实现:

 

#! /bin/sh

echo "$*" | sed -e $'s/\r$//' -e 's/sin *(/s(/g' -e 's/cos *(/c(/g' -e 's/atan *

        (/a(/g' -e 's/log *(/l(/g'

-e 's/exp *(/e(/g' | bc -l

 

 

该脚本把表达式转换成bc [1] 能接受的形式(把“sin(x)”转换成“s(x)”,等等),并通过标准输出送到 bc 的标准输入。

该映射较为复杂,此处不详加解释了——其中心思想都是选取待计算的表达式,放到无名寄存器中,然后使用“Ctrl-R"”粘贴到命令行上,使用 calcu 进行计算,再把结果粘贴回正在编辑的缓冲区中;最后一个最复杂,因为为了替换原先的表达式,还需要记住原先被选中的内容的起始和结束位置,你可能希望看一下“:help gv”、“:help v_o”、“:help m”、“:help `”,并复习节 1.11。可以注意一下,在映射中使用了“<silent>”(“:helpmap-<silent>”),这会防止命令行上回显执行的内容。

第 43-44 行:允许用户使用 F2 来取消搜索/替换的加亮显示。此处一个映射用于正常模式(nmap),一个用于插入模式(imap)。上面已经提过一次,“Ctrl-O”可以在插入模式中执行一个正常模式的命令。

第 46-47 行:这两个映射用于 taglist 插件,使用 F9 直接打开(或关闭)taglist 的窗口。

第 49-50 行:方便快速修订窗口(1.10 节)的使用,可使用 F11(和 F12)查看下一个(上一个)错误(或 grep 项等)。

第 52-65 行:一些适用于文本模式运行的 Vim 的设定;详见下面的具体说明。

第 54-56 行:将变量 Tlist_Inc_Winwidth 的值设为 0,防止 taglist 插件改变终端窗口的大小(有些情况下会引起系统不稳定)。使用“has('eval')”是让该语句仅在功能较为完整、至少支持表达式的 Vim 版本中运行。

第 58-64 行:在系统支持 wildmenu 特性(“:help'wildmenu'”)启用文本模式的菜单。

第 59 行:打开 wildmenu 选项,启动具有菜单项提示的命令行自动完成。

第 60 行:确保字符序列“<C-Z>”被理解为 Ctrl-Z 而不是分开的五个字符(“:help 'cpoptions'”)。

第 61 行:设置使用 Ctrl-Z 激活自动完成提示。

第 62-63 行:把正常模式和插入模式下的 F10 映射成执行菜单项,并自动提示菜单内容。注意缺省菜单仍不会自动载入,我使用该特性的主要目的是在文本模式的 Vim 中使用 CVS 菜单。图 16 是按 F10 键后再按 Tab 键的结果。


图 16

第 66-161 行:使用自动命令(autocmd)特性的设置。使用“has”来防止该部分内容在不支持自动命令的 Vim 版本中运行。

第 67-129 行:定义了若干个下面的自动命令会用到的函数,具体在下面的自动命令中讲。请注意在每个“function”之后都用了一个“!”(“:help E122”):这也是为了方便调试,让“source ~/.vimrc”能正确运行而不会报告函数已定义的错误。

第 131-133 行:只要没有将环境变量 VIM_HATE_SPACE_ERRORS 的值设为零,则把变量c_space_errors 的值设为 1——效果是在 C/C++ 代码中“不正确”的空白字符(行尾的空白字符和紧接在制表符之前的空格字符)将会被高亮显示。图 17所示的代码中,第 3 行的行尾多了两个空格,第5 行的第一个制表符之前多了个空格。Vim 提示#935 里有一些额外的说明。同时请参看对第 160 行的说明。


图 17

第 135 行:使用的英文拼写变体为加拿大风格,即:使用拼写“abridgement”(而不是“abridgment”)、“colour”(而不是“color”)、“realize”(而不是“realise”)、“theatre”(而不是“theater”)等,比较符合中国人一般的英语教科书中的拼写方式,也比较适合于写“国际”英语。

第 138 行:使用键盘映射“\a”来查看光标下字符的属性,主要用于调试 Vim 的语法文件。图 18显示了光标下的字符所属的语法“组”为 vimOption,使用配色方案中的 PreProc(预处理符号)项,前景色为紫色(RGB:#a020f0)。有兴趣可查看 Vim脚本#383 的具体内容。


图 18

第 140 行:在函数找不到时(“:help FuncUndefined”),自动在运行环境(Linux下一般为 ~/.vim)的 autoload 目录下读入与函数名同名的 .vim 文件。这是脚本#383 的建议安装方式(SyntaxAttr.vim文件放在 autoload 目录下,仅在执行时载入)。

第 142 行:设置适用于 C/C++ 文件的选项(1.4 节)。

第 143 行:把补丁文件的缩进和制表符宽度设定设成和 C/C++ 文件相同(1.4 节)。

第 144 行:取消 Vim 对 HTML 标记自动产生的缩进,但打开自动缩进选项(1.4 节)。

第 145 行:对于变更日志类型的文件,设置行宽为 76 个字符(1.12 节)。

第 147 行:当文件后缀为“.gb”时,认为这是一个 GBK 编码的文件,在读入文件之前(“:helpBufReadPre”)调用函数 SetFileEncodings 把原先的 fileencodings 选项的内容保存在本缓冲区的一个变量中(3.1.1 节),然后把 fileencodings 设成 gbk,即只尝试对文件内容作为 GBK 字符序列来解释。

第 148 行:类似于上面把“.big5”后缀的文件当作 Big5 编码的文件,在读入文件之前把fileencodings 设成 big5,只尝试对文件内容作为Big5 字符序列来解释。

第 149 行:类似于上面把“.nfo”后缀的文件当作 CP437 编码(即英文 DOS 的 OEM 字符集编码)的文件。效果可参看图 19。


图 19

第 150 行:在读入 .gb、.big5 或 .nfo 文件之后(“:help BufReadPost”),调用函数RestoreFileEncodings 恢复保存起来的 fileencodings 原数值。

第 151 行:对于 .txt 后缀的文件,在显示文件时(“:help BufWinEnter”,确保在模式行被执行之后)调用函数 CheckFileEncoding 检查文件是否已修改并且fileencoding 设有数值。条件满足的话说明该文件在模式行中修改了 fileencoding,因而使用该编码(“:help++enc”)重新强制(“!”)读入该文件以保证文件被正确解码。Vim 提示#911 里有一些额外的说明。

第 153 行:在遇到 HTML 文件时,如果 Vim 判断出的编码类型和HTML 代码中使用“<metahttp-equiv="Content-Type" content="text/html; charset=编码">”规定的编码不一致,将使用网页中规定的编码重新读入该文件。函数 ConvertHtmlEncoding 会把一些网页中使用的编码名称转换成 Vim 能够正确处理的编码名称;函数 DetectHtmlEncoding 在判断文件类型确实是 HTML 之后,会记下当前的光标位置,并搜索上面这样的 HTML 代码行,找出字符集编码后,在编码不等于当前文件编码(fileencoding)时且当前文件编码为空或等于系统判断出的文件编码时,使用该编码强制重新读入文件,忽略任何错误(“silent!”)。该自动命令写成是可嵌套执行的(“:help autocmd-nested”),目的是保证语法高亮显示有效,且上次打开文件的光标位置能够正确保持。Vim 提示#1074 里有一些额外的说明。

第 155-156 行:确保把 /usr/include/c++ 和/usr/include/g++-3 目录下的所有文件都当成 C++ 类型的文件,不管 Vim原先认定这些文件类型是什么(“:help BufEnter”)。C++ 的很多标准头文件(如“algorithm”)没有文件后缀,缺省情况下不会被 Vim 当作 C++ 文件。

第 158 行:第 142 行把 C/C++ 文件的制表符宽度设成了4(个人设置),但系统的源代码一般使用 GNU 编码规范,制表符宽度为8。该行设置所有 /usr 目录下的文件都使用GNU 编码规范(1.4 节)。

第 160 行:在写文件之前(“:help BufWritePre”),调用函数RemoveTrailingSpace:只要没有将环境变量 VIM_HATE_SPACE_ERRORS 的值设为零,则对于文件类型为 C、C++、Vim 脚本类型的文件,自动悄悄清除所有的行尾空白字符;“normal m`”记忆当前的光标位置,“normal``”恢复记忆下来的光标位置。

至此为此,我已经介绍了Vim 的基本知识、很多实用技巧和一些最常用的 Vim 插件,并通过定制.vimrc 文件介绍了脚本的基本知识。如果有需要进一步深入学习 Vim 或是想提什么关于 Vim的特定问题的话,不妨参加从 Vim 的网站上参加 Vim 的邮件讨论列表,应该会获益良多。而作者也希望本文至此也已经完成了引导读者学习、了解 Vim 的高级特性的任务。



 

原创粉丝点击