vim默认是在一个窗口中编辑所有文件,在文件间移动或者移动到文件的不同部分时只显示一个缓冲区。但vim也提供了多窗口编辑功能,可以简化复合的编辑任务。这篇文章将学习如何在一个运行的vim进程里使用多窗口,包括多窗口编辑工作的初始化与启动,在窗口间移动光标,在显示区中移动窗口等。
启动多窗口编辑:
可以在打开vim时启动多窗口编辑,也可以在编辑会话中分割窗口。
从命令行(shell)启动多窗口:
默认情况下,vim为一个会话只打开一个窗口,即使打开时已经指定多个文件。如果想从命令行中打开多个窗口,需要使用vim的" -o "选项,此时vim会试着为命令行上列出的每个文件打开一个窗口。也可以在" -o "后面附上数值,从而指定打开窗口的数量。关于" -o "选项,在《学习vi和vim编辑器(15):vim对vi的主要改进》中已经讲过。
当vim创建超过一个窗口时,它默认为每个窗口创建状态行(如果只是一个窗口时,默认不呈现任何状态行)。可以使用vim的laststatus选项控制这项行为,默认laststatus=1。如果将laststatus设置为2,则可看到每个窗口的状态行,即使只打开一个窗口。
vim的多窗口编辑:
在启动vim后,可以使用" :split "创建新窗口。该命令将当前窗口分成两半,均显示相同缓冲区中的内容,因此可以在两个窗口中浏览相同的文件。类似地,使用" :vsplit "命令,可以创建全新的垂直分隔窗口。
本章中提到的许多命令,都有更为便捷的命令序列。例如" ^Ws "(按下CTRL+W,再按下s键)等价于" :split "命令。所有vim的窗口命令都以" ^W "开始(W代表Window的意思)。但是使用ex命令的形式可以让我们提供可选参数,从而可自定义缺省功能。
vim以上述方式(水平或垂直地)分隔窗口,且" :split "命令未指定文件时,我们将于两个窗口中编辑同一份文件。如果想要编辑或浏览另一个文件,可以将新的文件作为参数传给" :split "命令,例如" :split otherfile "。
打开窗口:
接下来将详细介绍在分割窗口时如何取得更为精确的行为。
分隔窗口的选项:
完整的打开新的水平窗口的" :split "命令如下: " :[n]split [++opt] [+cmd] [file] "。命令中:
n :为vim指定新窗口中显示的行数,新窗口位于画面顶端;
opt:传递vim选项信息给新的窗口会话;
cmd:传入欲在新窗口中执行的命令;
file:指定欲在新窗口中编辑的文件;
" :[n]new [++opt] [+cmd] [file] "命令也可以按上述方式打开一个水平窗口,但有一点细微差别:除了创建新窗口外,自动命令WinLeave,WinEnter,BufLeave,BufEnter也被执行了。
除了水平分割命令,vim也提供类似的垂直分割命令:" :vsplit "或 " vnew "。但是有两个水平分割命令没有对应的垂直分割命令:
" :sview filename ":水平分割屏幕以打开新窗口,并将缓冲区设置为readonly。" :sview "中的filename为必要参数。
" :sfind [++opt][+cnd] filename ":与" :split "命令类似,但是在path中寻找filename,如果未找到,则不分割窗口。
有条件的分割命令:
vim可以让我们执行一种命令,在找到新文件时才打开新窗口。" :topleft cmd "告诉vim:执行cmd并显示一个新窗口,如果cmd成功打开新文件,光标需在左上角。该命令的三种可能结果:
cmd水平分割了窗口,新窗口占据vim窗口的上半部;
cmd垂直分割了窗口,新窗口占据vim窗口的左半边;
cmd未分割窗口,而是把光标移动到当前窗口的左上角。
游走窗口间(在窗口间移动光标):
使用gvim和vim时,在窗口间移动很方便。gvim已默认支持鼠标点击,而vim则可通过" :set mouse =a "命令来打开mouse选项,为所有用途激活鼠标的使用。vim也提供全套导航命令,可在会话窗口间快速而准确地移动。这些窗口间的移动命令紧密地对应编辑时的行动命令。
" ^Wj "或者"^W<DOWN> ":移动到下一个窗口,这个命令不会循环移动,如果已经是最底端的窗口,则该命令无效。而且该命令在往下移动时,还会跳过同一行中的其他窗口;
" ^Wk "或者" ^W<UP> ":移动到上一个窗口,刚好与" ^Wj "命令相反;
" ^Wh "或者" ^W<LEFT> ":移动到当前窗口左边的窗口;" ^Wl "或者" ^W<RIGHT> ":移动到当前窗口右边的窗口;
" ^Ww "或者" ^W^W ":移动到下方的窗口或右边的窗口。这个命令会在所有vim窗口间循环移动。移动顺序为:从左到右,从上到下;
" ^Wt " 或者" ^W^t ":移动到最左上角的窗口(t代表top);
" ^Wb "或者" ^W^b ":移动最右下角的窗口(b代表bottom);
" ^Wp "或者" ^W^p ":移动到前一个(最后访问的)窗口(p代表previous);
移动窗口:
vim有两种移动窗口本身的方式:一种是简单地在屏幕上切换窗口,另一种则是改变窗口的实际布局。第一种情况:虽然窗口在屏幕上的位置有变,但尺寸维持不变,第二种情况下,窗口不只移动,还调整尺寸,以填充它们移向的位置。
移动窗口本身(轮换或交换):
接下来的命令能够移动窗口,但不会调整布局。即窗口以轮换的形式进行移动。这些命令的对象只限当前窗口所在的行或列上。
移动窗口并改变布局:" ^Wr ":向右或向下轮换窗口,即当前行或当前列的每一个窗口按指定方向移动一位,最末尾的窗口移动到第一位;
" ^WR ":与" ^Wr "类似,只是轮换方向相反。如果没有其它窗口与当前窗口同行或同列,则这些命令不会有动作。而且轮换窗口时,光标随着窗口移动;
" ^Wx ":能交换同行或同列窗口的位置。默认是交换当前窗口与它的下一个窗口的位置,如果下方没有窗口,则试着与上一个窗口交换位置。也可以在此命令前加上数量,从而与指定的窗口交换位置;
" ^WK ":移动当前窗口至屏幕顶端,使用屏幕的全部宽度;
" ^WJ ":移动当前窗口至屏幕底端,使用屏幕的全部宽度;
" ^WH ":移动当前窗口至屏幕左端,使用屏幕的全部高度;
" ^WL ":移动当前窗口至屏幕右端,使用屏幕的全部高度;
" ^WT ":移动当前窗口至新的现有分页,如果当前窗口是当前分页里的唯一窗口,则不发生任何操作;
在移动并扩展窗口为满屏的宽度和高度后,vim重新以合理的方式分配其他窗口。当然,重新分配时,也会受到一些窗口选项设置的影响。
本章vim命令总结:
" -o "选项," laststatus "选项," split "," vsplit "," ^Ws "," new "," vnew "," :sview "," :sfind "," :topleft "," :set mouse=a "," ^Wj "," ^W<Down> "," ^Wk "," ^W<Up> ", " ^Wh "," ^W<Left> "," ^Wl "" ^W<Right> "," ^Ww "," ^W^W "," ^Wt "," ^W^t "," ^Wb "," ^W^b "," ^Wp "," ^W^p "," ^Wr "," ^WR "," ^Wx "," ^WK "," ^WJ "," ^WH "," ^WL "," ^WT "。