Vi使用简介
Vi 是 Unix 世界里极为普遍的全萤幕文书编辑器,几乎可以说任何一台 Unix 机器都
会提供这套软体。Linux 当然也有,它的 vi 其实是 elvis(版权问题),不过它们都
差不多。熟悉 DOS 下的文书处理後,也许会感到 vi 并不好用;Unix 上也已经发展出
许多更新、更好用的文书编辑器,但是并不一定每一台 Unix 机器上都会安装这些额外
的软体。所以,学习 vi 的基本操作还是有好处,让你在各个不同的机器上得心应手。
Vi 基本观念
Unix 提供一系列的 ex 编辑器,包括 ex, edit 和 vi 。相对於全萤幕编辑器,现在
可能很难想像如何使用 ex,edit 这种行列编辑器(有人用过DOS 3.3 版以前所附的
EDLIN 吗?)。 Vi 的原意是 :Visual:,它是一个立即反应的编辑程式,也就是说可
以立刻看到操作结果。
也由於 vi 是全萤幕编辑器,所以它必须控制整个终端机萤幕哪里该显示些什麽。而终
端机的种类有许多种,特性又不尽相同,所以 vi 有必要知道现在所使用的是哪一种终
端机。这是藉由 TERM 这个环境变数来设定,设定环境变数方面请查看所使用 shell
的说明。(除非执行 vi 的时候回应 unknow terminal type ,否则可以不用设定。)
只要简单的执行 vi 就可以进入 vi 的编辑环境。在实际操作之前先对它有个概略的了
解会比较好。Vi 有两种模式,输入模式以及指令模式。输入模式即是用来输入文字资
料,而指令模式则是用来下达一些编排文件、存档、以及离开 vi 等等的操作指令。当
执行 vi 後,会先进入指令模式,此时输入的任何字元都视为指令。
进入与离开
要进入 vi 可以直接在系统提示字元下键入 vi <档案名称>,vi 可以自动帮你载入
所要编辑的档案或是开启一个新档。进入 vi 後萤幕左方会出现波浪符号,凡是列首有
该符号就代表此列目前是空的。要离开 vi 可以在指令模式下键入 :q,:wq 指令则是
存档後再离开(注意冒号)。要切换到指令模式下则是用 [ESC] 键,如果不晓得现在
是处於什麽模式, 可以多按几次 [ESC],系统会发出哔哔声以确定进入指令模式。
Vi 输入模式
要如何输入资料呢?有好几个指令可以进入输入模式:
新增 (append)
a 从游标所在位置後面开始新增资料,游标後的资料随新增资料向後移动。
A 从游标所在列最後面的地方开始新增资料。
插入 (insert)
i 从游标所在位置前面开始插入资料,游标後的资料随新增资料向後移动。
I 从游标所在列的第一个非空白字元前面开始插入资料。
开始 (open)
o 在游标所在列下新增一列并进入输入模式。
O 在游标所在列上方新增一列并进入输入模式。
也许文字叙述看起来有点繁杂,但是只要实际操作一下马上可以了解这些操作方式。实
务很重要,尤其是电脑方面的东西随时可以尝试及验证结果。极力建议实际去使用它而
不要只是猛 K文件,才有事半功倍的效用。(注:此段为废话。)
Vi 基本编辑
配合一般键盘上的功能键,像是方向键、[Insert] 、[Delete] 等等,现在你应该已经
可以利用 vi 来处理文字资料了。当然 vi 还提供其他许许多多功能让文字的处理更形
方便,有兴趣的看倌请继续。
在继续下去之前先来点 BCC吧。电脑有许多厂牌,不同的硬体及作业系统。PC 也不是
仅仅只有 IBM PC 及其相容品而已。事实上,包括键盘,终端机等等往往都有不同的规
格。这代表什麽?
在文书编辑软体上会遇这样的问题,某些电脑的键盘上没有特定的几个功能键!那麽不
就有某些功能不能用了?这个问题在 Unix 系统上也一样,几乎各大电脑厂商都有自己
的 Unix 系统,而 vi 的操作方法也会随之有点出入。我们固然可以用 PC 的键盘来说
明 vi 的操作,但是还是得提一下这个问题。
删除与修改
何谓编辑?在这里我们认为是文字的新增修改以及删除,甚至包括文字区块的搬移、复
制等等。这里先介绍 vi 的如何做删除与修改。(注意:在 vi 的原始观念里,输入跟
编辑是两码子事。编辑是在指令模式下操作的,先利用指令移动游标来定位要进行编辑
的地方,然後才下指令做编辑。)
x 删除游标所在字元。
dd 删除游标所在的列。
r 修改游标所在字元,r 後接著要修正的字元。
R 进入取代状态,新增资料会覆盖原先资料,直到按 [ESC] 回到指令模式下为止。
s 删除游标所在字元,并进入输入模式。
S 删除游标所在的列,并进入输入模式。
其实呢,在 PC 上根本没有这麽麻烦!输入跟编辑都可以在输入模式下完成。例如要删
除字元,直接按[Delete] 不就得了。而插入状态与取代状态可以直接用 [Insert] 切
换,犯不著用什麽指令模式的编辑指令。不过就如前面所提到的,这些指令几乎是每台
终端机都能用,而不是仅仅在PC 上。
在指令模式下移动游标的基本指令是 h, j, k, l 。想来各位现在也应该能猜到只要直
接用 PC 的方向键就可以了,而且无论在指令模式或输入模式下都可以。多容易不是。
当然 PC 键盘也有不足之处。有个很好用的指令 u 可以恢复被删除的资料,而 U 指令
则可以恢复游标所在列的所有改变。这与某些电脑上的 [Undo] 按键功能相同。
Vi 进阶应用
相信现在对於 vi 应该已经有相当的认识。处理文字也不会有什麽麻烦才对。如果有兴
趣善用 vi 的其它功能进一步简化操作过程,不妨继续看下去。
移动游标
由於许多编辑工作是藉由游标来定位,所以 vi 提供许多移动游标的方式,这个我们列
几张简表来说明(这些当然是指令模式下的指令):
┌—————┬—————————————┬—————┐
│指令 │说明 │功能键 │
├—————┼—————————————┼—————┤
│0 │移动到游标所在列的最前面│[Home] │
├—————┼—————————————┼—————┤
│$ │移动到游标所在列的最後面│[End] │
├—————┼—————————————┼—————┤
│[CTRL][d] │向下半页 │ │
├—————┼—————————————┼—————┤
│[CTRL][f] │向下一页│[PageDown]│
├—————┼—————————————┼—————┤
│[CTRL][u] │向上半页 │ │
├—————┼—————————————┼—————┤
│[CTRL][b] │向上一页 │[PageUp]│
└—————┴—————————————┴—————┘
┌——┬—————————————————┐
│指令│说明 │
├——┼—————————————————┤
│H │移动到视窗的第一列 │
├——┼—————————————————┤
│M │移动到视窗的中间列 │
├——┼—————————————————┤
│L │移动到视窗的最後列 │
├——┼—————————————————┤
│b │移动到下个字的第一个字母 │
├——┼—————————————————┤
│w │移动到上个字的第一个字母 │
├——┼—————————————————┤
│e │移动到下个字的最後一个字母│
├——┼—————————————————┤
│^ │移动到游标所在列的第一个非空白字元│
└——┴—————————————————┘
┌——┬———————————————————┐
│指令│说明 │
├——┼———————————————————┤
│n- │减号移动到上一列的第一个非空白字元 │
│ │前面加上数字可以指定移动到以上 n 列 │
├——┼———————————————————┤
│n+ │加号移动到下一列的第一个非空白字元 │
│ │前面加上数字可以指定移动到以下 n 列 │
├——┼———————————————————┤
│nG │直接用数字 n 加上大写 G 移动到第 n 列 │
└——┴———————————————————┘
┌————┬———————————————┐
│指令 │说明 │
├————┼———————————————┤
│fx │往右移动到 x 字元上 │
│Fx │往左移动到 x 字元上 │
├————┼———————————————┤
│tx │往右移动到 x 字元前 │
│Tx │往左移动到 x 字元前 │
├————┼———————————————┤
│; │配合 f&t 使用,重复一次 │
│, │配合 f&t 使用,反方向重复一次 │
├————┼———————————————┤
│/string │往右移动到有 string 的地方 │
│?string │往左移动到有 string 的地方 │
├————┼———————————————┤
│n │配合 /&? 使用,重复一次 │
│N │配合 /&? 使用,反方向重复一次 │
└————┴———————————————┘
┌————┬———————————————————┬——————————┐
│指令 │说明 │备注 │
├————┼———————————————————┼——————————┤
│n( │左括号移动到句子的最前面 │句子是以 │
│ │前面加上数字可以指定往前移动n 个句子 │! . ? 三种符号来界定│
│n) │右括号移动到下个句子的最前面│ │
│ │前面加上数字可以指定往後移动n 个句子 │ │
├————┼———————————————————┼——————————┤
│n{ │左括弧移动到段落的最前面 │段落是以 │
│ │前面加上数字可以指定往前移动n 个段落 │段落间的空白列界定 │
│n} │右括弧移动到下个段落的最前面│ │
│ │前面加上数字可以指定往後移动n 个段落 │ │
└————┴———————————————————┴——————————┘
不要尝试背诵这些指令,否则後果自行负责。它们看起来又多又杂乱,事实上这是文字
叙述本身的障碍。再强调一次,实际去使用它只要几次就可以不经大脑直接下达这些奇
奇怪怪的指令,远比死记活背搞得模模糊糊强多了。(注:若真的不经大脑而误删资料
与我无关。另,此段为废话。)
进阶编辑指令
这些编辑指令非常有弹性,基本上可以说是由指令与范围所构成。例如 dw 是由删除指
令 d 与范围 w 所组成,代表删除一个字 d(elete) w(ord) 。
指令列表如下:
d 删除(delete)
y 复制(yank)
p 放置(put)
c 修改(change)
范围可以是下列几个:
e 游标所在位置到该字的最後一个字母
w 游标所在位置到下个字的第一个字母
b 游标所在位置到上个字的第一个字母
$ 游标所在位置到该列的最後一个字母
0 游标所在位置到该列的第一个字母
) 游标所在位置到下个句子的第一个字母
( 游标所在位置到该句子的第一个字母
} 游标所在位置到该段落的最後一个字母
{ 游标所在位置到该段落的第一个字母
说实在的,组合这些指令来编辑文件有一点点艺术气息。不管怎麽样,它们提供更多编
辑文字的能力。值得注意的一点是删除与复制都会将指定范围的内容放到暂存区里,然
後就可以用指令 p 贴到其它地方去,这是 vi 用来处理区段拷贝与搬移的办法。
某些 vi 版本,例如 Linux 所用的 elvis 可以大幅简化这一坨指令。如果稍微观察一
下这些编辑指令就会发现问题其实是定范围的方式有点杂,实际上只有四个指令罢了。
指令 v 非常好用,只要按下 v 键,游标所在的位置就会反白,然後就可以移动游标来
设定范围,接著再直接下指令进行编辑即可。
对於整列操作, vi 另外提供了更方便的编辑指令。前面曾经提到过删除整列文字的指
令 dd 就是其中一个;cc 可以修改整列文字;而 yy 则是复制整列文字;指令 D 则可
以删除游标到该列结束为止所有的文字。
档案指令
档案指令多以 : 开头,跟编辑指令有点区别。例如前面提到结束编辑的指令就是 :q。
现在就简单说明一下作为本篇故事的结尾:
∶q 结束编辑(quit)
如果不想存档而要放弃编辑过的档案则用 :q! 强制离开。
∶w 存档(write)
其後可加所要存档的档名。
可以将档案指令合在一起,例如:wq 即存档後离开。
zz 功能与 :wq 相同。
另外值得一提的是 vi 的部份存档功能。可以用 :n,mw filename 将第 n 列到第 m 列
的文字存放的所指定的filename 里去哩。时代在变,世界在变,vi 也在变,不过大
致上就这样。好了,但愿从此以後王子跟公主过著幸福快乐的生活。
键盘移动 (Move)
一切都从键盘的移动
k -> 上 up
j -> 下 down
h -> 左 left
l -> 右 right
z -> 重画屏幕,当前光标变成屏幕的第一行 (redraw current line at top of window)
CTRL-f -> 跳到下一页 (page down)
CTRL-b -> 跳到上一页 (page up)
跳跃指令 (jumps)
跳跃指令类似于游览器中的<前进><后退>按钮
CTRL-] -> 跟着link/tag转入 (follow link/tag)
CTRL-o -> 回到上一次的jump (go back)
CTRL-i -> 跳回下一个 (go forward)
:ju -> 显示所有的可以跳跃的地方(print jump list)
重做/回复
u -> undo
CTRL-r -> redo
vim的undo是树结构的,你可以回到这个结构中的任何地方
:undo 2 -> undo到结构的2层 (undo to tree 2)
:undolist -> 显示所有的undo列表 (show undo list)
:earlier 10s ->undo到10秒前的编辑 (undo to 10 seconds ago)
:earlier 10h ->undo到10小时前的编辑 (back to 10 hours ago)
:earlier 1m ->undo到1分钟前 (back to 1 minutes ago)
下面是undo的tree结构的解释
………..one
…………. |
……..change 1
…………. |
………one too
………. /……..\
…..change 2 ……. change 3
………… | ………………… |
…….one two ………. me too
……….. |
….. change 4
………..|
…… not two
视觉模式 (visual)
v -> 进入视觉模式
在视觉模式内可以作block的编辑
CTRL-v -> visual block
打印 (print)
:hardcopy -> 打印vim中的内容 (print text)
混合视觉模式 (visual) 可以选择打印的区域
没试过是否可以直接给值打印(应该可以)例如 :1,15hardcopy 打印前15行
将文件写成网页格式 (html)
:source$VIMRUNTIME/syntax/2html.vim -> change current open file to html
格式 (format)
dos/windows跟unix/linux对于文件的结束是不一样的。vim可以直接设定/更改格式
用纸令:setfileformats=unix,dos 可以改变文件的格式 (change format)
:set ff=unix -> 设定文件成unix格式 (set file in unixformat)
:set ff=dos -> 设定文件成dos格式 (set file in dos format)
:set ff? -> 检查当前文件格式 (check the format of current file)
如果改变格式,直接:w存档就会存成新的格式了。
加密 (encryption)
vim可以给文件加密码
vim -x 文件名 (filename) -> 输入2次密码,保存后文件每次都会要密码才能进入 (encrypt the file with password)
vim 处理加密文件的时候,并不会作密码验证,也就是说,当你打开文件的时候,vim不管你输入的密码是否正确,直接用密码对本文进行解密。如果密码错误,你看到的就会是乱码,而不会提醒你密码错误(这样增加了安全性,没有地方可以得知密码是否正确)当然了,如果用一个够快的机器作穷举破解,vim还是可以揭开的
vim 语法显示 (syntax)
:syntax enable -> 打开语法的颜色显示 (turn on syntaxcolor)
:syntax clear -> 关闭语法颜色 (remove syntax color)
:syntax off -> 完全关闭全部语法功能 (turn off syntax)
:syntax manual -> 手动设定语法 (set the syntax manual, when needsyntax use :set syntax=ON)
输入特殊字符 (special character)
CTRL-v 编码就可以了
例如 CTRL-v 273-> ÿ 得到 ÿ
二进 制文件 (binary file)
vim可以显示,编辑2进位文件
vim -b datafile
:set display=uhex -> 这样会以uhex显示。用来显示一些无法显示的字符(控制字符之类)(display in uhex play non-display char)
:%!xxd -> 更改当前文件显示为2进位 (change display tobinary)
:%!xxd -r -> 更改二进位为text格式 (convert back to text)
自动完成 (auto-completion)
vim本身有自动完成功能(这里不是说ctag,而是vim内建的)
CTRL-p -> 向后搜索自动完成 (search backward)
CTRL-n -> 向前搜索自动完成 (search forward)
CTRL-x+CTRL-o -> 代码自动补全 (code completion)
自动备份 (backup)
vim可以帮你自动备份文件(储存的时候,之前的文件备份出来)
:set backup -> 开启备份,内建设定备份文件的名字是 源文件名加一个 ‘~’ (enable backup default filename+~)
:set backupext=.bak -> 设定备份文件名为源文件名.bak (change backup as filename.bak)
自动备份有个问题就是,如果你多次储存一个文件,那么这个你的备份文件会被不断覆盖,你只能有最后一次存文件之前的那个备份。没关系,vim还提供了patchmode,这个会把你第一次的原始文件备份下来,不会改动
:set patchmode=.orig -> 保存原始文件为 文件名.orig (keep orignal file asfilename.orig)
开启,保存与退出 (save & exit)
:w -> 保存文件 (write file)
:w! -> 强制保存 (force write)
:q -> 退出文件 (exit file without save)
:q! -> 强制退出 (force quite without save)
:e filename -> 打开一个文件名为filename的文件 (open file to edit)
:e! filename -> 强制打开一个文件,所有未保存的东西会丢失 (force open, drop dirty buffer)
:saveas filename -> 另存为 filename (save file as filename)
编辑指令 (edit)
a -> 在光表后插入 (append aftercursor)
A -> 在一行的结尾插入 (append at end of the line)
i -> 在光标前插入 (insert before cursor)
I -> 在第一个非空白字符前插入 (insert before first non-blank)
o -> 光标下面插入一个新行 (open line below)
O -> 光标上面插入一个新行 (open line above)
x -> 删除光标下(或者之后)的东西 (delete under and after cursor)
例如x就是删除当前光标下,3x就是删除光标下+光标后2位字符
X -> 删除光标前的字符 (delete before cursor)
d -> 删除 (delete)
可以用dd删除一行,或者3dw删除3个词等等
J -> 将下一行提到这行来 (join line)
r -> 替换个字符 (replace characters)
R -> 替换多个字符 (replace mode – continue replace)
gr -> 不影响格局布置的替换 (replace without affecting layout)
c -> 跟d键一样,但是删除后进入输入模式 (same as “d” but after delete, ininsert mode)
S -> 删除一行(好像dd一样)但是删除后进入输入模式 (same as “dd” but after delete, ininsert mode)
s -> 删除字符,跟(d)一样,但是删除后进入输入模式 (same as “d” but after delete, ininsert mode)
s4s 会删除4个字符,进入输入模式 (delete 4 char and put in insert mode)
~ -> 更改大小写,大变小,小变大 (change case upper-> lower or lower->upper)
gu -> 变成小写 (change to lower case)
例如 guG 会把光标当前到文件结尾全部变成小写 (change lower case all the way to the end)
gU -> 变成大写 (change to upper case)
例如 gUG 会把光标当前到文件结尾全部变成大写 (change upper case all the way to the end)
复制与粘贴 (copy & paste)
y -> 复制 (yank line)
yy -> 复制当前行 (yank current line)
“{a-zA-Z}y -> 把信息复制到某个寄存中 (yank the link into register {a-zA-Z})
例如我用 “ayy 那么在寄存a,就复制了一行,然后我再用“byw复制一个词在寄存b
粘贴的时候,我可以就可以选择贴a里面的东西还是b里面的,这个就好像是多个复制版一样
“*y -> 这个是把信息复制进系统的复制版(可以在其他程序中贴出来)(yank to OS buffer)
p -> 当前光标下粘贴 (paste below)
P -> 当前光标上粘贴 (paste above)
“{a-zA-Z}p -> 将某个寄存的内容贴出来 (paste from register)
例如“ap那么就在当前光标下贴出我之前在寄存a中的内容。“bP就在当前光标上贴出我之前寄存b的内容
“*p -> 从系统的剪贴板中读取信息贴入vim (paste from OS buffer to vim)
reg -> 显示所有寄存中的内容 (list all registers)
书签 (Mark)
书签是vim中非常强大的一个功能,书签分为文件书签跟全局书签。文件书签是你标记文件中的不同位置,然后可以在文件内快速跳转到你想要的位置。而全局书签是标记不同文件中的位置。也就是说你可以在不同的文件中快速跳转
m{a-zA-Z} -> 保存书签,小写的是文件书签,可以用(a-z)中的任何字母标记。大写的是全局 书签,用大写的(A-Z)中任意字母标记。(mark position as bookmark. when lower,only stay in file. when upper, stay in global)
‘{a-zA-Z} -> 跳转到某个书签。如果是全局书签,则会开启被书签标记的文件跳转至标记的行 (go to mark. in file {a-z} or global{A-Z}. in global, it will open the file)
’0 -> 跳转入现在编辑的文件中上次退出的位置 (go to last exit in file)
” -> 跳转如最后一次跳转的位置 (go to last jump -> go back to last jump)
‘” -> 跳转至最后一次编辑的位置 (go to last edit)
g’{mark} -> 跳转到书签 (jump to {mark})
:delm{marks} -> 删除一个书签 (delete a mark) 例如:delma那么就删除了书签a
:delm! -> 删除全部书签 (delete all marks)
:marks -> 显示系统全部书签 (show all bookmarks)
标志 (tag)
:ta -> 跳转入标志 (jump to tag)
:ts -> 显示匹配标志,并且跳转入某个标志 (list matching tags and select one to jump)
:tags -> 显示所有标志 (print tag list)
运行外部命令 (using an external program)
:! -> 直接运行shell中的一个外部命令 (call any externalprogram)
:!make -> 就直接在当前目录下运行make指令了 (run make on current path)
:r !ls -> 读取外部运行的命令的输入,写入当然vim中。这里读取ls的输出 (read the output of ls and append theresult to file)
:3r !date -u -> 将外部命令date -u的结果输入在vim的第三行中 (read the date -u, and append result to3rd line of file)
:w !wc -> 将vim的内容交给外部指令来处理。这里让wc来处理vim的内容 (send vim’s file to external command.this will send the current file to wc command)
vim对于常用指令有一些内建,例如wc (算字数)(vim has some buildin functions, suchlike wc)
g CTRL-G -> 计算当前编译的文件的字数等信息 (word count on current buffer)
!!date -> 插入当前时间 (insert current date)
多个文件的编辑 (edit multifiles)
vim可以编辑多个文件,例如
vim a.txt b.txt c.txt 就打开了3个文件
:next -> 编辑下一个文件 (next file inbuffer)
:next! -> 强制编辑下个文件,这里指如果更改了第一个文件 (force to next file in buffer ifcurrent buffer changed)
:wnext -> 保存文件,编辑下一个 (save the file and goto next)
:args -> 查找目前正在编辑的文件名 (find out which buffer is editing now)
:previous -> 编辑上个文件 (previous buffer)
:previous! -> 强制编辑上个文件,同 :next! (force to previous buffer, sameas :next!)
:last -> 编辑最后一个文件 (last buffer)
:first -> 编辑最前面的文件 (first buffer)
:set autowrite -> 设定自动保存,当你编辑下一个文件的时候,目前正在编辑的文件如果改动,将会自动保存 (automatic write the buffer when youswitch to next buffer)
:set noautowrite -> 关闭自动保存 (turn autowrite off)
:hide e abc.txt -> 隐藏当前文件,打开一个新文件 abc.txt进行编辑 (hide the current buffer and editabc.txt)
:buffers -> 显示所有vim中的文件 (display all buffers)
:buffer2 -> 编辑文件中的第二个 (edit buffer 2)
vim中很多东西可以用简称来写,就不用打字那么麻烦了,例如 :edit=:e, :next=:n 这样.
分屏 (split)
vim提供了分屏功能(跟screen里面的split一样)
:split -> 将屏幕分成2个 (split screen)
:split abc.txt -> 将屏幕分成两个,第二个新的屏幕中显示abc.txt的内容 (split the windows, on new window,display abc.txt)
:vsplit -> 竖着分屏 (split vertically)
:{d}split -> 设定分屏的行数,例如我要一个屏幕只有20行,就可以下:20split (split the windows with {d} line.20split: open new windows with 3 lines)
:new -> 分屏并且在新屏中建立一个空白文件 (split windows with a new blank file)
CTRL-w+j/k/h/l -> 利用CTRL加w加上j/k/h/l在不同的屏内切换 (switch, move between split screens)
CTRL-w+ -/+ -> 增减分屏的大小 (change split size)
CTRL-w+t -> 移动到最顶端的那个屏 (move to the top windows)
CTRL-w+b -> 移动到最下面的屏 (move to bottom window)
:close -> 关闭一个分出来的屏 (close splited screen)
: only -> 只显示光标当前屏,其他将会关闭(only display current active screen,close all others )
:qall -> 退出所有屏 (quite all windows)
:wall -> 保存所有屏 (write to all windows)
:wqall -> 保存并退出所有屏 (write and quite all windows)
:qall! -> 退出所有屏,不保存任何变动 (quite all windows without save)
开启文件的时候,利用 -o选项,就可以直接开启多个文件在分屏中 (with -o option from command line, itwill open files and display in split mode)
vim -o a.txt b.txt
今天有人说不会看diff,其实vim也可以用来看diff,这个也是属于分屏的部分,这里也写一下。
vimdiff a.txt b.txt 如果直接给 -d选项是一样的 vim -d a.txt b.txt
:diffsplit abc.txt 如果你现在已经开启了一个文件,想vim帮你区分你的文件跟abc.txt有什么区别,可以在vim中用diffsplit的方式打开第二个文件,这个时候vim会用split的方式开启第二个文件,并且通过颜色,fold来显示两个文件的区别
这样vim就会用颜色帮你区分开2个文件的区别。如果文件比较大(源码)重复的部分会帮你折叠起来(折叠后面会说)
现在来说patch
:diffpatch filename 通过:diffpatch 你的patch的文件名,就可以以当前文件加上你的patch来显示。vim会split一个新的屏,显示patch后的信息并且用颜色标明区别。
如果不喜欢上下对比,喜欢左右(比较符合视觉)可以在前面加vert,例如:
:vert diffsplit abc.txt
:vert diffpatch abc.txt
看完diff,用: only回到原本编辑的文件,觉 得diff的讨厌颜色还是在哪里,只要用:diffoff关闭就好了。
还有个常用的diff中的就是 :diffu 这个是 :diffupdate 的简写,更新用
TAB
除了split之外, vim还可以用 tab
:tab split filename -> 这个就用tab的方式来显示多个文件 (use tab to display buffers)
gt -> 到下一个tab (go to next tab)
gT -> 到上一个tab (go to previous tab)
vim大多数东西都是可一给数字来执行的,tab也是一样
0gt ->跳到第一个tab (switch to 1st tab)
5gt -> 跳到第五个tab (switch to 5th tab)
关闭所有的tab可以使用qall的指令。另外让vim在启动的时候就自动用tabnew的方式来开启多个文件,可以用alias
linux: 添加 alias vim=’vim -p’到 ~/.bashrc
windows: 自己写个vim.bat的文件,然后放在path中,文件内容:
@echo off
vim -p %*
当需要更改多个tab中的文件的时候,可以用 :tabdo 这个指令这个就相当于 loop 到你的所有的 tab 中然后运行指令。
例如有5个文件都在tab里面,需要更改一个变量名称:abc 到 def, 就可以用 :tabdo %s/abc/def/g 这样所有的5个tab里面的abc就都变成def了
折叠 (folding)
vim的折叠功能。。。我记得应该是6版出来的时候才推出的吧。这个对于写程序的人来说,非常有用。
zfap -> 按照段落折叠 (fold by paragraph)
zo -> 打开一个折叠 (open fold)
zc -> 关闭一个折叠 (close fold)
zf -> 创建折叠 (create fold) 这个可以用v视觉模式,可以直接给行数等等
zr -> 打开一定数量的折叠,例如3rz (reduce the folding by number like 3zr)
zm -> 折叠一定数量(之前你定义好的折叠) (fold by number)
zR -> 打开所有的折叠 (open all fold)
zM -> 关闭所有的摺叠 (close all fold)
zn -> 关闭折叠功能 (disable fold)
zN -> 开启折叠功能 (enable fold)
zO -> 将光标下所有折叠打开 (open all folds at the cursor line)
zC -> 将光标下所有折叠关闭 (close all fold at cursor line)
zd -> 将光标下的折叠删除,这里不是删除内容,只是删除折叠标记 (delete fold at cursor line)
zD -> 将光标下所有折叠删除 (delete all folds at the cursor line)
按照tab来折叠,python最好用的 (ford by indent,very useful for python)
:set foldmethod=indent -> 设定后用zm 跟 zr 就可以的开关关闭了 (use zm zr)
保存 (save view)
对于vim来说,如果你设定了折叠,但是退出文件,不管是否保持文件,折叠部分会自动消失的。这样来说非常不方便。所以vim给你方法去保存折叠,标签,书签等等记录。最厉害的是,vim对于每个文件可以保存最多10个view,也就是说你可以对同一个文件有10种不同的标记方法,根据你的需要,这些东西都会保存下来。
:mkview -> 保存记录 (save setting)
:loadview -> 读取记录 (load setting)
:mkview 2 -> 保存记录在寄存2 (save view to register 2)
:loadview 3 -> 从寄存3中读取记录 (load view from register 3)
常用指令 (commands)
:set ic ->设定为搜索时不区分大小 写 (search caseinsensitive)
:set noic ->搜索时区分大小写。 vim内定是这个(case sensitive )
& -> 重复上次的”:s” (repeat previous “:s”)
. -> 重复上次的指令 (repeat last command)
K -> 在man中搜索当前光标下的词 (search man page under cursor)
{0-9}K -> 查找当前光标下man中的章节,例如5K就是同等于man 5 (search section of man. 5K searchfor man 5)
:history -> 查看命令历史记录 (see command line history)
q: -> 打开vim指令窗口 (open vim command windows)
:e -> 打开一个文件,vim可以开启http/ftp/scp的文件 (open file. alsoworks with http/ftp/scp)
:e http://www.google.com/index.html -> 这里就在vim中打开google的index.html (open google’s index.html)
:cd -> 更换vim中的目录 (change current directory in vim)
:pwd -> 显示vim当前目录 (display pwd in vim)
gf -> 打开文件。例如你在vim中有一行写了#include 那么在abc.h上面按gf,vim就会把abc.h这个文件打开 (look for file. if you have a file with#include , then the cursor is on abc.h press gf, it will open the file abc.h invim )
记录指令 (record)
q{a-z} -> 在某个寄存中记录指令 (record typed char into register)
q{A-Z} -> 将指令插入之前的寄存器 (append typed char into register{a-z})
q -> 结束记录 (stop recording)
@{a-z} -> 执行寄存中的指令 (execute recording)
@@ -> 重复上次的指令 (repeat previours :@{a-z})
还是给个例子来说明比较容易明白
我现在在一个文件中下qa指令,然后输入itest然后ESC然后q
这里qa就是说把我的指令记录进a寄存,itest实际是分2步,i 是插入 (insert) 写入的文字是 text 然后用ESC退回指令模式q结束记录。这样我就把itest记录再一个寄存了。
下面我执行@a那么就会自动插入test这个词。@@就重复前一个动作,所以还是等于@a
搜索 (search)
vim超级强大的一个功能就是搜索跟替换了。要是熟悉正表达(regular expressions)这个搜索跟后面的替换将会是无敌利器(支持RE的编辑器不多吧)
从简单的说起
# -> 光标下反向搜索关键词 (search the word under cursor backward)
* -> 光标下正向搜索关键词 (search the word under cursor forward)
/ -> 向下搜索 (search forward)
? -> 向上搜索 (search back)
这里可以用 /abc 或 ?abc的方式向上,向下搜索abc
% -> 查找下一个结束,例如在”(“下查找下一个”)”,可以找”()”, “[]” 还有shell中常用的 if, else这些 (find next brace,bracket, comment or #if/#else/#endif)
下面直接用几个例子说话
/a* -> 这个会搜到 a aa aaa
/\(ab\)* -> 这个会搜到 ab abab ababab
/ab\+ -> 这个会搜到 ab abb abbb
/folers\= -> 这个会搜到 folder folders
/ab\{3,5} -> 这个会搜到 abbb abbbb abbbbb
/ab\{-1,3} -> 这个会在abbb中搜到ab (will match ab in abbb)
/a.\{-}b -> 这个会在axbxb中搜到axb (match ‘axb’ in ‘axbxb’)
/a.*b -> 会搜索到任何a开头后面有b的 (match a*b any)
/foo\|bar -> 搜索foo或者bar,就是同时搜索2个词 (match ‘foo’ or ‘bar’)
/one\|two\|three -> 搜索3个词 (match ‘one’, ‘two’ or ‘three’)
/\(foo\|bar\)\+ -> 搜索foo, foobar, foofoo, barfoobar等等 (match ‘foo’,‘foobar’, ‘foofoo’, ‘barfoobar’ … )
/end\(if\|while\|for\) -> 搜索endif, endwhile endfor (match ‘endif’,‘endwhile’, ‘endfor’)
/forever\&… -> 这个会在forever中搜索到”for”但是不会在fortuin中搜索到”for” 因为我们这里给了&…的限制 (match ‘for’ in ‘forever’ will notmatch ‘fortuin’)
特殊字符前面加^就可以 (for special character, user “^” at thestart of range)
/”[^"]*”
这里解释一下
” 双引号先引起来 (double quote)
[^"] 任何不是双引号的东西(any character that is not a double quote)
* 所有的其他 (as many as possible)
” 结束最前面的引号 (double quote close)
上面那个会搜到“foo” “3!x”这样的包括引号 (match “foo” ->and “3!x” include double quote)
更多例子,例如搜索车牌规则,假设车牌是 “1MGU103” 也就是说,第一个是数字,3个大写字幕,3个数字的格式。那么我们可以直接搜索所有符合这个规则的字符
(A sample license plate number is “1MGU103″. It has one digit, three upper case
letters and three digits. Directly putting this into a search pattern)
这个应该很好懂,我们搜索
\数字\大写字母\大写字母\大写字母\数字\数字\数字
/\d\u\u\u\d\d\d
另外一个方法,是直接定义几位数字(不然要是30位,难道打30个\u去?)
(specify there are three digits and letters with a count)
/\d\u\{3}\d\{3}
也可以用范围来搜索 (Using [] ranges)
/[0-9][A-Z]\{3}[0-9]\{3}
用到范围搜索,列出一些范围(range)
这个没什么好说了,看一下就都明白了,要全部记住。。。用的多了就记住了,用的少了就忘记了。每次看帮助,呵呵
/[a-z]
/[0123456789abcdef] = /[0-9a-f]
\e
\t
\r
\b
简写 (item matchesequivalent)
\d digit [0-9]
\D non-digit [^0-9]
\x hex digit [0-9a-fA-F]
\X non-hex digit [^0-9a-fA-F]
\s white space [ ] ( and )
\S non-white characters [^ ] (not and )
\l lowercase alpha [a-z]
\L non-lowercase alpha [^a-z]
\u uppercase alpha [A-Z]
\U non-uppercase alpha [^A-Z]
:help /[] –> 特殊的定义的,可以在vim中用用help来看 (everything about special)
:help /\s –> 普通的也可以直接看一下 (everything about normal)
替换 (string substitute) – RX
替换其实跟搜索是一样的。只不过替换是2个值,一个是你搜索的东西,一个是搜索到之后要替换的 string substitute (use rx)
%s/abc/def/ -> 替换abc到def (substitute abcto def)
%s/abc/def/c -> 替换abc到def,会每次都问你确定(substitute on all text withconfirmation (y,n,a,q,l))
1,5s/abc/def/g -> 只替换第一行到第15行之间的abc到def (substitute abc to def only betweenline 1 to 5)
54s/abc/def/ -> 只替换第54行的abc到def (only substitute abc to def on line54)
结合上面的搜索正表达式,这个替换功能。。。就十分只强大。linux中很多地方都是用正表达来做事请的,所以学会了受益无穷。
全局 (global)
这个不知道怎么翻译,反正vim是叫做global,可以对搜索到的东西执行一些vim的命令。我也是2-3个星期前因为读log中一些特殊的东西,才学会用的。 (find the match pater and execute acommand)
global具体自行方法是 g/pattern/command
:g/abc/p -> 查找并显示出只有abc的行 (only print line with “abc” )
:g/abc/d -> 删除所有有abc的行 (delete all line with “abc”)
:v/abc/d -> 这个会把凡是不是行里没有abc的都删掉 (delete all line without “abc”)
信息过滤 (filter)
vim又一强大功能
! -> 用!就是告诉vim,执行过滤流程 (tell vim toperforming a filter operation)
!5G -> 从光标下向下5行执行过滤程序 (tell vim to start filter under cursorand go down 5 lines)
正式指令开始,这里用sort来做例子:
!5Gsort -> 从光标下开始执行sort,一共执行5行,就是说我只要sort5行而已 (this will sort the text from cursorline down to 5 lines)
!Gsort -k3 -> 可以直接代sort的参数,我要sort文字中的第三段 (sort to the end of file by column 3)
!! -> 值过滤当前的这行 (filter the current line)
如果觉得!这样的方法5G这样的方法用起来别扭(我是这么觉得),可以用标准的命令模式来做
!其实就是个:.,而已(to type the command)
:.,start,end!sort 这里定义:.,起始行,结束行!运行指令
:.,$!sort -> 从当前这行一直执行至文件结束 (sort from current line to end)
:.0,$!sort -> 从文件的开始第一个行一直执行到文件结束 (sort from start of file to end)
:.10,15!sort -> 只在文件的第10行到第15行之间执行 (sort between line 10 to 15)