本节介绍通过 拆分(splitting) 现有窗口来创建新窗口的函数。注意,部分窗口具有特殊性,这些函数可能无法按此处描述的方式拆分它们。这类窗口的例子包括侧边窗口(see 侧边窗口)和原子窗口(see 原子窗口)。
该函数在窗口 window 旁边创建一个新的活动窗口。如果 window 被省略或为 nil,则默认为选中窗口。该窗口会被拆分并缩小尺寸,腾出的空间由新窗口占据,函数返回这个新窗口。
可选的第二个参数 size 决定 window 和/或新窗口的尺寸。如果它被省略或为 nil,两个窗口会被分配相等的尺寸;如果总行数是奇数,多余的一行会分给新窗口。如果 size 是正数,window 会被分配 size 行(或列,取决于 side 的值)。如果 size 是负数,新窗口会被分配 −size 行(或列)。
如果 size 为 nil,该函数会遵守变量 window-min-height 和 window-min-width(see 窗口尺寸)。因此,如果拆分后会导致某个窗口小于这些变量规定的尺寸,它会抛出错误。但是,size 为非 nil 时会忽略这些变量;在这种情况下,允许的最小窗口被认为是可以容纳一行高、两列宽文本的窗口。
因此,如果指定了 size,调用者有责任检查拆分出来的窗口是否足够大,以容纳它们的所有装饰,例如模式行或滚动条。函数 window-min-size(see 窗口尺寸)可用于确定 window 在这方面的最小尺寸要求。由于新窗口通常会从 window 继承模式行或滚动条这类区域,该函数也适合用来估算新窗口的最小尺寸。调用者只有在下次重绘前相应移除继承区域时,才应该指定更小的尺寸。
可选的第三个参数 side 决定新窗口相对于 window 的位置。如果它是 nil 或 below,新窗口放在 window 下方。如果是 above,新窗口放在 window 上方。在这两种情况下,size 都以行为单位指定窗口总高度。
如果 side 是 t 或 right,新窗口放在 window 右侧。如果是 left,新窗口放在 window 左侧。在这两种情况下,size 都以列为单位指定窗口总宽度。
可选的第四个参数 pixelwise 如果非 nil,表示以像素为单位解释 size,而不是以行和列为单位。
如果 window 是活动窗口,新窗口会从它继承多种属性,包括边距和滚动条。如果 window 是内部窗口,新窗口会继承在 window 所在框架内被选中窗口的属性。
只要变量 ignore-window-parameters 为 nil,该函数的行为就可能被 window 的窗口参数改变。如果 split-window 窗口参数的值为 t,该函数会忽略所有其他窗口参数。否则,如果 split-window 窗口参数的值是一个函数,该函数会以 window、size 和 side 为参数被调用,替代 split-window 原本的行为。除此之外,该函数会遵守 window-atom 或 window-side 窗口参数(如果有的话)。See 窗口参数。
举个例子,下面是一系列 split-window 调用,可以得到 窗口与框架 中讨论的窗口布局。这个例子同时演示了拆分活动窗口和拆分内部窗口。我们从一个只包含单个窗口(活动根窗口)的框架开始,用 W4 表示它。调用 (split-window W4) 会得到这样的窗口布局:
______________________________________
| ____________________________________ |
|| ||
|| ||
|| ||
||_________________W4_________________||
| ____________________________________ |
|| ||
|| ||
|| ||
||_________________W5_________________||
|__________________W3__________________|
这次 split-window 调用创建了一个新的活动窗口,记为 W5。它还创建了一个新的内部窗口,记为 W3,该窗口成为根窗口,同时也是 W4 和 W5 的父窗口。
接下来,我们调用 (split-window W3 nil 'left),将内部窗口 W3 作为参数传入。结果如下:
______________________________________
| ______ ____________________________ |
|| || __________________________ ||
|| ||| |||
|| ||| |||
|| ||| |||
|| |||____________W4____________|||
|| || __________________________ ||
|| ||| |||
|| ||| |||
|| |||____________W5____________|||
||__W2__||_____________W3_____________ |
|__________________W1__________________|
一个新的活动窗口 W2 被创建在内部窗口 W3 的左侧。一个新的内部窗口 W1 被创建,成为新的根窗口。
对于交互式使用,Emacs 提供了两个总是拆分选中窗口的命令。它们内部都会调用 split-window。
该函数将窗口 window-to-split 拆分为左右并排的两个窗口,将 window-to-split 放在左侧。window-to-split 默认为选中窗口。如果 size 为正数,左侧窗口占据 size 列;如果 size 为负数,右侧窗口占据 −size 列。
该函数将窗口 window-to-split 拆分为上下两个窗口,保持上方窗口被选中。window-to-split 默认为选中窗口。如果 size 为正数,上方窗口占据 size 行;如果 size 为负数,下方窗口占据 −size 行。
该函数将整个框架一分为二。上方保留当前窗口布局,并在下方创建一个占据整个框架宽度的新窗口。size 的处理方式与 split-window-below 相同。
该函数将整个框架一分为二。左侧保留当前窗口布局,并在右侧创建一个占据整个框架高度的新窗口。size 的处理方式与 split-window-right 相同。
如果这个变量的值为非 nil(默认值),split-window-below 就按上面描述的方式工作。
如果它为 nil,split-window-below 会调整两个窗口中的光标位置,以最小化重绘。(这在慢速终端上很有用。)它会选中光标原本所在屏幕行所属的窗口。注意这只影响 split-window-below,不影响更底层的 split-window 函数。