1 Star 0 Fork 3

rookieagle/Elisp

forked from advanceflow/Elisp 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
29-窗口.org 238.33 KB
一键复制 编辑 原始数据 按行查看 历史
advanceflow 提交于 2022-05-28 10:12 . finish s2

29 窗口

本章描述了与 Emacs 窗口相关的函数和变量。 请参阅框架,了解如何为窗口分配可供 Emacs 使用的屏幕区域。 有关文本如何在窗口中显示的信息,请参阅 Emacs 显示。

29.1 Emacs Windows的基本概念

窗口是可用于显示缓冲区的屏幕区域(请参阅缓冲区)。 窗户被分组到框架中(请参阅框架)。 每一帧至少包含一个窗口; 用户可以将一个帧细分为多个不重叠的窗口,以便一次查看多个缓冲区。 Lisp 程序可以将多个窗口用于各种目的。 例如,在 Rmail 中,您可以在一个窗口中查看邮件标题的摘要,并在另一个窗口中查看所选邮件的内容。

Emacs 使用的术语“窗口”与图形桌面环境和窗口系统(例如 X 窗口系统)中的含义不同。 当 Emacs 在 X 上运行时,Emacs 进程拥有的每个图形 X 窗口对应一个 Emacs 框架。 当 Emacs 在文本终端上运行时,每个 Emacs 框架会填满整个终端屏幕。 在任何一种情况下,框架都可能包含一个或多个 Emacs 窗口。 为了消除歧义,当我们指的是对应于 Emacs 框架的窗口系统窗口时,我们使用术语窗口系统窗口。

与 X 窗口不同,Emacs 窗口是平铺的; 它们从不在框架区域内重叠。 当创建、调整大小或删除窗口时,窗口空间的变化取自或给予同一框架上的其他窗口,因此框架的总面积不变。

在 Emacs Lisp 中,窗口由一种特殊的 Lisp 对象类型表示(参见窗口类型)。

Function: windowp object ¶

如果对象是窗口(无论它是否显示缓冲区),此函数将返回 t。 否则,它返回零。

实时窗口是实际在帧中显示缓冲区的窗口。

Function: window-live-p object ¶

如果对象是活动窗口,则此函数返回 t,否则返回 nil。 实时窗口是显示缓冲区的窗口。

每个框架中的窗口被组织成一个窗口树。 请参阅窗和框架。 每个窗口树的叶节点都是活动窗口——实际显示缓冲区的窗口。 窗口树的内部节点是内部窗口,它们不是活的。

有效的窗口是活动的或内部的。 一个有效的窗口可以被删除,即从它的框架中删除(见删除窗口); 那么它不再有效,但表示它的 Lisp 对象可能仍被其他 Lisp 对象引用。 通过恢复已保存的窗口配置,可以使已删除的窗口再次生效(请参阅窗口配置)。

您可以使用 window-valid-p 区分有效窗口和已删除窗口。

Function: window-valid-p object ¶

如果对象是活动窗口或窗口树中的内部窗口,则此函数返回 t。 否则,它返回 nil,包括对象是已删除窗口的情况。

以下示意图显示了实时窗口的结构:

	____________________________________________
       |________________ Tab Line _______________|RD| ^
       |______________ Header Line ______________|  | |
     ^ |LS|LM|LF|                       |RF|RM|RS|  | |
     | |  |  |  |                       |  |  |  |  | |
Window |  |  |  |                       |  |  |  |  | Window
Body | |  |  |  |      Window Body      |  |  |  |  | Total
Height |  |  |  |                       |  |  |  |  | Height
     | |  |  |  |<- Window Body Width ->|  |  |  |  | |
     v |__|__|__|_______________________|__|__|__|  | |
       |_________ Horizontal Scroll Bar _________|  | |
       |_______________ Mode Line _______________|__| |
       |_____________ Bottom Divider _______________| v
	<---------- Window Total Width ------------>

该窗口的中心是显示缓冲区文本的主体。 身体可以被一系列我们称之为窗户装饰的可选区域包围。 在左边和右边,从最里面到最外面,这些是左右边缘,用LF和RF表示(见Fringes); 左右边距,在示意图中用 LM 和 RM 表示(参见在边距中显示); 左侧或右侧垂直滚动条,在任何时候都只存在一个,用 LS 和 RS 表示(参见滚动条); 右分隔线,用 RD 表示(参见窗口分隔线)。 这些一起是窗户的左右装饰。

窗口顶部是选项卡行和标题行(请参阅窗口标题行)。 窗口的文本区域包括标题行和制表符行(如果它们存在于窗口中)。 窗口底部是水平滚动条(参见滚动条); 模式线(参见模式线格式); 和底部分隔线(请参阅窗口分隔线)。 这些共同构成了窗户的顶部和底部装饰。

原理图中省略了两个特殊区域:

当缺少任何边缘时,如果文本行不适合窗口,则显示引擎可能会使用一个字符单元来显示延续或截断字形。 当垂直滚动条和右分隔线都缺失时,如果存在这样的窗口,则显示引擎会占用一个像素来在该窗口与其右侧的窗口之间绘制一条垂直分隔线。 在文本终端上,此分隔符始终占据整个字符单元格。

在任何一种情况下,生成的工件都​​被视为窗口主体的一部分,尽管它的屏幕空间不能用于显示缓冲区文本。

另请注意,由 display-line-numbers-mode 显示的行号(及其周围的空白)(请参阅 GNU Emacs 手册中的 Display Custom )也不算作装饰; 它们也是窗户主体的一部分。

内部窗口既不显示任何文字,也没有装饰。 因此,“身体”的概念对他们来说没有意义。 事实上,大多数在窗口主体上运行的函数在应用于内部窗口时都会产生错误。

默认情况下,Emacs 框架展示了一个特殊的实时窗口,用于显示消息和接受用户输入 - minibuffer 窗口(请参阅 Minibuffer Windows)。 由于 minibuffer 窗口用于显示文本,它有一个主体,但它没有制表符或标题行或任何边距。 最后,用于在工具提示框架中显示工具提示的工具提示窗口(请参阅工具提示)也有一个主体,但根本没有装饰。

29.2 窗户和框架

每个窗口恰好属于一个框架(请参阅框架)。 对于属于特定框架的所有窗口,我们有时也说这些窗口归该框架所有,或者简单地说它们在该框架上。

Function: window-frame &optional window ¶

该函数返回指定窗口的框架——窗口所属的框架。 如果 window 被省略或为零,则默认为选定的窗口(请参阅选择窗口)。

Function: window-list &optional frame minibuffer window ¶

此函数返回指定框架拥有的所有活动窗口的列表。 如果 frame 被省略或为零,则默认为选定的帧(请参阅输入焦点)。

可选参数 minibuffer 指定是否在该列表中包含 minibuffer 窗口(请参阅 Minibuffer Windows)。 如果 minibuffer 为 t,则包含 minibuffer 窗口。 如果为 nil 或省略,则仅当 minibuffer 窗口处于活动状态时才包含它。 如果 minibuffer 既不是 nil 也不是 t,则永远不会包含 minibuffer 窗口。

可选参数窗口,如果非零,则必须是指定帧上的活动窗口; 那么 window 将是返回列表中的第一个元素。 如果 window 被省略或为零,则在框架内选择的窗口(请参阅选择窗口)是第一个元素。

同一帧上的窗口被组织成一个窗口树,其叶子节点是活动窗口。 窗口树的内部节点不是活的; 它们的存在是为了组织活动窗口之间的关系。 窗口树的根节点称为根窗口。 它是实时窗口或内部窗口。 如果它是一个活动窗口,那么该帧除了 minibuffer 窗口之外只有一个窗口,或者该帧是一个 minibuffer-only 帧,请参阅帧布局。

一个不在其框架上的 minibuffer 窗口(参见 Minibuffer Windows)没有父窗口,因此严格来说它不是其框架窗口树的一部分。 尽管如此,它是框架根窗口的兄弟窗口,因此可以通过 window-next-sibling 从根窗口访问,见下文。 此外,本节末尾描述的函数 window-tree 在实际窗口树旁边列出了 minibuffer 窗口。

Function: frame-root-window &optional frame-or-window ¶

此函数返回框架或窗口的根窗口。 参数 frame-or-window 应该是窗口或框架; 如果省略或为零,则默认为选定的帧。 如果 frame-or-window 是一个窗口,则返回值是该窗口框架的根窗口。

当一个实时窗口被拆分时(请参阅拆分窗口),有两个实时窗口,而之前是一个。 其中一个由与原始窗口相同的 Lisp 窗口对象表示,另一个由新创建的 Lisp 窗口对象表示。 这两个活动窗口都成为窗口树的叶节点,作为单个内部窗口的子窗口。 如有必要,Emacs 会自动创建这个内部窗口,也称为父窗口,并将其分配到窗口树中的适当位置。 共享同一个父窗口的一组窗口称为兄弟窗口。

Function: window-parent &optional window ¶

该函数返回窗口的父窗口。 如果 window 被省略或为零,则默认为选定的窗口。 如果窗口没有父窗口,则返回值为 nil(即,它是一个 minibuffer 窗口或其框架的根窗口)。

一个父窗口总是至少有两个子窗口。 如果这个数字由于窗口删除而下降到 1(请参阅删除窗口),Emacs 也会自动删除父窗口,并且其唯一剩余的子窗口将在窗口树中占据它的位置。

子窗口可以是活动窗口,也可以是内部窗口(而内部窗口又会有自己的子窗口)。 因此,每个内部窗口都可以被认为占据了某个矩形屏幕区域——最终从它下降的活动窗口所占据的区域的并集。

对于每个内部窗口,直接子级的屏幕区域垂直或水平排列(从不同时排列)。 如果子窗口上下排列,则称它们形成垂直组合; 如果它们并排排列,则称它们形成水平组合。 考虑以下示例:

 ______________________________________
| ______  ____________________________ |
||      || __________________________ ||
||      |||                          |||
||      |||                          |||
||      |||                          |||
||      |||____________W4____________|||
||      || __________________________ ||
||      |||                          |||
||      |||                          |||
||      |||____________W5____________|||
||__W2__||_____________W3_____________ |
|__________________W1__________________|

这个框架的根窗口是一个内部窗口,W1。 它的子窗口形成一个横向组合,由活动窗口W2和内部窗口W3组成。 W3 的子窗口形成一个垂直组合,由活动窗口 W4 和 W5 组成。 因此,此窗口树中的活动窗口是 W2、W4 和 W5。

以下函数可用于检索内部窗口的子窗口以及子窗口的兄弟窗口。 它们的窗口参数始终默认为选定的窗口(请参阅选择窗口)。

Function: window-top-child &optional window ¶

如果 window 是内部窗口,其子窗口形成垂直组合,则此函数返回 window 的最顶层子窗口。 对于任何其他类型的窗口,返回值为 nil。

Function: window-left-child &optional window ¶

该函数返回window最左边的子窗口,如果window是一个内部窗口,它的子窗口形成一个水平组合。 对于任何其他类型的窗口,返回值为 nil。

Function: window-child window ¶

这个函数返回内部窗口窗口的第一个子窗口——垂直组合的最上面的子窗口,或者水平组合的最左边的子窗口。 如果 window 是活动窗口,则返回值为 nil。

Function: window-combined-p &optional window horizontal ¶

当且仅当 window 是垂直组合的一部分时,此函数才返回非 nil 值。

如果可选参数水平是非零,这意味着当且仅当窗口是水平组合的一部分时才返回非零。

Function: window-next-sibling &optional window ¶

此函数返回指定窗口的下一个兄弟。 如果 window 是其父级的最后一个子级,则返回值为 nil。

Function: window-prev-sibling &optional window ¶

此函数返回指定窗口的前一个兄弟。 如果 window 是其父级的第一个子级,则返回值为 nil。

函数 window-next-sibling 和 window-prev-sibling 不应与函数 next-window 和 previous-window 混淆,后者以窗口的循环顺序返回下一个和上一个窗口(请参阅 Windows 的循环排序)。

以下函数可用于在其框架内定位窗口。

Function: frame-first-window &optional frame-or-window ¶

此函数返回由 frame-or-window 指定的帧左上角的实时窗口。 参数 frame-or-window 必须表示一个窗口或一个活动框架,并且默认为选定的框架。 如果 frame-or-window 指定了一个窗口,则此函数返回该窗口框架上的第一个窗口。 假设选择了我们规范示例中的帧(帧优先窗口),则返回 W2。

Function: window-at-side-p &optional window side ¶

如果窗口位于其包含框架的一侧,则此函数返回 t。 参数窗口必须是有效的窗口,并且默认为选定的窗口。 参数侧可以是左、上、右或下的任何符号。 默认值 nil 像底部一样处理。

请注意,此函数忽略了 minibuffer 窗口(请参阅 Minibuffer Windows)。 因此,当小缓冲区窗口出现在窗口的正下方时,当边等于底部时,它也可能返回 t。

Function: window-in-direction direction &optional window ignore sign wrap minibuf ¶

此函数返回从窗口窗口中窗口点位置看的方向上最近的实时窗口。 参数方向必须是上、下、左或右之一。 可选参数 window 必须表示一个活动窗口,并且默认为选定的窗口。

此函数不返回 no-other-window 参数为非 nil 的窗口(请参阅窗口参数)。 如果最近窗口的 no-other-window 参数为非 nil,则此函数尝试在指定方向上查找 no-other-window 参数为 nil 的另一个窗口。 如果可选参数 ignore 不为 nil,则即使其 no-other-window 参数为非 nil,也可能返回一个窗口。

如果可选参数符号为负数,则表示使用窗口的右边缘或下边缘作为参考位置,而不是窗口点。 如果符号为正数,则表示以窗口的左边缘或上边缘作为参考位置。

如果可选参数 wrap 不为零,这意味着将方向环绕在框架边框周围。 例如,如果窗口位于框架的顶部并且方向在上方,则此函数通常在它处于活动状态时返回该框架的 minibuffer 窗口,否则返回一个位于框架底部的窗口。

如果可选参数 minibuf 为 t,则此函数可能会返回 minibuffer 窗口,即使它未处于活动状态。 如果可选参数 minibuf 为 nil,这意味着当且仅当它当前处于活动状态时才返回 minibuffer 窗口。 如果 minibuf 既不是 nil 也不是 t,这个函数永远不会返回 minibuffer 窗口。 然而,如果 wrap 不是 nil,它总是表现得好像 minibuf 是 nil。

如果没有找到合适的窗口,这个函数返回 nil。

请勿使用此功能检查方向是否有窗口。 调用上面描述的 window-at-side-p 是一种更有效的方法。

以下函数检索框架的整个窗口树:

Function: window-tree &optional frame ¶

此函数返回一个表示框架框架的窗口树的列表。 如果 frame 被省略或为零,则默认为选定的框架。

返回值是一个形式为(root mini)的列表,其中root代表frame的根窗口的窗口树,mini是frame的minibuffer窗口。

如果根窗口是活动的,那么根就是那个窗口本身。 否则,root 是一个列表 (dir edges w1 w2 …),其中 dir 表示水平组合,t 表示垂直组合,edges 给出组合的大小和位置,其余元素是子窗口。 每个子窗口可能又是一个窗口对象(对于活动窗口)或具有与上述相同格式的列表(对于内部窗口)。 边缘元素是一个列表(左上右下),类似于 window-edges 返回的值(参见坐标和窗口)。

29.3 选择窗口

在每一帧中,在任何时候,都恰好有一个 Emacs 窗口被指定为在该帧中被选中。 对于选定的帧,该窗口称为选定窗口 — 进行大部分编辑的窗口,其中显示选定窗口的光标(请参阅光标参数)。 插入或删除文本的键盘输入通常也指向此窗口。 所选窗口的缓冲区通常也是当前缓冲区,除非使用了 set-buffer(请参阅当前缓冲区)。 对于未选择的框架,如果曾经选择过该框架,则在该框架内选择的窗口将成为选定的窗口。

Function: selected-window ¶

此函数返回选定的窗口(始终是活动窗口)。

以下函数显式选择一个窗口及其框架。

Function: select-window window &optional norecord ¶

此函数使 window 成为选定窗口和在其框架内选定的窗口,并选择该框架。 它还使窗口的缓冲区(参见缓冲区和窗口)成为当前缓冲区,并将该缓冲区的点值设置为窗口中窗口点的值(参见窗口和点)。 窗口必须是活动窗口。 返回值为窗口。

默认情况下,此函数还将窗口的缓冲区移动到缓冲区列表的前面(请参阅缓冲区列表)并使窗口成为最近选择的窗口。 如果可选参数 norecord 不为零,则省略这些附加操作。

此外,该函数默认情况下还告诉显示引擎在下次重新显示窗口的框架时更新窗口的显示。 如果 norecord 不为零,则通常不执行此类更新。 但是,如果 norecord 等于特殊符号 mark-for-redisplay,则省略上述附加操作,但仍会更新窗口的显示。

请注意,有时选择一个窗口不足以显示它,或者使其框架成为显示的最顶层框架:您可能还需要提升框架或确保输入焦点指向该框架。 请参阅输入焦点。

由于历史原因,Emacs 不会在选择窗口时运行单独的钩子。 应用程序和内部例程通常会临时选择一个窗口来对其执行一些操作。 他们这样做是为了简化编码——因为许多函数在没有指定窗口参数时默认在选定的窗口上运行——或者因为某些函数没有(并且仍然没有)将窗口作为参数并且总是在选择的窗口。 每次短时间选择一个窗口时运行一个钩子,当恢复先前选择的窗口时再次运行一个钩子是没有用的。

然而,当它的 norecord 参数为 nil 时,select-window 会更新缓冲区列表,从而间接运行正常的钩子 buffer-list-update-hook(请参阅缓冲区列表)。 因此,该挂钩提供了一种在窗口被更“永久”选择时运行函数的方法。

由于 buffer-list-update-hook 也由与窗口管理无关的函数运行,因此将所选窗口的值保存在某处并在运行该钩子时将其与 selected-window 的值进行比较通常是有意义的。 此外,为避免在使用 buffer-list-update-hook 时出现误报,最好的做法是每个应该选择窗口的 select-window 调用仅临时传递一个非 nil norecord 参数。 如果可能,在这种情况下应使用带有选定窗口的宏(见下文)。

每当重新显示例程检测到自上次重新显示以来已选择另一个窗口时,Emacs 也会运行挂钩窗口选择更改函数。 有关详细说明,请参阅 Hooks for Window Scrolling and Changes。 window-state-change-functions (在同一部分中描述)是另一个在选择了不同的窗口后运行的异常钩子,但也被其他窗口更改触发。

使用非 nil norecord 参数调用 select-window 的顺序根据它们的选择或使用时间确定窗口的顺序,见下文。 例如,函数 get-lru-window 可用于检索最近最少选择的窗口(请参阅 Windows 的循环排序)。

Function: frame-selected-window &optional frame ¶

此函数返回在该框架内选择的框架上的窗口。 帧应该是实时帧; 如果省略或为零,则默认为选定的帧。

Function: set-frame-selected-window frame window &optional norecord ¶

该函数使窗口成为在框架框架内选择的窗口。 帧应该是实时帧; 如果为零,则默认为选定的帧。 窗口应该是一个活动窗口; 如果为零,则默认为选定的窗口。

如果 frame 是选定的框架,这会使 window 成为选定的窗口。

如果可选参数 norecord 不为 nil,则此函数不会更改最近选择的窗口的顺序,也不会更改缓冲区列表。

以下宏可用于临时选择一个窗口,而不影响最近选择的窗口或缓冲区列表的顺序。

Macro: save-selected-window forms… ¶

该宏记录选中的帧,以及每一帧的选中窗口,依次执行窗体,然后恢复之前选中的帧和窗口。 它还保存和恢复当前缓冲区。 它返回表单中最后一个表单的值。

该宏不保存或恢复任何有关窗口大小、排列或内容的信息; 因此,如果表格改变了它们,那么改变仍然存在。 如果某个框架的先前选择的窗口在退出表单时不再存在,则该框架的选定窗口将保持不变。 如果先前选择的窗口不再有效,则在表单末尾选择的任何窗口都将保持选中状态。 当且仅当退出表单时当前缓冲区仍然存在时,才会恢复当前缓冲区。

这个宏既不会改变最近选择的窗口的顺序,也不会改变缓冲区列表。

Macro: with-selected-window window forms… ¶

该宏选择窗口,依次执行表单,然后恢复先前选择的窗口和当前缓冲区。 最近选择的窗口和缓冲区列表的顺序保持不变,除非您在表单中故意更改它们; 例如,通过使用参数 norecord nil 调用 select-window。 因此,此宏是临时使用窗口作为选定窗口而不不必要地运行缓冲区列表更新挂钩的首选方法。

Macro: with-selected-frame frame forms… ¶

此宏执行以框架为选定框架的表单。 返回的值是表单中最后一个表单的值。 此宏保存和恢复选定的帧,并且既不改变最近选择的窗口也不改变缓冲区列表中的缓冲区的顺序。

Function: window-use-time &optional window ¶

该函数返回窗口窗口的使用时间。 window 必须是活动窗口,并且默认为选定的窗口。

窗口的使用时间并不是真正的时间值,而是一个整数,它会随着每次调用带有 nil norecord 参数的 select-window 单调增加。 使用时间最短的窗口通常称为最近最少使用的窗口,而使用时间最长的窗口称为最近使用的窗口(参见窗口的循环排序)。

Function: window-bump-use-time &optional window ¶

此功能将窗口标记为最近使用的窗口。 这在编写某些弹出到缓冲区场景时很有用(请参阅在窗口中切换到缓冲区)。 window 必须是活动窗口,并且默认为选定的窗口。

有时,几个窗口共同协作显示缓冲区,例如,在跟随模式的管理下(参见 (emacs)跟随模式),其中窗口一起显示的缓冲区比一个窗口单独显示的缓冲区更大。 将这样的窗口组视为单个实体通常很有用。 诸如 window-group-start 之类的几个函数(请参阅窗口开始和结束位置)允许您通过提供一个作为参数的窗口作为整个组的替身来做到这一点。

Function: selected-window-group ¶

当所选窗口是一组窗口的成员时,此功能将返回该组中的窗口列表,以使列表中的第一个窗口显示了缓冲区的最早部分,依此类推。 否则,该函数将返回一个仅包含所选窗口的列表。

当缓冲区局部变量 selected-window-group-function 设置为函数时,所选窗口被视为组的一部分。 在这种情况下, selected-window-group 不带参数调用它并返回其结果(应该是组中的窗口列表)。

29.4 窗口大小

Emacs 提供了各种函数来查找窗口的高度和宽度。 许多这些函数的返回值可以以像素为单位或以行和列为单位指定。 在图形显示上,后者实际上对应于由 frame-char-height 和 frame-char-width 返回的框架默认字体指定的默认字符的高度和宽度(请参阅 Frame Font)。 因此,如果窗口正在显示具有不同字体或大小的文本,则该窗口报告的行高和列宽可能与其中显示的实际文本行数或列数不同。

窗口的总高度是由其主体及其顶部和底部装饰组成的行数(请参阅 Emacs Windows 的基本概念)。

Function: window-total-height &optional window round ¶

此函数返回窗口窗口的总高度(以行为单位)。 如果 window 被省略或为零,则默认为选定的窗口。 如果 window 是内部窗口,则返回值是其子窗口占据的总高度。

如果窗口的像素高度不是其框架默认字符高度的整数倍,则窗口占用的行数在内部四舍五入。 这样做的方式是,如果窗口是父窗口,则其所有子窗口的总高度在内部等于其父窗口的总高度。 这意味着虽然两个窗口具有相同的像素高度,但它们的内部总高度可能相差一行。 这也意味着,如果窗口是垂直组合的并且有下一个兄弟,则该兄弟的最顶行可以计算为此窗口的最顶行和总高度之和(请参阅坐标和窗口)

如果可选参数 round 是上限,则此函数返回大于窗口像素高度除以其框架字符高度的最小整数; 如果是地板,则返回小于该值的最大整数; 对于任何其他回合,它会返回窗口总高度的内部值。

窗口的总宽度是由其主体及其左右装饰组成的行数(请参阅 Emacs Windows 的基本概念)。

Function: window-total-width &optional window round ¶

此函数返回窗口窗口的总宽度(以列为单位)。 如果 window 被省略或为零,则默认为选定的窗口。 如果 window 是 internal,则返回值是其后代窗口占用的总宽度。

如果窗口的像素宽度不是其框架字符宽度的整数倍,则窗口占用的行数在内部四舍五入。 这样做的方式是,如果窗口是父窗口,则其内部所有子窗口的总宽度之和等于其父窗口的总宽度。 这意味着尽管两个窗口具有相同的像素宽度,但它们的内部总宽度可能相差一列。 这也意味着,如果这个窗口是水平组合的并且有下一个兄弟,那么这个兄弟的最左边的列可以计算为这个窗口最左边的列和总宽度的总和(参见坐标和窗口)。 可选参数 round 的行为与 window-total-height 的行为相同。

Function: window-total-size &optional window horizontal round ¶

此函数返回窗口窗口的总高度(以行为单位)或以列为单位的总宽度。 如果horizo​​ntal被省略或nil,这相当于为window调用window-total-height; 否则相当于为window调用window-total-width。 可选参数 round 的行为与 window-total-height 的行为相同。

以下两个函数可用于以像素为单位返回窗口的总大小。

Function: window-pixel-height &optional window ¶

此函数以像素为单位返回窗口窗口的总高度。 window 必须是有效的窗口,并且默认为选定的窗口。

返回值包括窗口顶部和底部装饰的高度。 如果 window 是一个内部窗口,它的像素高度就是它的子窗口跨越的屏幕区域的像素高度。

Function: window-pixel-width &optional window ¶

此函数以像素为单位返回窗口窗口的宽度。 window 必须是有效的窗口,并且默认为选定的窗口。

返回值包括窗口左右装饰的宽度。 如果 window 是一个内部窗口,它的像素宽度就是它的子窗口跨越的屏幕区域的宽度。

以下函数可用于确定给定窗口是否有任何相邻窗口。

Function: window-full-height-p &optional window ¶

如果窗口在其框架上方或下方没有其他窗口,则此函数返回非零。 更准确地说,这意味着窗口的总高度等于该框架上根窗口的总高度。 minibuffer 窗口在这方面不计算在内。 如果 window 被省略或为零,则默认为选定的窗口。

Function: window-full-width-p &optional window ¶

如果窗口在其框架的左侧或右侧没有其他窗口,则此函数返回非零,即,其总宽度等于该框架上根窗口的总宽度。 如果 window 被省略或为零,则默认为选定的窗口。

窗口的主体高度是其主体的高度,不包括其顶部或底部的任何装饰(请参阅 Emacs Windows 的基本概念)。

Function: window-body-height &optional window pixelwise ¶

此函数返回窗口窗口主体的高度(以行为单位)。 如果 window 被省略或为零,则默认为选中的窗口; 否则它必须是一个活动窗口。

如果可选参数 pixelwise 不为零,则此函数返回以像素为单位的窗口的主体高度。

如果 pixelwise 为 nil,则返回值向下舍入为最接近的整数(如有必要)。 这意味着如果文本区域底部的一行仅部分可见,则该行不计算在内。 这也意味着窗口主体的高度永远不能超过 window-total-height 返回的总高度。

窗口的主体宽度是它的主体和文本区域的宽度,不包括它的任何左右装饰(请参阅 Emacs Windows 的基本概念)。

请注意,当删除一个或两个边缘时(通过将它们的宽度设置为零),显示引擎会保留两个字符单元格,一个在窗口的每一侧,用于显示连续和截断字形,这会减少 2 列用于文本显示. (下面描述的函数 window-max-chars-per-line 考虑了这种特性。)

Function: window-body-width &optional window pixelwise ¶

此函数返回窗口窗口主体的宽度(以列为单位)。 如果 window 被省略或为零,则默认为选中的窗口; 否则它必须是一个活动窗口。

如果可选参数 pixelwise 不为零,则此函数以像素为单位返回窗口的主体宽度。

如果 pixelwise 为 nil,则返回值向下舍入为最接近的整数(如有必要)。 这意味着如果文本区域右侧的一列仅部分可见,则该列不计算在内。 这也意味着窗口主体的宽度永远不能超过 window-total-width 返回的总宽度。

Function: window-body-size &optional window horizontal pixelwise ¶

此函数返回窗口的主体高度或主体宽度。 如果horizo​​ntal省略或nil,则相当于为window调用window-body-height; 否则相当于调用window-body-width。 在任何一种情况下,可选参数 pixelwise 都会传递给调用的函数。

可以使用下面给出的函数检索窗口模式、选项卡和标题行的像素高度。 它们的返回值通常是准确的,除非该窗口之前没有显示过:在这种情况下,返回值基于对用于窗口框架的字体的估计。

Function: window-mode-line-height &optional window ¶

此函数返回窗口模式线的高度(以像素为单位)。 window 必须是活动窗口,并且默认为选定的窗口。 如果窗口没有模式行,则返回值为零。

Function: window-tab-line-height &optional window ¶

此函数返回窗口标签行的高度(以像素为单位)。 window 必须是活动窗口,并且默认为选定的窗口。 如果窗口没有制表符行,则返回值为零。

Function: window-header-line-height &optional window ¶

此函数返回窗口标题行的高度(以像素为单位)。 window 必须是活动窗口,并且默认为选定的窗口。 如果窗口没有标题行,则返回值为零。

用于检索窗口分隔符(参见窗口分隔符)、边缘(参见边缘)、滚动条(参见滚动条)和显示边距(参见在边距中显示)的函数在相应部分中进行了描述。

如果您的 Lisp 程序需要做出布局决策,您会发现以下函数很有用:

Function: window-max-chars-per-line &optional window face ¶

该函数返回指定窗口窗口(必须是活窗口)中指定人脸面显示的字符数。 如果重新映射面部(请参阅面部重新映射),则返回重新映射面部的信息。 如果省略或为零,则面默认为默认面,窗口默认为所选窗口。

与 window-body-width 不同,此函数考虑了脸部字体的实际大小,而不是以窗口框架的规范字符宽度为单位工作(请参阅框架字体)。 如果窗口缺少一个或两个边缘,它还考虑了延续字形使用的空间。

更改窗口大小(请参阅调整窗口大小)或拆分窗口(请参阅拆分窗口)的命令遵循变量 window-min-height 和 window-min-width,它们指定允许的最小窗口高度和宽度。 它们还遵循变量 window-size-fixed,通过该变量可以固定窗口的大小(请参阅保留窗口大小)。

User Option: window-min-height ¶

此选项指定任何窗口的最小总高度(以行为单位)。 它的值必须容纳至少一个文本行和任何顶部或底部装饰。

User Option: window-min-width ¶

此选项指定任何窗口的最小总宽度(以列为单位)。 它的值必须容纳至少两个文本列和任何左或右装饰。

下面的函数告诉一个特定的窗口可以变得多小,考虑到它的区域大小以及 window-min-height、window-min-width 和 window-size-fixed 的值(请参阅保留窗口大小)。

Function: window-min-size &optional window horizontal ignore pixelwise ¶

该函数返回窗口的最小尺寸。 window 必须是有效的窗口,并且默认为选定的窗口。 可选参数水平非零表示返回窗口的最小列数; 否则返回窗口的最小行数。

如果实际设置了窗口大小,则返回值确保窗口的所有组件保持完全可见。 对于水平 nil,它包括任何顶部或底部装饰。 对于水平非零,它包括窗口的任何左侧或右侧装饰。

可选参数忽略,如果非零,则意味着忽略固定大小的窗口、窗口最小高度或窗口最小宽度设置施加的限制。 如果忽略等于安全,则活动窗口可能会变得像 window-safe-min-height 行和 window-safe-min-width 列一样小。 如果 ignore 是一个窗口,则仅忽略该窗口的限制。 任何其他非零值意味着忽略所有窗口的所有上述限制。

可选参数 pixelwise non-nil 表示返回以像素为单位的最小窗口大小。

29.5 调整窗口大小

本节描述了在不改变框架大小的情况下调整窗口大小的函数。 因为实时窗口不重叠,所以这些函数只对包含两个或更多窗口的帧有意义:调整窗口大小也会改变至少一个其他窗口的大小。 如果框架上只有一个窗口,则只能通过调整框架大小来更改其大小(请参阅框架大小)。

除非另有说明,这些函数还接受内部窗口作为参数。 调整内部窗口的大小会导致其子窗口调整大小以适应相同的空间。

Function: window-resizable window delta &optional horizontal ignore pixelwise ¶

如果窗口的大小可以通过增量线垂直更改,则此函数返回增量。 如果可选参数水平非零,则如果窗口可以通过增量列水平调整大小,则返回增量。 它实际上并没有改变窗口大小。

如果 window 为 nil,则默认为选定的窗口。

delta 为正值表示检查窗口是否可以放大该行数或列数; delta 的负值表示检查窗口是否可以缩小那么多行或列。 如果 delta 不为零,则返回值 0 表示无法调整窗口大小。

通常,变量 window-min-height 和 window-min-width 指定允许的最小窗口大小(请参阅窗口大小)。 但是,如果可选参数 ignore 不为 nil,则此函数将忽略 window-min-height 和 window-min-width,以及 window-size-fixed。 相反,它将窗口的最小高度视为其顶部和底部装饰加上一行文本的总和; 它的最小宽度是它的左右装饰加上两列文本的总和。

如果可选参数 pixelwise 为非零,则 delta 被解释为像素。

Function: window-resize window delta &optional horizontal ignore pixelwise ¶

此函数按增量调整窗口大小。 如果水平为 nil,它通过增量线改变高度; 否则,它会按增量列更改宽度。 正 delta 表示扩大窗口,负 delta 表示缩小窗口。

如果 window 为 nil,则默认为选定的窗口。 如果窗口不能按要求调整大小,则会发出错误信号。

可选参数 ignore 与上面的函数 window-resizable 具有相同的含义。

如果可选参数 pixelwise 不为零,则 delta 将被解释为像素。

该函数改变哪个窗口边缘的选择取决于选项 window-combination-resize 的值和所涉及窗口的组合限制; 在某些情况下,它可能会改变两个边缘。 请参阅重新组合 Windows。 要通过仅移动窗口的底部或右侧边缘来调整大小,请使用函数adjust-window-trailing-edge。

Function: adjust-window-trailing-edge window delta &optional horizontal pixelwise ¶

此函数通过增量线移动窗口的底部边缘。 如果可选参数水平非零,它改为将右边缘移动增量列。 如果 window 为 nil,则默认为选定的窗口。

如果可选参数 pixelwise 为非零,则 delta 被解释为像素。

正 delta 使边缘向下或向右移动; 负增量将其向上或向左移动。 如果边缘无法移动到 delta 指定的距离,则此函数将其移动到尽可能远,但不会发出错误信号。

此函数尝试调整与移动边缘相邻的窗口大小。 如果由于某种原因(例如,如果该相邻窗口是固定大小的)这是不可能的,它可能会调整其他窗口的大小。

User Option: window-resize-pixelwise ¶

如果此选项的值为非零,Emacs 会以像素为单位调整窗口大小。 这目前会影响拆分窗口(请参阅拆分窗口)、最大化窗口、最小化窗口、适合窗口到缓冲区、适合帧到缓冲区和缩小窗口如果大于缓冲区(全部列在下面)。

请注意,当帧的像素大小不是其字符大小的倍数时,即使此选项为零,至少一个窗口可能会按像素调整大小。 默认值为无。

以下命令以更具体的方式调整窗口大小。 当以交互方式调用时,它们作用于选定的窗口。

Command: fit-window-to-buffer &optional window max-height min-height max-width min-width preserve-size ¶

此命令调整窗口的高度或宽度以适合其中的文本。 如果能够调整窗口大小,则返回非 nil,否则返回 nil。 如果 window 被省略或为零,则默认为选定的窗口。 否则,它应该是一个实时窗口。

如果窗口是垂直组合的一部分,则此函数调整窗口的高度。 新高度是根据其缓冲区可访问部分的实际高度计算的。 可选参数 max-height,如果非零,指定此函数可以给窗口的最大总高度。 可选参数 min-height,如果非 nil,指定它可以给出的最小总高度,它会覆盖变量 window-min-height。 最大高度和最小高度都在行中指定,包括窗口的任何顶部或底部装饰。

如果窗口是水平组合的一部分,并且选项 fit-window-to-buffer-horizo​​ntally (见下文)的值非零,则此函数调整窗口的宽度。 窗口的新宽度是根据窗口当前起始位置之后的缓冲区行的最大长度计算的。 可选参数 max-width 指定最大宽度,默认为窗口框架的宽度。 可选参数 min-width 指定最小宽度,默认为 window-min-width。 max-width 和 min-width 都在列中指定,并且包括窗口的任何左侧或右侧装饰。

可选参数 preserve-size,如果非零,将安装一个参数以在将来的调整大小操作期间保留窗口的大小(请参阅保留窗口大小)。

如果选项 fit-frame-to-buffer(见下文)不为 nil,则此函数将尝试通过调用 fit-frame-to-buffer(见下文)来调整窗口框架的大小以适应其内容。

User Option: fit-window-to-buffer-horizontally ¶

如果这是非零,fit-window-to-buffer 可以水平调整窗口大小。 如果这是 nil (默认) fit-window-to-buffer 从不水平调整窗口大小。 如果仅此,它只能水平调整窗口大小。 任何其他值意味着 fit-window-to-buffer 可以在两个维度上调整窗口大小。

User Option: fit-frame-to-buffer ¶

如果此选项不为零,则 fit-window-to-buffer 可以将帧适合其缓冲区。 当且仅当其根窗口是活动窗口并且此选项为非零时,框架才适合。 如果这是水平的,则框架仅水平适合。 如果这是垂直的,则框架仅垂直适合。 任何其他非零值意味着框架可以在两个维度上调整大小。

如果您有一个只显示一个窗口的框架,您可以使用命令 fit-frame-to-buffer 将该框架适应其缓冲区。

Command: fit-frame-to-buffer &optional frame max-height min-height max-width min-width only ¶

此命令调整帧的大小以准确显示其缓冲区的内容。 frame 可以是任何实时帧,默认为选定的帧。 仅当框架的根窗口处于活动状态时才进行拟合。 参数 max-height、min-height、max-width 和 min-width 指定框架根窗口的新总大小的界限。 min-height 和 min-width 分别默认为 window-min-height 和 window-min-width 的值。

如果可选参数仅是垂直的,则此函数只能垂直调整框架的大小。 如果 only 是水平的,它可能只会水平调整框架的大小。

可以借助下面列出的两个选项来控制 fit-frame-to-buffer 的行为。

User Option: fit-frame-to-buffer-margins ¶

此选项可用于指定要通过 fit-frame-to-buffer 适应的帧周围的边距。 例如,这样的边距对于避免调整大小的框架与任务栏或其父框架的一部分重叠可能很有用。

它指定要在应适合的帧的左侧、上方、右侧和下方留出的像素数。 默认为每个指定 nil,这意味着不使用边距。 此处指定的值可以通过该帧的 fit-frame-to-buffer-margins 参数(如果存在)覆盖特定帧。

User Option: fit-frame-to-buffer-sizes ¶

此选项指定 fit-frame-to-buffer 的大小边界。 它指定应适合其缓冲区的任何帧的根窗口的总最大和最小行以及最大和最小列。 如果这些值中的任何一个不是 nil,它会覆盖 fit-frame-to-buffer 的相应参数。

Command: shrink-window-if-larger-than-buffer &optional window ¶

此命令尝试尽可能减少窗口的高度,同时仍显示其完整缓冲区,但不少于 window-min-height 行。 如果调整了窗口大小,则返回值非 nil,否则返回 nil。 如果 window 被省略或为零,则默认为选定的窗口。 否则,它应该是一个实时窗口。

如果窗口已经太短而无法显示其所有缓冲区,或者任何缓冲区滚动到屏幕外,或者窗口是其框架中唯一的活动窗口,则此命令不执行任何操作。

该命令调用 fit-window-to-buffer(见上文)来完成它的工作。

Command: balance-windows &optional window-or-frame ¶

此功能以一种为全宽和/或全高窗口提供更多空间的方式平衡窗口。 如果 window-or-frame 指定一个框架,它会平衡该框架上的所有窗口。 如果 window-or-frame 指定了一个窗口,它只平衡那个窗口和它的兄弟窗口(参见窗口和框架)。

Command: balance-windows-area ¶

此函数尝试为选定框架上的所有窗口提供大致相同的屏幕区域份额。 全宽或全高窗口没有比其他窗口更多的空间。

Command: maximize-window &optional window ¶

此函数尝试在两个维度上使窗口尽可能大,而不调整其框架大小或删除其他窗口。 如果 window 被省略或为零,则默认为选定的窗口。

Command: minimize-window &optional window ¶

此函数尝试在两个维度上使窗口尽可能小,而不删除它或调整其框架的大小。 如果 window 被省略或为零,则默认为选定的窗口。

29.6 保留窗口大小

可以通过使用上一节中的函数之一显式或隐式调整窗口的大小,例如,在调整相邻窗口的大小时、拆分或删除窗口时(请参阅拆分窗口,请参阅删除窗口)或调整窗口框架的大小时 (见帧大小)。

当同一帧上有一个或多个其他可调整大小的窗口时,可以避免隐式调整特定窗口的大小。 为此,必须建议 Emacs 保留该窗口的大小。 有两种基本方法可以做到这一点。

Variable: window-size-fixed ¶

如果此缓冲区局部变量不为 nil,则显示缓冲区的任何窗口的大小通常都无法更改。 如果别无选择,删除窗口或更改框架大小仍可能更改窗口大小。

如果值为高度,则只有窗口的高度是固定的; 如果值为宽度,则只有窗口的宽度是固定的。 任何其他非零值都固定宽度和高度。

如果此变量为零,这并不一定意味着任何显示缓冲区的窗口都可以在所需方向上调整大小。 要确定这一点,请使用函数 window-resizable。 请参阅调整窗口大小。

通常 window-size-fixed 过于激进,因为它也禁止任何显式调整或拆分受影响窗口的尝试。 这甚至可能在隐式调整窗口大小后发生,例如,在删除相邻窗口或调整窗口框架大小时。 下面的函数尽量避免显式地禁止调整窗口大小:

Function: window-preserve-size &optional window horizontal preserve ¶

此函数(取消)将窗口窗口的高度标记为保留以供将来调整大小操作。 window 必须是活动窗口,并且默认为选定的窗口。 如果可选参数水平非零,它(取消)将窗口的宽度标记为保留。

如果可选参数 preserve 是 t,这意味着保留窗口主体的当前高度/宽度。 只有当 Emacs 没有更好的选择时,窗口的高度/宽度才会改变。 调整此函数保留高度/宽度的窗口大小不会引发错误。

如果 preserve 为 nil,这意味着停止保留窗口的高度/宽度,解除由先前调用此函数为窗口引起的任何相应限制。 使用 window 作为参数调用放大窗口、缩小窗口或适合窗口到缓冲区也可以删除相应的约束。

window-preserve-size 当前由以下函数调用:

display-buffer

如果该函数的可选参数保留大小(请参阅调整窗口大小)为非零,则保留该函数建立的大小。

fit-window-to-buffer

如果该函数的 alist 参数(请参阅选择用于显示缓冲区的窗口)包含一个保留大小条目,则保留该函数生成的窗口的大小。

window-preserve-size 安装一个名为 window-preserved-size 的窗口参数(请参阅窗口参数),窗口大小调整函数会参考该参数。 当窗口显示另一个缓冲区而不是调用 window-preserve-size 时的缓冲区或此后其大小发生变化时,此参数不会阻止调整窗口大小。

以下函数可用于检查特定窗口的高度是否保留:

功能:window-preserved-size &可选窗口水平¶

此函数返回窗口窗口的保留高度(以像素为单位)。 window 必须是活动窗口,并且默认为选定的窗口。 如果可选参数水平非零,它返回窗口的保留宽度。 如果未保留窗口大小,则返回 nil。

29.7 分割窗口

本节介绍通过拆分现有窗口创建新窗口的功能。 请注意,某些窗口是特殊的,因为这些函数可能无法按照此处所述拆分它们。 此类窗口的示例是侧窗(请参阅侧窗)和原子窗(请参阅原子窗)。

Function: split-window &optional window size side pixelwise ¶

此函数在窗口窗口旁边创建一个新的实时窗口。 如果 window 被省略或为零,则默认为选定的窗口。 该窗口被拆分并缩小。 该空间被新窗口占用,并被返回。

可选的第二个参数大小确定窗口和/或新窗口的大小。 如果省略或为零,则两个窗口的大小相同; 如果有奇数行,则分配给新窗口。 如果 size 为正数,则窗口的大小为行(或列,取决于 side 的值)。 如果 size 是负数,则新窗口被赋予 -size 行(或列)。

如果 size 为 nil,则此函数遵循变量 window-min-height 和 window-min-width(请参阅窗口大小)。 因此,如果拆分会导致窗口小于这些变量指定的值,则会发出错误信号。 但是,大小的非零值会导致这些变量被忽略; 在这种情况下,最小的允许窗口被认为是具有容纳一行高和/或两列宽的文本空间的窗口。

因此,如果指定了大小,则调用者有责任检查发出的窗口是否足够大以包含它们的所有装饰,例如模式行或滚动条。 函数window-min-size(参见Window Sizes)可用于确定window在这方面的最低要求。 由于新窗口通常从窗口继承模式行或滚动条等区域,因此该函数也是新窗口最小尺寸的一个很好的猜测。 只有在下一次重新显示之前相应地删除继承区域时,调用者才应指定较小的大小。

可选的第三个参数 side 确定新窗口相对于窗口的位置。 如果为 nil 或更低,则新窗口放置在窗口下方。 如果在上方,则新窗口位于窗口上方。 在这两种情况下,大小都指定了总窗口高度,以行为单位。

如果 side 为 t 或 right,则新窗口放置在窗口的右侧。 如果 side 位于左侧,则新窗口放置在窗口的左侧。 在这两种情况下,size 都指定了总窗口宽度,以列为单位。

可选的第四个参数pixelwise,如果非零,意味着以像素为单位解释大小,而不是行和列。

如果 window 是活动窗口,则新窗口会继承它的各种属性,包括边距和滚动条。 如果 window 是内部窗口,则新窗口将继承在窗口框架内选择的窗口的属性。

只要变量 ignore-window-parameters 为 nil,此函数的行为可能会被 window 的窗口参数改变。 如果拆分窗口窗口参数的值为 t,则此函数忽略所有其他窗口参数。 否则,如果拆分窗口窗口参数的值是一个函数,则使用参数窗口、大小和边调用该函数,以代替拆分窗口的通常操作。 否则,此函数遵循 window-atom 或 window-side window 参数(如果有)。 请参见窗口参数。

例如,这里是一系列拆分窗口调用,它们产生了在 Windows 和 Frames 中讨论的窗口配置。 此示例演示了拆分实时窗口以及拆分内部窗口。 我们从一个包含单个窗口(活动根窗口)的框架开始,我们用 W4 表示。 调用 (split-window W4) 产生这个窗口配置:

 ______________________________________
| ____________________________________ |
||                                    ||
||                                    ||
||                                    ||
||_________________W4_________________||
| ____________________________________ |
||                                    ||
||                                    ||
||                                    ||
||_________________W5_________________||
|__________________W3__________________|

split-window 调用创建了一个新的实时窗口,用 W5 表示。 它还创建了一个新的内部窗口,用 W3 表示,它成为 W4 和 W5 的根窗口和父窗口。

接下来,我们调用 (split-window W3 nil ‘left),将内部窗口 W3 作为参数传递。 结果:

 ______________________________________
| ______  ____________________________ |
||      || __________________________ ||
||      |||                          |||
||      |||                          |||
||      |||                          |||
||      |||____________W4____________|||
||      || __________________________ ||
||      |||                          |||
||      |||                          |||
||      |||____________W5____________|||
||__W2__||_____________W3_____________ |
|__________________W1__________________|

在内部窗口 W3 的左侧创建一个新的实时窗口 W2。 创建一个新的内部窗口 W1,成为新的根窗口。

对于交互式使用,Emacs 提供了两个命令,它们总是分割选定的窗口。 这些在内部调用拆分窗口。

Command: split-window-right &optional size ¶

此函数将选定的窗口拆分为两个并排的窗口,将选定的窗口放在左侧。 如果 size 为正,则左侧窗口获取 size 列; 如果 size 为负数,则右侧窗口将获得 -size 列。

Command: split-window-below &optional size ¶

此函数将选定的窗口拆分为两个窗口,一个在另一个之上,使上面的窗口处于选中状态。 如果 size 为正,则上部窗口获取大小线; 如果 size 为负数,则下部窗口将获得 -size 行。

User Option: split-window-keep-point ¶

如果此变量的值为非零(默认值),则 split-window-below 的行为如上所述。

如果它为 nil,split-window-below 会调整两个窗口中的每个窗口中的点以最小化重新显示。 (这在慢速终端上很有用。)它选择包含该点先前所在的屏幕行的任何窗口。 请注意,这仅影响 split-window-below,而不影响较低级别的拆分窗口功能。

29.8 删除窗口

删除窗口会将其从框架的窗口树中删除。 如果窗口是活动窗口,它会从屏幕上消失。 如果窗口是一个内部窗口,它的子窗口也会被删除。

即使在一个窗口被删除之后,它仍然作为一个 Lisp 对象存在,直到不再有对它的引用。 可以通过恢复保存的窗口配置来撤销窗口删除(请参阅窗口配置)。

Command: delete-window &optional window ¶

此函数从显示中删除窗口并返回 nil。 如果 window 被省略或为零,则默认为选定的窗口。

如果删除窗口将不会在窗口树中留下更多窗口(例如,如果它是框架中唯一的活动窗口)或窗口框架上的所有剩余窗口都是侧窗口(请参阅侧窗口),则会发出错误信号。 如果窗口是原子窗口的一部分(请参阅原子窗口),则此函数尝试删除该原子窗口的根。

默认情况下,窗口占用的空间将分配给其相邻的兄弟窗口之一(如果有)。 但是,如果变量 window-combination-resize 不为零,则空间将按比例分布在同一窗口组合中的任何剩余窗口中。 请参阅重新组合 Windows。

只要变量 ignore-window-parameters 为 nil,此函数的行为可能会被 window 的窗口参数改变。 如果 delete-window 窗口参数的值为 t,此函数将忽略所有其他窗口参数。 否则,如果 delete-window window 参数的值是一个函数,则使用参数 window 调用该函数,以代替 delete-window 的通常操作。 请参见窗口参数。

当 delete-window 删除其框架的选定窗口时,它必须使另一个窗口成为该框架的新选定窗口。 以下选项允许配置选择哪个窗口。

User Option: delete-window-choose-selected ¶

此选项允许指定在 delete-window 删除先前选定的窗口后哪个窗口应成为框架的选定窗口。 可能的选择是

mru(默认)选择该框架上最近使用的窗口。 pos 选择包含该帧上先前选择的窗口的点的帧坐标的窗口。 nil 选择该帧上的第一个窗口(由 frame-first-window 返回的窗口)。

只有当该帧上的所有其他窗口也将该参数设置为非零值时,才会选择具有非零 no-other-window 参数的窗口。

Command: delete-other-windows &optional window ¶

此功能使窗口填充其框架,并根据需要删除其他窗口。 如果 window 被省略或为零,则默认为选定的窗口。 如果窗口是侧窗(请参阅侧窗),则会发出错误信号。 如果窗口是原子窗口的一部分(请参阅原子窗口),则此函数会尝试使该原子窗口的根填充其框架。 返回值为零。

只要变量 ignore-window-parameters 为 nil,此函数的行为可能会被 window 的窗口参数改变。 如果 delete-other-windows 窗口参数的值为 t,则此函数忽略所有其他窗口参数。 否则,如果 delete-other-windows 窗口参数的值是一个函数,则使用参数 window 调用该函数,以代替 delete-other-windows 的通常操作。 请参见窗口参数。

此外,如果 ignore-window-parameters 为 nil,则此函数不会删除 no-delete-other-windows 参数为非 nil 的任何窗口。

Command: delete-windows-on &optional buffer-or-name frame ¶

此函数通过在这些窗口上调用 delete-window 来删除所有显示缓冲区或名称的窗口。 buffer-or-name 应该是一个缓冲区,或者是一个缓冲区的名称; 如果省略或为零,则默认为当前缓冲区。 如果没有显示指定缓冲区的窗口,则此函数不执行任何操作。 如果指定的缓冲区是迷你缓冲区,则会发出错误信号。

如果有一个显示缓冲区的专用窗口,并且该窗口是其框架上的唯一窗口,则此功能还会删除该框架,如果它不是终端上的唯一框架。

可选参数 frame 指定要对哪些帧进行操作:

nil 表示对所有帧进行操作。 t 表示对选定的帧进行操作。 可见意味着对所有可见帧进行操作。 0 表示对所有可见或图标化的帧进行​​操作。 帧表示对该帧进行操作。

请注意,此参数与扫描所有活动窗口的其他函数的含义不同(请参阅 Windows 的循环排序)。 具体来说,这里 t 和 nil 的含义与它们在其他函数中的含义相反。

29.9 重新组合窗口

当删除窗口 W 的最后一个兄弟时,它的父窗口也被删除,W 在窗口树中替换它。 这意味着 W 必须与其父级的兄弟重新组合以形成新的窗口组合(请参阅窗口和框架)。 在某些情况下,删除一个实时窗口甚至可能需要删除两个内部窗口。

 ______________________________________
| ______  ____________________________ |
||      || __________________________ ||
||      ||| ___________  ___________ |||
||      ||||           ||           ||||
||      ||||____W6_____||_____W7____||||
||      |||____________W4____________|||
||      || __________________________ ||
||      |||                          |||
||      |||                          |||
||      |||____________W5____________|||
||__W2__||_____________W3_____________ |
|__________________W1__________________|

在此配置中删除 W5 通常会导致删除 W3 和 W4。 剩余的活动窗口 W2、W6 和 W7 重新组合以与父 W1 形成新的水平组合。

然而,有时不删除像 W4 这样的父窗口是有意义的。 特别是,当父窗口用于保留嵌入在相同类型组合中的组合时,不应将其删除。 这样的嵌入可以确保当您拆分一个窗口并随后删除新窗口时,Emacs 会重新建立关联框架的布局,因为它在拆分之前存在。

考虑从两个实时窗口 W2 和 W3 及其父窗口 W1 开始的场景。

______________________________________
| ____________________________________ |
||                                    ||
||                                    ||
||                                    ||
||                                    ||
||                                    ||
||                                    ||
||_________________W2_________________||
| ____________________________________ |
||                                    ||
||                                    ||
||_________________W3_________________||
|__________________W1__________________|

拆分 W2 以创建一个新窗口 W4,如下所示。

 ______________________________________
| ____________________________________ |
||                                    ||
||                                    ||
||_________________W2_________________||
| ____________________________________ |
||                                    ||
||                                    ||
||_________________W4_________________||
| ____________________________________ |
||                                    ||
||                                    ||
||_________________W3_________________||
|__________________W1__________________|

现在,当垂直放大一个窗口时,Emacs 会尝试从它的下层兄弟那里获取相应的空间,前提是存在这样的窗口。 在我们的场景中,扩大 W4 将从 W3 中窃取空间。

______________________________________
| ____________________________________ |
||                                    ||
||                                    ||
||_________________W2_________________||
| ____________________________________ |
||                                    ||
||                                    ||
||                                    ||
||                                    ||
||_________________W4_________________||
| ____________________________________ |
||_________________W3_________________||
|__________________W1__________________|

删除 W4 现在会将其整个空间分配给 W2,包括之前从 W3 窃取的空间。

| ____________________________________ |
||                                    ||
||                                    ||
||                                    ||
||                                    ||
||                                    ||
||                                    ||
||                                    ||
||                                    ||
||_________________W2_________________||
| ____________________________________ |
||_________________W3_________________||
|__________________W1__________________|

这可能违反直觉,特别是如果 W4 仅用于临时显示缓冲区(请参阅临时显示),并且您希望继续使用初始布局。

可以通过在拆分 W2 时创建一个新的父窗口来修复该行为。 接下来描述的变量允许这样做。

User Option: window-combination-limit ¶

此变量控制拆分窗口是否应生成新的父窗口。 识别以下值:

nil

这意味着允许新的活动窗口共享现有的父窗口(如果存在),前提是拆分发生在与现有窗口组合相同的方向(否则,无论如何都会创建一个新的内部窗口)。

window-size

这意味着 display-buffer 在拆分窗口时会创建一个新的父窗口,并在 alist 参数中传递一个 window-height 或 window-width 条目(请参阅缓冲区显示的操作函数)。 否则,窗口拆分的行为与 nil 值相同。

temp-buffer-resize

在这种情况下,with-temp-buffer-window 在拆分窗口并启用 temp-buffer-resize-mode 时会创建一个新的父窗口(请参阅临时显示)。 否则,窗口拆分的行为与 nil 相同。

temp-buffer

在这种情况下,with-temp-buffer-window 在拆分现有窗口时总是会创建一个新的父窗口(请参阅临时显示)。 否则,窗口拆分的行为与 nil 相同。

display-buffer

这意味着当 display-buffer(请参阅为显示缓冲区选择窗口)拆分窗口时,它总是会创建一个新的父窗口。 否则,窗口拆分的行为与 nil 相同。

t

这意味着拆分窗口总是会创建一个新的父窗口。 因此,如果此变量的值始终为 t,则始终每个窗口树都是二叉树(除了根窗口之外的每个窗口都只有一个兄弟节点的树)。

默认值为窗口大小。 其他值保留供将来使用。

如果由于该变量的设置,split-window 创建了一个新的父窗口,它还会在新创建的内部窗口上调用 set-window-combination-limit(见下文)。 这会影响删除子窗口时窗口树的重新排列方式(见下文)。

如果 window-combination-limit 是 t,在我们场景的初始配置中拆分 W2 会产生这样的结果:

 ______________________________________
| ____________________________________ |
|| __________________________________ ||
|||                                  |||
|||________________W2________________|||
|| __________________________________ ||
|||                                  |||
|||________________W4________________|||
||_________________W5_________________||
| ____________________________________ |
||                                    ||
||                                    ||
||_________________W3_________________||
|__________________W1__________________|

已创建新的内部窗口 W5; 它的孩子是 W2 和新的直播窗口 W4。 现在,W2 是 W4 的唯一兄弟,因此扩大 W4 会尝试缩小 W2,而不会影响 W3。 观察 W5 表示嵌入在垂直组合 W1 中的两个窗口的垂直组合。

Function: set-window-combination-limit window limit ¶

该函数将窗口窗口的组合限制设置为限制。 该值可以通过函数 window-combination-limit 检索。 其效果见下文; 请注意,它仅对内部窗口有意义。 split-window 函数自动调用此函数,将 t 作为 limit 传递,前提是调用时变量 window-combination-limit 的值为 t。

Function: window-combination-limit window ¶

此函数返回窗口的组合限制。

组合限制仅对内部窗口有意义。 如果为 nil,则允许 Emacs 自动删除窗口,以响应窗口删除,以便将 window 的子窗口与其兄弟窗口分组,形成新的窗口组合。 如果组合限制为 t,则 window 的子窗口永远不会自动与其兄弟窗口重新组合。

如果在本节开头显示的配置中,W4(W6 和 W7 的父窗口)的组合限制为 t,则删除 W5 也不会隐式删除 W4。

或者,可以通过在拆分或删除其中一个窗口时始终以相同组合调整所有窗口的大小来避免上述问题。 这也允许拆分窗口,否则这些窗口对于这种操作来说太小了。

User Option: window-combination-resize ¶

如果此变量为 nil,则 split-window 只能在窗口的屏幕区域足够大以容纳其自身和新窗口的情况下拆分窗口(用 window 表示)。

如果这个变量是 t,split-window 会尝试调整与 window 相同组合的所有窗口的大小,以适应新窗口。 特别是,即使窗口是固定大小的窗口或太小而无法正常拆分,这也可能允许拆分窗口成功。 此外,随后调整或删除窗口的大小可能会调整其组合中的所有其他窗口的大小。

默认值为无。 其他值保留供将来使用。 如果特定的拆分操作受 window-combination-limit 的非 nil 值影响,则可能会忽略此变量的值。

为了说明窗口组合调整大小的效果,请考虑以下框架布局。

 ______________________________________
| ____________________________________ |
||                                    ||
||                                    ||
||                                    ||
||                                    ||
||_________________W2_________________||
| ____________________________________ |
||                                    ||
||                                    ||
||                                    ||
||                                    ||
||_________________W3_________________||
|__________________W1__________________|

如果 window-combination-resize 为 nil,则拆分窗口 W3 使 W2 的大小保持不变:

 ______________________________________
| ____________________________________ |
||                                    ||
||                                    ||
||                                    ||
||                                    ||
||_________________W2_________________||
| ____________________________________ |
||                                    ||
||_________________W3_________________||
| ____________________________________ |
||                                    ||
||_________________W4_________________||
|__________________W1__________________|

如果 window-combination-resize 为 t,则拆分 W3 会使所有三个活动窗口的高度大致相同:

 ______________________________________
| ____________________________________ |
||                                    ||
||                                    ||
||_________________W2_________________||
| ____________________________________ |
||                                    ||
||                                    ||
||_________________W3_________________||
| ____________________________________ |
||                                    ||
||                                    ||
||_________________W4_________________||
|__________________W1__________________|

删除任何活动窗口 W2、W3 或 W4 将在剩余的两个活动窗口之间按比例分配其空间。

29.10 Windows的循环排序

当您使用命令 Cx o (other-window) 选择某个其他窗口时,它会以特定顺序在活动窗口中移动。 对于任何给定的窗口配置,此顺序永远不会改变。 它被称为窗口的循环排序。

排序由每个帧的窗口树的深度优先遍历确定,检索作为树的叶节点的活动窗口(请参阅窗口和帧)。 如果 minibuffer 处于活动状态,则 minibuffer 窗口也包括在内。 顺序是循环的,因此序列中的最后一个窗口后面是第一个窗口。

Function: next-window &optional window minibuf all-frames ¶

此函数返回一个实时窗口,即窗口循环排序中的下一个窗口。 窗口应该是一个活动窗口; 如果省略或为零,则默认为选定的窗口。

可选参数 minibuf 指定是否应将 minibuffer 窗口包含在循环排序中。 通常,当 minibuf 为 nil 时,仅当 minibuffer 窗口当前处于活动状态时才包含它; 这与 Cx o 的行为相匹配。 (请注意,只要 minibuffer 正在使用,minibuffer 窗口就处于活动状态;请参阅 Minibuffers)。

如果 minibuf 为 t,则循环排序包括所有 minibuffer 窗口。 如果 minibuf 既不是 t 也不是 nil,即使 minibuffer 窗口处于活动状态,也不包括在内。

可选参数 all-frames 指定要考虑的帧:

nil 表示考虑窗口框架上的窗口。 如果考虑了 minibuffer 窗口(由 minibuf 参数指定),那么共享 minibuffer 窗口的帧也会被考虑。 t 表示考虑所有现有框架上的窗口。 可见意味着考虑所有可见框架上的窗口。 0 表示考虑所有可见或图标化框架上的窗口。 框架意味着考虑该特定框架上的窗口。 其他任何事情都意味着考虑窗口框架上的窗口,而不是其他。

如果考虑多于一帧,则通过附加这些帧的排序来获得循环排序,其顺序与所有活动帧列表的顺序相同(请参阅查找所有帧)。

Function: previous-window &optional window minibuf all-frames ¶

此函数返回一个实时窗口,即窗口循环排序中的前一个窗口。 其他参数的处理方式与下一个窗口类似。

Command: other-window count &optional all-frames ¶

此函数选择一个实时窗口,从选定的窗口开始按窗口的循环顺序计数。 如果 count 为正数,则向前跳过 count 个窗口; 如果 count 是负数,它会向后跳过 -count 个窗口; 如果计数为零,则只是重新选择选定的窗口。 当以交互方式调用时,count 是数字前缀参数。

可选参数 all-frames 与 next-window 中的含义相同,就像 next-window 的 nil minibuf 参数。

如果 ignore-window-parameters 为 nil,则此函数不会选择具有非 nil no-other-window 窗口参数的窗口(请参阅窗口参数)。

如果所选窗口的 other-window 参数是一个函数,并且 ignore-window-parameters 为 nil,则将使用参数 count 和 all-frames 调用该函数,而不是该函数的正常操作。

Function: walk-windows fun &optional minibuf all-frames ¶

此函数为每个活动窗口调用一次函数 fun,并以窗口作为参数。

它遵循窗口的循环排序。 可选参数 minibuf 和 all-frames 指定包含的窗口集; 这些参数与下一个窗口中的参数相同。 如果 all-frames 指定一个框架,则第一个经过的窗口是该框架上的第一个窗口(由 frame-first-window 返回的窗口),不一定是选定的窗口。

如果 fun 通过拆分或删除窗口来更改窗口配置,则不会改变已行走的窗口集,这是在第一次调用 fun 之前确定的。

Function: one-window-p &optional no-mini all-frames ¶

如果所选窗口是唯一的活动窗口,则此函数返回 t,否则返回 nil。

如果 minibuffer 窗口处于活动状态,则通常会考虑它(因此该函数返回 nil)。 但是,如果可选参数 no-mini 不为零,则即使处于活动状态,也会忽略 minibuffer 窗口。 可选参数 all-frames 与 next-window 具有相同的含义。

以下函数返回一个满足某些标准的窗口,而不选择它:

Function: get-lru-window &optional all-frames dedicated not-selected no-other ¶

此函数返回一个活动窗口,它是启发式的最近最少使用的窗口。 最近最少使用的窗口是最近最少选择的窗口——其使用时间少于所有其他活动窗口的使用时间的窗口(请参阅选择窗口)。 可选参数 all-frames 与 next-window 中的含义相同。

如果存在任何全角窗口,则仅考虑这些窗口。 minibuffer 窗口永远不是候选对象。 除非可选参数 dedicated 不为零,否则专用窗口(请参阅专用窗口)永远不是候选窗口。 选定的窗口永远不会返回,除非它是唯一的候选者。 但是,如果可选参数 not-selected 为非 nil,则此函数在这种情况下返回 nil。 可选参数 no-other,如果非 nil,则意味着永远不会返回 no-other-window 参数为非 nil 的窗口。

Function: get-mru-window &optional all-frames dedicated not-selected no-other ¶

此函数类似于 get-lru-window,但它返回最近使用的窗口。 最近使用的窗口是最近选择的窗口——使用时间超过所有其他活动窗口的使用时间的窗口(请参阅选择窗口)。 参数的含义与 get-lru-window 相同。

由于在实践中最近使用的窗口总是被选中的窗口,所以通常只用一个非 nil 未选中的参数调用这个函数是有意义的。

Function: get-largest-window &optional all-frames dedicated not-selected no-other ¶

此函数返回面积最大的窗口(高度乘以宽度)。 如果有两个大小相同的候选窗口,它会优先选择在窗口循环排序中排在第一位的窗口,从所选窗口开始。 参数的含义与 get-lru-window 相同。

Function: get-window-with-predicate predicate &optional minibuf all-frames default ¶

该函数按窗口的循环顺序依次调用每个窗口的函数谓词,并将窗口作为参数传递给它。 如果谓词为任何窗口返回非零,则此函数停止并返回该窗口。 如果没有找到这样的窗口,则返回值为 default(默认为 nil)。

可选参数 minibuf 和 all-frames 指定要搜索的窗口,并且与 next-window 中的含义相同。

29.11 缓冲区和窗口

本节介绍用于检查和设置窗口内容的低级函数。 有关在窗口中显示特定缓冲区的高级函数,请参阅切换到窗口中的缓冲区。

Function: window-buffer &optional window ¶

此函数返回窗口正在显示的缓冲区。 如果 window 被省略或 nil 它默认为选定的窗口。 如果 window 是内部窗口,则此函数返回 nil。

Function: set-window-buffer window buffer-or-name &optional keep-margins ¶

此函数使窗口显示缓冲区或名称。 窗口应该是一个活动窗口; 如果为零,则默认为选定的窗口。 buffer-or-name 应该是一个缓冲区,或现有缓冲区的名称。 此函数不会更改选择了哪个窗口,也不会直接更改当前缓冲区(请参阅当前缓冲区)。 它的返回值为 nil。

如果 window 专用于缓冲区并且 buffer-or-name 没有指定该缓冲区,则此函数会发出错误信号。 请参阅专用窗口。

默认情况下,此函数根据指定缓冲区中的局部变量重置窗口的位置、显示边距、边缘宽度和滚动条设置。 但是,如果可选参数 keep-margins 不为 nil,它将单独保留窗口的显示边距、边缘和滚动条设置。

在编写应用程序时,通常应该使用 display-buffer(请参阅选择用于显示缓冲区的窗口)或在窗口中切换到缓冲区中描述的更高级别的函数,而不是直接调用 set-window-buffer。

这会运行 window-scroll-functions,然后是 window-configuration-change-hook。 请参阅用于窗口滚动和更改的挂钩。

Variable: buffer-display-count ¶

这个缓冲区局部变量记录缓冲区在窗口中显示的次数。 每次为缓冲区调用 set-window-buffer 时,它都会递增。

Variable: buffer-display-time ¶

这个缓冲区局部变量记录缓冲区最后一次显示在窗口中的时间。 如果缓冲区从未显示过,则该值为 nil。 每次为缓冲区调用 set-window-buffer 时都会更新它,其值由当前时间返回(请参阅时间)。

Function: get-buffer-window &optional buffer-or-name all-frames ¶

此函数以窗口的循环顺序返回第一个显示缓冲区或名称的窗口,从选定的窗口开始(请参阅 Windows 的循环排序)。 如果不存在这样的窗口,则返回值为 nil。

buffer-or-name 应该是一个缓冲区或缓冲区的名称; 如果省略或为零,则默认为当前缓冲区。 可选参数 all-frames 指定要考虑的窗口:

t 表示考虑所有现有框架上的窗口。 可见意味着考虑所有可见框架上的窗口。 0 表示考虑所有可见或图标化框架上的窗口。 框架意味着仅考虑该框架上的窗口。 任何其他值都意味着考虑选定框架上的窗口。

请注意,这些含义与 next-window 的 all-frames 参数的含义略有不同(请参阅 Windows 的循环排序)。 在 Emacs 的未来版本中可能会更改此功能以消除这种差异。

Function: get-buffer-window-list &optional buffer-or-name minibuf all-frames ¶

此函数返回当前显示缓冲区或名称的所有窗口的列表。 buffer-or-name 应该是一个缓冲区或现有缓冲区的名称。 如果省略或为零,则默认为当前缓冲区。 如果当前选择的窗口显示缓冲区或名称,它将是此函数返回的列表中的第一个。

参数 minibuf 和 all-frames 与函数 next-window 中的含义相同(请参阅 Windows 的循环排序)。 请注意,所有帧参数的行为与 get-buffer-window 中的行为不完全相同。

Command: replace-buffer-in-windows &optional buffer-or-name ¶

此命令在显示它的所有窗口中将 buffer-or-name 替换为其他缓冲区。 buffer-or-name 应该是一个缓冲区,或者是现有缓冲区的名称; 如果省略或为零,则默认为当前缓冲区。

每个窗口中的替换缓冲区是通过 switch-to-prev-buffer 选择的(请参阅窗口历史记录)。 除了侧窗(参见侧窗),如果可能,任何显示缓冲区或名称的专用窗口都会被删除(参见专用窗口)。 如果这样的窗口是其框架上的唯一窗口,并且同一终端上还有其他框架,则该框架也将被删除。 如果专用窗口是其终端上唯一框架上的唯一窗口,则无论如何都会替换缓冲区。

29.12 切换到窗口中的缓冲区

本节介绍在某些窗口中切换到指定缓冲区的高级函数。 一般来说,“切换到缓冲区”意味着(1)在某个窗口中显示缓冲区,(2)使该窗口成为选定的窗口(并将其框架作为选定的帧),以及(3)使缓冲区成为当前缓冲区。

不要使用这些函数来临时使缓冲区成为当前缓冲区,以便 Lisp 程序可以访问或修改它。 它们有副作用,例如更改窗口历史记录(请参阅窗口历史记录),如果以这种方式使用,用户会感到惊讶。 如果你想在 Lisp 中修改当前缓冲区,请使用 with-current-buffer、save-current-buffer 或 set-buffer。 请参阅当前缓冲区。

Command: switch-to-buffer buffer-or-name &optional norecord force-same-window ¶

此命令尝试在所选窗口中显示缓冲区或名称并将其设为当前缓冲区。 它通常以交互方式使用(作为 Cx b 的绑定),以及在 Lisp 程序中。 返回值是切换到的缓冲区。

如果 buffer-or-name 为 nil,则默认为 other-buffer 返回的缓冲区(请参阅缓冲区列表)。 如果 buffer-or-name 是一个不是任何现有缓冲区名称的字符串,则此函数创建一个具有该名称的新缓冲区; 新缓冲区的主模式由变量主模式确定(请参阅主模式)。

通常,指定的缓冲区放在缓冲区列表的前面——全局缓冲区列表和选定帧的缓冲区列表(请参阅缓冲区列表)。 但是,如果可选参数 norecord 为非零,则不会这样做。

有时,所选窗口可能不适合显示缓冲区。 如果所选窗口是一个 minibuffer 窗口,或者如果所选窗口强烈专用于其缓冲区(请参阅专用窗口),则会发生这种情况。 在这种情况下,该命令通常会尝试通过调用 pop-to-buffer(见下文)在其他窗口中显示缓冲区。

如果可选参数 force-same-window 不为 nil 并且所选窗口不适合显示缓冲区,则此函数在非交互调用时总是会发出错误信号。 在交互使用中,如果选择的窗口是一个 minibuffer 窗口,这个函数会尝试使用其他的窗口来代替。 如果所选窗口强烈专用于其缓冲区,则可以使用下面描述的选项 switch-to-buffer-in-dedicated-window 继续。

User Option: switch-to-buffer-in-dedicated-window ¶

此选项,如果非 nil,则允许在交互调用时继续切换到缓冲区,并且所选窗口强烈专用于其缓冲区。

遵循以下值:

nil

在非交互式使用中不允许切换并发出错误信号。

prompt

提示用户是否允许切换。

pop

调用 pop-to-buffer 以继续。

t

将选定的窗口标记为非专用并继续。

此选项不影响 switch-to-buffer 的非交互式调用。

默认情况下,切换到缓冲区尝试保留窗口点。 可以使用以下选项调整此行为。

User Option: switch-to-buffer-preserve-window-point ¶

如果此变量为 nil,则 switch-to-buffer 将在该缓冲区点的位置显示由 buffer-or-name 指定的缓冲区。 如果此变量已显示,它会尝试在所选窗口中的先前位置显示缓冲区,前提是缓冲区当前显示在任何可见或图标框架上的某个其他窗口中。 如果此变量为 t,则 switch-to-buffer 无条件地尝试在所选窗口中的先前位置显示缓冲区。

如果缓冲区已经显示在所选窗口中或以前从未出现在其中,或者如果 switch-to-buffer 调用 pop-to-buffer 来显示缓冲区,则忽略此变量。

User Option: switch-to-buffer-obey-display-actions ¶

如果此变量不为 nil,则 switch-to-buffer 遵循由 display-buffer-overriding-action、display-buffer-alist 和其他显示相关变量指定的显示操作。

接下来的两个命令类似于 switch-to-buffer,除了所描述的功能。

Command: switch-to-buffer-other-window buffer-or-name &optional norecord ¶

此函数在选定窗口以外的某个窗口中显示由 buffer-or-name 指定的缓冲区。 它在内部使用了 pop-to-buffer 函数(见下文)。

如果选定的窗口已经显示了指定的缓冲区,它会继续这样做,但仍然会找到另一个窗口来显示它。

buffer-or-name 和 norecord 参数与 switch-to-buffer 中的含义相同。

Command: switch-to-buffer-other-frame buffer-or-name &optional norecord ¶

此函数在新帧中显示由 buffer-or-name 指定的缓冲区。 它在内部使用了 pop-to-buffer 函数(见下文)。

如果指定的缓冲区已经显示在另一个窗口中,则在当前终端上的任何框架中,这将切换到该窗口而不是创建新框架。 但是,所选窗口从未用于此目的。

buffer-or-name 和 norecord 参数与 switch-to-buffer 中的含义相同。

上面的命令使用了pop-to-buffer功能,可以灵活的在某个窗口中显示一个缓冲区,并选择该窗口进行编辑。 反过来,pop-to-buffer 使用 display-buffer 来显示缓冲区。 因此,所有影响显示缓冲区的变量也会影响它。 有关 display-buffer 的文档,请参阅选择显示缓冲区的窗口。

Command: pop-to-buffer buffer-or-name &optional action norecord ¶

此函数使 buffer-or-name 成为当前缓冲区并将其显示在某个窗口中,最好不是当前选择的窗口。 然后它选择显示窗口。 如果该窗口位于不同的图形框架上,则尽可能为该框架提供输入焦点(请参阅输入焦点)。

如果 buffer-or-name 为 nil,则默认为 other-buffer 返回的缓冲区(请参阅缓冲区列表)。 如果 buffer-or-name 是一个不是任何现有缓冲区名称的字符串,则此函数创建一个具有该名称的新缓冲区; 新缓冲区的主模式由变量主模式确定(请参阅主模式)。 在任何情况下,即使没有找到合适的窗口来显示它,该缓冲区也会成为当前缓冲区并返回。

如果 action 不是 nil,它应该是传递给 display-buffer 的显示操作(请参阅选择用于显示缓冲区的窗口)。 或者,非零、非列表值意味着弹出到选定窗口以外的窗口——即使缓冲区已经显示在选定窗口中。

与 switch-to-buffer 一样,此函数更新缓冲区列表,除非 norecord 为非零。

29.13 在合适的窗口中显示缓冲区

本节介绍 Emacs 用于查找或创建用于显示指定缓冲区的窗口的低级函数。 这些函数的共同主力是 display-buffer,它最终处理所有传入的缓冲区显示请求(请参阅选择显示缓冲区的窗口)。

display-buffer 将寻找合适窗口的任务委托给所谓的动作函数(请参阅缓冲区显示的动作函数)。 首先,display-buffer 编译一个所谓的动作列表——一个特殊的关联列表,动作函数可以使用它来微调它们的行为。 然后它将该列表传递给它调用的每个操作函数(请参阅用于缓冲区显示的操作列表)。

显示缓冲区的行为是高度可定制的。 要了解如何在实践中使用自定义,您可能希望研究说明显示缓冲区用于调用操作函数的优先顺序的示例(请参阅操作函数的优先级)。 为避免调用 display-buffer 的 Lisp 程序与其行为的用户自定义之间发生冲突,遵循本节最后部分概述的一些指南可能是有意义的(请参阅缓冲区显示之禅)。

29.13.1 选择显示缓冲区的窗口

display-buffer 命令可以灵活选择一个窗口进行显示,并在该窗口中显示一个指定的缓冲区。 它可以通过键绑定 Cx 4 Co 以交互方式调用。它还被许多函数和命令用作子例程,包括切换到缓冲区和弹出到缓冲区(请参阅在窗口中切换到缓冲区)。

该命令执行几个复杂的步骤来查找要在其中显示的窗口。这些步骤通过显示操作进行描述,其形式为 (functions .alist)。 在这里,functions 要么是单个函数,要么是一个函数列表,称为“动作函数”(参见用于缓冲区显示的动作函数); 而alist是一个关联列表,称为“action alist”(见Action Alists for Buffer Display)。 有关显示操作的示例,请参阅缓冲区显示之禅。

动作函数接受两个参数:要显示的缓冲区和动作列表。 它尝试在某个窗口中显示缓冲区,根据自己的标准选择或创建一个窗口。 如果成功,则返回窗口; 否则,它返回 nil。

display-buffer 通过组合来自多个来源的显示动作并依次调用动作函数来工作,直到其中一个设法显示缓冲区并返回非零值。

Command: display-buffer buffer-or-name &optional action frame ¶

此命令使缓冲区或名称出现在某个窗口中,而不选择窗口或使缓冲区成为当前的。 参数 buffer-or-name 必须是缓冲区或现有缓冲区的名称。 返回值是选择显示缓冲区的窗口,如果没有找到合适的窗口,则返回 nil。

可选参数动作,如果非零,通常应该是一个显示动作(如上所述)。 display-buffer 通过合并来自以下来源的显示操作(按照它们的优先级,从高到低)来构建操作函数列表和操作列表:

变量 display-buffer-overriding-action。 用户选项 display-buffer-alist。 行动论据。 用户选项 display-buffer-base-action。 恒定的显示缓冲区回退动作。

在实践中,这意味着 display-buffer 构建了由这些显示操作指定的所有操作函数的列表。 此列表的第一个元素是 display-buffer-overriding-action 指定的第一个操作函数(如果有)。 它的最后一个元素是 display-buffer-pop-up-frame — display-buffer-fallback-action 指定的最后一个动作函数。 重复项不会从此列表中删除——因此,在一次显示缓冲区调用期间,可能会多次调用同一个操作函数。

display-buffer 依次调用此列表指定的操作函数,将缓冲区作为第一个参数传递,将组合的操作 alist 作为第二个参数传递,直到其中一个函数返回非零。 请参阅动作函数的优先级,例如 display-buffer 如何处理不同来源指定的显示动作。

请注意,第二个参数始终是上述来源指定的所有操作列表条目的列表。 因此,该列表的第一个元素是 display-buffer-overriding-action 指定的第一个 action alist 条目,如果有的话。 它的最后一个元素是 display-buffer-base-action 的最后一个 alist 条目,如果有的话(display-buffer-fallback-action 的 action alist 为空)。

另请注意,组合操作列表可能包含重复条目和具有不同值的相同键的条目。 通常,动作函数总是使用它们找到的键的第一个关联。 因此,动作函数使用的关联不一定是指定该动作函数的显示动作提供的关联,

参数动作也可以有一个非零、非列表值。 这具有特殊含义,即缓冲区应显示在所选窗口之外的窗口中,即使所选窗口已经在显示它。 如果使用前缀参数交互调用,则 action 为 t。 Lisp 程序应该总是提供一个列表值。

可选参数 frame,如果非 nil,则指定在确定缓冲区是否已显示时要检查哪些帧。 相当于在动作的动作列表中添加一个元素(reusable-frames .frame)(请参阅用于缓冲区显示的动作列表)。 提供 frame 参数是出于兼容性原因,Lisp 程序不应该使用它。

Variable: display-buffer-overriding-action ¶

这个变量的值应该是一个显示动作,它被显示缓冲区以最高优先级处理。 默认值为空显示动作,即 (nil . nil)。

User Option: display-buffer-alist ¶

该选项的值是一个列表映射条件来显示动作。 每个条件可以是匹配缓冲区名称的正则表达式,也可以是带有两个参数的函数:缓冲区名称和传递给显示缓冲区的操作参数。 如果传递给 display-buffer 的缓冲区名称与此 alist 中的正则表达式匹配,或者条件指定的函数返回非 nil,则 display-buffer 使用相应的显示操作来显示缓冲区。

User Option: display-buffer-base-action ¶

这个选项的值应该是一个显示动作。 此选项可用于定义调用显示缓冲区的标准显示操作。

Constant: display-buffer-fallback-action ¶

如果没有给出其他显示操作,此显示操作指定显示缓冲区的后备行为。

29.13.2 缓冲区显示的动作函数

动作函数是一个函数显示缓冲区调用,用于选择一个窗口来显示缓冲区。 动作函数有两个参数:缓冲区,要显示的缓冲区,和 alist,一个动作列表(请参阅用于缓冲区显示的动作列表)。 如果它们成功,它们应该返回一个显示缓冲区的窗口,如果它们失败,则返回 nil。

Emacs 中定义了以下基本操作函数。

Function: display-buffer-same-window buffer alist ¶

此函数尝试在所选窗口中显示缓冲区。 如果所选窗口是一个 minibuffer 窗口或专用于另一个缓冲区,则它会失败(请参阅专用窗口)。 如果 alist 有一个非零禁止相同窗口条目,它也会失败。

Function: display-buffer-reuse-window buffer alist ¶

此函数尝试通过查找已显示缓冲区的窗口来显示缓冲区。 所选框架上的窗口优先于其他框架上的窗口。

如果 alist 有一个非 nil 禁止相同窗口条目,则所选窗口不符合重用条件。 可以在 reusable-frames action alist 条目的帮助下指定用于搜索已显示缓冲区的窗口的帧集。 如果 alist 不包含可重用帧条目,则此函数仅搜索选定的帧。

如果此函数在另一个框架上选择一个窗口,它将使该框架可见,并且除非 alist 包含禁止切换框架条目,否则在必要时提升该框架。

Function: display-buffer-reuse-mode-window buffer alist ¶

此函数尝试通过查找以给定模式显示缓冲区的窗口来显示缓冲区。

如果 alist 包含模式条目,则其值指定主要模式(符号)或主要模式列表。 如果 alist 不包含模式条目,则使用缓冲区的当前主要模式。 如果一个窗口显示一个缓冲区,其模式派生自这样指定的模式之一,则该窗口是候选窗口。

该行为还由禁止相同窗口、可重用帧和禁止切换帧的列表条目控制,就像 display-buffer-reuse-window 一样。

Function: display-buffer-pop-up-window buffer alist ¶

此函数尝试通过拆分最大或最近最少使用的窗口(通常位于所选框架上)来显示缓冲区。 它实际上通过调用 split-window-preferred-function 指定的函数来执行拆分(请参阅显示缓冲区的附加选项)。

可以通过在 alist 中提供 window-height 和 window-width 条目来调整新窗口的大小。 如果 alist 包含一个保留大小条目,Emacs 还将尝试在以后的调整大小操作期间保留新窗口的大小(请参阅保留窗口大小)。

如果没有窗口可以分割,则此功能失败。 通常情况下,发生这种情况是因为没有足够大的窗口允许拆分。 在这方面,将 split-height-threshold 或 split-width-threshold 设置为较低的值可能会有所帮助。 当所选帧具有不可拆分的帧参数时,拆分也会失败; 请参阅缓冲区参数。

Function: display-buffer-in-previous-window buffer alist ¶

此函数尝试在先前显示缓冲区的窗口中显示缓冲区。

如果 alist 包含非 nil 禁止相同窗口条目,则所选窗口不符合使用条件。 只有当它已经显示缓冲区时,专用窗口才可用。 如果 alist 包含前一个窗口条目,则该条目指定的窗口是可用的,即使它之前从未显示过缓冲区。

如果 alist 包含可重用帧条目(请参阅缓冲区显示的动作列表),则其值确定要搜索合适窗口的帧。 如果 alist 不包含 reusable-frames 条目,如果 display-buffer-reuse-frames 和 pop-up-frames 都为 nil,则此函数仅搜索选定的帧; 如果这些变量中的任何一个不为零,它就会搜索当前终端上的所有帧。

如果根据这些规则有多个窗口符合可用条件,则此函数按以下优先顺序进行选择:

由任何先前窗口列表条目指定的窗口,前提是它不是选定的窗口。 以前显示缓冲区的窗口,前提是它不是选定的窗口。 选定的窗口,如果它由先前窗口列表条目指定或之前显示缓冲区。

Function: display-buffer-use-some-window buffer alist ¶

此函数尝试通过选择现有窗口并在该窗口中显示缓冲区来显示缓冲区。 如果所有窗口都专用于其他缓冲区,则它可能会失败(请参阅专用窗口)。

Function: display-buffer-use-least-recent-window buffer alist ¶

此功能类似于 display-buffer-use-some-window,但不会重用当前窗口,而是使用最近最少切换到的窗口。

Function: display-buffer-in-direction buffer alist ¶

此函数尝试在 alist 指定的位置显示缓冲区。 为此,alist 应包含一个方向条目,其值为左、上(或上)、右和下(或下)之一。 其他值通常解释如下。

如果 alist 还包含一个窗口条目,则它的值指定一个引用窗口。 该值可以是一个特殊符号,例如 main 代表所选框架的主窗口(请参阅侧窗口选项和功能)或 root 代表所选框架的根窗口(请参阅 Windows 和框架)。 它还可以指定任意有效窗口。 任何其他值(或完全省略窗口条目)意味着将所选窗口用作参考窗口。

该函数首先尝试在指定方向重用一个已经显示缓冲区的窗口。 如果不存在这样的窗口,它会尝试拆分参考窗口,以便在指定方向上生成一个新窗口。 如果这也失败了,它将尝试在指定方向的现有窗口中显示缓冲区。 在任何一种情况下,选择的窗口都将出现在方向条目指定的参考窗口的一侧,与参考窗口共享至少一条边。

如果参考窗口是活动的,则所选窗口将与其共享的边缘始终与方向条目指定的边缘相反。 例如,如果方向条目的值为左,则所选窗口的右边缘坐标(请参阅坐标和窗口)将等于参考窗口的左边缘坐标。

如果参考窗口是内部的,则重用窗口必须与其共享方向条目指定的边。 因此,例如,如果参考窗口是框架的根窗口并且方向条目的值是左,则重用窗口必须在框架的左侧。 这意味着所选窗口的左边缘坐标与参考窗口的左边缘坐标相同。

但是,将通过拆分参考窗口来创建一个新窗口,这样所选窗口将与参考窗口共享相反的边缘。 在我们的示例中,将创建一个新的根窗口,其中一个新的实时窗口和参考窗口作为其子窗口。 所选窗口的右边缘坐标将等于参考窗口的左边缘坐标。 它的左边缘坐标将等于框架的新根窗口的左边缘坐标。

方向条目的四个特殊值允许隐式指定选定框架的主窗口作为参考窗口:最左、最上、最右和最下。 这意味着,例如,可以只指定 (direction .leftmost) 而不是 (direction .left) (window .main)。 在这种情况下,将忽略现有的窗口列表条目。

Function: display-buffer-below-selected buffer alist ¶

此函数尝试在所选窗口下方的窗口中显示缓冲区。 如果所选窗口下方有一个窗口并且该窗口已显示缓冲区,则它会重用该窗口。

如果没有这样的窗口,该函数会尝试通过拆分选定的窗口来创建一个新窗口,并在那里显示缓冲区。 如果 alist 包含合适的窗口高度或窗口宽度条目,它还将尝试调整该窗口的大小,请参见上文。

如果拆分所选窗口失败并且所选窗口下方有一个非专用窗口显示其他缓冲区,则此函数尝试使用该窗口显示缓冲区。

如果 alist 包含 window-min-height 条目,则此函数确保使用的窗口至少与该条目的值指定的一样高。 请注意,这只是保证。 为了实际调整所用窗口的大小,alist 还必须提供适当的窗口高度条目。

Function: display-buffer-at-bottom buffer alist ¶

此函数尝试在所选帧底部的窗口中显示缓冲区。

这要么尝试拆分框架底部的窗口或框架的根窗口,要么重用所选框架底部的现有窗口。

Function: display-buffer-pop-up-frame buffer alist ¶

此函数创建一个新框架,并在该框架的窗口中显示缓冲区。 它实际上是通过调用 pop-up-frame-function 中指定的函数来执行框架创建(请参阅显示缓冲区的附加选项)。 如果 alist 包含一个 pop-up-frame-parameters 条目,则将关联的值添加到新创建的框架的参数中。

Function: display-buffer-in-child-frame buffer alist ¶

此函数尝试在所选框架的子框架(请参阅子框架)中显示缓冲区,重用现有子框架或创建新子框架。 如果 alist 有一个非 nil child-frame-parameters 条目,则对应的值是一个帧参数列表,用于给出新的帧。 默认提供指定所选框架的父框架参数。 如果子框架应该成为另一个框架的子框架,则必须将相应的条目添加到 alist。

子框架的外观很大程度上取决于通过 alist 提供的参数。 建议至少使用比率来指定子框架的大小(请参阅大小参数)和位置(请参阅位置参数),并添加保持比率参数(请参阅帧交互参数),以确保子框架保持可见。 有关应考虑的其他参数,请参阅子框架。

Function: display-buffer-use-some-frame buffer alist ¶

此函数尝试通过查找满足谓词的帧(默认情况下为选定帧以外的任何帧)来显示缓冲区。

如果此函数在另一个框架上选择一个窗口,它将使该框架可见,并且除非 alist 包含禁止切换框架条目,否则在必要时提升该框架。

如果 alist 有一个非 nil 帧谓词条目,它的值是一个接受一个参数(一个帧)的函数,如果该帧是候选帧,则返回非 nil; 此函数替换默认谓词。

如果 alist 有一个非 nil 禁止相同窗口条目,则不使用选定的窗口; 因此,如果所选框架只有一个窗口,则不使用它。

Function: display-buffer-no-window buffer alist ¶

如果 alist 有一个非零的 allow-no-window 条目,则此函数不显示缓冲区并返回符号失败。 这构成了操作函数返回 nil 或显示缓冲区的窗口的约定的唯一例外。 如果 alist 没有这样的 allow-no-window 条目,则此函数返回 nil。

如果此函数返回失败,则显示缓冲区将跳过任何进一步的显示操作并立即返回 nil。 如果此函数返回 nil,则显示缓冲区将继续执行下一个显示操作(如果有)。

假设当 display-buffer 的调用者指定一个非 nil 的 allow-no-window 条目时,它也能够处理一个 nil 返回值。

其他两个动作函数在其适当的部分中描述 - display-buffer-in-side-window(请参阅在侧窗口中显示缓冲区)和 display-buffer-in-atom-window(请参阅原子窗口)。

29.13.3 缓冲区显示的动作列表

动作列表是一个关联列表,将动作函数识别的预定义符号映射到这些函数应该相应解释的值。 在每次调用中,display-buffer 都会构造一个新的、可能为空的 action alist,并将整个列表传递给它调用的任何 action 函数。

按照设计,动作函数在解释动作列表条目时是自由的。 事实上,像allow-no-window 或previous-window 这样的条目只对一个或几个动作函数有意义,其余的都忽略了。 其他条目,如禁止相同窗口或窗口参数,应该受到大多数动作函数的尊重,包括应用程序和外部包提供的那些。

在前面的小节中,我们详细描述了各个动作函数如何解释他们关心的动作列表条目。 在这里,我们根据其符号提供所有已知动作列表条目的参考列表,以及它们的值和识别它们的动作函数(请参阅缓冲区显示的动作函数)。 在整个列表中,术语“buffer”指的是缓冲区 display-buffer 应该显示的,“value”指的是条目的值。

inhibit-same-window

如果该值为非零,这表示所选窗口不得用于显示缓冲区。 所有(重新)使用现有窗口的操作函数都应该尊重这个条目。

previous-window

该值必须指定一个以前可能已显示缓冲区的窗口。 display-buffer-in-previous-window 将优先考虑这样的窗口,前提是它仍然是活动的并且不专用于另一个缓冲区。

mode

该值是主要模式或主要模式列表。 只要此条目指定的值与该窗口缓冲区的主要模式匹配,display-buffer-reuse-mode-window 就可以重用一个窗口。 其他操作函数会忽略此类条目。

frame-predicate

该值必须是一个带有一个参数(一帧)的函数,如果该帧是显示缓冲区的候选者,则应该返回非零。 此条目由 display-buffer-use-some-frame 使用。

reusable-frames

该值指定用于搜索可重复使用的窗口的帧集,因为它已经显示了缓冲区。 可以如下设置:

nil 表示只考虑选定框架上的窗口。 (实际上,使用的最后一帧不是 minibuffer-only 帧。) t 表示考虑所有框架上的窗口。 可见意味着考虑所有可见框架上的窗口。 0 表示考虑所有可见或图标化框架上的窗口。 框架意味着仅考虑该框架上的窗口。

请注意,nil 的含义与 next-window 的 all-frames 参数的含义略有不同(请参阅 Windows 的循环排序)。

它的一个主要客户端是 display-buffer-reuse-window,但所有其他尝试重用窗口的操作函数也会受到影响。 display-buffer-in-previous-window 在搜索先前在另一帧上显示缓冲区的窗口时会查询它。

inhibit-switch-frame

如果 display-buffer 选择的窗口显示在那里,则非 nil 值可防止引发或选择另一个帧。 主要受此影响的是 display-buffer-use-some-frame 和 display-buffer-reuse-window。 理想情况下,display-buffer-pop-up-frame 也应该受到影响,但不能保证窗口管理器会遵守。

window-parameters

该值指定了一个窗口参数列表,以提供所选窗口。 所有选择一个窗口的动作函数都应该处理这个条目。

window-min-height

该值指定使用的窗口的最小高度,以行为单位。 如果窗口没有或不能达到此条目指定的高度,则不考虑使用该窗口。 此条目的唯一客户端当前是 display-buffer-below-selected。

请注意,仅提供此类条目并不一定会使窗口与其值指定的一样高。 要实际调整现有窗口的大小或使新窗口与该值指定的一样高,还应提供指定该值的窗口高度条目。 然而,这样的窗口高度条目可以指定一个完全不同的值或要求窗口高度适合其缓冲区的高度,在这种情况下,窗口最小高度条目提供所用窗口的保证最小高度。

window-height

该值指定是否以及如何调整所选窗口的高度,可以是以下之一:

nil 表示不考虑所选窗口的高度。 整数指定所选窗口的所需总高度(以行为单位)。 浮点数指定所选窗口的所需总高度相对于其框架根窗口的总高度的比例。 如果该值指定了一个函数,则该函数将使用一个参数调用 - 所选窗口。 该功能应该调整窗口的高度; 它的返回值被忽略。 合适的函数是 fit-window-to-buffer 和 shrink-window-if-larger-than-buffer,请参阅调整窗口大小。

按照惯例,仅当窗口是垂直组合的一部分时才调整所选窗口的高度(请参阅窗口和框架),以避免更改其他不相关窗口的高度。 此外,仅在此列表正下方指定的某些条件下才应处理此条目。

window-width

此条目类似于前面描述的 window-height 条目,但用于调整所选窗口的宽度。 该值可以是以下之一:

nil 表示不保留所选窗口的宽度。 一个整数指定所选窗口的所需总宽度(以列为单位)。 浮点数指定所选窗口的所需总宽度相对于框架根窗口的总宽度的比例。 如果该值指定了一个函数,则该函数将使用一个参数调用 - 所选窗口。 该功能应该调整窗口的宽度; 它的返回值被忽略。

按照惯例,仅当窗口是水平组合的一部分时才调整所选窗口的宽度(请参阅窗口和框架),以避免更改其他不相关窗口的宽度。 此外,仅应在此列表正下方指定的某些条件下处理此条目。

dedicated

如果非零,则此类条目会告诉 display-buffer 将其创建的任何窗口标记为专用于其缓冲区(请参阅专用窗口)。 它通过调用 set-window-dedicated-p 来实现,其中选择的窗口作为第一个参数,条目的值作为第二个参数。 默认情况下,侧窗专用于值侧((请参阅侧窗选项和功能)。

preserve-size

如果非 nil,这样的条目会告诉 Emacs 保留所选窗口的大小(请参阅保留窗口大小)。 该值应该是 (t . nil) 以保留窗口的宽度, (nil . t) 以保留其高度或 (t . t) 以保留其宽度和高度。 仅在此列表之后指定的某些条件下才应处理此条目。

pop-up-frame-parameters

该值指定了一个框架参数列表,以提供一个新框架(如果已创建)。 display-buffer-pop-up-frame 是它唯一的收件人。

parent-frame

该值指定当缓冲区显示在子框架上时要使用的父框架。 此条目仅由 display-buffer-in-child-frame 使用。

child-frame-parameters

该值指定当缓冲区显示在子框架上时要使用的框架参数列表。 此条目仅由 display-buffer-in-child-frame 使用。

side

该值表示应创建显示缓冲区的新窗口的框架或窗口的一侧。 此条目由 display-buffer-in-side-window 用于指示应放置新侧窗的框架的一侧(请参阅在侧窗中显示缓冲区)。 display-buffer-in-atom-window 也使用它来指示新窗口应位于的现有窗口的一侧(请参阅原子窗口)。

slot

如果非零,则该值指定应该显示缓冲区的侧窗口的插槽。 此条目仅由 display-buffer-in-side-window 使用。

direction

该值指定了一个方向,该方向与窗口条目一起允许 display-buffer-in-direction 确定窗口的位置以显示缓冲区。

window

该值指定一个窗口,该窗口在某种程度上与 display-buffer 选择的窗口相关。 此条目当前由 display-buffer-in-atom-window 用于指示应在其一侧创建新窗口的窗口。 display-buffer-in-direction 也使用它来指定结果窗口应出现在哪一侧的参考窗口。

allow-no-window

如果该值为非 nil,则 display-buffer 不一定必须显示缓冲区并且调用者准备接受它。 此条目不适用于用户自定义,因为无法保证 display-buffer 的任意调用者能够处理没有窗口将显示缓冲区的情况。 display-buffer-no-window 是唯一关心这个条目的动作函数。

body-function

该值必须是一个接受一个参数的函数(显示的窗口)。 此函数可用于用可能取决于显示窗口尺寸的一些内容填充显示窗口的主体。 它在显示缓冲区之后调用,在应用条目窗口高度、窗口宽度和保留大小之前,可以调整窗口大小以适应插入的内容。

按照惯例,window-height、window-width 和 preserve-size 条目是在设置了所选窗口的缓冲区之后并且当且仅当该窗口之前从未显示过另一个缓冲区时才应用的。 更准确地说,后者意味着该窗口必须是由当前 display-buffer 调用创建的,或者该窗口是由 display-buffer 较早创建的以显示缓冲区,并且在被当前重用之前从未用于显示另一个缓冲区调用显示缓冲区。

29.13.4 显示缓冲区的附加选项

缓冲区显示操作的行为(请参阅选择用于显示缓冲区的窗口)可以通过以下用户选项进一步修改。

User Option: pop-up-windows ¶

如果此变量的值为非 nil,则允许 display-buffer 拆分现有窗口以创建一个新窗口用于显示。这是默认设置。

提供此变量仅用于向后兼容。 display-buffer通过display-buffer-fallback-action中的一种特殊机制来遵守它,当该选项的值为non时调用action函数display-buffer-pop-up-window(见缓冲区显示的动作函数) -零。 display-buffer-pop-up-window 本身不参考它,用户可以直接在 display-buffer-alist 等中指定。

User Option: split-window-preferred-function ¶

该变量指定一个分割窗口的函数,以便创建一个新窗口来显示缓冲区。 display-buffer-pop-up-window 操作函数使用它来实际拆分窗口。

该值必须是一个函数,它接受一个参数,一个窗口,并返回一个新窗口(将用于显示所需的缓冲区)或 nil(这意味着拆分失败)。 默认值是 split-window-sensibly,接下来会记录。

Function: split-window-sensibly &optional window ¶

此函数尝试拆分窗口并返回新创建的窗口。 如果窗口无法拆分,则返回 nil。 如果 window 被省略或为零,则默认为选定的窗口。

此函数遵循确定何时可以拆分窗口的常用规则(请参阅拆分窗口)。 它首先尝试通过将新窗口放置在下方来进行拆分,除了任何其他限制外,还受到 split-height-threshold (见下文)的限制。 如果失败,它会尝试通过将新窗口放在右侧进行拆分,受拆分宽度阈值限制(见下文)。 如果这也失败了,并且窗口是其框架上的唯一窗口,则此函数再次尝试拆分并将新窗口放置在下方,而忽略拆分高度阈值。 如果这也失败了,这个函数放弃并返回 nil。

User Option: split-height-threshold ¶

此变量指定是否允许 split-window-sensibly 拆分窗口并将新窗口放置在下方。 如果它是一个整数,这意味着只有当原始窗口至少有那么多行时才拆分。 如果为nil,则表示不以这种方式拆分。

User Option: split-width-threshold ¶

此变量指定是否允许 split-window-sensibly 拆分窗口,将新窗口放置在右侧。 如果该值是整数,则意味着仅当原始窗口至少具有那么多列时才进行拆分。 如果该值为 nil,则表示不以这种方式拆分。

User Option: even-window-sizes ¶

如果此变量非零,则每当它重用现有窗口并且该窗口与所选窗口相邻时,都会导致显示缓冲区均匀窗口大小。

如果其值为仅宽度,则仅当重用窗口位于所选窗口的左侧或右侧并且所选窗口比重用窗口宽时,尺寸才会均匀。 如果其值为仅高度,则仅当重用窗口高于或低于所选窗口且所选窗口高于重用窗口时,尺寸才会均匀。 任何其他非零值都意味着在任何这些情况下均等大小,前提是所选窗口在它们组合的意义上大于重用窗口。

User Option: pop-up-frames ¶

如果此变量的值为非零,则意味着 display-buffer 可以通过创建新帧来显示缓冲区。 默认值为无。

非零值还意味着当 display-buffer 正在寻找已经显示缓冲区或名称的窗口时,它可以搜索任何可见或图标化的框架,而不仅仅是选定的框架。

提供此变量主要是为了向后兼容。 display-buffer 通过 display-buffer-fallback-action 中的特殊机制遵守它,如果值为非 nil,则调用操作函数 display-buffer-pop-up-frame (请参阅缓冲区显示的操作函数)。 (这是在尝试拆分窗口之前完成的。) display-buffer-pop-up-frame 本身不咨询此变量,用户可以直接在 display-buffer-alist 等中指定。

User Option: pop-up-frame-function ¶

该变量指定一个用于创建新框架的函数,以便创建一个用于显示缓冲区的新窗口。 它由 display-buffer-pop-up-frame 动作函数使用。

该值应该是一个不带参数并返回一个框架的函数,如果无法创建框架,则返回 nil。 默认值是使用 pop-up-frame-alist 指定的参数创建框架的函数(见下文)。

User Option: pop-up-frame-alist ¶

此变量保存帧参数列表(请参阅帧参数),由 pop-up-frame-function 指定的函数用于创建新帧。 默认值为无。

提供此选项只是为了向后兼容。 注意,当 display-buffer-pop-up-frame 调用 pop-up-frame-function 指定的函数时,它会将所有 pop-up-frame-parameters action alist 条目的值添加到 pop-up-frame-alist以便 action alist 条目指定的值有效地覆盖 pop-up-frame-alist 的任何相应值。

因此,用户应该在 display-buffer-alist 中设置一个 pop-up-frame-parameters action alist 条目,而不是自定义 pop-up-frame-alist。 只有这样才能保证用户指定的参数值会覆盖显示缓冲区调用者指定的参数值。

在显示缓冲区的设计中已经付出了许多努力来保持与使用旧选项的代码的兼容性,例如弹出窗口、弹出框、弹出框列表、相同窗口缓冲区名称和相同的窗口正则表达式。 Lisp 程序和用户应避免使用这些选项。 上面我们已经警告不要自定义 pop-up-frame-alist。 在这里,我们描述了如何将剩余的选项转换为使用显示操作。

pop-up-windows ¶

此变量默认为 t。 与其将其自定义为 nil 并因此告诉 display-buffer 不该做什么,不如在 display-buffer-base-action 中列出它应该尝试的操作函数,例如:

   (customize-set-variable
    'display-buffer-base-action
    '((display-buffer-reuse-window display-buffer-same-window
	  display-buffer-in-previous-window
	  display-buffer-use-some-window)))
pop-up-frames ¶

不要将此变量自定义为 t,而是自定义 display-buffer-base-action,例如,如下所示:

    (customize-set-variable
     'display-buffer-base-action
     '((display-buffer-reuse-window display-buffer-pop-up-frame)
	 (reusable-frames . 0)))
same-window-buffer-names ¶
same-window-regexps

不是向这些选项之一添加缓冲区名称或正则表达式,而是为该缓冲区使用 display-buffer-alist 条目,指定操作函数 display-buffer-same-window。

(customize-set-variable
 'display-buffer-alist
 (cons '("\\*foo\\*" (display-buffer-same-window))
	      display-buffer-alist))

29.13.5 动作函数的优先级

从前面的小节中我们已经知道 display-buffer 必须提供许多显示操作(请参阅选择用于显示缓冲区的窗口)才能显示缓冲区。 在完全非自定义的 Emacs 中,这些动作由 display-buffer-fallback-action 指定,按以下优先顺序:重用一个窗口,在同一帧上弹出一个新窗口,使用以前显示缓冲区的窗口,使用某个窗口并弹出一个新框架。 (请注意,由 display-buffer-fallback-action 命名的其余操作在未自定义的 Emacs 中是无效的)。

考虑以下形式:

(display-buffer (get-buffer-create "*foo*"))

在未自定义的 Emacs 会话的缓冲区 scratch 中评估此表单通常无法重用已显示 foo 的窗口,但会成功弹出一个新窗口。 再次评估相同的表单现在不会导致任何可见的变化——display-buffer 重用了已经显示 foo 的窗口,因为该操作是适用的并且在所有适用的操作中具有最高优先级。

如果所选框架上没有足够的空间,则弹出新窗口将失败。 在未定制的 Emacs 中,当一个框架上已经有两个窗口时,它通常会失败。 例如,如果您现在键入 Cx 1,然后键入 Cx 2 并再次计算表单,*foo* 应该显示在下部窗口中 - display-buffer 刚刚使用了“some”窗口。 如果在键入 Cx 2 之前您已键入 Cx o,*foo* 将显示在上部窗口中,因为“some”窗口代表“最近最少使用”窗口,并且选定的窗口最近最少使用当且仅当它独自一人在它的框架上。

假设您没有键入 Cx o 并且 foo 显示在下部窗口中。 输入 Cx o 到达那里,然后输入 Cx left 并再次评估表单。 这应该在同一个较低的窗口中显示 *foo*,因为该窗口之前已经显示了 *foo*,因此被选择而不是其他一些窗口。

到目前为止,我们只观察了未自定义的 Emacs 会话中的默认行为。 要了解如何自定义此行为,让我们考虑选项 display-buffer-base-action。 它提供了一个非常粗略的自定义,在概念上会影响任何缓冲区的显示。 它可用于补充 display-buffer-fallback-action 提供的操作,方法是重新排序或添加不存在但更适合用户编辑实践的操作。 但是,它也可以用于以更深刻的方式更改默认行为。

让我们考虑一个用户,他通常喜欢在另一帧上显示缓冲区。 这样的用户可能会提供以下定制:

(customize-set-variable
 'display-buffer-base-action
 '((display-buffer-reuse-window display-buffer-pop-up-frame)
   (reusable-frames . 0)))

此设置将导致 display-buffer 首先尝试在可见或图标化框架上找到显示缓冲区的窗口,如果不存在此类框架,则弹出一个新框架。 您可以通过在显示 scratch 的窗口中键入 Cx 1 并评估我们的规范显示缓冲区形式来观察图形系统上的这种行为。 这通常会创建(并关注)其根窗口显示 foo 的新框架。 图标化该框架并再次评估规范形式:显示缓冲区将重用新框架上的窗口(通常提升框架并为其提供焦点)。

只有在创建新框架失败时,display-buffer 才会应用 display-buffer-fallback-action 提供的操作,这意味着再次尝试重用窗口、弹出新窗口等。 以下形式提供了一种使框架创建失败的简单方法:

(let ((pop-up-frame-function 'ignore))
  (display-buffer (get-buffer-create "*foo*")))

在观察到它无法创建新框架并使用回退操作后,我们将立即忘记该表单。

请注意,display-buffer-reuse-window 在 display-buffer-base-action 的自定义中显得多余,因为它已经是 display-buffer-fallback-action 的一部分,无论如何都应该在那里尝试。 但是,这会失败,因为由于 display-buffer-base-action 优先于 display-buffer-fallback-action,那时 display-buffer-pop-up-frame 已经赢得了比赛。 事实上,这个:

(customize-set-variable
 'display-buffer-base-action
 '(display-buffer-pop-up-frame (reusable-frames . 0)))

会导致显示缓冲区总是弹出一个新的帧,这可能不是我们用户想要的。

到目前为止,我们只展示了用户如何自定义显示缓冲区的默认行为。 现在让我们看看应用程序如何改变显示缓冲区的过程。 执行此操作的规范方法是使用 display-buffer 的 action 参数或调用它的函数,例如 pop-to-buffer(请参阅在窗口中切换到缓冲区)。

假设应用程序希望在所选窗口下方显示 *foo*(以立即将用户的注意力吸引到新窗口),或者如果失败,则在框架底部的窗口中显示。 它可以通过这样的调用来做到这一点:

(customize-set-variable
 'display-buffer-base-action
 '(display-buffer-pop-up-frame (reusable-frames . 0)))

为了查看这个新的、修改后的表单是如何工作的,删除任何显示 foo 的框架,在显示 scratch 的窗口中键入 Cx 1 后跟 Cx 2,然后评估该表单。 display-buffer 应该分割上面的窗口,并在新窗口中显示 *foo*。 或者,如果在 Cx 2 之后您输入了 Cx o,则显示缓冲区将在底部拆分窗口。

现在假设,在评估新表单之前,您已经使所选窗口尽可能小,例如,通过评估该窗口中的表单 (fit-window-to-buffer)。 在这种情况下,显示缓冲区将无法拆分所选窗口,而是拆分框架的根窗口,从而在框架底部有效地显示 *foo*。

在任何一种情况下,第二次评估新表单都应该重用已经显示 foo 的窗口,因为 action 参数提供的两个函数都尝试首先重用这样的窗口。

通过设置 action 参数,应用程序有效地否决了 display-buffer-base-action 的任何自定义。 我们的用户现在可以接受应用程序的选择,或者通过自定义选项 display-buffer-alist 来加倍,如下所示:

(customize-set-variable
 'display-buffer-alist
 '(("\\*foo\\*"
    (display-buffer-reuse-window display-buffer-pop-up-frame))))

在不显示 foo 的配置中尝试使用上面的新修改形式,将在单独的帧上显示 *foo*,完全忽略显示缓冲区的操作参数。

请注意,我们并不关心在我们的 display-buffer-alist 规范中指定可重用帧操作 alist 条目。 display-buffer 总是取它找到的第一个——在我们的例子中是 display-buffer-base-action 指定的那个。 如果我们想使用不同的规范,例如,从可重复使用的列表中排除显示 foo 的图标化框架,我们必须单独指定,但是:

(customize-set-variable
 'display-buffer-alist
 '(("\\*foo\\*"
    (display-buffer-reuse-window display-buffer-pop-up-frame)
    (reusable-frames . visible))))

如果你尝试这个,你会注意到重复尝试显示 foo 将成功地重用一个框架,只有当该框架可见时。

上面的示例可以得出这样的结论:用户自定义 display-buffer-alist 的唯一目的是推翻应用程序选择的操作参数。 这样的结论是不正确的。 display-buffer-alist 是用户以首选方式指导特定缓冲区显示过程的标准选项,无论显示是否也由操作参数引导。

然而,我们可以合理地得出结论,自定义 display-buffer-alist 与自定义 display-buffer-base-action 在两个主要方面不同:它更强大,因为它覆盖了 display-buffer 的 action 参数,并且它允许显式指定受影响的缓冲区。 事实上,显示其他缓冲区不受 foo 自定义的任何影响。 例如,

(display-buffer (get-buffer-create "*bar*"))

继续受 display-buffer-base-action 和 display-buffer-fallback-action 的设置控制。

我们可以在这里停止我们的示例,但 Lisp 程序仍然有一个王牌,他们可以使用它来推翻对 display-buffer-alist 的任何自定义。 这是变量 display-buffer-overriding-action ,它们可以围绕 display-buffer 调用绑定,如下所示:

(let ((display-buffer-overriding-action
	 '((display-buffer-same-window))))
  (display-buffer
   (get-buffer-create "*foo*")
   '((display-buffer-below-selected display-buffer-at-bottom))))

无论操作参数和任何用户自定义如何,评估此表单通常会在所选窗口中显示 *foo*。 (通常,应用程序不会费心也提供一个动作参数。这里它只是用来说明它被覆盖的事实。)

查看显示缓冲区将尝试使用我们在此处提供的自定义项显示 foo 的操作函数列表可能是说明性的。 列表(包括解释谁添加了这个和后续元素的评论)是:

(display-buffer-same-window  ;; `display-buffer-overriding-action'
 display-buffer-reuse-window ;; `display-buffer-alist'
 display-buffer-pop-up-frame
 display-buffer-below-selected ;; ACTION argument
 display-buffer-at-bottom
 display-buffer-reuse-window ;; `display-buffer-base-action'
 display-buffer-pop-up-frame
 display-buffer--maybe-same-window ;; `display-buffer-fallback-action'
 display-buffer-reuse-window
 display-buffer--maybe-pop-up-frame-or-window
 display-buffer-in-previous-window
 display-buffer-use-some-window
 display-buffer-pop-up-frame)

请注意,在此处列出的内部函数中,display-buffer–maybe-same-window 被有效地忽略,而 display-buffer–maybe-pop-up-frame-or-window 实际上运行 display-buffer-pop-up-window .

每个函数调用中传递的动作列表是:

((reusable-frames . visible)
 (reusable-frames . 0))

这表明我们使用了上面 display-buffer-alist 的第二个规范,覆盖了 display-buffer-base-action 提供的规范。 假设我们的用户将其写为

(customize-set-variable
 'display-buffer-alist
 '(("\\*foo\\*"
    (display-buffer-reuse-window display-buffer-pop-up-frame)
    (inhibit-same-window . t)
    (reusable-frames . visible))))

在这种情况下,inhibit-same-window alist 条目将成功地使 display-buffer-overriding-action 中的 display-buffer-same-window 规范无效,并且 display-buffer 将在另一个帧上显示 *foo*。 为了使 display-buffer-overriding-action 在这方面更加健壮,应用程序还必须指定适当的禁止相同窗口条目,例如,如下所示:

(let ((display-buffer-overriding-action
	 '(display-buffer-same-window (inhibit-same-window . nil))))
  (display-buffer (get-buffer-create "*foo*")))

最后一个示例表明,虽然操作函数的优先顺序是固定的,如选择用于显示缓冲区的窗口中所述,但由按该顺序排列较低的显示操作指定的操作列表条目可能会影响排名较高的显示操作的执行.

29.13.6 缓冲区显示之禅

在其最简单的形式中,一个框架始终容纳一个可用于显示缓冲区的单个窗口。 因此,总是最后一次调用 display-buffer 会成功地把它的缓冲区放在那里。

由于使用这样的框架不是很实用,默认情况下,Emacs 允许更复杂的框架布局,由框架大小的默认值以及 split-height-threshold 和 split-width-threshold 选项控制。 显示尚未在帧上显示的缓冲区,然后拆分该帧上的单个窗口或(重新)使用其两个窗口之一。

一旦用户自定义这些阈值之一或手动更改框架的布局,就会放弃默认行为。 当使用非 nil 操作参数调用 display-buffer 或用户自定义前面小节中提到的选项之一时,默认行为也会被放弃。 由于过多的适用显示动作和由此产生的帧布局,很快掌握显示缓冲区可能会变得令人沮丧。

但是,避免使用缓冲区显示功能并退回到拆分和删除窗口的比喻也不是一个好主意。 缓冲区显示功能为 Lisp 程序和用户提供了一个框架来协调他们的不同需求; 不存在用于拆分和删除窗口的类似框架。 缓冲区显示功能还允许在以后从框架中删除缓冲区时至少部分恢复框架的布局(请参阅退出 Windows)。

下面我们将给出一些指导来弥补上面提到的挫败感,从而避免在帧的窗口之间丢失缓冲区。

轻松编写显示动作

编写显示动作可能会很痛苦,因为必须将动作函数和动作列表放在一个巨大的列表中。 (历史原因使我们无法让显示缓冲区支持单独的参数。)这可能有助于记住一些基本形式,如下所示:

'(nil (inhibit-same-window . t))

仅指定动作列表条目,不指定动作函数。 其唯一目的是禁止在其他地方指定的 display-buffer-same-window 函数在同一窗口中显示缓冲区,另请参见上一小节的最后一个示例。

'(display-buffer-below-selected)

另一方面,指定一个动作函数和一个空动作列表。 要结合上述两种规范的效果,可以编写以下形式

'(display-buffer-below-selected (inhibit-same-window . t))

添加另一个动作功能,人们会写

     '((display-buffer-below-selected display-buffer-at-bottom)
	(inhibit-same-window . t))

并添加另一个 alist 条目,人们会写

     '((display-buffer-below-selected display-buffer-at-bottom)
	(inhibit-same-window . t)
	(window-height . fit-window-to-buffer))

最后一种形式可以通过以下方式用作显示缓冲区的操作参数:

    (display-buffer
     (get-buffer-create "*foo*")
     '((display-buffer-below-selected display-buffer-at-bottom)
	 (inhibit-same-window . t)
	 (window-height . fit-window-to-buffer)))

在 display-buffer-alist 的定制中,它将按如下方式使用:

   (customize-set-variable
    'display-buffer-alist
    '(("\\*foo\\*"
	  (display-buffer-below-selected display-buffer-at-bottom)
	  (inhibit-same-window . t)
	  (window-height . fit-window-to-buffer))))

要为第二个缓冲区添加自定义项,可以编写:

    (customize-set-variable
     'display-buffer-alist
     '(("\\*foo\\*"
	  (display-buffer-below-selected display-buffer-at-bottom)
	  (inhibit-same-window . t)
	  (window-height . fit-window-to-buffer))
	 ("\\*bar\\*"
	  (display-buffer-reuse-window display-buffer-pop-up-frame)
	  (reusable-frames . visible))))

互相尊重

display-buffer-alist 和 display-buffer-base-action 是用户选项——Lisp 程序绝不能设置或重新绑定它们。 另一方面,display-buffer-overriding-action 是为应用程序保留的——他们很少使用该选项,如果他们使用它,那么要格外小心。

显示缓冲区的旧实现经常导致用户和应用程序争夺用户选项的设置,例如弹出框和弹出窗口(请参阅显示缓冲区的附加选项)。 这是重新设计显示缓冲区的一个主要原因——提供一个明确的框架来指定用户和应用程序应该被允许做什么。

Lisp 程序必须做好准备,以防用户自定义可能导致缓冲区以意想不到的方式显示。 他们不应该在随后的行为中假设缓冲区已按照他们在 display-buffer 的 action 参数中要求的方式精确显示。

用户不应该对任意缓冲区的显示方式施加太多太严格的限制。 否则,他们将面临失去为特定目的显示缓冲区的特性的风险。 假设编写了一个 Lisp 程序来并排比较两个窗口中不同版本的缓冲区。 如果 display-buffer-alist 的自定义规定任何此类缓冲区应始终显示在所选窗口中或下方,则程序将很难通过 display-buffer 设置所需的窗口配置。

要指定显示任意缓冲区的首选项,用户应自定义 display-buffer-base-action。 上一小节中给出了喜欢使用多个框架的用户如何执行此操作的示例。 display-buffer-alist 应保留用于以特定方式显示特定缓冲区。 考虑重用已经显示缓冲区的窗口

一般来说,对于用户和 Lisp 程序员来说,为窗口已经显示有问题的缓冲区的情况做好准备并重用该窗口总是一个好主意。 在前面的小节中,我们已经表明,如果没有正确执行此操作,可能会导致 display-buffer 不断弹出一个新帧,尽管显示该缓冲区的帧已经存在。 仅在少数情况下,可能不希望重用窗口,例如,当缓冲区的不同部分应显示在该窗口中时。

因此,display-buffer-reuse-window 是一个应该尽可能频繁地使用的动作函数,无论是在动作参数还是自定义中。 action 参数中的禁止相同窗口条目通常处理最常见的情况,即应避免重用显示缓冲区的窗口 - 所讨论的窗口是选定的窗口。 将焦点吸引到所选窗口

这对于使用多个帧的人来说是一件很容易的事——显示缓冲区的帧将自动提升并获得焦点,除非禁止切换帧条目禁止它。 对于单帧用户,这项任务可能要困难得多。 特别是,display-buffer-pop-up-window 和 display-buffer-use-some-window 在这方面可能会变得突兀。 他们拆分或使用看似任意的(通常是最大的或最近最少使用的)窗口,分散用户的注意力。

因此,一些 Lisp 程序会尝试在框架底部选择一个窗口,例如,为了在 minibuffer 窗口附近显示缓冲区,用户应该在该窗口中回答与新窗口相关的问题。 对于与输入无关的操作,display-buffer-below-selected 可能更可取,因为所选窗口通常已经引起了用户的注意。 处理显示缓冲区的后续调用

display-buffer 不太适合按顺序显示多个缓冲区并确保所有这些缓冲区在生成的窗口配置中有序显示。 同样,标准操作函数 display-buffer-pop-up-window 和 display-buffer-use-some-window 不太适合此目的,因为它们在更复杂的配置中有些混乱。

为了在同一个显示周期中生成显示多个缓冲区(或同一个缓冲区的不同视图)的窗口配置,Lisp 程序员不可避免地必须编写自己的动作函数。 下面列出的一些技巧可能会在这方面有所帮助。

使窗口原子化(请参阅原子窗口)可避免在弹出新窗口时破坏现有窗口组合。 新窗口将改为在合成之外弹出。 临时将窗口专用于其缓冲区(请参阅专用窗口)可避免使用窗口来显示不同的缓冲区。 将改为使用非专用窗口。 调用 window-preserve-size(请参阅保留窗口大小)将尝试在弹出新窗口时保持参数窗口的大小不变。 但是,您必须确保可以缩小相同组合中的另一个窗口。 侧窗(请参阅侧窗)可用于始终在窗口中的同一帧位置显示特定缓冲区。 这允许对不竞争在帧上同时显示的缓冲区进行分组,并在同一窗口中显示任何此类缓冲区,而不会中断其他缓冲区的显示。 子帧(请参阅子帧)可用于在选定帧的屏幕范围内显示缓冲区,而不会破坏该帧的窗口配置,也不会产生与 display-buffer-pop-up-frame 造成的完整帧相关的开销.

29.14 窗口历史

每个窗口都会在一个列表中记住它之前显示的缓冲区,以及这些缓冲区从其中删除的顺序。 例如,replace-buffer-in-windows(请参阅缓冲区和 Windows)和退出窗口时(请参阅退出 Windows)使用此历史记录。 该列表由 Emacs 自动维护,但您可以使用以下函数显式检查或更改它:

Function: window-prev-buffers &optional window ¶

此函数返回一个列表,指定窗口的先前内容。 可选参数窗口应该是一个活动窗口,默认为选定的窗口。

每个列表元素的格式为 (buffer window-start window-pos),其中 buffer 是先前显示在窗口中的缓冲区,window-start 是上次显示该缓冲区时的窗口开始位置(请参阅窗口开始和结束位置) , window-pos 是该缓冲区最后一次显示在窗口中时的点位置(请参阅 Windows 和 Point)。

该列表是有序的,以便较早的元素对应于最近显示的缓冲区,第一个元素通常对应于最近从窗口中删除的缓冲区。

Function: set-window-prev-buffers window prev-buffers ¶

此函数将窗口的先前缓冲区设置为 prev-buffers 的值。 参数窗口必须是活动窗口,并且默认为选定的窗口。 参数 prev-buffers 应该是一个与 window-prev-buffers 返回的形式相同的列表。

此外,每个窗口都维护一个下一个缓冲区列表,这是一个由 switch-to-prev-buffer 重新显示的缓冲区列表(见下文)。 此列表主要由 switch-to-prev-buffer 和 switch-to-next-buffer 用于选择要切换到的缓冲区。

Function: window-next-buffers &optional window ¶

此函数通过 switch-to-prev-buffer 返回最近在窗口中重新显示的缓冲区列表。 window 参数必须表示一个活动窗口或 nil(表示选定的窗口)。

Function: set-window-next-buffers window next-buffers ¶

该函数将窗口的下一个缓冲区列表设置为下一个缓冲区。 window 参数应该是一个活动窗口或 nil(表示选定的窗口)。 参数 next-buffers 应该是一个缓冲区列表。

以下命令可用于循环遍历全局缓冲区列表,很像 bury-buffer 和 unbury-buffer。 但是,它们根据指定窗口的历史列表循环,而不是全局缓冲区列表。 此外,它们恢复特定于窗口的窗口开始和点位置,并且可能显示缓冲区,即使它已经显示在另一个窗口中。 特别是 switch-to-prev-buffer 命令被 replace-buffer-in-windows、bury-buffer 和 quit-window 用于查找窗口的替换缓冲区。

Command: switch-to-prev-buffer &optional window bury-or-kill ¶

此命令在窗口中显示上一个缓冲区。 参数窗口应该是一个活动窗口或零(表示选定的窗口)。 如果可选参数 bury-or-kill 不是 nil,这意味着当前显示在 window 中的缓冲区即将被掩埋或杀死,因此不应在将来调用此命令时切换到该缓冲区。

前一个缓冲区通常是在窗口中当前显示的缓冲区之前显示的缓冲区。 但是,已被掩埋或杀死的缓冲区,或已通过最近调用 switch-to-prev-buffer 显示的缓冲区不符合先前缓冲区的条件。

如果此命令的重复调用已经显示了以前在窗口中显示的所有缓冲区,则进一步调用将显示来自帧窗口缓冲区列表的缓冲区(请参阅缓冲区列表)。

下面描述的 switch-to-prev-buffer-skip 选项可用于禁止切换到某些缓冲区,例如,切换到已在另一个窗口中显示的缓冲区。 此外,如果窗口的框架具有缓冲区谓词参数(请参阅缓冲区参数),则该谓词可能会禁止切换到某些缓冲区。

Command: switch-to-next-buffer &optional window ¶

此命令切换到 window 中的下一个缓冲区,从而撤消 window 中最后一个 switch-to-prev-buffer 命令的效果。 参数窗口必须是活动窗口,并且默认为选定的窗口。

如果最近没有可以撤消的 switch-to-prev-buffer 调用,则此函数尝试从出现的帧窗口的缓冲区列表中显示一个缓冲区(请参阅缓冲区列表)。

选项 switch-to-prev-buffer-skip 和窗口框架的缓冲区谓词(请参阅缓冲区参数)影响此命令,就像它们对 switch-to-prev-buffer 所做的一样。

默认情况下 switch-to-prev-buffer 和 switch-to-next-buffer 可以切换到已经在另一个窗口中显示的缓冲区。 以下选项可用于覆盖此行为。

User Option: switch-to-prev-buffer-skip ¶

如果此变量为 nil,则 switch-to-prev-buffer 可以切换到任何缓冲区,包括已在其他窗口中显示的缓冲区。

如果此变量非零,则 switch-to-prev-buffer 将避免切换到某些缓冲区。 可以使用以下值:

这意味着不要切换到显示在承载窗口 switch-to-prev-buffer 的帧上的缓冲区。 可见意味着不切换到任何可见帧上显示的缓冲区。 0(数字零)表示不切换到任何可见或图标化框架上显示的缓冲区。 t 表示不切换到任何实时帧上显示的缓冲区。 一个接受三个参数的函数——switch-to-prev-buffer 的 window 参数、switch-to-prev-buffer 打算切换到的缓冲区和 switch-to-prev-buffer 的 bury-or-kill 参数。 如果该函数返回非零,switch-to-prev-buffer 将避免切换到第二个参数指定的缓冲区。

命令 switch-to-next-buffer 以类似的方式遵循此选项。 如果此选项指定了一个函数,switch-to-next-buffer 将调用该函数,第三个参数始终为零。

请注意,由于 bury-buffer、replace-buffer-in-windows 和 quit-restore-window 也会调用 switch-to-prev-buffer,因此自定义此选项也可能会影响 Emacs 在窗口退出或退出时的行为缓冲区被掩埋或杀死。

另请注意,在某些情况下 switch-to-prev-buffer 和 switch-to-next-buffer 可能会忽略此选项,例如,当只剩下一个缓冲区时,这些函数可以切换到。

29.15 专用窗口

通过将这些窗口标记为专用于它们的缓冲区,可以告诉用于显示缓冲区的函数不使用特定窗口。 display-buffer(请参阅选择一个窗口来显示缓冲区)从不使用专用窗口来显示其中的另一个缓冲区。 get-lru-window 和 get-largest-window(请参阅 Windows 的循环排序)在其专用参数为非零时不将专用窗口视为候选窗口。 set-window-buffer(见缓冲区和窗口)相对于专用窗口的行为略有不同,见下文。

当它们操作的窗口是专用的时,应该从窗口中删除缓冲区或从框架中删除窗口的函数可以表现得特别。 我们将区分四种基本情况,即(1)窗口不是其框架上的唯一窗口,(2)窗口是其框架上的唯一窗口但在同一终端左侧还有其他框架,(3) window 是同一终端上唯一框架上的唯一窗口,并且 (4) 奉献的价值是 side(请参阅在 Side Windows 中显示缓冲区)。

特别是,delete-windows-on(请参阅删除窗口)通过删除关联的框架来处理案例 (2),并通过在该框架的唯一窗口中显示另一个缓冲区来处理案例 (3) 和 (4)。 当缓冲区被杀死时调用的函数 replace-buffer-in-windows(请参阅缓冲区和 Windows),在情况(1)中删除窗口,否则行为类似于 delete-windows-on。

当 bury-buffer(参见缓冲区列表)在选定的窗口(显示应被隐藏的缓冲区)上操作时,它通过调用 frame-auto-hide-function(参见退出窗口)来处理情况(2)来处理选定的框架。 其他两种情况的处理方式与窗口中的替换缓冲区一样。

Function: window-dedicated-p &optional window ¶

如果窗口专用于其缓冲区,则此函数返回非 nil,否则返回 nil。 更准确地说,返回值是最后一次调用 set-window-dedicated-p 为 window 分配的值,如果从未以 window 作为参数调用该函数,则返回 nil。 窗口的默认值是选定的窗口。

Function: set-window-dedicated-p window flag ¶

如果 flag 为非 nil,则此函数将窗口标记为专用于其缓冲区,否则将其标记为非专用。

作为一种特殊情况,如果 flag 为 t,则窗口变得强烈专用于其缓冲区。 当它所作用的窗口高度专用于其缓冲区并且尚未显示它被要求显示的缓冲区时,set-window-buffer 会发出错误信号。 其他函数不会将 t 与任何非 nil 值区别对待。

您还可以通过提供合适的专用操作列表条目来告诉 display-buffer 将它创建的窗口标记为专用于其缓冲区(请参阅用于缓冲区显示的操作列表)。

29.16 退出窗口

在命令使用 display-buffer 在屏幕上放置一个缓冲区后,用户可能决定隐藏它并返回到 Emacs 显示的先前配置。 我们称之为退出窗口。 这样做的方法是在 display-buffer 使用的窗口是选定的窗口时调用 quit-window。

恢复显示器先前配置的正确方法取决于对现在出现缓冲区的窗口所做的操作。 删除那个窗口,或者删除它的框架,或者只是在那个窗口中显示另一个缓冲区可能是正确的。 一个复杂的问题是,用户可能在显示缓冲区后更改了窗口配置,并且不希望撤消用户明确请求的更改。

为了让 quit-window 做正确的事,display-buffer 在窗口的 quit-restore 参数中保存了关于它所做的事情的信息(请参阅窗口参数)。

Command: quit-window &optional kill window ¶

此命令退出窗口并掩埋其缓冲区。 参数窗口必须是活动窗口,并且默认为选定的窗口。 使用前缀参数 kill 非 nil,它会杀死缓冲区而不是掩埋它。

函数 quit-window 首先运行 quit-window-hook。 然后它调用函数 quit-restore-window,如下所述,它完成了艰苦的工作。

您可以通过调用 quit-restore-window 来获得更多控制权。

Function: quit-restore-window &optional window bury-or-kill ¶

此函数在退出后处理窗口及其缓冲区。 可选参数窗口必须是活动窗口,并且默认为选定的窗口。 该函数考虑了窗口的退出恢复参数。

可选参数 bury-or-kill 指定如何处理窗口的缓冲区。 以下值是有意义的:

nil

这意味着不以任何特定方式处理缓冲区。 因此,如果没有删除窗口,调用 switch-to-prev-buffer 通常会再次显示缓冲区。

append

这意味着如果没有删除窗口,它的缓冲区将移动到窗口先前缓冲区列表的末尾(请参阅窗口历史记录),因此将来对 switch-to-prev-buffer 的调用不太可能切换到它。 此外,它将缓冲区移动到帧缓冲区列表的末尾(请参阅缓冲区列表)。

bury

这意味着如果没有删除窗口,它的缓冲区将从窗口的先前缓冲区列表中删除。 此外,它将缓冲区移动到帧缓冲区列表的末尾。 这是防止 switch-to-prev-buffer 再次切换到此缓冲区的最可靠方法,而不是杀死缓冲区。

kill

这意味着杀死窗口的缓冲区。

参数 bury-or-kill 还指定当窗口应该被删除时如何处理窗口的框架,如果它是其框架上的唯一窗口,并且该框架的终端上还有其他框架。 如果bury-or-kill等于kill,则表示删除帧。 否则,框架的命运是通过调用 frame-auto-hide-function(见下文)以该框架作为唯一参数来确定的。

此函数始终将窗口的退出恢复参数设置为 nil,除非它删除了窗口。

窗口窗口的 quit-restore 参数(请参阅窗口参数)应为 nil 或四个元素的列表:

(method obuffer owindow this-buffer)

第一个元素method 是window、frame、same 和other 四个符号之一。 frame 和 window 控制如何删除窗口,同时在其中显示一些其他缓冲区的相同和其他控件。

具体来说,window 表示该窗口是由 display-buffer 专门创建的; frame 表示已经创建了一个单独的框架; 同样,窗口只显示过这个缓冲区; 其他,该窗口之前显示了另一个缓冲区。

第二个元素,obuffer,要么是符号窗口或框架之一,要么是表单列表

(prev-buffer prev-window-start prev-window-point height)

它表示之前在窗口中显示了哪个缓冲区,该缓冲区的窗口开始(请参阅窗口开始和结束位置)和窗口点(请参阅窗口和点)当时的位置,以及当时窗口的高度。 如果退出窗口时prev-buffer仍然存在,退出窗口可能会重新使用窗口来显示prev-buffer。

第三个元素 owindow 是在显示完成之前选择的窗口。 如果退出删除窗口,它会尝试选择 owindow。

第四个元素this-buffer是显示设置了quit-restore参数的缓冲区。 仅当它仍然显示该缓冲区时,退出窗口可能会删除该窗口。

退出窗口尝试删除它当且仅当 (1) 方法是窗口或框架,(2) 窗口没有先前显示的缓冲区的历史记录,并且 (3) 此缓冲区等于当前显示在窗口中的缓冲区。 如果窗口是原子窗口的一部分(参见原子窗口),退出将尝试删除该原子窗口的根。 在任何一种情况下,它都会尝试避免在无法删除窗口时发出错误信号。

如果obuffer 是一个列表,并且prev-buffer 仍然存在,则退出根据obuffer 的其余元素在窗口中显示prev-buffer。 如果临时调整大小以显示此缓冲区,这包括将窗口大小调整为高度。

否则,如果 window 以前用于显示其他缓冲区(请参阅 Window History),则将显示该历史记录中的最新缓冲区。

以下选项指定了一个函数,用于在退出该窗口时对包含一个窗口的框架执行正确的操作。

User Option: frame-auto-hide-function ¶

调用此选项指定的函数以自动隐藏框架。 这个函数用一个参数调用——一个框架。

此处指定的函数由 bury-buffer 调用(请参阅缓冲区列表),当所选窗口专用并显示要掩埋的缓冲区时。 当要退出的窗口的框架是专门为显示该窗口的缓冲区而创建的并且缓冲区没有被杀死时,它也被 quit-restore-window (见上文)调用。

默认是调用 iconify-frame (请参阅框架的可见性)。 或者,您可以指定 delete-frame(请参阅删除框架)以从其显示中删除框架,使框架不可见以使框架不可见,忽略以保持框架不变,或任何其他可以将框架作为它的唯一论据。

请注意,仅当指定帧仅包含一个实时窗口并且同一终端上至少有一个其他帧时,才会调用此选项指定的函数。

对于特定帧,此处指定的值可能会被该帧的自动隐藏功能帧参数覆盖(请参阅帧交互参数)。

29.17 侧窗

侧窗是位于框架根窗口的四个侧面中的任何一个的特殊窗(请参阅窗和框架)。 实际上,这意味着框架的根窗口区域被细分为一个主窗口和围绕该主窗口的多个侧窗口。 主窗口要么是“普通”实时窗口,要么指定包含所有普通窗口的区域。

在最简单的使用形式中,侧窗允许始终在帧的同一区域显示特定缓冲区。 因此,它们可以被视为由 display-buffer-at-bottom 提供的概念的概括(请参阅缓冲区显示的动作函数)到帧的其余边。 然而,通过适当的定制,侧窗也可用于提供类似于在所谓的集成开发环境 (IDE) 中发现的框架布局。

29.17.1 在侧窗中显示缓冲区

下面的 display-buffer 操作函数(请参阅缓冲区显示的操作函数)创建或重用一个侧窗口来显示指定的缓冲区。

Function: display-buffer-in-side-window buffer alist ¶

此函数在所选帧的侧窗口中显示缓冲区。 它返回用于显示缓冲区的窗口,如果找不到或创建这样的窗口,则返回 nil。

alist 是用于显示缓冲区的符号和值的关联列表。 alist 中的以下符号对于此功能是特殊的:

side

表示窗口应位于的框架的一侧。 有效值为左、上、右和下。 如果未指定,则窗口位于框架的底部。

slot

表示窗口位于指定一侧的插槽。 零值意味着最好将窗口定位在指定边的中间。 负值表示使用中间槽之前(即,上方或左侧)的槽。 正值表示使用中间槽之后(即下方或右侧)的槽。 因此,特定一侧的所有窗口都按其槽值排序。 如果未指定,则窗口位于指定边的中间。

dedicated

专用标志(请参阅专用窗口)对侧窗的含义略有不同。 创建侧窗口时,该标志设置为值侧,以防止显示缓冲区在其他操作功能中使用该窗口。 它的值在退出窗口、kill-buffer、previous-buffer 和 next-buffer 的调用中保持不变。

特别是,这些命令将避免在侧窗口中显示以前未在该窗口中显示的缓冲区。 他们还将避免让正常的非侧窗口显示已在侧窗口中显示的缓冲区。 当应用程序在显示缓冲区后重置该缓冲区的局部变量时,会出现后一条规则的一个显着例外。 要覆盖这些规则并始终使用 quit-window 或 kill-buffer 删除侧窗口,并最终阻止使用 previous-buffer 和 next-buffer,请将此值设置为 t 或通过 display-buffer-mark-dedicated 指定一个值.

如果为两个或多个不同的缓冲区指定同一侧的同一插槽,则最后显示的缓冲区将显示在相应的窗口中。 因此,槽可用于在缓冲区之间共享相同的侧窗。

此函数安装 window-side 和 window-slot 参数(请参阅 Window 参数)并使它们持久化。 它不会安装任何其他窗口参数,除非它们已通过 alist 中的窗口参数条目明确提供。

默认情况下,无法通过拆分窗口拆分侧窗(请参阅拆分窗口)。 此外,任何缓冲区显示操作都不会重用或拆分侧窗(请参阅缓冲区显示的操作函数),除非它被明确指定为该操作的目标。 另请注意,delete-other-windows 不能使侧窗成为其框架上的唯一窗口(请参阅删除窗口)。

29.17.2 侧窗选项和功能

以下选项提供了对侧窗位置的额外控制。

User Option: window-sides-vertical ¶

如果非零,则框架左侧和右侧的侧窗占据框架的全高。 否则,框架顶部和底部的侧窗将占据框架的整个宽度。

User Option: window-sides-slots ¶

此选项指定框架每一侧的最大侧窗数量。 该值是一个由四个元素组成的列表,用于指定(按此顺序)每个框架的左侧、顶部、右侧和底部的侧窗插槽数。 如果一个元素是一个数字,则意味着在对应的一侧最多显示多少个窗口。 如果元素为 nil,则表示该侧的插槽数没有限制。

如果任何指定的值为零,则不能在相应的一侧创建窗口。 在这种情况下,display-buffer-in-side-window 不会发出错误信号,但会返回 nil。 如果指定的值只是禁止创建额外的侧窗,则重用该侧最合适的窗口,并且可能会相应地更改其 window-slot 参数。

User Option: window-sides-reversed ¶

此选项指定顶部/底部窗口是否应以相反的顺序显示。 当它为 nil 时,框架顶部和底部的侧窗总是从左到右绘制,并且槽值增加。 当这是 t 时,绘制顺序颠倒,框架顶部和底部的侧窗从右到左绘制,槽值增加。

当这是双向时,当且仅当双向段落方向(请参阅双向显示)的值在此主窗口区域内最近选择的窗口中显示的缓冲区中从右到左时,绘制顺序才会反转框架。 有时该窗口可能很难找到,因此使用启发式方法来避免在选择另一个窗口时无意中更改绘图顺序。

框架左侧或右侧的侧窗布局不受此变量值的影响。

当框架有侧窗时,以下函数返回该框架的主窗口。

Function: window-main-window &optional frame ¶

该函数返回指定框架的主窗口。 可选参数框架必须是活动框架,并且默认为选定的框架。

如果框架没有侧窗,则返回框架的根窗口。 否则,它返回一个内部非侧窗口,以便框架上的所有其他非侧窗口从它下降,或者返回框架的单个活动非侧窗口。 请注意,框架的主窗口不能通过 delete-window 删除。

以下命令可以方便地切换指定框架上所有侧窗的外观。

Command: window-toggle-side-windows &optional frame ¶

此命令在指定框架上切换侧窗。 可选参数框架必须是活动框架,并且默认为选定的框架。

如果框架至少有一个侧窗,该命令将框架的根窗口的状态保存在框架的窗口状态框架参数中,然后删除框架上的所有侧窗。

如果框架没有侧窗,但有一个窗口状态参数,则此命令使用该参数的值来恢复框架上的侧窗,而只保留框架的主窗口。

如果框架没有侧窗并且没有找到它的保存状态,则会发出错误信号。

29.17.3 带有侧窗的框架布局

侧窗可用于创建更复杂的框架布局,例如集成开发环境 (IDE) 提供的框架布局。 在这样的布局中,主窗口区域是进行正常编辑活动的地方。 侧窗不是为通常意义上的编辑而设计的。 相反,它们应该显示与当前编辑活动互补的信息,例如文件列表、标签或缓冲区、帮助信息、搜索或 grep 结果或 shell 输出。

这种框架的布局可能如下所示:

 ___________________________________
|          *Buffer List*            |
|___________________________________|
|     |                       |     |
|  *  |                       |  *  |
|  d  |                       |  T  |
|  i  |                       |  a  |
|  r  |   Main Window Area    |  g  |
|  e  |                       |  s  |
|  d  |                       |  *  |
|  *  |                       |     |
|_____|_______________________|_____|
| *help*/*grep*/  |  *shell*/       |
| *Completions*   |  *compilation*  |
|_________________|_________________|
|             Echo Area             |
|___________________________________|

以下示例说明了如何将窗口参数(请参阅窗口参数)与 display-buffer-in-side-window(请参阅在侧窗口中显示缓冲区)一起使用来设置代码以生成上述框架布局。



(defvar parameters
  '(window-parameters . ((no-other-window . t)
			   (no-delete-other-windows . t))))

(setq fit-window-to-buffer-horizontally t)
(setq window-resize-pixelwise t)

(setq
 display-buffer-alist
 `(("\\*Buffer List\\*" display-buffer-in-side-window
    (side . top) (slot . 0) (window-height . fit-window-to-buffer)
    (preserve-size . (nil . t)) ,parameters)
   ("\\*Tags List\\*" display-buffer-in-side-window
    (side . right) (slot . 0) (window-width . fit-window-to-buffer)
    (preserve-size . (t . nil)) ,parameters)
   ("\\*\\(?:help\\|grep\\|Completions\\)\\*"
    display-buffer-in-side-window
    (side . bottom) (slot . -1) (preserve-size . (nil . t))
    ,parameters)
   ("\\*\\(?:shell\\|compilation\\)\\*" display-buffer-in-side-window
    (side . bottom) (slot . 1) (preserve-size . (nil . t))
    ,parameters)))

这为具有固定名称的缓冲区指定了 display-buffer-alist 条目(请参阅选择用于显示缓冲区的窗口)。 特别是,它要求在框架顶部显示高度可调的 Buffer List*,在框架右侧显示宽度可调的 *Tags List*。 它还要求 *help*、*grepCompletions 缓冲区在框架的左下方共享一个窗口,并且 shellcompilation 缓冲区出现在​​框架右下方的窗口中框架。

请注意,选项 fit-window-to-buffer-horizo​​ntally 必须具有非零值才能允许水平调整窗口。 还添加了要求保留框架顶部和底部的侧窗高度以及框架左侧或右侧的侧窗宽度的条目。 为了确保在最大化帧时侧窗保持其各自的大小,变量 window-resize-pixelwise 设置为非零值。 请参阅调整窗口大小。

最后一种形式还通过为每个窗口安装 no-other-window 参数来确保通过 Cx o 无法访问任何已创建的侧窗口。 此外,它通过为每个窗口安装 no-delete-other-windows 参数来确保不会通过 Cx 1 删除侧窗口。

由于 dired 缓冲区没有固定名称,我们使用特殊函数 dired-default-directory-on-left 来在框架左侧显示精简目录缓冲区。

(defun dired-default-directory-on-left ()
  "Display `default-directory' in side window on left, hiding details."
  (interactive)
  (let ((buffer (dired-noselect default-directory)))
    (with-current-buffer buffer (dired-hide-details-mode t))
    (display-buffer-in-side-window
     buffer `((side . left) (slot . 0)
		(window-width . fit-window-to-buffer)
		(preserve-size . (t . nil)) ,parameters))))

评估前面的表单并按任意顺序键入 Mx list-buffers、Ch f、Mx shell、Mx list-tags 和 Mx dired-default-directory-on-left 现在应该重现上面勾勒的框架布局。

29.18 原子窗口

原子窗口是至少两个活动窗口的矩形组合。 它们具有以下显着特征:

函数 split-window(请参阅拆分窗口)在应用于原子窗口的组成部分时,将尝试在原子窗口之外创建新窗口。 函数 delete-window(请参阅删除窗口)在应用于原子窗口的组成部分时,将尝试删除整个原子窗口。 函数 delete-other-windows(请参阅删除窗口)在应用于原子窗口的组成部分时,将尝试使原子窗口填充其框架或主窗口(请参阅侧窗口)。

这意味着改变窗口结构的基本函数组将原子窗口视为活窗口,从而保留原子窗口的内部结构。

原子窗口有助于构建和保留仅当所有涉及的缓冲区以特定方式同时显示时才有意义的窗口布局,例如显示文件修订之间的差异,或不同语言或标记的相同文本时。 它们还可用于永久显示与特定窗口相关的信息,并在该窗口两侧的条形图中显示。

原子窗口是在保留的窗口原子窗口参数(参见窗口参数)和一个称为原子窗口根窗口的内部窗口(参见 Emacs Windows 的基本概念)的帮助下实现的。 属于同一原子窗口的所有窗口都将此根窗口作为它们的共同祖先,并分配有一个非零窗口原子参数。

以下函数返回指定窗口所属的原子窗口的根:

Function: window-atom-root &optional window ¶

这个函数返回原子窗口的根窗口是窗口的一部分。 指定的窗口必须是有效的窗口,并且默认为选定的窗口。 如果窗口不是原子窗口的一部分,则返回 nil。

制作新原子窗口的最简单方法是采用现有的内部窗口并应用以下函数:

Function: window-make-atom window ¶

此函数将窗口转换为原子窗口。 指定的窗口必须是内部窗口。 这个函数所做的只是将window的每个后代的window-atom参数设置为t。

要从现有的实时窗口创建新的原子窗口或将新窗口添加到现有的原子窗口,可以使用以下缓冲区显示操作函数(请参阅缓冲区显示的操作函数):

Function: display-buffer-in-atom-window buffer alist ¶

此函数尝试在新窗口中显示缓冲区,该新窗口将与现有窗口组合形成一个原子窗口。 如果现有窗口已经是原子窗口的一部分,它会将新窗口添加到该原子窗口。

指定的 alist 是符号和值的关联列表。 以下符号具有特殊含义:

window

这样一个元素的值指定了新窗口应与之组合的现有窗口。 如果它指定了一个内部窗口,那么该窗口的所有子窗口也将成为原子窗口的一部分。 如果未指定窗口,则新窗口将成为选定窗口的同级窗口。 如果窗口是活动的并且它的窗口原子参数尚未设置,则现有窗口的窗口原子参数设置为 main。

side

这种元素的值表示新窗口应位于的现有窗口的一侧。 有效值是下、右、上和左。 默认值如下。 新窗口的 window-atom 参数设置为此值。

返回值为新窗口,创建该窗口失败时返回 nil。

请注意,window-atom 参数的值并不重要,只要它不是 nil 即可。 display-buffer-in-atom-window 分配的值只允许在应用该函数后轻松检索原始窗口和新窗口。 另请注意,window-atom 参数是 display-buffer-in-atom-window 分配的唯一窗口参数。 应用程序必须通过 alist 中的窗口参数条目显式设置更多参数。

当其组成部分之一被删除时,原子窗口将自动不存在。 要手动分解原子窗口,请重置其组成部分的 window-atom 参数 - 原子窗口的根及其所有后代。

以下代码片段在应用于单窗口框架时,首先拆分选定的窗口,并使选定的窗口和新窗口组成原子窗口,其父窗口为根。 然后它将缓冲区 Messages 显示在框架底部的新窗口中,并使该新窗口成为刚刚创建的原子窗口的一部分。

(let ((window (split-window-right)))
  (window-make-atom (window-parent window))
  (display-buffer-in-atom-window
   (get-buffer-create "*Messages*")
   `((window . ,(window-parent window)) (window-height . 5))))

此时在该框架的任何窗口中键入 Cx 2 都会在框架底部生成一个新窗口。 相反,键入 Cx 3 会将新窗口放在框架的右侧。 在任何一种情况下,现在在原子窗口的任何窗口中键入 Cx 1 都只会删除新窗口。 在原子窗口的任何窗口中键入 Cx 0 将使新窗口填满框架。

29.19 窗口和点

每个窗口都有自己的点值(请参阅点),与显示相同缓冲区的其他窗口中的点值无关。 这使得让多个窗口显示一个缓冲区很有用。

窗口点是在第一次创建窗口时建立的; 它从缓冲区的点初始化,或者如果存在这样的窗口,则从缓冲区上打开的另一个窗口的窗口点初始化。 选择一个窗口会根据窗口的点值设置其缓冲区中的点值。 相反,取消选择窗口会将窗口的点值设置为缓冲区的值。 因此,当您在显示给定缓冲区的窗口之间切换时,所选窗口的点值在缓冲区中有效,而其他窗口的点值存储在这些窗口中。 只要选中的窗口显示当前缓冲区,窗口的点和缓冲区的点总是一起移动; 他们保持平等。

默认情况下,Emacs 将光标显示为一个矩形块,在每个窗口中该窗口点的位置。 当用户切换到窗口中的另一个缓冲区时,Emacs 将该窗口的光标移动到该缓冲区中的点。 如果点的确切位置隐藏在某个显示元素之后,例如显示字符串或图像,Emacs 会在该显示元素之前或之后立即显示光标。

Function: window-point &optional window ¶

此函数返回窗口中点的当前位置。 对于未选择的窗口,如果选择了该窗口,这是(在该窗口的缓冲区中)的值点。 窗口的默认值是选定的窗口。

当 window 为选中窗口时,返回的值为该窗口缓冲区中的 point 值。 严格来说,在任何保存-游览形式之外返回点的顶级值会更正确。 但这个价值很难找到。

Function: set-window-point window position ¶

此函数将窗口中的点定位在窗口缓冲区中的位置位置。 它返回位置。

如果选择了窗口,这只是在窗口的缓冲区中执行 goto-char 。

Variable: window-point-insertion-type ¶

此变量指定窗口点的标记插入类型(请参阅标记插入类型)。 默认值为 nil,因此窗口点将停留在插入的文本后面。

29.20 窗口开始和结束位置

每个窗口都维护一个标记,用于跟踪缓冲区位置,该位置指定缓冲区显示应从何处开始。 这个位置称为窗口的显示开始位置(或只​​是开始)。 此位置之后的字符是出现在窗口左上角的字符。 它通常但并非不可避免地位于文本行的开头。

在切换窗口或缓冲区之后,以及在某些其他情况下,如果窗口开始位于行的中间,Emacs 会将窗口开始调整到行的开头。 这可以防止某些操作使窗口从一行中的无意义点开始。 此功能可能会干扰使用 Lisp 模式的命令执行某些 Lisp 代码来测试它,因为它们会触发这种重新调整。 要测试此类代码,请将其放入命令并将命令绑​​定到键。

Function: window-start &optional window ¶

该函数返回窗口窗口的显示开始位置。 如果 window 为 nil,则使用选定的窗口。

当您创建一个窗口或在其中显示不同的缓冲区时,显示开始位置设置为最近用于同一缓冲区的显示开始位置,或者如果缓冲区没有任何缓冲区,则设置为 point-min。

重新显示会更新窗口起始位置(如果自上次重新显示后您没有明确指定它)— 以确保点出现在屏幕上。 除了重新显示之外,没有什么会自动更改窗口开始位置; 如果您移动点,请不要期望窗口开始位置会在下一次重新显示之前响应更改。

Function: window-group-start &optional window ¶

这个函数和window-start类似,只是当window是一组窗口的一部分时(见Window Group),window-group-start返回整个组的起始位置。 当缓冲区局部变量 window-group-start-function 设置为函数时,此条件成立。 在这种情况下,window-group-start 使用单个参数 window 调用该函数,然后返回其结果。

Function: window-end &optional window update ¶

此函数返回其缓冲区显示在窗口中结束的位置。 窗口的默认值是选定的窗口。

简单地更改缓冲区文本或移动点不会更新 window-end 返回的值。 仅当 Emacs 重新显示并且重新显示完成而不被抢占时,才会更新该值。

如果最后一次重新显示窗口被抢占,并且没有完成,Emacs 不知道显示结束在该窗口中的位置。 在这种情况下,此函数返回 nil。

如果 update 不为零,则 window-end 始终根据当前 window-start 值返回显示结束位置的最新值。 如果先前保存的该位置的值仍然有效,则 window-end 返回该值; 否则它通过扫描缓冲区文本来计算正确的值。

即使更新不为零,如果点已移出屏幕,window-end 也不会尝试滚动显示,就像真正的重新显示一样。 它不会改变窗口开始值。 实际上,如果不需要滚动,它会报告显示的文本将在哪里结束。 请注意,它返回的位置可能只是部分可见。

Function: window-group-end &optional window update ¶

此函数与 window-end 类似,不同之处在于当 window 是一组窗口的一部分时(参见 Window Group),window-group-end 返回整个组的结束位置。 当缓冲区局部变量 window-group-end-function 设置为函数时,此条件成立。 在这种情况下,window-group-end 使用两个参数 window 和 update 调用该函数,然后返回其结果。 参数 update 与 window-end 中的含义相同。

Function: set-window-start window position &optional noforce ¶

此函数将窗口的显示开始位置设置为窗口缓冲区中的位置。 它返回位置。

显示例程坚持在显示缓冲区时点的位置是可见的。 通常,他们根据其内部逻辑选择显示开始位置(并在必要时滚动窗口)以使点可见。 但是,如果您使用 nil 为 noforce 指定此函数的开始位置,则意味着您希望显示从位置开始,即使这会使点的位置远离屏幕。 如果这确实将点放置在屏幕外,则显示例程会尝试将点移动到窗口中线的左边距。

例如,如果 point 为 1 并且您将窗口的起点设置为 37,则下一行的起点将位于窗口顶部的上方。 重新显示时显示程序会自动移动点,如果它仍然是 1。 这是一个例子:



    ;; Here is what ‘foo’ looks like before executing
    ;;   the set-window-start expression.


    ---------- Buffer: foo ----------
    ∗This is the contents of buffer foo.
    2
    3
    4
    5
    6
    ---------- Buffer: foo ----------


    (set-window-start
     (selected-window)
     (save-excursion
	 (goto-char 1)
	 (forward-line 1)
	 (point)))
    ⇒ 37


    ;; Here is what ‘foo’ looks like after executing
    ;;   the set-window-start expression.
    ---------- Buffer: foo ----------
    2
    3
    ∗4
    5
    6
    ---------- Buffer: foo ----------

如果尝试使点可见(即,在完全可见的屏幕行中)失败,则显示例程将忽略请求的窗口开始位置并无论如何计算一个新位置。 因此,为了获得可靠的结果,调用此函数的 Lisp 程序应该总是将点移动到显示开始于位置的窗口内。

如果 noforce 不为零,并且 position 将在下一次重新显示时将点置于屏幕外,则重新显示会计算一个新的窗口开始位置,该位置与点配合得很好,因此不使用位置。

Function: set-window-group-start window position &optional noforce ¶

这个函数和 set-window-start 类似,只是当 window 是一组窗口的一部分时(参见 Window Group),set-window-group-start 设置整个组的开始位置。 当缓冲区局部变量 set-window-group-start-function 设置为函数时,此条件成立。 在这种情况下,set-window-group-start 使用三个参数 window、position 和 noforce 调用该函数,然后返回其结果。 此函数中的参数 position 和 noforce 与 set-window-start 中的含义相同。

Function: pos-visible-in-window-p &optional position window partially ¶

如果位置在 window 屏幕上当前可见的文本范围内,则此函数返回非 nil。 如果位置垂直滚动到视图之外,则返回 nil。 除非部分为非零,否则部分被遮挡的位置不被视为可见。 参数位置默认为窗口中点的当前位置; 窗口默认为选定的窗口。 如果位置是 t,这意味着检查窗口中最后一个屏幕行的第一个可见位置,或缓冲区结束位置,以先到者为准。

此函数仅考虑垂直滚动。 如果仅因为窗口已水平滚动而无法查看位置,则 pos-visible-in-window-p 无论如何都会返回非零。 请参阅水平滚动。

如果位置可见,则 pos-visible-in-window-p 如果部分为 nil,则返回 t; 如果 partial 为非 nil,并且跟随位置的字符完全可见,则返回 (xy) 形式的列表,其中 x 和 y 是相对于窗口左上角的像素坐标; 否则返回格式为 (xy rtop rbot rowh vpos) 的扩展列表,其中 rtop 和 rbot 指定位置所在行的顶部和底部的窗口外像素数,rowh 指定该行的可见高度,以及vpos 指定该行的垂直位置(从零开始的行号)。

这是一个例子:

   ;; If point is off the screen now, recenter it now.
   (or (pos-visible-in-window-p
	   (point) (selected-window))
	  (recenter 0))
Function: pos-visible-in-window-group-p &optional position window partially ¶

这个函数和 pos-visible-in-window-p 类似,只是当 window 是一组窗口的一部分时(参见 Window Group),pos-visible-in-window-group-p 测试 pos 在整个组,而不仅仅是在单个窗口中。 当缓冲区局部变量 pos-visible-in-window-group-p-function 设置为函数时,此条件成立。 在这种情况下,pos-visible-in-window-group-p 使用三个参数位置、窗口和部分调用函数,然后返回其结果。 参数 position 和 partial 与 pos-visible-in-window-p 中的含义相同。

Function: window-line-height &optional line window ¶

该函数返回窗口中文本行的高度。 如果 line 是 header-line 或 mode-line 之一,则 window-line-height 返回有关窗口相应行的信息。 否则,line 是从 0 开始的文本行号。负数从窗口末尾开始计数。 line 的默认值是 window 中的当前行; 窗口的默认值是选定的窗口。

如果显示不是最新的,window-line-height 返回 nil。 在这种情况下,可以使用 pos-visible-in-window-p 来获取相关信息。

如果没有与指定行对应的行,则 window-line-height 返回 nil。 否则,它返回一个列表(height vpos ypos offbot),其中 height 是行的可见部分的高度(以像素为单位),vpos 和 ypos 是行的垂直位置和行的像素相对于第一个文本的顶部行,offbot 是文本行底部的窗口外像素数。 如果(第一)文本行顶部有窗口外像素,则 ypos 为负。

29.21 文本滚动

文本滚动意味着在窗口中上下移动文本。 它通过更改窗口的显示开始位置来工作。 它还可以更改 window-point 的值以保持屏幕上的点(请参阅 Windows 和点)。

基本的文本滚动功能是向上滚动(向前滚动)和向下滚动(向后滚动)。 在这些函数名称中,“向上”和“向下”指的是缓冲区文本相对于窗口的运动方向。 想象一下,文本写在一长卷纸上,滚动命令使纸上下移动。 因此,如果您正在查看缓冲区的中间并反复调用向下滚动,您最终会看到缓冲区的开头。

不幸的是,这有时会引起混乱,因为有些人倾向于按照相反的约定来思考:他们想象窗口在保留在原处的文本上移动,因此“向下”命令会将您带到缓冲区的末尾。 这个约定与这样一个命令绑定到现代键盘上名为 PageDown 的键的事实是一致的。

如果当前缓冲区不是所选窗口中显示的缓冲区,则文本滚动函数(除了 scroll-other-window 之外)会产生不可预知的结果。 请参阅当前缓冲区。

如果窗口包含比窗口高度高的行(例如存在大图像时),滚动函数将调整窗口的垂直滚动位置以滚动部分可见的行。 Lisp 调用者可以通过将变量 auto-window-vscroll 绑定到 nil 来禁用此功能(请参阅垂直分数滚动)。

Command: scroll-up &optional count ¶

此功能在所选窗口中按计数行向前滚动。

如果 count 是负数,它会向后滚动。 如果 count 为 nil(或省略),则滚动的距离为 next-screen-context-lines lines 小于窗口主体的高度。

如果所选窗口不能再滚动,此函数会发出错误信号。 否则,它返回零。

Command: scroll-down &optional count ¶

此功能在所选窗口中向后滚动计数行。

如果 count 是负数,它会向前滚动。 在其他方面,它的行为方式与向上滚动相同。

Command: scroll-up-command &optional count ¶

这类似于向上滚动,除了如果所选窗口不能再滚动并且变量 scroll-error-top-bottom 的值为 t,它会尝试移动到缓冲区的末尾。 如果点已经存在,则表示错误。

Command: scroll-down-command &optional count ¶

这类似于向下滚动,除了如果所选窗口不能再滚动并且变量 scroll-error-top-bottom 的值为 t,它会尝试移动到缓冲区的开头。 如果点已经存在,则表示错误。

Command: scroll-other-window &optional count ¶

此函数将另一个窗口中的文本向上滚动计数行。 count 的负值或 nil 的处理方式与向上滚动相同。

您可以通过将变量 other-window-scroll-buffer 设置为缓冲区来指定要滚动的缓冲区。 如果该缓冲区尚未显示,则 scroll-other-window 将其显示在某个窗口中。

When the selected window is the minibuffer, the next window is normally the leftmost one immediately above it. You can specify a different window to scroll, when the minibuffer is selected, by setting the variable minibuffer-scroll-window. This variable has no effect when any other window is selected. 当它为非 nil 并且选择了 minibuffer 时,它优先于 other-window-scroll-buffer。 请参阅 minibuffer-scroll-window 的定义。

Command: scroll-other-window-down &optional count ¶

此函数将另一个窗口中的文本向下滚动数行。 count 的负值或 nil 的处理方式与向下滚动相同。 在其他方面,它的行为方式与 scroll-other-window 相同。

Variable: other-window-scroll-buffer ¶

如果这个变量是非零,它告诉 scroll-other-window 要滚动哪个缓冲区的窗口。

User Option: scroll-margin ¶

此选项指定滚动边距的大小——点与窗口顶部或底部之间的最小行数。 每当点进入窗口顶部或底部的这么多行时,重新显示会自动滚动文本(如果可能)以将点移出边缘,更靠近窗口的中心。

User Option: maximum-scroll-margin ¶

此变量将滚动边距的有效值限制为当前窗口行高的一小部分。 例如,如果当前窗口有 20 行且最大滚动边距为 0.1,则滚动边距永远不会大于 2 行,无论滚动边距有多大。

maximum-scroll-margin 本身的最大值为 0.5,这允许设置较大的边距以将光标保持在窗口的中间线(如果窗口的行数为偶数,则为两条中间线)。 如果将其设置为更大的值(或除介于 0.0 和 0.5 之间的浮点数以外的任何值),则将使用默认值 0.25。

User Option: scroll-conservatively ¶

此变量控制当点移出屏幕(或进入滚动边距)时如何自动滚动。 如果该值为正整数 n,则 redisplay 会在任一方向上滚动文本最多 n 行,如果这将使 point 回到正确的视图中。 这种行为称为保守滚动。 否则,滚动以通常的方式发生,在其他变量的控制下,例如积极向上滚动和积极向下滚动。

默认值为零,这意味着保守滚动永远不会发生。

User Option: scroll-down-aggressively ¶

此变量的值应为 nil 或介于 0 和 1 之间的分数 f。如果是分数,则指定向下滚动时在屏幕上放置点的位置。 更准确地说,当一个窗口向下滚动时,因为点在窗口开始上方,新的开始位置被选择为将点 f 从顶部放置窗口高度的一部分。 f 越大,滚动越激进。

nil 的值相当于 0.5,因为它的作用是指向中心点。 当以任何方式设置时,此变量会自动变为缓冲区本地。

User Option: scroll-up-aggressively ¶

同样,用于向上滚动。 值 f 指定点应放置在距窗口底部多远的位置; 因此,与scroll-down-aggressively 一样,较大的值会更积极地滚动。

User Option: scroll-step ¶

此变量是滚动保守的旧变体。 不同之处在于,如果它的值为 n,则只允许滚动精确的 n 行,而不是更小的数字。 此功能不适用于滚动边距。 默认值为零。

User Option: scroll-preserve-screen-position ¶

如果此选项为 t,则每当滚动命令将点移出窗口时,Emacs 都会尝试调整点以将光标保持在窗口中的旧垂直位置,而不是窗口边缘。

如果值不是 nil 而不是 t,Emacs 会调整 point 以使光标保持在相同的垂直位置,即使滚动命令没有将 point 移出窗口。

此选项影响所有具有非零滚动命令符号属性的滚动命令。

User Option: next-screen-context-lines ¶

此变量的值是全屏滚动时要保留的连续行数。 例如,使用 nil 参数向上滚动滚动,以便窗口底部的这么多行出现在顶部而不是顶部。 默认值为 2。

User Option: scroll-error-top-bottom ¶

如果此选项为 nil(默认值),scroll-up-command 和 scroll-down-command 只会在无法再滚动时发出错误信号。

如果值为 t,这些命令将移动指向缓冲区的开头或结尾(取决于滚动方向); 只有当点已经在那个位置时,它们才会发出错误信号。

Command: recenter &optional count redisplay ¶

此函数滚动选定窗口中的文本,以便点显示在窗口内指定的垂直位置。 它不会相对于文本移动点。

如果 count 是非负数,则将包含点计数行的行从窗口顶部向下放置。 如果 count 是负数,则从窗口底部向上计数,因此 -1 代表窗口中最后一个可用行。

如果 count 为 nil(或非 nil 列表),则 centerer 将包含点的行放在窗口的中间。 如果count为nil且redisplay为非nil,该函数可能会根据recenter-redisplay的值重绘帧。 因此,省略第二个参数可用于抵消最近重新显示为非零的效果。 交互式调用传递非“零”以重新显示。

当以交互方式调用 centerer 时,count 是原始前缀参数。 因此,输入 Cu 作为前缀会将 count 设置为非 nil 列表,而输入 Cu 4 会将 count 设置为 4,这会将当前行定位为距顶部四行。

使用零参数,recenterer 将当前行定位在窗口的顶部。 命令 centerer-top-bottom 提供了一种更方便的方法来实现这一点。

Function: recenter-window-group &optional count ¶

此功能就像最近一样,只是当所选窗口是一组窗口的一部分(请参阅窗口组)时,近来的窗口组将整个组滚动。 当缓冲区局部变量 centerer-window-group-function 设置为函数时,此条件成立。 在这种情况下,recenter-window-group 使用参数 count 调用该函数,然后返回其结果。 参数计数与最近的含义相同,但与整个窗口组有关。

User Option: recenter-redisplay ¶

如果此变量不为 nil,则使用 nil count 参数和非 nil redisplay 参数调用 centerer 会重绘帧。 默认值为 tty,这意味着只有当它是一个 tty 帧时才重绘该帧。

Command: recenter-top-bottom &optional count ¶

此命令是 Cl 的默认绑定,它的作用类似于重新定位器,除非在不带参数的情况下调用。 在这种情况下,连续调用将根据变量recenter-positions 定义的循环顺序放置点。

User Option: recenter-positions ¶

此变量控制无参数调用时,recenter-top-bottom 的行为方式。 默认值为 (middle top bottom),表示在将点放置在窗口的中间、顶部和底部之间时,连续调用无参数循环的 centerer-top-bottom。

29.22 垂直小数滚动

垂直小数滚动意味着将窗口中的文本向上或向下移动指定的倍数或行的分数。 例如,Emacs 在比窗口高的图像和屏幕行上使用它。 每个窗口都有一个垂直滚动位置,它是一个数字,从不小于零。 它指定在显示窗口内容时将其提升多远。 提高窗口内容通常会使某些行的全部或部分从顶部消失,而其他某些行的全部或部分会出现在底部。 通常的值为零。

垂直滚动位置以正常行高为单位,即默认字体的高度。 因此,如果值为 .5,则意味着窗口内容将向上滚动到正常行高的一半。 如果它是 3.3,则意味着窗口内容向上滚动到正常行高的三倍以上。

垂直滚动覆盖一行的哪一部分,或多少行,取决于这些行包含什么。 0.5 的值可以滚动一条高度非常短的线离开屏幕,而 3.3 的值可以只滚动一条高线或图像的一部分。

Function: window-vscroll &optional window pixels-p ¶

该函数返回当前窗口的垂直滚动位置。 窗口的默认值是选定的窗口。 如果pixels-p 不为零,则返回值以像素为单位,而不是以法线高度为单位。

  (window-vscroll)
	   ⇒ 0
Function: set-window-vscroll window lines &optional pixels-p ¶

此函数将窗口的垂直滚动位置设置为行。 如果 window 为 nil,则使用选定的窗口。 参数行应该为零或正数; 如果不是,则将其视为零。

实际的垂直滚动位置必须始终对应于整数个像素,因此您指定的值会相应地四舍五入。

返回值是此四舍五入的结果。

  (set-window-vscroll (selected-window) 1.2)
	   ⇒ 1.13

如果pixels-p 不为零,则lines 指定像素数。 在这种情况下,返回值是行。

Variable: auto-window-vscroll ¶

如果此变量不为 nil,则 line-move、scroll-up 和 scroll-down 函数将自动修改垂直滚动位置以滚动显示高于窗口高度的行,例如在存在大图像。

29.23 水平滚动

水平滚动意味着将窗口中的图像向左或向右移动正常字符宽度的指定倍数。 每个窗口都有一个水平滚动位置,它是一个数字,从不小于零。 它指定将内容向左移动多远。 将窗口内容向左移动通常会使某些字符的全部或部分从左侧消失,而某些其他字符的全部或部分则出现在右侧。 通常的值为零。

水平滚动位置以正常字符宽度为单位测量,即默认字体中的空间宽度。 因此,如果值为 5,则意味着窗口内容向左滚动正常字符宽度的 5 倍。 有多少字符实际上消失在左侧取决于它们的宽度,并且可能因行而异。

因为我们在内循环中从一边到另一边阅读,在外循环中从上到下阅读,水平滚动的效果不像文本或垂直滚动​​。 文本滚动涉及选择要显示的部分文本,垂直滚动会连续移动窗口内容; 但是水平滚动会导致每行的一部分离开屏幕。

通常,没有水平滚动生效; 那么最左边的列位于窗口的左边缘。 在这种状态下,向右滚动是没有意义的,因为边缘左侧没有数据可以显示; 所以这是不允许的。 允许向左滚动; 它将第一列文本滚动到窗口边缘,并可以在右侧显示之前被截断的其他列。 一旦一个窗口有一个非零的向左水平滚动量,您可以将它滚动回右边,但只能将净水平滚动减少到零。 您可以向左滚动多远没有限制,但最终所有文本都会从左边缘消失。

如果设置了 auto-hscroll-mode,redisplay 会根据需要自动更改窗口的水平滚动,以确保该点始终可见。 但是,您仍然可以显式设置水平滚动值。 您指定的值用作自动滚动的下限,即自动滚动不会将窗口滚动到小于指定列的列。

auto-hscroll-mode 的默认值为 t; 将其设置为 current-line 会激活自动水平滚动的一种变体,其中仅显示光标的行水平滚动以使点可见,窗口的其余部分要么未滚动,要么处于由 scroll-left 设置的最小滚动量和向右滚动,见下文。

Command: scroll-left &optional count set-minimum ¶

此函数将选定的窗口计数列向左滚动(如果计数为负数,则向右滚动)。 count 的默认值是窗口宽度,负 2。

返回值是更改后有效的向左水平滚动的总量——就像 window-hscroll 返回的值(如下)。

请注意,基本方向为从右到左的段落中的文本(请参阅双向显示)以相反的方向移动:例如,当使用正值 count 调用向左滚动时,它会向右移动。

一旦您将窗口尽可能向右滚动,回到其向左滚动总量为零的正常位置,尝试再向右滚动将无效。

如果 set-minimum 不为零,则新的滚动量成为自动滚动的下限; 也就是说,自动滚动不会将窗口滚动到小于此函数返回值的列。 交互式调用通过非零设置最小值。

Command: scroll-right &optional count set-minimum ¶

此函数将选定的窗口计数列向右滚动(如果计数为负数,则向左滚动)。 count 的默认值是窗口宽度,减 2。除了滚动方向之外,这就像向左滚动一样。

Function: window-hscroll &optional window ¶

此函数返回窗口的总向左水平滚动——窗口中的文本向左滚动超过左边距的列数。 (在从右到左的段落中,该值是向右滚动的总量。) window 的默认值是选定的窗口。

返回值永远不会是负数。 当窗口中没有进行水平滚动时(通常是这种情况),它为零。



  (window-hscroll)
	   ⇒ 0

  (scroll-left 5)
	   ⇒ 5

  (window-hscroll)
	   ⇒ 5
Function: set-window-hscroll window columns ¶

该函数设置窗口的水平滚动。 columns 的值指定滚动量,以从左边距(从右到左段落中的右边距)为单位的列。 参数列应为零或正数; 如果不是,则将其视为零。 目前不支持列的小数值。

请注意,如果您通过使用 M-: 以简单的方式评估调用来测试 set-window-hscroll,它可能看起来不起作用。 发生的情况是该函数设置水平滚动值并返回,但随后重新显示调整水平滚动以使点可见,这会覆盖函数所做的。 如果在 point 距离左边距足够远以保持可见的情况下调用它,您可以观察到该函数的效果。

返回的值是列。

  (set-window-hscroll (selected-window) 10)
	   ⇒ 10

以下是如何确定给定位置位置是否由于水平滚动而不在屏幕上:

(defun hscroll-on-screen (window position)
  (save-excursion
    (goto-char position)
    (and
     (>= (- (current-column) (window-hscroll window)) 0)
     (< (- (current-column) (window-hscroll window))
	  (window-width window)))))

29.24 坐标和窗口

本节介绍报告窗口位置和窗口内的函数。 大多数这些函数报告相对于窗口框架的原始位置的原点的位置(请参阅框架几何)。 一些函数报告相对于窗口框架显示原点的位置。 在任何情况下,原点都有坐标 (0, 0),X 和 Y 坐标分别向右和向下增加。

对于以下函数,X 和 Y 坐标以整数字符单位报告,即分别为行数和列数。 在图形显示上,每个“行”和“列”对应于由框架的默认字体指定的默认字符的高度和宽度(请参阅框架字体)。

Function: window-edges &optional window body absolute pixelwise ¶

此函数返回窗口边缘坐标的列表。 如果 window 被省略或为零,则默认为选定的窗口。

返回值的形式为(左上右下)。 这些列表元素分别是窗口占据的最左边一列的X坐标、最顶行的Y坐标、最右边一列的X坐标、最底下一行的Y坐标排。

请注意,这些是窗口的实际外边缘,包括它的任何装饰。 在文本终端上,如果窗口右侧有邻居,则其右边缘包括窗口与其邻居之间的分隔线。

如果可选参数 body 为 nil,这意味着返回对应于窗口总大小的边。 body non-nil 表示返回窗口主体的边缘。 如果 body 不为零,则 window 必须指定一个活动窗口。

如果可选参数 absolute 为 nil,这意味着返回相对于窗口框架的原始位置的边。 absolute 非 nil 表示返回相对于窗口显示原点 (0, 0) 的坐标。 在非图形系统上,此参数无效。

如果可选参数 pixelwise 为 nil,这意味着根据窗口框架的默认字符宽度和高度(请参阅框架字体)返回坐标,必要时进行四舍五入。 pixelwise non-nil 表示以像素为单位返回坐标。 请注意,由 right 和 bottom 指定的像素就在这些边缘之外。 如果 absolute 为非 nil,则 pixelwise 也隐式为非 nil。

Function: window-body-edges &optional window ¶

此函数返回窗口主体的边缘(请参阅窗口大小)。 调用 (window-body-edges window) 等价于调用 (window-edges window t),见上文。

以下函数可用于将一组相对于框架的坐标与窗口相关联:

Function: window-at x y &optional frame ¶

此函数返回坐标 x 和 y 处的实时窗口,坐标为默认字符大小(请参阅帧字体)相对于帧的原始位置(请参阅帧几何)。

如果该位置没有窗口,则返回值为 nil。 如果 frame 被省略或为零,则默认为选定的框架。

Function: coordinates-in-window-p coordinates window ¶

该函数检查一个窗口窗口是否占据了框架的相对坐标坐标,如果是,则占据了窗口的哪一部分。 窗口应该是一个活动窗口。

坐标应该是 (x . y) 形式的 cons 单元格,其中 x 和 y 以相对于窗口框架的原始位置(参见框架几何)的默认字符大小(参见框架字体)给出。

如果指定位置没有窗口,则返回值为 nil 。 否则,返回值为以下之一:

(relx . rely)

坐标在窗口内。 数字 relx 和 trust 是指定位置的等效窗口相对坐标,从窗口左上角的 0 开始计数。

mode-line

坐标在窗口的模式行中。

header-line

坐标在窗口的标题行中。

tab-line

坐标在窗口的标签行中。

right-divider

坐标位于分隔窗口与右侧窗口的分隔符中。

bottom-divider

坐标位于分隔窗口和下方窗口的分隔线中。

vertical-line

坐标位于窗口与其右侧邻居之间的垂直线上。 仅当窗口没有滚动条时才会出现此值; 出于这些目的,滚动条中的位置被考虑在窗口之外。

left-fringe
right-fringe

坐标位于窗口的左边缘或右边缘。

left-margin
right-margin

坐标位于窗口的左边距或右边距。

nil

坐标不在窗口的任何部分。

函数 coordinate-in-window-p 不需要框架作为参数,因为它总是使用窗口所在的框架。

以下函数以像素而不是字符单位返回窗口位置。 虽然在图形显示上最有用,但它们也可以在文本终端上调用,其中每个文本字符的屏幕区域被视为一个像素。

Function: window-pixel-edges &optional window ¶

此函数返回窗口边缘的像素坐标列表。 调用 (window-pixel-edges window) 等价于调用 (window-edges window nil nil t),见上文。

Function: window-body-pixel-edges &optional window ¶

此函数返回窗口主体的像素边缘。 调用 (window-body-pixel-edges window) 等价于调用 (window-edges window t nil t),见上文。

以下函数以像素为单位返回窗口位置,相对于显示屏的原点而不是框架的原点:

Function: window-absolute-pixel-edges &optional window ¶

此函数返回窗口相对于窗口框架显示的原点 (0, 0) 的像素坐标。 调用 (window-absolute-pixel-edges) 等效于调用 (window-edges window nil tt),见上文。

Function: window-absolute-body-pixel-edges &optional window ¶

此函数返回窗口主体相对于窗口框架显示的原点 (0, 0) 的像素坐标。 调用 (window-absolute-body-pixel-edges window) 等价于调用 (window-edges window ttt),见上文。

结合 set-mouse-absolute-pixel-position,该函数可用于将鼠标指针移动到某个窗口中可见的任意缓冲区位置:

     (let ((edges (window-absolute-body-pixel-edges))
	    (position (pos-visible-in-window-p nil nil t)))
	(set-mouse-absolute-pixel-position
	 (+ (nth 0 edges) (nth 0 position))
	 (+ (nth 1 edges) (nth 1 position))))

在图形终端上,此表单将鼠标光标“扭曲”到所选窗口点处字形的左上角。 以这种方式计算的位置也可用于在此处显示工具提示窗口。

以下函数返回窗口中可见的缓冲区位置的屏幕坐标:

Function: window-absolute-pixel-position &optional position window ¶

如果缓冲区位置位置在窗口窗口中可见,则此函数返回字形在位置的上/左角的显示坐标。 返回值是该角的 X 坐标和 Y 坐标的 cons,相对于窗口显示的 (0, 0) 处的原点。 如果位置在窗口中不可见,则返回 nil。

window 必须是活动窗口,并且默认为选定的窗口。 position 默认为 window 的 window-point 的值。

这意味着为了将鼠标指针移动到所选窗口中点的位置,编写以下内容就足够了:

     (let ((position (window-absolute-pixel-position)))
	(set-mouse-absolute-pixel-position
	 (car position) (cdr position)))

以下函数返回可以在窗口中内接而不覆盖该窗口中显示的文本的最大矩形。

Function: window-largest-empty-rectangle &optional window count min-width min-height positions left ¶

此函数计算可以在指定窗口的文本区域中内接的最大空矩形的尺寸。 window 必须是活动窗口,并且默认为选定的窗口。

返回值是窗口文本区域的空白空间(不显示任何文本的空间)中最大矩形的宽度和开始和结束 y 坐标的三倍。 此函数不返回 x 坐标——任何此类矩形都假定在窗口文本区域的右边缘结束。 如果找不到空格,则返回值为 nil。

可选参数计数,如果非零,则指定要返回的最大矩形数。 这意味着返回值是一个三元组列表,指定矩形的最大矩形在前。 count 也可以是一个 cons 单元格,其 car 指定要返回的矩形数量,并且其 CDR(如果非零)表示返回的所有矩形必须是不相交的。

可选参数 min-width 和 min-height,如果非零,则指定返回的任何矩形的最小宽度和高度。

可选参数位置,如果非零,是一个 cons 单元格,其 CAR 指定最上方,其 CDR 指定必须由返回的任何矩形覆盖的最低像素位置。 这些位置从窗口的文本区域开始测量。

可选参数 left,如果非 nil,则表示返回适用于从右到左显示文本的缓冲区的值。 在这种情况下,假定返回的任何矩形都从窗口文本区域的左边缘开始。

请注意,此函数必须通过 window-lines-pixel-dimensions 检索窗口字形矩阵的每一行的尺寸(请参阅显示文本的大小)。 因此,当窗口的当前字形矩阵不是最新的时,此函数也可能返回 nil。

29.25 鼠标窗口自动选择

以下选项允许自动选择鼠标指针下的窗口。 这实现了类似于窗口管理器的策略,只要鼠标指针进入其窗口系统窗口(请参阅输入焦点),就会将焦点赋予框架(并因此触发其后续选择)。

User Option: mouse-autoselect-window ¶

如果这个变量不为 nil,Emacs 将尝试自动选择鼠标指针下的窗口。 以下值是有意义的:

一个正数

这指定了以秒为单位的延迟,之后自动选择触发。 在鼠标停留在整个延迟期间后,鼠标指针下方的窗口被选中。 一个负数

负数具有与正数类似的效果,但只有在鼠标指针停留在该数字的绝对值的整个持续时间内并且停止移动之后,才会选择鼠标指针下方的窗口。 其他价值

任何其他非 nil 值意味着鼠标指针进入时立即选择一个窗口。

在任何一种情况下,鼠标指针都必须进入窗口的文本区域才能触发其选择。 从概念上讲,拖动滚动条滑块或窗口的模式线不应导致其自动选择。

鼠标自动选择仅在 minibuffer 窗口处于活动状态时选择它,并且永远不会取消选择活动的 minibuffer 窗口。

鼠标自动选择可用于模拟窗口管理器通常不跟踪的子框架的焦点跟随鼠标策略(请参阅子框架)。 这需要将 focus-follows-mouse 的值(请参阅输入焦点)设置为非零值。 如果 focus-follows-mouse 的值是 auto-raise,则使用鼠标进入子框架将自动将其提升到该框架的父框架的所有其他子框架之上。

29.26 窗口配置

一个窗口配置记录了一帧的整个布局——所有窗口,它们的大小,它们的装饰,它们包含哪些缓冲区,这些缓冲区是如何滚动的,以及它们的点值,它还包括 minibuffer-scroll-window 的值。 作为一个特殊的例外,窗口配置不会为当前缓冲区记录所选窗口中的点值。

您可以通过恢复以前保存的窗口配置来恢复整个框架布局。 如果要记录所有框架的布局而不是只记录一个,请使用框架配置而不是窗口配置。 请参阅框架配置。

Function: current-window-configuration &optional frame ¶

此函数返回一个表示框架当前窗口配置的新对象。 框架的默认值是选定的框架。 变量 window-persistent-parameters 指定此函数保存哪些窗口参数(如果有)。 请参见窗口参数。

Function: set-window-configuration configuration &optional dont-set-frame dont-set-miniwindow ¶

此函数恢复配置指定的窗口和缓冲区的配置,对于为其创建配置的框架,无论是否选择了该框架。 参数配置必须是先前由当前窗口配置为该帧返回的值。 通常该函数也会选择配置中记录的帧,但如果 dont-set-frame 为非零,它会保留在函数开始时已选择的帧。

通常,该函数会恢复保存的 minibuffer(如果有),但如果 dont-set-miniwindow 为非 nil,则函数开始时的 minibuffer 当前(如果有)仍保留在 mini-window 中。

如果保存配置的帧已死,则此函数所做的只是恢复变量 minibuffer-scroll-window 的值并调整 minibuffer-selected-window 返回的值。 在这种情况下,函数返回 nil。 否则,它返回 t。

如果配置窗口的缓冲区在配置完成后已被终止,则该窗口通常会从恢复的配置中删除。 但是,如果该窗口是恢复配置中剩余的最后一个窗口,则会在其中显示另一个实时缓冲区。

这是使用此函数获得与 save-window-excursion 相同效果的一种方法:

     (let ((config (current-window-configuration)))
	(unwind-protect
	    (progn (split-window-below nil)
		   …)
	  (set-window-configuration config)))
Macro: save-window-excursion forms… ¶

该宏记录选中框架的窗口配置,依次执行窗体,然后恢复之前的窗口配置。 返回值是表单中最终表单的值。

大多数 Lisp 代码不应该使用这个宏; save-selected-window 通常就足够了。 特别是,这个宏不能可靠地阻止表单中的代码打开新窗口,因为新窗口可能会在其他框架中打开(请参阅选择用于显示缓冲区的窗口),并且 save-window-excursion 仅保存和恢复窗口配置在当前帧上。

Function: window-configuration-p object ¶

如果对象是窗口配置,则此函数返回 t。

Function: compare-window-configurations config1 config2 ¶

这个函数在窗口结构方面比较两个窗口配置,但忽略点的值和保存的滚动位置——即使这些方面不同,它也可以返回 t。

Function: window-configuration-frame config ¶

此函数返回为其进行窗口配置配置的框架。

查看窗口配置内部的其他原语是有意义的,但没有实现,因为我们不需要它们。 有关 Windows 配置的更多操作,请参见文件 winner.el。

current-window-configuration 返回的对象与 Emacs 进程一起死亡。 为了将窗口配置存储在磁盘上并在另一个 Emacs 会话中读回,您可以使用接下来描述的功能。 这些函数也可用于将帧的状态克隆到任意实时窗口(set-window-configuration 有效地将帧的窗口克隆到该帧的根窗口)。

Function: window-state-get &optional window writable ¶

此函数将窗口的状态作为 Lisp 对象返回。 参数窗口必须是有效窗口,并且默认为所选框架的根窗口。

如果可选参数 writable 为非零,这意味着不使用标记来采样位置,如窗口点或窗口开始。 当状态将被写入磁盘并在另一个会话中读回时,此参数应为非零。

参数 writable 和变量 window-persistent-parameters 一起指定此函数保存哪些窗口参数。 请参见窗口参数。

window-state-get 返回的值可以在同一个会话中用于在另一个窗口中克隆一个窗口。 它也可以写入磁盘并在另一个会话中读回。 无论哪种情况,都可以使用以下函数来恢复窗口的状态。

Function: window-state-put state &optional window ignore ¶

该函数将窗口状态状态放入窗口。 参数 state 应该是由较早的 window-state-get 调用返回的窗口的状态,见上文。 可选参数窗口可以是实时窗口或内部窗口(请参阅窗口和框架)。 如果 window 不是实时窗口,则在将状态放入其中之前,它会被在同一帧上创建的新实时窗口替换。 如果 window 为 nil,它将窗口状态放入一个新窗口。

如果可选参数 ignore 不为 nil,则意味着忽略最小窗口大小和固定大小限制。 如果忽略是安全的,这意味着窗口可以小到一行和/或两列。

函数 window-state-get 和 window-state-put 还允许交换两个活动窗口的内容。 以下函数正是这样做的:

Command: window-swap-states &optional window-1 window-2 size ¶

此命令交换两个活动窗口 window-1 和 window-2 的状态。 window-1 必须指定一个活动窗口并默认为选定的窗口。 window-2 必须指定一个活动窗口,并且默认为在窗口的循环排序中跟随 window-1 的窗口,不包括 minibuffer 窗口并包括所有可见帧上的活动窗口。

可选参数大小非零意味着尝试交换窗口 1 和窗口 2 的大小。 height 值表示仅交换高度,width 值表示仅交换宽度,而 t 表示尽可能交换宽度和高度。 此功能不会调整框架的大小。

29.27 窗口参数

本节介绍可用于将附加信息与窗口相关联的窗口参数。

功能:window-parameter窗口参数¶

此函数返回窗口的参数值。 窗口的默认值是选定的窗口。 如果 window 没有设置参数,这个函数返回 nil。

Function: window-parameter window parameter ¶

此函数返回窗口的所有参数及其值。 窗口的默认值是选定的窗口。 返回值要么是 nil,要么是一个关联列表,其元素的形式为(参数 .value)。

Function: window-parameters &optional window ¶

该函数将窗口的参数值设置为值并返回值。 窗口的默认值是选定的窗口。

Function: set-window-parameter window parameter value ¶
Variable: window-persistent-parameters ¶

此变量是一个列表,指定哪些参数由 current-window-configuration 和 window-state-get 保存,随后由 set-window-configuration 和 window-state-put 恢复。 请参阅窗口配置。

此列表的每个条目的 CAR 是指定参数的符号。 CDR 应为以下之一:

该值表示该参数既不是由 window-state-get 也不是由 current-window-configuration 保存。 吨

此值指定参数由 current-window-configuration 保存,并且(如果其可写参数为 nil)由 window-state-get 保存。 可写

这意味着参数被当前窗口配置和窗口状态获取无条件地保存。 此值不应用于其值没有读取语法的参数。 否则,在另一个会话中调用 window-state-put 可能会因无效读取语法错误而失败。

某些函数(特别是 delete-window、delete-other-windows 和 split-window)可能会在其 window 参数指定的窗口具有名称与函数名称相同的参数时表现特殊。 您可以通过将以下变量绑定到非零值来覆盖此类特殊行为:

Variable: ignore-window-parameters ¶

如果此变量不为 nil,则某些标准函数不会处理窗口参数。 目前受此影响的功能是 split-window、delete-window、delete-other-windows 和 other-window。

应用程序可以在调用这些函数时将此变量绑定到一个非零值。 如果这样做,应用程序将完全负责在退出该功能时正确分配所有相关窗口的参数。

窗口管理代码当前使用以下参数:

delete-window ¶

此参数影响 delete-window 的执行(请参阅删除窗口)。

delete-other-windows ¶

此参数影响 delete-other-windows 的执行(请参阅删除 Windows)。

no-delete-other-windows ¶

此参数将窗口标记为不可被 delete-other-windows 删除(请参阅删除窗口)。

split-window ¶

此参数影响拆分窗口的执行(请参阅拆分窗口)。

other-window ¶

该参数影响 other-window 的执行(参见 Cyclic Ordering of Windows)。

no-other-window ¶

此参数将窗口标记为其他窗口不可选择(请参阅窗口的循环排序)。

clone-of ¶

此参数指定从中克隆该窗口的窗口。 它由 window-state-get 安装(请参阅窗口配置)。

window-preserved-size ¶

此参数指定缓冲区、nil 表示垂直和 t 水平的方向以及以像素为单位的大小。 如果这个窗口显示指定的缓冲区并且它在指定方向上的大小等于这个参数指定的大小,那么 Emacs 将尝试在指定方向上保持这个窗口的大小。 此参数由函数 window-preserve-size 安装和更新(请参阅保留窗口大小)。

quit-restore ¶

此参数由缓冲区显示函数安装(请参阅选择用于显示缓冲区的窗口)并由 quit-restore-window 查询(请参阅退出窗口)。 它是一个由四个元素组成的列表,详细信息请参见退出 Windows 中的 quit-restore-window 描述。

window-side ¶
window-slot

这些参数在内部用于实现侧窗(请参阅侧窗)。

window-atom ¶

此参数在内部用于实现原子窗口,请参阅原子窗口。

mode-line-format ¶

每当显示此窗口时,此参数都会替换此窗口缓冲区的缓冲区局部变量 mode-line-format(请参阅模式行基础)的值。 符号 none 表示禁止显示此窗口的模式行。 显示此缓冲区的其他窗口上的模式行的显示和内容不受影响。

header-line-format ¶

每当显示此窗口时,此参数都会替换此窗口缓冲区的缓冲区局部变量 header-line-format(请参阅模式行基础)的值。 符号 none 表示禁止显示此窗口的标题行。 显示此缓冲区的其他窗口上的标题行的显示和内容不受影响。

tab-line-format ¶

每当显示此窗口时,此参数都会替换此窗口缓冲区的缓冲区局部变量 tab-line-format(请参阅模式行基础)的值。 符号 none 表示禁止显示此窗口的制表符行。 显示此缓冲区的其他窗口上的选项卡行的显示和内容不受影响。

min-margins ¶

此参数的值是一个 cons 单元格,其 CAR 和 CDR,如果非零,则指定此窗口左右边距的最小值(以列为单位)(请参阅在边距中显示。当存在时,Emacs 将使用这些值而不是实际的边距宽度,用于确定窗口是否可以水平拆分或缩小。

Emacs 在拆分或调整大小后从不自动调整任何窗口的边距。 任何应用程序设置此参数来调整此窗口的边距以及由于拆分而​​继承此窗口边距的任何新窗口的边距是所有应用程序的唯一责任。 应为此目的使用 window-configuration-change-hook 和 window-size-change-functions (请参阅 Hooks for Window Scrolling and Changes)。

此参数是在 Emacs 版本 25.1 中引入的,以支持使用大边距在窗口中居中缓冲文本的应用程序,并且应谨慎使用这些应用程序。 在 Emacs 的未来版本中,它可能会被改进的解决方案所取代。

29.28 窗口滚动和改变的钩子

本节描述 Lisp 程序如何在窗口滚动或发生其他窗口修改后采取行动。 我们首先考虑窗口显示其缓冲区的不同部分的情况。

Variable: window-scroll-functions ¶

这个变量保存了 Emacs 在重新显示带有滚动的窗口之前应该调用的函数列表。 在窗口中显示不同的缓冲区并创建新窗口也调用这些函数。

这个变量不是一个普通的钩子,因为每个函数都用两个参数调用:窗口和它的新显示开始位置。 在调用的时候,参数窗口的显示开始位置已经被设置为它的新值,并且要在窗口中显示的缓冲区被设置为当前缓冲区。

这些函数在使用 window-end 时必须小心(参见窗口开始和结束位置); 如果你需要一个最新的值,你必须使用 update 参数来确保你得到它。

警告:不要使用此功能来改变窗口的滚动方式。 它不是为此而设计的,这样的使用可能行不通。

此外,您可以使用 jit-lock-register 注册一个 Font Lock 字体化函数,该函数将在缓冲区的某些部分因窗口滚动或大小更改而被(重新)字体化时调用。 请参阅其他字体锁定变量。

本节的其余部分涵盖了在重新显示期间调用的六个挂钩,前提是已检测到窗口的显着非滚动更改。 为简单起见,这些钩子及其调用的函数将统称为窗口更改函数。 与任何钩子一样,这些钩子可以在安装钩子时通过 add-hook 的本地参数(请参阅设置钩子)全局或本地缓冲区设置。

这些钩子中的第一个在检测到窗口缓冲区更改后运行,这意味着创建、删除或分配了另一个缓冲区的窗口。

Variable: window-buffer-change-functions ¶

此变量指定在窗口缓冲区更改时重新显示期间调用的函数。 该值应该是一个接受一个参数的函数列表。

如果自上次运行窗口更改函数以来已创建或分配该缓冲区,则为显示相应缓冲区的任何窗口调用本地指定缓冲区的函数。 在这种情况下,窗口作为参数传递。

如果自上次运行窗口更改函数以来已添加、删除或分配了另一个缓冲区,则为该帧调用由默认值指定的函数。 在这种情况下,框架作为参数传递。

当检测到窗口大小发生变化时,将运行第二个钩子,这意味着创建了一个窗口,分配了另一个缓冲区,或者改变了它的总大小或其文本区域的大小。

Variable: window-size-change-functions ¶

此变量指定在发生窗口大小更改时重新显示期间调用的函数。 该值应该是一个接受一个参数的函数列表。

如果自上次运行窗口更改函数以来已添加或分配另一个缓冲区或更改了其总大小或主体大小,则为显示相应缓冲区的任何窗口调用本地指定缓冲区的函数。 在这种情况下,窗口作为参数传递。

如果自上次运行窗口更改函数以来已添加或分配了另一个缓冲区或更改了其总大小或主体大小,则为该帧调用由默认值指定的函数。 在这种情况下,框架作为参数传递。

当窗口选择更改自上次重新显示后选择了另一个窗口时,将运行这些钩子中的第三个。

Variable: window-selection-change-functions ¶

此变量指定在选定窗口或框架的选定窗口发生更改时重新显示期间调用的函数。 该值应该是一个接受一个参数的函数列表。

如果自上次运行窗口更改函数以来已选择或取消选择该窗口(在所有窗口中或在其框架上的所有窗口中),则为显示相应缓冲区的任何窗口调用本地指定缓冲区的函数。 在这种情况下,窗口作为参数传递。

如果该框架已被选择或取消选择,或者自上次运行窗口更改函数以来该框架的选定窗口已更改,则为该框架调用由默认值指定的函数。 在这种情况下,框架作为参数传递。

这些钩子中的第四个在检测到窗口状态更改时运行,这意味着至少发生了前面三个窗口更改中的一个。

Variable: window-state-change-functions ¶

此变量指定在重新显示期间在发生窗口缓冲区或大小更改或选定窗口或框架的选定窗口已更改时调用的函数。 该值应该是一个接受一个参数的函数列表。

如果该窗口已添加或分配另一个缓冲区、更改其总大小或主体大小或已选择或取消选择(在所有窗口中或在其框架上的所有窗口中),则为显示相应缓冲区的任何窗口调用本地指定缓冲区的函数上次运行窗口更改功能。 在这种情况下,窗口作为参数传递。

如果该框架上的至少一个窗口已添加、删除或分配另一个缓冲区、更改其总大小或主体大小、或该框架已被选择或取消选择或该框架的选定窗口已更改,则为该框架调用由默认值指定的函数自上次运行窗口更改功能以来。 在这种情况下,框架作为参数传递。

当自上次重新显示以来已设置该帧的窗口状态更改标志(见下文)时,默认值指定的函数也会为该帧运行。

当检测到窗口配置更改时运行这些钩子中的第五个,这意味着缓冲区或窗口大小发生了变化。 它与前面四个钩子的不同之处在于它的运行方式。

Variable: window-configuration-change-hook ¶

此变量指定在缓冲区或窗口大小发生更改时重新显示期间调用的函数。 该值应该是不带参数的函数列表。

如果自上次运行窗口更改函数以来,该帧上的至少一个窗口已添加、删除或分配另一个缓冲区或更改了其总大小或主体大小,则为显示相应缓冲区的任何窗口调用本地指定缓冲区的函数。 每次调用都使用显示临时选择的缓冲区及其当前缓冲区的窗口来执行。

如果自上次运行窗口更改函数以来已添加、删除或分配另一个缓冲区或更改了其总大小或主体大小,则为每一帧调用由默认值指定的函数。 每次调用都是在临时选定的帧和当前选定窗口的缓冲区中执行的。

最后,Emacs 运行一个普通的钩子来概括窗口状态更改函数的行为。

Variable: window-state-change-hook ¶

此变量的默认值指定在检测到窗口状态更改或已在至少一帧上设置了窗口状态更改标志时在重新显示期间调用的函数。 该值应该是不带参数的函数列表。

只有当应用程序想要对自上次重新显示以来发生在(或已发出信号)两个或多个帧上的更改做出反应时,应用程序才应在此挂钩上放置一个函数。 在所有其他情况下,应该首选将函数放在窗口状态更改函数上。

在每帧重新显示期间调用窗口改变函数如下:首先,按此顺序调用任何缓冲区局部窗口缓冲区改变函数、窗口大小改变函数、选定窗口改变和窗口状态改变函数。 接下来,以相同的顺序调用这些函数的默认值。 然后调用任何缓冲区本地窗口配置更改函数,然后调用这些函数的默认值指定的函数。 最后,运行 window-state-change-hook 上的函数。

仅当先前为该帧注册了相应的更改时,才会为特定帧运行窗口更改函数。 此类更改包括创建或删除窗口或将另一个缓冲区或大小分配给窗口。 请注意,即使已注册此类更改,这也不意味着运行上述任何挂钩。 例如,如果在窗口偏移范围内注册了更改(请参阅窗口配置),则只有在运行更改函数时该偏移仍然存在时,才会触发窗口更改函数的调用。 如果它提前退出,则只有在该偏移范围之外的更改注册时才会运行挂钩。

框架的窗口状态更改标志,如果设置,将导致窗口状态更改函数的默认值(对于该框架)和窗口状态更改挂钩在下一次重新显示期间运行,无论窗口状态是否该帧是否实际发生了变化。 在这些钩子上运行任何函数后,将为每一帧重置标志。 应用程序可以使用以下函数设置该标志并检查其值。

Function: set-frame-window-state-change &optional frame arg ¶

如果 arg 不为零,则此函数设置框架的窗口状态更改标志,否则将其重置。 frame 必须是实时帧,默认为选定的帧。

Function: frame-window-state-change &optional frame ¶

如果设置了框架的窗口状态更改标志,则此函数返回 t,否则返回 nil。 frame 必须是实时帧,默认为选定的帧。

在运行窗口更改函数时,可以调用接下来描述的函数来更深入地了解自上次重新显示以来特定窗口或框架的更改内容。 所有这些函数都将实时窗口作为单个可选参数,默认为选定窗口。

Function: window-old-buffer &optional window ¶

此函数返回上次窗口更改函数为窗口框架运行时窗口中显示的缓冲区。 如果它返回 nil,则在此之后创建了窗口。 如果它返回 t,则窗口当时未显示,但之后已从先前保存的窗口配置中恢复。 否则,返回值为 window 当时显示的缓冲区。

Function: window-old-pixel-width &optional window ¶

此函数返回窗口的总像素宽度,最后一次窗口更改函数在其框架上找到窗口。 如果在此之后创建窗口,则为零。

Function: window-old-pixel-height &optional window ¶

此函数返回最后一次窗口更改函数在其框架上发现窗口时窗口的总像素高度。 如果在此之后创建窗口,则为零。

Function: window-old-body-pixel-width &optional window ¶

此函数返回上次窗口更改函数在其框架上发现窗口时窗口文本区域的像素宽度。 如果在此之后创建窗口,则为零。

Function: window-old-body-pixel-height &optional window ¶

该函数返回上次窗口更改函数在其框架上发现窗口时窗口文本区域的像素高度。 如果在此之后创建窗口,则为零。

为了找出上次运行窗口更改函数时选择了哪个窗口或框架,可以使用以下函数:

Function: frame-old-selected-window &optional frame ¶

此函数返回上次运行窗口更改函数时选定的帧窗口。 如果省略或 nil 框架默认为选定的框架。

Function: old-selected-window ¶

此函数返回上次运行窗口更改函数时选定的窗口。

Function: old-selected-frame ¶

此函数返回上次运行窗口更改函数时选定的帧。

请注意,窗口更改函数不提供有关自上次运行以来已删除哪些窗口的信息。 如有必要,应用程序应记住在该缓冲区的局部变量中显示特定缓冲区的任何窗口,并在检测到窗口缓冲区更改时运行的任何挂钩的默认值运行的函数中更新它。

向窗口更改函数添加函数时应考虑以下注意事项:

某些操作不会触发窗口更改函数的调用。 这些包括在 minibuffer 窗口中显示另一个缓冲区或工具提示窗口的任何更改。 窗口更改函数不应创建或删除窗口或更改任何窗口的缓冲区、大小或选择状态,因为无法保证有关此类更改的信息将传播到其他窗口更改函数。 如果有的话,任何此类更改都应仅由 window-state-change-hook 的默认值列出的最后一个函数执行。 运行窗口更改函数时,可以使用诸如 save-window-excursion、with-selected-window 或 with-current-buffer 之类的宏。 运行窗口更改函数不会保存和恢复匹配数据。 除非运行 window-configuration-change-hook 它不会保存或恢复选定的窗口或框架或当前缓冲区。 可能会中止任何触发窗口更改功能运行的重新显示。 如果中止发生在窗口更改函数运行完成之前,它们将使用以前的值再次运行,也就是说,就好像没有执行重新显示一样。 如果稍后中止,它们将使用新值运行,也就是说,就像实际执行了重新显示一样。

马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/rookieagle/elisp.git
git@gitee.com:rookieagle/elisp.git
rookieagle
elisp
Elisp
main

搜索帮助