43.1.1 概述:启动时的操作序列

Emacs 启动时会执行以下操作(参见 startup.el 中的 normal-top-level):

  1. 通过运行列表中每个目录下的 subdirs.el 文件,将子目录添加到 load-path。 通常该文件会将目录的子目录加入列表,并依次扫描。subdirs.el 一般在安装 Emacs 时自动生成。
  2. 加载在 load-path 目录中找到的所有 leim-list.el。该文件用于注册输入法。 搜索仅针对你可能创建的个人 leim-list.el,会跳过包含标准 Emacs 库的目录 (这些目录应仅有一个已编译进 Emacs 可执行文件的 leim-list.el)。
  3. 将变量 before-init-time 设置为 current-time 的值(see 时刻)。 同时将 after-init-time 设为 nil,向 Lisp 程序表明 Emacs 正在初始化。
  4. 根据 LANG 等环境变量的设置,配置语言环境与终端编码系统。
  5. 对命令行参数进行基础解析。
  6. 加载早期初始化文件(see Early Init File in The GNU Emacs Manual)。 若指定了 ‘-q’、‘-Q’ 或 ‘--batch’ 选项,则不执行此步骤。 若指定了 ‘-u’ 选项,Emacs 会在对应用户的家目录中查找初始化文件。
  7. 调用函数 package-activate-all,激活已安装的所有可选 Emacs Lisp 包。see 软件包基础。 但当 package-enable-at-startupnil,或启动时带有 ‘-q’、‘-Q’、‘--batch’ 选项时,Emacs 不会自动激活包。在后一种情况下,需要显式调用 package-activate-all (例如通过 ‘--funcall’ 选项)。
  8. 若未运行在批处理模式下,初始化变量 initial-window-system 指定的窗口系统(see initial-window-system)。 初始化函数 window-system-initialization 是一个 泛型函数(generic function)(see 泛型函数), 对每种支持的窗口系统有不同实现。若 initial-window-system 的值为 windowsystem, 则对应初始化函数的实现位于文件 term/windowsystem-win.el。 该文件在构建 Emacs 时应已编译进可执行文件。
  9. 运行常规钩子 before-init-hook
  10. 在合适的情况下创建图形化框架。创建图形化框架的过程中, 通过调用对应窗口系统的 window-system-initialization 函数, 按照 initial-frame-alistdefault-frame-alist(see 初始框架参数) 初始化该图形化框架。批处理(非交互)或守护进程模式下不执行此步骤。
  11. 初始化初始框架的文本视觉样式,并根据需要设置菜单栏与工具栏。 若支持图形化框架,即使当前框架并非图形化,也会设置工具栏,以备后续可能创建图形化框架。
  12. 使用 custom-reevaluate-setting 重新初始化列表 custom-delayed-init-variables 中的成员。 这些是预加载的用户选项,其默认值依赖运行时环境而非构建时环境。 See custom-initialize-delay.
  13. 若存在则加载 site-start 库。指定 ‘-Q’ 或 ‘--no-site-file’ 选项时不执行。
  14. 加载你的初始化文件(see 初始化文件)。指定 ‘-q’、‘-Q’ 或 ‘--batch’ 选项时不执行。 若指定了 ‘-u’ 选项,Emacs 会在对应用户的家目录中查找初始化文件。
  15. 若存在则加载 default 库。当 inhibit-default-initnil, 或指定了 ‘-q’、‘-Q’、‘--batch’ 选项时不执行。
  16. abbrev-file-name 指定的文件中加载缩写,若该文件存在且可读(see abbrev-file-name)。 指定 ‘--batch’ 选项时不执行。
  17. 将变量 after-init-time 设置为 current-time 的值。 该变量此前设为 nil,设置为当前时间表示初始化阶段结束, 并与 before-init-time 一同用于计算启动耗时。
  18. 运行常规钩子 after-init-hookdelayed-warnings-hook。 后者用于显示启动前期阶段被自动延迟的警告信息。
  19. 若缓冲区 *scratch* 存在且仍为基本模式(默认状态), 根据 initial-major-mode 设置其主模式。
  20. 若在文本终端启动,加载终端专用 Lisp 库(see 终端专用初始化), 并运行钩子 tty-setup-hook--batch 模式或 term-file-prefixnil 时不执行。
  21. 除非使用 inhibit-startup-echo-area-message 禁用,否则显示初始回显区消息。
  22. 处理此前未处理的命令行选项。
  23. 若指定了 --batch 选项,在此处退出。
  24. *scratch* 缓冲区存在且为空,向其中插入 (substitute-command-keys initial-scratch-message)
  25. initial-buffer-choice 为字符串,则打开对应名称的文件(或目录)。 若为函数,则无参调用该函数并选中其返回的缓冲区。 若命令行参数指定了一个文件,则打开该文件并与 initial-buffer-choice 并列显示。 若指定多个文件,则全部打开并将 *Buffer List*initial-buffer-choice 并列显示。
  26. 运行 emacs-startup-hook
  27. 调用 frame-notice-user-settings,根据初始化文件中的设置修改当前选中框架的参数。
  28. 运行 window-setup-hook。该钩子与 emacs-startup-hook 的唯一区别是, 它在框架参数修改完成后运行。
  29. 显示 启动屏幕(startup screen),这是一个特殊缓冲区,包含版权声明与 Emacs 基本使用说明。 若 inhibit-startup-screeninitial-buffer-choicenil, 或指定了 ‘--no-splash’、‘-Q’ 命令行选项,则不显示。
  30. 若请求以守护进程运行,则调用 server-start。 (在 POSIX 系统上,若请求后台守护进程,会与控制终端分离。)See Emacs Server in The GNU Emacs Manual
  31. 若由 X 会话管理器启动,调用 emacs-session-restore 并传入上一会话 ID 作为参数。See Session 会话管理

以下选项会影响启动流程的部分行为。

User Option: inhibit-startup-screen

若该变量非 nil,则禁用启动屏幕。此时 Emacs 通常显示 *scratch* 缓冲区, 具体可参见下方的 initial-buffer-choice

请勿在新用户的初始化文件中设置该变量,或以影响多用户的方式设置, 否则会导致新用户无法查看版权声明与 Emacs 基础使用信息。

inhibit-startup-messageinhibit-splash-screen 是该变量的别名。

User Option: initial-buffer-choice

若非 nil,该变量为字符串,指定 Emacs 启动后显示的文件或目录,替代启动屏幕。 若值为函数,Emacs 调用该函数并显示其返回的缓冲区。 若值为 t,Emacs 显示 *scratch* 缓冲区。

User Option: inhibit-startup-echo-area-message

该变量控制启动时回显区消息的显示。可在初始化文件中添加如下代码禁用该消息:

(setq inhibit-startup-echo-area-message
      "your-login-name")

Emacs 会在你的初始化文件中显式检查上述形式的表达式;登录名必须以 Lisp 字符串常量形式出现。 你也可以使用自定义界面。其他设置 inhibit-startup-echo-area-message 为相同值的方式 不会禁用启动消息。这样你可以按需为自己禁用消息,而他人随意复制你的配置文件不会生效。

User Option: initial-scratch-message

若该变量非 nil,应为字符串,作为说明文本在 Emacs 启动或 *scratch* 缓冲区重建时插入。 若为 nil*scratch* 缓冲区为空。

以下命令行选项会影响启动流程的部分行为。See Initial Options in The GNU Emacs Manual

--no-splash

不显示启动屏幕。

--batch

无交互终端运行。See 批处理模式

--daemon
--bg-daemon
--fg-daemon

不初始化任何显示,仅启动服务器。 (“后台(background)” 守护进程会自动在后台运行。)

--no-init-file
-q

不加载初始化文件与 default 库。

--no-site-file

不加载 site-start 库。

Do not initialize any display; just start a server. (A “background” daemon automatically runs in the background.)

--quick
-Q

等价于 ‘-q --no-site-file --no-splash’。

--init-directory

指定 Emacs 查找初始化文件的目录。