43.2.2 挂起 Emacs

在文本终端上,可以 挂起 Emacs(suspend Emacs), 即暂时停止 Emacs 并将控制权交还给上级进程(通常是 Shell)。 这让你可以稍后在同一个 Emacs 进程中恢复编辑, 保留所有缓冲区、剪切板环、撤销历史等状态。 要恢复 Emacs,需在父 Shell 中执行对应命令—最常见的是 fg

挂起操作仅对启动 Emacs 会话的终端设备有效, 我们将该设备称为该会话的 控制终端(controlling terminal)。 如果控制终端是图形化终端,则不允许挂起。 挂起在图形环境中通常没有意义,因为你可以直接切换应用,无需对 Emacs 做特殊处理。

部分操作系统(不支持 SIGTSTP 的系统或 MS-DOS)不支持任务挂起; 在这类系统上,挂起操作实际上会临时创建一个新 Shell 作为 Emacs 的子进程, 之后退出该 Shell 即可返回 Emacs。

Command: suspend-emacs &optional string

该函数暂停 Emacs 并将控制权交还给上级进程。 当上级进程恢复 Emacs 时,suspend-emacs 会向 Lisp 调用者返回 nil

该函数仅对 Emacs 会话的控制终端生效; 若要放弃对其他 tty 设备的控制,请使用 suspend-tty(见下文)。 如果 Emacs 会话使用多个终端,必须先删除其他所有终端上的 框架 才能挂起 Emacs, 否则该函数会抛出错误。See 多终端

如果 string 为非 nil,其字符会被发送给 Emacs 的上级 Shell, 作为终端输入被读取。

挂起前,suspend-emacs 会运行常规钩子 suspend-hook。 用户恢复 Emacs 后,会运行常规钩子 suspend-resume-hook。See 钩子

除非变量 no-redraw-on-reenter 为非 nil, 否则恢复后的第一次刷新会重绘整个屏幕。See 刷新屏幕

以下是使用这些钩子的示例:

(add-hook 'suspend-hook
          (lambda () (or (y-or-n-p "Really suspend?")
                         (error "Suspend canceled"))))
(add-hook 'suspend-resume-hook (lambda () (message "Resumed!")
                                 (sit-for 2)))

Here is what you would see upon evaluating (suspend-emacs "pwd"):

---------- Buffer: Minibuffer ----------
Really suspend? y
---------- Buffer: Minibuffer ----------

---------- Parent Shell ----------
bash$ pwd
/home/username
bash$ fg

---------- Echo Area ----------
Resumed!

注意,在部分操作系统中,向父 Shell 发送 string 可能需要特殊权限, 此时可能会静默失败。在另一些系统中该功能不受支持,尝试使用会抛出错误。 此外,即使 string 被 Shell 执行,也可能不会回显。 因此不建议在可移植 Lisp 程序中依赖该特性。

Variable: suspend-hook

该变量是一个常规钩子,Emacs 在挂起前运行。

Variable: suspend-resume-hook

该变量是一个常规钩子,Emacs 在挂起后恢复时运行。

Function: suspend-tty &optional tty

如果 tty 指定了 Emacs 使用的某个终端设备, 该函数会释放该设备并恢复其之前的状态。 使用该设备的 框架 会继续存在,但不会刷新,Emacs 也不再从中读取输入。 tty 可以是终端对象、某个 框架(表示该框架对应的终端), 或 nil(表示当前选中框架对应的终端)。See 多终端

如果 tty 已被挂起,该函数不执行任何操作。

该函数会运行钩子 suspend-tty-functions, 并将终端对象作为参数传递给每个函数。

Function: resume-tty &optional tty

该函数恢复之前被挂起的终端设备 ttytty 的可选取值与 suspend-tty 一致。

该函数会重新打开终端设备、重新初始化,并使用该终端的选中框架重绘界面。 随后运行钩子 resume-tty-functions, 并将终端对象作为参数传递给每个函数。

如果同一设备已被另一个 Emacs 终端使用,该函数会抛出错误。 如果 tty 未被挂起,该函数不执行任何操作。

Function: controlling-tty-p &optional tty

如果 tty 是 Emacs 会话的控制终端,该函数返回非 niltty 可以是终端对象、某个 框架,或 nil

Command: suspend-frame

该命令会 挂起(suspends) 一个 框架。 对于 GUI 框架,它会调用 iconify-frame(see 框架的可见性); 对于文本终端上的框架,则根据该框架是否显示在控制终端设备上, 调用 suspend-emacssuspend-tty