Doom Guide
Doom 基础介绍
bin/doom
功能
bin/doom help
可查看所有命令,不过这里总结了最重要的几个:
bin/doom sync
: 该命令使 Doom Emacs 同步你的配置。它确保需要的 package 被安装,鼓励的程序报会被删除并正确生成必要的元数据。无论你何时修改了doom!
块或packages.el
文件都应运行该命令。bin/doom upgrade
: 更新 Doom Emacs(如果可更新)和所有的 package。bin/doom env
: (重新)生成“envvar 文件”,这是 Doom 在启动时加载的 Shell 环境快照。如果你的应用启动器或操作系统在错误的环境中启动 Emacs,那么你需要该文件。**在 MacOS 上的 GUI Emacs 用户必须使用该命令**bin/doom doctor
: 如果 Doom 行为不当,doctor 会诊断你的安装,系统和环境的常见问题。bin/doom purge
: 随着时间的流逝,DOom 插件的藏困会不断积累。时不时运行该命令以删除旧的、孤立的 packages,并且 与-g
参数一起使用可以切换压缩现在有的 package。
使用 bin/doom help
查看所有 bin/doom
提供的可用命令,并用 bin/doom help COMMAND
来显示特定 COMMAND
的所有文档。
建议将
~/.emacs.d/bin
添加到PATH
中,所以你可以从任何地方直接调用doom
。通过将以下内容添加到.bashrc 或.zshrc 文件中来达成此目的:
export PATH="$HOME/.emacs.d/bin:$PATH"
外部/系统依赖
Doom 由模块组成,其提供了 doom 的大部分功能,包括语言支持和与外部工具集成。其中许多具有外部依赖,你必须自己安装。你可以在模块的 README。org 文件中或通过运行 bin/doom docktor
找到模块所需依赖和如何安装依赖。
使用
M-x doom/help-modules
(绑定到了SPC h d m
或C-h d m
)来在 Doom 中跳转到一个模块的文档。否则,将光标放到boom!
块中的模块上(在~/.doom.d/init.el
)并按下K
来跳转到它的文档(或gd
跳转到它的源代码)。对于非 evil 用户,则分别使用C-c g k
和C-c g d
。否则,请检查Module Index。
记住文档是一项持续的工作。某些模块可能还有没有 README.org 文件。
更新和回滚
Doom 是一个活跃的项目并且其 300+ packages 中的大多数也 package 也在积极开发中。偶尔更新 Doom 是明智的。Doom 努力使这一个过程尽可能轻松。
bin/doom
脚本提供了一个用于升级 DOom 和 package 的简单命令。
doom upgrade # or 'doom up'
如果你想手动更新 Doom, doom upgrade
等于:
cd ~/.emacs.d git pull # updates Doom doom clean # Ensure your config isn't byte-compiled doom sync # synchronizes your config with Doom Emacs doom update # updates installed packages
仅更新 packages(不包括 Doom 自身):
doom upgrade --packages
Doom 暂不支持回滚。
升级/降级 Emacs
重要:你可能在升级/降级 Emacs 后遇到错误。 Emacs bytecode 通常不向前兼容。你必须重新编译或重新安装你的 packages 来解决该问题,例如:
doom build
来重新构建所有已安装的 package- 或删除
~/.emacs.d/.local
然后doom sync
来重新安装它们
迁移
如果你来自另一个 Emacs 发行版(或你自己的发行版),在你将旧配置转换为 Doom 时,需要注意以下几点:
Doom 不使用
package.el
来管理 packages,但是use-package
使用package.el
!如果你在use-package
块中有:ensure ...
属性,你会看见报错。删除这些并替代的,添加package!
声明到~/.doom.d/package.el
来添加你的 package。具体见本指南中的“包管理”。
(该章节尚不完善)
配置
Doom 在以下位置查找你的私有配置:
$XDG_CONFIG_HOME/doom
~/.doom.d
该目录也是 DOOMDIR
。
你可以通过更改具有相同名称的环境变量来覆盖
DOOMDIR
的位置。符号链接也起作用。
doom install
将会部署三个文件到 DOOMDIR
:
init.el
你可以在这里找到 doom!
块,它控制了哪些 Doom 模块开启和以什么顺序载入。
该文件在启动过程早期被执行,在任何模块被载入之前。
config.el
99.99%的个人配置应该放在这里。任何放在这里的配置将会在所有其他模块加载完运行。
packages.el
在该文件中声明要安装的 package 以及从何处安装。
Note:通常不要使用
M-x customize
或 customize API。Doom 被设计为通过 config.el 以编程方式进行配置,这可能与 Customize 的将变量写入custom-file
的方式冲突。Doom 提供了
setq!
宏用于触发defcustom
setters。
模块
Doom 包含大约 130 个模块。一个 Doom 模块是 a bundle of packages、配置和命令,组织成一个可以通过从 doom!
block(可以在 $DOOMDIR/init.el
中找到)添加或删除它们来启用或禁用的但原。
doom!
block 看起来会像是这样:
;; To comment something out, you insert at least one semicolon before it. The ;; Emacs Lisp interpreter will ignore whatever follows. (doom! :lang python ; this module is not commented, therefore enabled ;;javascript ; this module is commented out, therefore disabled ;;lua ; this module is disabled ruby ; this module is enabled php) ; this module is enabled
它控制哪些模块开启和以什么顺序载入。一些模块有 可选的功能 ,可以通过传递 flags(以加好前缀表示)开启这些功能:
(doom! :completion (company +auto) :lang (csharp +unity) (org +brain +dragndrop +gnuplot +hugo +jupyter) (sh +fish))
不同的模块支持不同的的 flags。模块不识别的 flags 将会被忽略。你可以在 Module Index 中找到可用模块及其支持的 flags 的完整列表。
重要 :不要忘记在改变
doom!
block 后运行 =bin/doom sync=,然后重新启动 Emacs 以使更改生效。
运行
doom doctor
来决定doom!
block 是否有任何问题,例如重复或拼写错误的模块。
包管理
Doom Emacs 不使用 package.el (Emacs 内置的包管理器)。替代的,doom 使用自己的构建在Straight之上的陈述式包管理器。
如果你来自另一个 Emacs 发行版(或原生 Emacs),注意
use package
block 中的:ensure
属性,因为它会尝试(并且失败)通过 package.el 安装 packages。
Package 在 Doom 模块中的 packages.el
文件中声明。这也适用于 DOOMDIR
,其被视为一个模块。你可以在 ~/.doom.d/packages.el
中安装自己的 packages。
如果一个 package 没有使用
package!
声明安装(例如,使用M-x package-install
或M-x straight-use-package
),它将会在下一次运行bin/doom sync
或bin/doom purge
时被删除。
安装 packages
要安装一个 package,添加 package!
声明到 DOOMDIR/packages.el
。
;; 从ELPA或MELPA安装名为“example”的package (package! example) ;; 或者告诉Doom完全不管理特定的package (package! example :ignore t)
package!
将返回 non-nil 如果 package 明确要安装并且没有在其他地方被禁用。使用这个事实可以将 package 依赖关系链接到一起。例如:
(when (package! example) (package! plugin-that-example-depends-on))
从外部源安装 package
为了直接从一个外部源(像 github、gitlab 等)安装一个 package,你需要指定一个MELPA-style straight recipe:
这里有几个例子:
;; 直接从github仓库安装。为了正常工作,package必须有一个适当的PACKAGENAME.el文件,其必须至少包含一个Package—Version或在头部有Version行。 (package! example :recipe (:host github :repo "username/my-example-fork")) ;; 如果package的源文件在所述仓库的子目录中,使用 ':files' 来瞄准它们。 (package! example :recipe (:host github :repo "username/my-example-fork" :files ("*.el" "src/lisp/*.el"))) ;; 获取特定的分支或标签: (package! example :recipe (:host gitlab :repo "username/my-example-fork" :branch "develop")) ;; 如果一个package的默认recipe在MELPA或emacsmirror上,你可以省略关键词并且recipe将会从它们的源继承剩余的reciple。 (package! example :recipe (:branch "develop")) ;; 如果仓库引入了许多不需要的子模块,你可以禁用递归clone (package! example :recipe (:nonrecursive t)) ;; 一个package可以通过设置:host为nil直接从git仓库安装: (package! example :recipe (:host nil :repo "https://some/git/repo"))
package!
宏的 :recipe
的规格在Straight.el’s README中。
重要 :每当你修改 packages.el 文件时, 运行
bin/doom sync
以确保更改生效。
Pinning package 到特定的 commits
所有 Doom 的 package 默认被 pinned。一个 pinned 的 package 时锁定到特定 commit 的 package,如下:
package! evil :pin "e00626d9fd"
要 unpin 一个 package,使用 unpin!
宏:
(unpin! evil) ;; 可以一次unpin多个packages (unpin! (:lang python ruby rust) (:tools docker)) ;;或unpin整个模块的目录 (unpin! :completion :lang :tools) ;; 这样也可以工作,如果你更喜欢这种语法,但这样并不简洁 ;; unpinning多个packages的语法: (package! helm :pin nil)
尽管 强烈 不鼓励这样做,但你可以 unpin 所有的 packages 并使 Doom Emacs 滚动发布:
(unpin! t)
unpin 所有的 packages 时不鼓励的,因为 Doom 的模块是针对 pinned 版本的 packages 而设计的。易失性较高的 packages(如 lsp-mode,ein 和 org)变化迅速,并且如果 unpin 它们,则很可能造成损坏。
相反,一个更好的主意是选择性的 unpin packages,或将其 repin 到你想要的确切 commit。
禁用 packages
package!
宏可以处理 :disable
属性:
(package! irony :disable t) (package! rtags :disable t)
一旦 package 被禁用, 它的 use-packages!
和 after!
blocks 将会被忽略,并且 package 将会在下一次运行 bin/doom sync
时被删除。 使用此功能来禁用不需要或不想要的 Doom 的 packages。
还有 disable-packages!
宏可以方便的禁用多个 packages:
(disable-packages! irony rtags)
重要 :每当你修改 packages.el 文件时, 运行
bin/doom sync
以确保更改生效。
更改已包含的 package 的 recipe
如果一个 Doom 模块从一个地方安装 package X,但是你想要从另一个地方安装,为它在 DOOMDIR/packages.el
添加 package!
声明。个人声明总是优先于模块(甚至是自己的)。
;; in modules/editor/evil/packages.el (package! evil) ; installs from MELPA ;; in DOOMIDR/packages.el (package! evil :recipe (:host github :repo "username/my-evil-fork"))
仅当内置 package 不存在时才安装 package,使用 :build-in 'prefer
:
(package! so-long :built-in 'prefer)
重要 :每当你修改 packages.el 文件时, 运行
bin/doom sync
以确保更改生效。
使用/载入本地 packages
如果你要安装本地的 elisp package。你有两个选择:
调整 load-path
Emacs 会在 load-path
中搜索 packages。添加你的 package 的路径当试图载入它时,Emacs 会找到它。例如:
(add-load-path! "lisp/package") ;; or (use-package my-package :load-path "/path/to/my/package")
:local-repo
或者,你可以在 package!
的 :recipe
声明中指定 :local-repo
:
(package! my-package :recipe (:local-repo "/path/to/my/package")) ;; 不要忘记在非常规项目结构中使用 :files 来包含文件: (package! my-package :recipe (:local-repo "/path/to/my/package" :files ("*.el" "src/lisp/*.el")))
记住运行 doom sync
来在你更改它后重新构建 package,并重新索引其中所有的 autoloads。
配置 Doom
配置 packages
如果你的配置需求很简单,那么 use-package!
, after!
, add-hook!
和 setq-hook!
宏时你的面包和黄油。
;;; ~/.doom.d/config.el (example) (setq doom-font (font-spec :family "Hack NF" :size 12)) ;; Take a feature symbol or a library name(string) (after! evil (setq evil-magic nil)) ;; Take a major-mode, a quoted hook function or a list of either (add-hook! python-mode (setq python-shell-interpreter "bpython")) ;; 这些是相等的 (setq-hook! 'python-mode-hook' python-indent-offset 2) (setq-hook! python-mode python-indent-offset 2) (use-package! hl-todo ;; 如果你省略 :defer,:hook,:commands或:after,那么package被立刻载入。 ;; 通过在这里使用:hook,`hl-todo` package不会被载入,知道prog-mode-hook被触发(通过激活从它派生的主要模式,例如python-mode :hook (prog-mode . hl-todo-mode) :init ;; 这里的代码会立刻运行 :config ;; 这里的代码会在package被载入之后运行 (setq hl-todo-highlight-punctuation ":"))
为了更多的灵活性, use-package-hook!
是另一个选项,但其应被视为最后一个选项(因为通常有更好的方法)。它允许禁用、append/prepend 和/或覆盖 Doom 的 use-package!
blocks。这些由 use-package
的 inject-hook under the hood 驱动的。
use-package-hook!
必须在 package 的 use-package!
block 之前使用 。因此它必须在个人的 init.el 文件中使用。
;;; ~/.doom.d/init.el (example) ;; 如果一个 :pre-init / :pre-config hook返回nil,i它会覆盖package的原有的 :init / :config block。 ;; 利用该方式来覆盖Doom的配置。 (use-package-hook! doom-themes :pre-config (setq doom-neotree-file-icons t) nil) ;; ...否则,确保它们总是返回non-nil! (use-package-hook! evil :pre-init (setq evil-magic nil) t) ;; `use-package-hook` 也有 :post-init 和 :ppost-config hooks
重载配置
你可能会发现让你的改变立即发挥作用非常帮助。对于不需要完全重启 Doom Emacs 的事情(像改变开启的模块或安装的 package),你可以即时评估 Emacs Lisp 代码。
evil 用户可以使用
gr
操作符来苹果一段代码。返回值会显示在 minibuffer 或 popup(如果结果足够大)中。gr
对于大多数语言都能正常工作,但是在 Elisp 中使用它是一个特殊情况;它会在你当前的 Emacs 会话中执行。你可以使用该方法即时修改 Emacs 的状态。- 非 evil 用户可以使用
C-x C-e
来运行eval-last-sexp
,以及M-x +eval/buffer-or-region
(绑定在SPC c e
)。 - 另一个选项是用
SPC x
开一个 scratch buffer,改变它的主要模式(M-x emacs-lisp-mode
),并使用上述的快捷键来评估代码。 - 可以通过按
SPC o r
(+eval/open-repl-other-window
)来使用 ielm REPL。 - 还有
M-:
或SPC ;
,其调用eval-expression
,让你可以运行 elisp 代码 inline。
尽管所有这些都有助于重新配置正在运行的 Emacs 会话,但也有助于调试。
绑定按键
- define-key
- global-set-key
- map!
- undefine-key!
- define-key!
编写自己的模块
加载顺序
模块文件以精确的顺序加载:
~/.emacs.d/early-init.el
(Emacs 27+ only)~/.emacs.d/init.el
$DOOMDIR/init.el
{~/.emacs.d, $DOOMDIR}/modules/*/*/init.el
{~/.emacs.d, $DOOMDIR}/modules/*/*/config.el
$DOOMDIR/config.el
位置
Doom 在 ~/.emacs.d/modules/CATEGORY/MODULE/
和 $DOOMDIR/modules/CATEGORY/MODULE
搜索模块。如果你有一个个人模块和 Doom 包含的模块名相同,将会隐藏包含的那一个(好像包含的那个从未存在过)。
Doom 用以下两种格式之一指明模块:
:category module
或category/module
文件结构
一个模块由数个文件组成,所有文件都是可选的。他们是:
modules/ category/ module/ test/*.el autoload/*.el autoload.el init.el config.el packages.el doctor.el
init.el
该文件在早期被载入,在其他任何文件之前,但是在 Doom core 载入之后。
使用该文件来:
- 配置 Emacs 或执行必须在早期色号只的/拆卸的操作;在其他模块(或本模块)被加载之前。
- 使用
use-package-hook!
重新配置定义在 Doom 里的 package(作为最后一种手段,当after!
和 hook 都不足够的时候)。 - 改变
bin/doom
的行为
不 要使用该文件来:
- 使用
use-package!
或after!
来配置 packages - 执行昂贵的或容易出错的操作;这些文件会在每当
bin/doom
使用时被评估。
config.el
该文件是每个模块的核心。
该文件中的代码应该预期依赖(在 packages.el
中)是已安装并可用的,但不应该假设哪些模块已被激活(使用 featurep!
来检测它们)。
package 应该使用 after!
或 use-package!
来配置:
;; from modules/completion/company/config.el (use-package! company :commands (company-mode global-company-mode company-complete company-complete-common company-manual-begin company-grab-line) :config (setq company-idle-delay nil company-tooltip-limit 10 company-dabbrev-downcase nil company-dabbrev-ignore-case nil) [...])
对于已经熟悉
use-package
的人来说,use-package!
仅是一个简单的包装。它支持所有相同的关键词并可以以几乎相同的方式使用。
packages.el
该文件是 package 升 ingde 地方。如果你像查看一个模块在管理哪些 packages(以及它们从何处安装),它也是一个好地方来查看。
一个 packages.el
文件不应该包含复杂逻辑。通常是条件语句和 package!
、 disable-package!
或 depend-on!
调用。它不应该产生副作用,并应该具有确定性。因为该文件在一个与你的交换会话隔离的环境中被评估,因此其中的代码不应该对当前会话进行任何假设。
详细信息见包管理章节。
autoload/*.el
或 autoload.el
这些文件中标记有 autoload cookie( ;;;##autoload
)的函数会将被延迟加载。
当你运行 bin/doom autoloads
,Doom 会扫描这些文件以将 autoload 文件填充到 ~/.emacs.d/.local/autoloads.el
,该文件会告诉 Emacs 当这些函数被调用时在哪里可以找到它们。
例如:
;; from modules/lang/org/autoload/org.el ;;;###autoload (defun +org/toggle-checkbox () (interactive) [...]) ;; from modules/lang/org/autoload/evil.el ;;;###autoload (autload '+org:attach "lang/org/autoload/evil" nil t) (evil-define-command +org:attach (&optional uri) (interactive "<a>") [...])
doctor.el
该文件被 make doctor
使用,并且应该为模块所有的依赖测试。如果缺少一个,它应该使用 warn!
、 error!
和 explain!
宏告诉用户为什么会出现问题,并且理想情况下,提供一个解决问题的方法。
例如, :lang cc
模块的 doctor 简直是否已安装了 irony server:
;; from lang//cc/doctor.el (require 'irony) (unless (file-directory-p irony-server-install-prefix) (warn! "Irony server isn't installed, Run M-x irony-install-server"))
附加文件
有时,最好将模块的 config.el 文件拆分为多个文件。惯例是将这些附加文件的的名称前加上 +
,例如 modules/feature/version-control/+git.el
。
该惯例没有语法或功能上的意义。目录必须遵循此惯例,这些目录中的文件也不必遵循。
这些附加文件 不 会被自动加载。 你需要使用 !load
宏来加载:
;; from modules/feature/version-control/config.el (load! +git)
load!
宏会长时加载相对于当前文件的 =+git.el=。
Flags
一个模块的 flag 可以是任意符号。惯例这些符号以 +
或 -
为前缀,分别表示添加或删除功能。该符号没有功能上的意义。
一个模块可以根据自己的喜好选择解释 flags。它们可以用 featurep!
宏测试:
;; 当前模块是否已启用+my-feature flag? (when (featurep! +my-feature) ...) ;; 它可以用于检查其他模块中flag是否存在: (when (featurep! :lang python +lsp) ...)
Module cookies
一个特别的语法存在叫做 module cookies。像 autoload cookies ( ;;;###autoload
),模块文件可能在或接进文件头部的地方有 ;;;###if FORM
。读取 FORM 可以确定是否在扫描该文件进行 autoloads( doom sync
)或 byte-compiling( doom compile
)时忽略该文件。
使用此功能可以防止错误发生,比如,如果文件包含(例如)调用不存在的函数如果一个特定功能对该模块不可用,例如:
;;;###if (featurep! +lsp)
;;;###if (not (locate-library "so-long"))
记住,它们在一个有限的、非交互式子会话中运行,所以不要在未启用任何模块的情况下调用 Doom 会话中不可用的任何内容。
Autodefs
autodef 是一种特殊的 autoloaded 函数或宏,无乱是否启用了其包含的模块,Doom 都保证会始终被定义(但当被禁用时不会对其参数进行评估操作)。
你可以使用 M-x doom/help-autodefs
( SPC h d u
或 C-h d u
)浏览在当前会话中可用的 autodefs。
使 autodef 与常规 autoload 区别开来的时 ;;;###autodef
cookie:
;;;###autodef (defun set-something! (value) ...)
一个例子时 :completion company
模块暴露的 set-company-backend!
函数。它允许你在特定的主要模式中注册 company 补全的 backeds。例如:
(set-company-backend! 'python-mode '(company-anaconda))
配置 Doom Emacs 时的常见错误
急切加载 package
在没有延迟关键字( :defer :after :commands :defer-incrementally :after-call
之一)情况下使用 use-package!
将会立即载入 package。这回导致其他 packages 被拉取并加载,从而违纪 Doom 的许多启动优化。
手动管理 package
许多 Emacs 文档和帮助都会包含使用 package.el 的 API(例如 package-install
)或使用 use-package 的 :ensure
关键字来安装 package 的建议。如果你愿意,你可以这样做,否则,Doom 拥有自己的 package 管理系统。
从 use-package
代码迁移到 Doom 通过只需要删除 :ensure
关键字并添加 (package! PACKAGENAME)
到 ~/.doom.d/package.el
(并运行 doom sync
同步你的配置)。
使用 org-babel-do-load-languages
来加载 babel packages
你不需要 org-babel-do-load-languages
。Doom 会基于在 #+BEGIN_SRC
blocks 中的语言名按需 lazy load babel package。只要 babel 插件已安装并且插件以它的语言命名(例如, #+BEGIN_SRC rust
会载入 ob-rust
),你不需要做其他任何操作。
然而,可能会有一些特殊的例子。Doom 尝试处理其中的几个(例如,ob-jupyter、ob-ipython 和 ob-async)。如果你在 org src blocks 中在尝试使用特定语言时遇到错误,查看:lang org module documentation以获取如果添加支持的具体信息。
使用 delete-trailing-whitespaces
或 whitespaces-cleanup
来管理多余的 whitespace
(add-hook 'after-save-hook' #'delete-trailing-whitespaces) ;; 或 (add-hook 'after-save-hook' #'whitespace-cleanup)
这两行时 Emacs 的常见配置,但在 Doom Emacs 中它们不是必须的。我们已经使用了更复杂的 wsbutler
来管理外来的 whitespace。然而,你可能会觉得它不起作用。这是因为 wsbutler
以两种不同寻常打方法工作,意味着没有其他选择那么强悍:
它只会清除你碰过的行中的尾随空格(但始终会在 EOF 清除多余的空行)。为什么这样做?因为我相信整个文件范围的重新格式化应该是个值的商榷的行为(而不是盲目自动化)。如果有必要,那么你可能正在从事其他人的项目 —— 或正与其他人一起工作,但在这里,大规模的 whitespace 改变可能造成问题或只是粗鲁。我们不赞同 1%贡献和 99% whitespace 的 PR!
然而,如果真的有必要,可以调用
deliberately
替代M-x delete-trailing-whitespace
或M-x whitespace-cleanup
。wsbutler
使用 虚拟 whitespace 替换尾随空格和多余空行。 该 whitespace 仅存在于 Emacs 的 buffer 中,不会真正写入到文件。为什么这样做?因为你可能想在当前的编辑会话中使用空格来存储某些内容,所以对编辑者来说在达到该内容之前将其删除是不方便的。
如果你使用 whitespace,它就在这里。如果你不适用,whitespace 也不会被写入到文件。
Troubleshoot
当遇到问题时,你应该准备收集信息以解决问题,或准备要编写的 bug report。Emacs 和 Doom 都提供了工具来使这一过程更加容易。这里有几件事你应该首先尝试:
- 查找
*Messages*
日志中的警告和错误信息。该日志可以使用SPC h e
、C-h e
或M-x view-echo-area-messages
打开。 - 在 FAQ和Doom的issue tracker中查找错误/警告。你的问题可能已存在解决方法。FAQ 可以在 Doom 中使用
SPC h d f
(或非 evil 用户使用C-h d f
)来搜索。 - 在命名行运行
bin/doom doctor
来诊断环境和配置的常见问题。它还会为问题提出解决方法。 bin/doom clean
会确保问题不是个人配置和 Doom core 的 bytecode 过时。如果你还没有使用bin/doom compile
,那么就不需要运行此命令。bin/doom sync
会确保问题不是丢失 packages 或过期的 autoload 文件。bin/doom build
会确保问题不是陈旧的 package bytecode 或损坏的符号连接。bin/doom update
会确保 packages 时最新的,从而消除上游产生的问题。- 如果你知道是哪个个模块相关的问题,检查它们的文档(按
SPC h d m
跳转到模块的文档)。你的问题可能已记录在文档中。 - 如果问题可以在原生 Emacs 并且/或者原生 Doom(没有个人配置的 Doom)中重现。Domm的shanbox可以帮助你检查。
- 在Discord服务器上请求帮助。这是得到帮助最快速的方法,有时直接从 Doom 的维护者那里获得帮助,Doom 的维护者在那里非常活跃。
如果以上这些都无法帮助到你,那么是时候提交错误报告了。关于如何提交有效的错误报错,见contributing guidelines中的"Reporting Issues"