29.13.2 缓冲区显示动作函数

一个 动作函数(action function)display-buffer 调用的、用于选择窗口以显示缓冲区的函数。动作函数接受两个参数:buffer,即要显示的缓冲区,以及 alist,即一个动作关联列表 (see 缓冲区显示动作关联列表)。它们在成功时应返回一个显示 buffer 的窗口,失败时返回 nil

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

Function: display-buffer-same-window buffer alist

该函数尝试在选中窗口中显示 buffer。 如果选中窗口是迷你缓冲区窗口,或专用于另一个缓冲区 (see 专用窗口),则失败。 如果 alist 中存在非 nilinhibit-same-window 条目,也会失败。

Function: display-buffer-reuse-window buffer alist

该函数通过查找已在显示 buffer 的窗口来尝试显示它。 选中框架上的窗口优先于其他框架上的窗口。

如果 alist 中存在非 nilinhibit-same-window 条目,则选中窗口不可被复用。 可通过 reusable-frames 动作关联列表条目指定要搜索的、已显示 buffer 的窗口所在的框架集合。 如果 alist 不含 reusable-frames 条目,该函数仅搜索选中框架。

如果该函数选择了另一个框架上的窗口,会使该框架可见; 除非 alist 包含 inhibit-switch-frame 条目,否则会在需要时将该框架前置。

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

该函数通过查找显示指定主模式下缓冲区的窗口,尝试显示 buffer

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

其行为同样受 alist 中的 inhibit-same-windowreusable-framesinhibit-switch-frame 条目控制,与 display-buffer-reuse-window 一致。

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

该函数通过拆分最大或最近最少使用的窗口(通常在选中框架上)尝试显示 buffer。 它实际通过调用 split-window-preferred-function 指定的函数完成拆分 (see 显示缓冲区的附加选项)。

可通过在 alist 中提供 window-heightwindow-width 条目调整新窗口大小。 如果 alist 包含 preserve-size 条目,Emacs 还会在后续调整大小操作中尝试保留新窗口的尺寸 (see 保留窗口尺寸)。

如果没有窗口可拆分,该函数失败。 这种情况通常是因为没有窗口足够大以允许拆分。 将 split-height-thresholdsplit-width-threshold 设为更小的值可能有所帮助。 当选中框架带有 unsplittable 框架参数时,拆分也会失败;see 缓冲区参数

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

该函数尝试在曾显示过 buffer 的窗口中显示它。

如果 alist 包含非 nilinhibit-same-window 条目,则选中窗口不可使用。 专用窗口仅在已显示 buffer 时才可使用。 如果 alist 包含 previous-window 条目,该条目指定的窗口即使从未显示过 buffer 也可使用。

如果 alist 包含 reusable-frames 条目 (see 缓冲区显示动作关联列表),其值决定搜索哪些框架以寻找合适窗口。 如果 alist 不含 reusable-frames 条目,当 display-buffer-reuse-framespop-up-frames 均为 nil 时,仅搜索选中框架; 任一变量非 nil 时,搜索当前终端上的所有框架。

如果符合规则的可用窗口不止一个,该函数按以下优先级选择:

  • alistprevious-window 指定的窗口,且非选中窗口。
  • 曾显示过 buffer 的窗口,且非选中窗口。
  • 选中窗口,前提是它由 previous-window 指定,或曾显示过 buffer
Function: display-buffer-use-some-window buffer alist

该函数通过选择一个现有窗口并在其中显示缓冲区,尝试显示 buffer。 它首先在 alistlru-frames 指定的任意框架上寻找最近未使用的窗口 (see 窗口循环顺序),无该条目时回退到选中框架。 它优先选择满足 window-min-widthwindow-min-height 约束的窗口; 未找到 window-min-width 条目时,优先选择全宽窗口。 最后,它不会返回使用时间高于 alistlru-time 指定值的窗口。

如果未找到最近最少使用的窗口,该函数会尝试使用其他窗口,优先选择可见框架上的大窗口。 如果所有窗口均专用于其他缓冲区,则可能失败 (see 专用窗口)。

以上为 alistsome-window 条目为 lrunil(默认)时的行为。 另一个可选值为 mru。 例如,若将 display-buffer-base-action 定制为 (nil . ((some-window . mru))), 该函数将优先选择最近最多使用的窗口。 这会使连续调用 display-buffer 时尝试在同一窗口显示多个缓冲区。 设想有三个或更多窗口的布局,用户希望在非选中窗口中依次查看分布在多个缓冲区中的查询结果。 使用 lru 策略时,Emacs 可能不断更换窗口,因为每次调用 display-buffer-use-some-window 都会改变最近最少使用窗口。 使用 mru 策略时,选中窗口始终不变,带来可预测的使用体验。

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

该函数与 display-buffer-use-some-window 类似,但会更严格地避免使用最近使用过的窗口。 特别地,它不会使用选中窗口。 此外,它会首先尝试复用已显示 buffer 的窗口, 仅根据使用时间决定是否使用显示其他缓冲区的窗口, 若无可用窗口则弹出新窗口。

最后,该函数会提升其返回的所有窗口的使用时间 (see 选中窗口), 避免后续调用使用该窗口显示其他缓冲区。 需要连续显示多个缓冲区的应用可在 alist 中提供 lru-time 条目, 将其初始设为选中窗口的使用时间。 每次调用该函数后,返回窗口的使用时间会被提升至高于该值, 后续调用将不会再使用此前返回的窗口。

Function: display-buffer-in-direction buffer alist

该函数尝试在 alist 指定的位置显示 buffer。 为此,alist 应包含 direction 条目,其值为 leftabove(或 up)、rightbelow(或 down)之一。 其他值通常被解释为 below

如果 alist 还包含 window 条目,其值指定一个参考窗口。 该值可以是特殊符号,如 main 代表选中框架的主窗口 (see 侧边窗口选项与函数), 或 root 代表选中框架的根窗口 (see 窗口与框架)。 也可以指定任意有效窗口。 其他值(或完全省略 window 条目)表示使用选中窗口作为参考窗口。

该函数首先尝试复用指定方向上已显示 buffer 的窗口。 若无此窗口,尝试拆分参考窗口以在指定方向创建新窗口。 若仍失败,尝试在指定方向的现有窗口中显示 buffer。 无论哪种情况,选中窗口都会出现在参考窗口的 direction 指定一侧,并与参考窗口共享至少一条边。

如果参考窗口是活动窗口,选中窗口与之共享的边始终与 direction 指定方向相反。 例如,若 direction 值为 left,选中窗口的右边缘坐标 (see 坐标与窗口) 等于参考窗口的左边缘坐标。

如果参考窗口是内部窗口,复用窗口必须与其共享 direction 指定的边。 因此,若参考窗口为框架根窗口且 directionleft,复用窗口必须位于框架左侧。 即选中窗口与参考窗口的左边缘坐标相同。

但新窗口将通过拆分参考窗口创建,使选中窗口与参考窗口共享相反边。 在示例中,会创建新根窗口,子窗口为新活动窗口与原参考窗口。 选中窗口的右边缘坐标等于原参考窗口左边缘坐标, 其左边缘坐标等于框架新根窗口的左边缘坐标。

direction 条目的四个特殊值可隐式将选中框架的主窗口设为参考窗口: leftmosttoprightmostbottom。 这意味着,例如无需写 (direction . left) (window . main), 只需指定 (direction . leftmost)。 此类情况下已存在的 window 条目会被忽略。

Function: display-buffer-below-selected buffer alist

该函数尝试在选中窗口下方的窗口中显示 buffer。 如果选中窗口下方存在窗口且已显示 buffer,则复用该窗口。

若无此窗口,该函数尝试拆分选中窗口创建新窗口并在其中显示 buffer。 如果 alist 包含合适的 window-heightwindow-width 条目,还会尝试调整窗口大小,见上文。

如果拆分选中窗口失败,且选中窗口下方存在显示其他缓冲区的非专用窗口, 该函数会尝试使用该窗口显示 buffer

如果 alist 包含 window-min-height 条目, 该函数确保所用窗口高度至少达到条目值指定的高度。 注意这仅为保证,要实际调整窗口大小,alist 还需提供对应的 window-height 条目。

Function: display-buffer-at-bottom buffer alist

该函数尝试在选中框架底部的窗口中显示 buffer

它会尝试拆分框架底部窗口或框架根窗口, 或复用选中框架底部的现有窗口。

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

该函数创建新框架,并在该框架的窗口中显示缓冲区。 它实际通过调用 pop-up-frame-function 指定的函数完成框架创建 (see 显示缓冲区的附加选项)。 如果 alist 包含 pop-up-frame-parameters 条目,对应值会被添加到新创建框架的参数中。

Function: display-buffer-full-frame buffer alist

该函数在当前框架显示缓冲区,删除所有其他窗口,使其占满整个框架。

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

该函数尝试在选中框架的子框架 (see 子框架) 中显示 buffer, 可复用现有子框架或创建新框架。 如果 alist 包含非 nilchild-frame-parameters 条目, 对应值为新框架的框架参数关联列表。 默认提供指定选中框架的 parent-frame 参数。 如果子框架应作为另一框架的子级,必须向 alist 添加对应条目。

子框架的外观很大程度上取决于通过 alist 提供的参数。 建议至少使用比例指定子框架的大小 (see 尺寸参数) 和位置 (see 位置参数), 并添加 keep-ratio 参数 (see 框架交互参数), 以确保子框架保持可见。 其他需考虑的参数参见 子框架

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

该函数通过寻找满足谓词的框架(默认为除选中框架外的任意框架)尝试显示 buffer

如果该函数选择另一框架上的窗口,会使该框架可见; 除非 alist 包含 inhibit-switch-frame 条目,否则会在需要时将其前置。

如果 alist 包含非 nilframe-predicate 条目, 其值为接受一个参数(框架)的函数,框架为候选时返回非 nil; 该函数替换默认谓词。

如果 alist 包含非 nilinhibit-same-window 条目, 则不使用选中窗口;因此若选中框架仅有一个窗口,该框架不会被使用。

Function: display-buffer-no-window buffer alist

如果 alist 包含非 nilallow-no-window 条目, 该函数不显示 buffer 并返回符号 fail。 这是动作函数要么返回 nil 要么返回显示 buffer 的窗口这一惯例的唯一例外。 如果 alist 不含该 allow-no-window 条目,函数返回 nil

如果该函数返回 faildisplay-buffer 会跳过后续所有显示动作并立即返回 nil。 如果返回 nildisplay-buffer 会继续执行下一个显示动作(如有)。

假定调用 display-buffer 并指定非 nilallow-no-window 条目的代码, 能够处理 nil 返回值。

另外两个动作函数在对应章节描述—display-buffer-in-side-window (see 在侧边窗口中显示缓冲区) 和 display-buffer-in-atom-window (see 原子窗口)。