other-buffer 函数在作为需要缓冲区参数的函数的参数使用时,实际上会提供一个缓冲区。我们可以通过将 other-buffer 和 switch-to-buffer 配合使用来切换到不同缓冲区,以此观察其作用。
不过,先简要介绍一下 switch-to-buffer 函数。你之前在 Info 和 *scratch* 缓冲区之间来回切换以求值 (buffer-name) 时,很可能是在迷你缓冲区提示输入要切换的缓冲区名称时,输入了 C-x b,然后输入 *scratch*。7 按键 C-x b 会让 Lisp 解释器对交互式函数 switch-to-buffer 求值。如前所述,Emacs 就是这样工作的:不同的按键会调用或运行不同的函数。例如,C-f 调用 forward-char,M-e 调用 forward-sentence,等等。
通过在表达式中编写 switch-to-buffer 并为其提供要切换到的缓冲区,我们可以像使用 C-x b 那样切换缓冲区:
(switch-to-buffer (other-buffer))
符号 switch-to-buffer 是列表的第一个元素,因此 Lisp 解释器会将其视为函数并执行它所绑定的指令。但在执行之前,解释器会注意到 other-buffer 位于括号内,因此先处理该符号。other-buffer 是这个列表的第一个(在本例中也是唯一的)元素,所以 Lisp 解释器会调用或运行该函数,返回另一个缓冲区。接着,解释器运行 switch-to-buffer,将另一个缓冲区作为参数传递给它,这就是 Emacs 将要切换到的目标。如果你正在 Info 中阅读本文,现在可以试试这个。求值该表达式。(要返回,输入 C-x b RET。)8
在本文档后续章节的编程示例中,你会看到函数 set-buffer 比 switch-to-buffer 更常用。这是因为计算机程序和人类之间存在一个差异:人类有眼睛,希望在计算机终端上看到正在处理的缓冲区。这是显而易见的。然而,程序没有眼睛。当计算机程序处理一个缓冲区时,该缓冲区不需要在屏幕上可见。
switch-to-buffer 是为人类设计的,它做两件不同的事:切换 Emacs 关注的缓冲区;并将窗口中显示的缓冲区切换为新缓冲区。另一方面,set-buffer 只做一件事:切换计算机程序关注的缓冲区。屏幕上的缓冲区保持不变(当然,通常在命令运行完成之前,屏幕上不会有任何变化)。
此外,我们刚刚介绍了另一个专业术语:调用(call)。当你对一个列表求值,且该列表的第一个符号是函数时,你就是在调用这个函数。该术语源自“函数是一个可被调用的实体,能为你完成某些任务”的概念 — 就像水管工是一个可被你呼叫来修理漏水的实体。
或者,为了少输入一些字符,如果默认缓冲区就是 *scratch*,你可能只输入了 RET;如果不是,你可能只输入了名称的一部分,比如 *sc,然后按 TAB 键将其补全为完整名称,再输入 RET。
记住,这个表达式会将你切换到最近的、你看不到的另一个缓冲区。如果你真的想切换到最近选择的缓冲区,即使它仍然可见,你需要求值以下更复杂的表达式:
(switch-to-buffer (other-buffer (current-buffer) t))
在这种情况下,other-buffer 的第一个参数指定要跳过的缓冲区 — 即当前缓冲区;第二个参数告诉 other-buffer,可以切换到可见的缓冲区。在常规使用中,switch-to-buffer 会将你带到窗口中不可见的缓冲区,因为你通常会使用 C-x o(other-window)来切换到其他可见的缓冲区。