同时显示两个不同的文件, 或者同时查看同一个文件的两个不同位置, 或者是同步显示两个文件的不同之处. 所有这些都可以通过分隔窗口的功能来实现.
1. 分隔一个窗口
打开一个新窗口最简单的办法就是使用命令: (ex command)
:split
该命令将屏幕分为上下两个窗口并将光标定位在上面的窗口中:
+----------------------------------+
|/* file one.c */ |
|~ |
|~ |
|one.c=============================|
|/* file one.c */ |
|~ |
|one.c=============================|
| |
+----------------------------------+
你看到的是两个窗口, 显示的内容却来自同一个文件. 含有"===="的行表示状态行. 它显示了关于它上面的窗口的相关信息. (实际情况下状态行会反相显示)
同时打开两个窗口可以让你查看同一文件的两个不同部分. 比如你可以让上面的窗口来显示一个程序中的变量声明部分, 下面的窗口是使用了这些变量的编码区.
CTRL-W w命令可以切换当前活动窗口. 如果你在上面窗口, 它会把它带到下面. 如果你在下面的窗口, 同样的命令却是把你带到上面.
(CTRL-W CTRL-W功能相同, 只不过你可以迟一点松开CTRL键)
关闭窗口命令: (ex command)
:close
可以关闭当前窗口. 实际上, 任何退出文件编辑的命令象":quit"和"ZZ"都会关闭窗口, 但是用":close" 可以阻止你关闭最后一个Vim, 以免以意外地整个关闭了Vim.关闭除当前窗口外的所有其它窗口如果你打开了一大堆窗口, 但现在你只想把重心放在其中一个上面,这时命令: (ex command)
:only
就十分有用了. 它会关闭除当前窗口外的所有其它窗口. 如果这些窗口中有被修改过的, 你会得到一个错误信息1, 同时那个窗口会被留下来.
2. 为另一个文件分隔出一个窗口
下面的命令可以打开第二个窗口同时在新打开的窗口中开始编辑作为参数的文件: (ex command)
:split two.c
如果你目前正编辑的文件名为one.c, 那么执行该命令后的屏幕大致象这样:
+----------------------------------+
|/* file two.c */ |
|~ |
|~ |
|two.c=============================|
|/* file one.c */ |
|~ |
|one.c=============================|
| |
+----------------------------------+
如果要打开一个新窗口并开始编辑一个空的缓冲区, 使用命令: (ex command)
:new
你可以重复使用":split"和":new"命令打开任何你喜欢的窗口数目1
3. 窗口大小
":split"命令还可以接受一个参数. 如果指定了这个参数的话, 它将会作为新打开窗口的高度. 比如下面的命令就打开了一个高度为3行的新窗口并在其中编辑名为alpha.c的文件2: (ex command)
:3split alpha.c
对于已经打开的窗口有好几种办法可以改变它们的大小. 如果你还有鼠标可用的话就更容易了: 把鼠标移到分隔窗口的状态行上, 上下拖动它即可.
增加当前窗口高度: (normal mode command)
CTRL-W +
减小: (normal mode command)
CTRL-W -
这两个命令都可以接受一个命令记数, 用以一次将窗口的高度增减指定的行数. "4 CTRL-W +"将使当前窗口增加4行高度.将窗口高度指定为一个固定的高度: (normal mode command)
{height}CTRL-W _
这个命令的组成是: 一个代表行数的数字fheightg, CTRL-W和一个下划线(在标准键盘上同时按下Shift键和-键).
要让窗口达到它可能的最大高度, 不指定命令记数直接使用CTRL-W_ .
使用鼠标
在Vim中大多数工作都可以通过键盘有效地完成. 不幸的是调整窗口大小的命令需要敲太多的键. 这时用鼠标反而更快. 将鼠标置于状态行.按下鼠标左键拖动. 状态行就会跟着上下移动, 相应地窗口的高度也跟着变大变小.
相关选项
°winheight° 选项可以设置为一个你期望的最小的窗口高度. °winminheight°则用于设置一个强制的最小高度同样地, 有一对对应的选项:°winwidth°和°winminwidth°, 分别用于指定期望的最小窗口宽度和强制的最小窗口宽度.如果设置了°equalalways°选项, 则Vim在每次打开或关闭窗口之际都会自动让所有窗口均摊屏幕上可用的高度和宽度.
4. 垂直分隔
":split"命令创建的新窗口位于当前窗口之上. 要让新窗口出现在当前窗口的左边, 可以用命令: (ex command)
:vsplit
或:
:vsplit two.c
分隔后的窗口大致象:
+--------------------------------------+
|/* file two.c */ |/* file one.c */ |
|~ |~ |
|~ |~ |
|~ |~ |
|two.c===============one.c=============|
| |
+--------------------------------------+
实际操作时这里窗口中间出现的|都会以反相显示. 这叫垂直分隔符. 它用来界定左右两个窗口.同样有一个对应的":vnew"命令, 用于垂直分隔窗口并在其中打开一个新的空缓冲区. 与此等价的一个命令是: (ex command)
:vertical new
实际上":vertical"可以出现在任何分隔窗口的命令前1. 这将使接下来的窗口分隔命令进行垂直方向的分隔而不是水平方向上. (如果随后的命令跟分隔窗口无关, 这个前辍就形同虚设).
切换窗口
因为你可以以水平和垂直方向任意分隔窗口, 最终的窗口布局也会五花八门. 置身于众多的窗口你需要在里面来去自如:
CTRL-W h 到左边的窗口
CTRL-W j 到下面的窗口
CTRL-W k 到上面的窗口
CTRL-W l 到右边的窗口
CTRL-W t 到顶部窗口
CTRL-W b 到底部窗口
有没有觉得这些字符有些眼熟2. 如果你愿意的话, 用光标键来也同样可以.
参考jQ wj可以了解更多的关于在窗口间移动的命令.
5. 移动窗口
如果你已经分隔出了几个窗口, 但对它们的位置不满意. 这时你需
要一个命令来移动它们的相对位置. 比如说, 你已经有了下面三个窗口:
Display
+----------------------------------+
|/* file two.c */ |
|~ |
|~ |
|two.c=============================|
|/* file three.c */ |
|~ |
|~ |
|three.c===========================|
|/* file one.c */ |
|~ |
|one.c=============================|
| |
+----------------------------------+
显然最后一个窗口本应在最上面. 转到该窗口(使用CTRL-W w)然后键入如下命令: (normal mode command)
CTRL-W K
这里使用的是大写的字母K. 命令的结果是将当前窗口向上提升了一次. 有没有注意到K又被用于向上移动1.如果你已经有了几个垂直分隔的窗口, CTRL-W K会把当前窗口向上移动同时占据整个Vim程序窗口的宽度. 假如当前的窗口布局是:
+-------------------------------------------+
|/* two.c */ |/* three.c */ |/* one.c */ |
|~ |~ |~ |
|~ |~ |~ |
|~ |~ |~ |
|~ |~ |~ |
|~ |~ |~ |
|two.c=========three.c=========one.c========|
| |
+-------------------------------------------+
对中间的那个窗口(three.c)应用命令CTRL-W K将使窗口布局改为1:
Display
+-------------------------------------------+
|/* three.c */ |
|~ |
|~ |
|three.c====================================|
|/* two.c */ |/* one.c */ |
|~ |~ |
|two.c==================one.c===============|
| |
+-------------------------------------------+
另外三个相似的命令是(估计你已经猜到了):
CTRL-W H 向左移动窗口
CTRL-W J 向下移动窗口
CTRL-W L 向右移动窗口
6. 针对所有窗口操作的命令
在打开一大堆窗口的情况下要退出Vim, 你可以一个一个地关闭这些窗口. 还有另外一个专用的命令: (ex command)
:qall
意思很明显"quit all"3. 如果这些窗口中有被修改又没保存的,Vim 就不会退出. 光标也会自动被定位到该窗口中. 这样你可以用":write"来保存修改, 或用":quit!"放弃这些改动.
如果你已经知道有窗口被修改了而且还没有保存, 可以用命令: (ex command)
:wall
来保存所有被修改的窗口. 命令意为"write all"1. 但实际上, 它只会存盘那些改动过的. Vim很清楚重写一遍完全没有改变的文件毫无意义.还有一个对":qall"和":wall"的组合: 保存并退出所有窗口: (ex command)
:wqall
这个命令将保存所有被修改的文件然后退出Vim.最后, 还有一个放弃所有修改强制退出Vim的命令: (ex command)
:qall!
慎用! 这一丢可就再也回不来了!为每一个文件打开一个窗口,使用"-o"选项可以让Vim为每一个文件打开一个窗口: (shell command)
#: vim -o one.txt two.txt three.txt
结果是:
+-------------------------------+
|file one.txt |
|~ |
|one.txt========================|
|file two.txt |
|~ |
|two.txt========================|
|file three.txt |
|~ |
|three.txt======================|
| |
+-------------------------------+
"-O"参数可以使打开的窗口都垂直排列.
如果已经进入了vim, ":all"命令会为命令行上指定的所有文件各开一个窗口. ":vertical all"则让打开的窗口都是垂直分隔.
7. 使用vimdiff查看不同
Vim有一种特殊的启动方式, 可以显示两个文件的不同之处. 我们来以"main.c"文件为例, 在其中一行插入几个字符, 在打开°backup°选项的情况下保存文件, 这样名为"main.c~"的备份文件会保留该文件此前的版本.
在一个shell中键入如下命令(注意不是在Vim中):(shell command)
#: vimdiff main.c~ main.c
Vim将会打开左右两个垂直分隔的窗口. 你会只看到你多插入了几个字符的那行以及它周围的上下几行内容.
VV VV
+-----------------------------------------+
|+ +--123 lines: /* a|+ +--123 lines: /* a| <- fold
| text | text |
| text | text |
| text | text |
| text | changed text | <- changed line
| text | text |
| text | ------------------ | <- deleted line
| text | text |
| text | text |
| text | text |
|+ +--432 lines: text|+ +--432 lines: text| <- fold
| ~ | ~ |
| ~ | ~ |
|main.c~==============main.c==============|
| |
+-----------------------------------------+
(该图没有显示语法高亮, 实地使用vimdiff命令会更好看一些)没被修改的行被缩置到单独的一行中. 这叫折叠. 被执行的行以"<-fold"为标识. 单个的折叠行代表了123行的内容. 这些行对于两个文件来说都是一样的.
以"<- changed"标识的那一行以高亮显示, 被插入的字符也以另类的颜色突出显示. 这种方式清晰地展示了两个文件的异同之处.在man.c窗口中显示为"---"行表明该行被删除了. 如图中标以"<-delete line"的行. 注意这些字符并不真的是文件内容的一部分, 它们只是被用来填满main.c的空缺部分, 这样两个文件就可以显示相同的行数了.
折叠的栏位
两个比较窗口的左边都有一个背景略有不同的栏位. 上图中它们以"VV"标识. 看到折叠行前面的加号字符了吗. 把鼠标移到该字符上单击. 折叠的行就会展开, 这样你就可以看到被隐藏起来的内容了.折叠栏前面的减号表明这是已经被打开了折叠行. 单击该符号会再次折行. 当然, 你要有鼠标可用才行. 如果没有, 也可以用使用"zo"来展开折叠, 用"zc"再把它们折起.
运行VIM后比较不同
另一种进入diff模式的办法可以在Vim运行中操作. 编辑文件"main.c",然后打开另一个分隔窗口显示其不同1: (ex command)
:edit main.c
:vertical diffsplit main.c
":vertical"命令让打开的对比窗口以垂直方向分隔. 如果没有它,打开的窗口就是水平方向分隔的.
如果你有一个patch或diff文件, 还有第3种开始diff模式的方法.
首先编辑那个要应用patch 的文件. 然后告诉Vim patch文件的名字: (ex command)
:edit main.c
:vertical diffpatch main.c.diff
警告: patch文件必需只包含了单个文件的patch才行. 否则你会看到一大堆错误信息, 同时也有可能把文件打上错误的补丁.补丁会打到当前文件的一个副本上, 该文件本身并不会被修改(除非你决定以打完补丁后的内容保存它).
同步滚动
如果两个文件有很多不同之处, 你可以以通常方式滚动窗口进行查看. Vim会保证两个窗口总是显示文件中相同位置2的内容, 所以你可以一行对一行地看到它们的差异.
如果暂时不想让它这样, 使用命令: (ex command)
:set noscrollbind
即可
跳到不同之处
如果你禁用了折行显示, 要找到两个文件的不同之处就要费劲些, 命令: (normal mode command)
]c
可以直接向前定位到下一个不同之处. 向后定义下一个发生改变的行用: (normal mode command)
[c
以一个数字为命令记数可以加快跳转的步伐.
消除差异
你可以在两个对比窗口中移动文字. 这样做会引起两个文件对比结果的变化. 不同之处会减少或增多. Vim并不时时更新对应的高亮显示.
命令: (ex command)
:diffupdate
可以在需要的时候重新比较两个文件. 要消除一个不同之处, 你可以把高亮起来的文件从一个窗口移到另一个窗口去. 以上面的"main.c"和"main.c~"为例. 把光标置于左边窗口中比右边窗口多出的一行上.
现在使用命令: (normal mode command)
dp
两个文件的不同被消除了, 当前窗口中引起不同的内容被放到另一窗口中缺少这段内容的地方去了. "dp"是"diff put"的缩写.也可以用其它方法来做. 将光标移到右边的窗口, 到"changed"插入的位置.
键入命令: (normal mode command)
do
8. 其它
°laststatus°选项用于指定何时最近使用的窗口会有一个状态行:
0 永远没有
1 只有分隔窗口时(默认值)
2 总是存在
很多要打开另一个文件的命令都有一个变体, 可以新开一个窗口来打开指定的文件. 对于命令行命令而言通常是在一般命令前面附加一个"s". 例如":tag"可以跳转到一个tag, ":stag"则是打开一个新窗口跳转到该tag.
对于Normal模式的命令是在命令前使用CTRL-W. CTRL-^可以跳转到前一个编辑的文件, CTRL-W CTRL-^则分隔出一个窗口来编辑前一个文件.
°splitbelow°选项用来控制新开的窗口出现在当前窗口的下面. °splitright°则相应地使新开的垂直窗口出现在当前窗口的右边分隔窗口命令还可以有一个位置修饰限定词作为前辍, 用来指定新打开的窗口将出现的位置:
:leftabove {cmd} 当前窗口的左边或上面
:aboveleft {cmd} 同上
:rightbelow {cmd} 当前窗口的右边或下面
:belowright {cmd} 同上
:topleft {cmd} 当前窗口的上边或左边
:botright {cmd} 当前窗口的下面或右边