在第一季的部分介绍了怎样将窗口切割成自己需要的样子。这一季我们讨论一下如何对切割后窗口布局进行旋转。为什么需要旋转窗口布局呢?最简单的答案是:任何一个窗口布局,总有某一个时刻会让你感觉无法满足你当前的需要。这时候我们怎么办?改变窗口总比改变自己要好。既然选择了改变窗口布局,如何改变就成了下一个问题。如果能有一个传送门,让我们直接到达想要的地方,当然要把先回到最初的单窗口模式,然后再重新切割布局要方便的多了。旋转窗口就是这样的一个传送门。
让我们先从常用的多窗口模式开始说起。通常所用的多窗口模式以二窗口、三窗口、四窗口为多。四个以上窗口的环境一方面是比较少用(比较屏幕空间总是有限的,窗口切的太多,每一个窗口能用的面积就很有限了),另一方面,如果真的选择了如此复杂的窗口布局,一般也应该是经过慎重选择,专为某一种特定需求而打造的,通常需要重新布局的机会也不会很多。
所以在这里我们只讨论二窗口、三窗口、四窗口的情况。其中四窗口模式(就是田字形)由于同时具有轴对称和中心对称的特点,所以也不存在旋转的必要。这样以来,我们需要讨论的就只剩下二窗口和三窗口两种模式了。
二窗口模式的旋转
二窗口的旋转很容易理解啦。无非就是从横向转成竖向,再从竖向转成横向。 但是,这里有一个坏消息和一个好消息。坏消息是这样简单的事情 Emacs 的原生代码里面居然没有提供直接的支持。在原生 Emacs 里面只能选择先使用 Ctrl-x 0 或者 Ctrl-x 1 回到单窗口模式,然后再使用 Ctrl-x 2 或者 Ctrl-x 3 重新切割。在 tmux 和 Vim 里面,这样的旋转是被原生支持的。好消息是我自己写了一个 Emacs 扩展函数 change-split-type 来补上这个缺口。同学们在使用的时候可以自己把这个函数绑定到 Ctrl-x 4 c 上面。并且由于这个函数是自适应的,所以无论是从横向转成竖向,还是从竖向转成横向,都只需要这一个函数,及一个按键绑定就足够了。
在下面的示例当中仍然遵循第一季中的约定,命令/操作的示例按如下顺序给出 Emacs - tmux - vim
#+BEGIN_EXAMPLE
+--------------------------------+ +----------------+----------------+
| | change-split-type | | |
| a | Ctrl-b Alt-1 | | a |
| | Ctrl-w L | | |
+--------------------------------+ ----------------> | | |
| | | | |
| | | | |
| | | | |
+--------------------------------+ +----------------+----------------+
+---------------+----------------+ +--------------------------------+
| | | change-split-type | |
| a | | Ctrl-b Alt-2 | a |
| | | Ctrl-w K | |
| | | ----------------> +--------------------------------+
| | | | |
| | | | |
| | | | |
+---------------+----------------+ +--------------------------------+
#+END_EXAMPLE
三窗口模式的旋转
另外,由于窗口旋转涉及到的问题比较复杂,所以这次我们要把 Eamcs, tmux 和 Vim 分开来讲。首先是 Emacs
Emacs 的三窗口旋转
也许你已经猜到了,三窗口的旋转在 Emacs 当中也没有提供原生的支持。好消息是我也写了一个 Emacs 扩展函数 change-split-type-3 来解决这个问题。这个函数也是一个自适应函数,不论当前的窗口布局处于下图所示的那一种模式,这个函数都会将它们顺时针旋转。这样就不需要使用者自己去小心识别不同的场景,然后再去选择正确的函数了。这个函数在我的 Emacs 中是绑定在 Ctrl-x 4 C 上的。注意这里的 C 是大写,以便与上一个函数相区别。
#+BEGIN_EXAMPLE
+--------------------------------+ +----------------+---------------+
| | change-split-type-3 | | |
| a | Ctrl-x 4 C | | a |
| | | | |
+---------------+----------------+ ----------------> +----------------+ |
| | | | | |
| | | | | |
| | | | | |
+---------------+----------------+ +----------------+---------------+
^ |
| change-split-type-3 | change-split-type-3
| Ctrl-x 4 C | Ctrl-x 4 C
| |
| v
+---------------+----------------+ +----------------+---------------+
| | | change-split-type-3 | | |
| a | | Ctrl-x 4 C | | |
| | | | | |
| &#43;----------------&#43; <---------------- &#43;----------------&#43;---------------&#43;
| | | | |
| | | | a |
| | | | |
&#43;---------------&#43;----------------&#43; &#43;--------------------------------&#43;
#&#43;END_EXAMPLE
实际上在 Emacs 这里还有一个好消息。既然要自己写函数&#xff0c;我就索性再写一个&#xff0c;把旋转缓冲区的问题也一并解决了。所谓旋转缓冲区就是保持当前窗口模式不变&#xff0c;将三个窗口当中的编辑缓冲区按照顺时针的方向&#xff0c;相互调换。 这个函数的名字是 roll-v-3 。在我的 Emacs 当中被绑定在 Ctrl-x 4 r 按键组合上。
#&#43;BEGIN_EXAMPLE
&#43;--------------------------------&#43; &#43;--------------------------------&#43;
| | roll-v-3 | |
| A | Ctrl-x 4 r | B |
| | | |
&#43;---------------&#43;----------------&#43; ----------------> &#43;---------------&#43;----------------|
| | | | | |
| B | C | | C | A |
| | | | | |
&#43;---------------&#43;----------------&#43; &#43;---------------&#43;----------------&#43;
^ |
| roll-v-3 roll-v-3 |
| Ctrl-x 4 r Ctrl-x 4 r |
| |
| &#43;-------------------------------&#43; |
| | | |
&#43;------------- | C | <------------&#43;
| |
&#43;---------------&#43;---------------&#43;
| | |
| A | B |
| | |
&#43;---------------&#43;---------------&#43;
#&#43;END_EXAMPLE
tmux 的三窗口旋转
tmux 对三窗口模式提供了原生支持&#xff0c;所以在 tmux 里面进行三窗口旋转是最方便的。但是这种支持也是有限度的&#xff0c;大家可以看到在这里 tmux 比 Emacs 少了一种布局方式。
注&#xff1a; 下面示例中的 M 代表 Meta 键&#xff0c;对应到现代键盘上通常是 Alt 键
#&#43;BEGIN_EXAMPLE
&#43;----------------&#43;----------------&#43;
Ctrl-b M-3 | | |
&#43;-------------------------------------- | | b |
| | | |
| &#43;---------------------------------> | a &#43;----------------&#43;
| | Ctrl-b M-4 | | |
| | | | c |
v | | | |
&#43;--------------------------------&#43; &#43;----------------&#43;----------------&#43;
| | ^ |
| a | | |
| | | |
&#43;---------------&#43;----------------&#43; Ctrl-b M-4 | | Ctrl-b M-5
| | | | |
| b | c | | |
| | | | v
&#43;---------------&#43;----------------&#43; &#43;----------------&#43;----------------&#43;
| ^ | | |
| | | a | b |
| | Ctrl-b M-3 | | |
| &#43;---------------------------------- &#43;----------------&#43;----------------&#43;
| | |
&#43;-------------------------------------> | c |
Ctrl-b M-5 | |
&#43;---------------------------------&#43;
#&#43;END_EXAMPLE
Vim 的三窗口旋转
Vim 的窗口旋转在这里是最复杂的。首先 Vim 也对窗口的旋转提供了原生的支持。通过原生支持&#xff0c;可以实现各种各样的旋转支持&#xff0c;并且所有这些方式都具有浓郁的 Vim 色彩。
对于 Vim 的三窗口旋转需要分成两部分来介绍。首先是最简单的一种方式。这种方式严格来说不能称之为“旋转”&#xff0c;应该叫“对调”才对&#xff0c;但是因为也是可以在三窗口模式下使用的一种操作&#xff0c;所以在这里就一并介绍了。
#&#43;BEGIN_EXAMPLE
&#43;--------------------------------&#43; &#43;----------------&#43;----------------&#43;
| | | | |
| a | Ctrl-w J | b | c |
| | -----------------> | | |
&#43;---------------&#43;----------------&#43; &#43;----------------&#43;----------------&#43;
| | | <----------------- | |
| b | c | Ctrl-w K | a |
| | | | |
&#43;---------------&#43;----------------&#43; &#43;---------------------------------&#43;
#&#43;END_EXAMPLE
下面要介绍的就是真正的旋转了。虽然 Vim 原生提供了丰富的多窗口操作支持&#xff0c;但是其中的有些操作并不是非常直接的。从下面的示例中就能看到&#xff0c;需要一个中间状态来过渡&#xff0c;才能够完成。
注1&#xff1a; 在一下示例中&#xff0c;标有字母 a 的窗口代表当前窗口&#xff0c;也就是光标所在的窗口。
注2&#xff1a;在右下角的旋转示例当中&#xff0c;标有字母 b 的窗口代表当前窗口。
#&#43;BEGIN_EXAMPLE
&#43;-----------------&#43; &#43;-----&#43;-----&#43;-----&#43; &#43;--------&#43;--------&#43;
| a | Ctrl-w H | | | | Ctrl-w J | b | c |
| | --------------> | | | | --------------> | | |
&#43;--------&#43;--------&#43; | a | b | c | &#43;--------&#43;--------&#43;
| b | c | <-------------- | | | | <-------------- | a |
| | | Ctrl-w K | | | | Ctrl-w H | |
&#43;--------&#43;--------&#43; &#43;-----&#43;-----&#43;-----&#43; &#43;-----------------&#43;
&#43;--------&#43;--------&#43; &#43;-----------------&#43; &#43;--------&#43;--------&#43;
| | b | Ctrl-w K | a | Ctrl-w L | b | |
| | | --------------> &#43;-----------------&#43; -------------> | | |
| a &#43;--------&#43; | b | &#43;--------&#43; a |
| | | <-------------- &#43;-----------------&#43; <------------- | | |
| | c | Ctrl-w H | c | Ctrl-w K | c | |
&#43;--------&#43;--------&#43; &#43;-----------------&#43; &#43;--------&#43;--------&#43;
^ |
| Ctrl-w H | Ctrl-w H
| v
&#43;-----------------&#43; &#43;--------&#43;--------&#43;
| | | | |
| | | | |
&#43;--------&#43;--------&#43; &#43;--------&#43;--------&#43;
| | | | |
| | a | | b |
&#43;--------&#43;--------&#43; &#43;-----------------&#43;
#&#43;END_EXAMPLE
注&#xff1a; 关于这一季当中提到的所以 Emacs 扩展函数&#xff0c;请访问 EmacsWiki