Reference
doom/help-modules 绑定到 SPC h d m
doom/delete-this-file 绑定到 SPC f D
doom/reload SPC h r r 不用重启 emacs 就能刷新个人配置的更新
doom/restart SPC q R
doom/restart-and-restore SPC q r
doom/open-scratch-buffer SPC x
doom/help-*
doom/help-modules
doom/help-packages
Keybinding Management
which-key
which-key 现已包含在 Emacs 的主分支中,并可能随 Emacs v30 发布。
which-key 的 Bug 报告和贡献现在将通过标准的 Emacs 渠道进行处理,此仓库将被存档。
目前 doom 貌似没有支持 官方的which-key
Session Management
doom/quicksave-session SPC q s
doom/quickload-session SPC q l
doom/save-session SPC q S
doom/load-session SPC q L
我有一个问题就是,这些 session 多久会被删除?
Projects Management
<~/.config/emacs/lisp/doom-projects.el>
有
projectile 将会被弃用
我想要知道它具体的判定规则!
search-project
+default/search-project
SPC /
Debugging
Dev Notes
doom-cli
<~/.config/emacs/lisp/doom-cli.el>
doom bash脚本
它使用了 :; 技巧,把两种语言(shell 和 emacs lisp)的脚本放到一个文件里了
doom-cli.el
doom-lib
debug
Others’ Doom Emacs Config
在这里放的是基于 doomemacs 的 emacs 配置
对于 vanilla emacs 的配置放在 Others’ Emacs Config
hlissner’s .doom.d
tecosaur’s Doom Emacs Configuration
这不只是一个配置!
我应该能学到很多东西
Emacs can be thought of as a platform within which various elements of your workflow may settle, with the potential for rich integrations between them — a life IDE if you will.
Official Modules
:emacs
vc
其实叫 git 更好,本质还是 git 的更优秀的集成
git-timemachine
+vc/browse-at-remote SPC g o o
+vc/browse-at-remote-kill SPC g y
+vc/browse-at-remote-homepage SPC g o h
+vc/browse-at-remote-kill-homepage SPC g Y
undo
还有一个 undo-fu-session 是和 undo-fu 配合的
:tools
magit
majutsu
这是我打算写的 majutsu 预设
tree-sitter
它有一个 treesit 分支,准备完全替代掉 elisp-tree-sitter
上次提交是在 5 月,作者还在努力中
现在已经合并到主分支了!
Comparing b1826a0c6469f57b377b08ef7d54005504b12d59…26a5ad72e161f53151e78580…
biblio
<:tools biblio>
pass
-
pass.el
-
TODO 我打算做 org-roam 和 pass.el 的集成
我想要实现的功能是
自动收集所有有 pass 标签(非继承)的节点
在下面查 pass_key 属性
然后显示的时候可以显示节点的 olp,
然后之后再用 pass_key 对应的条目下选一遍字段我觉得相当不错
-
debugger
用的是 dape
dape-configs
:ui
popup
临时 window
非常好用的功能!
-
Chat: 和我解释一下我应该如何理解这个 doom module,如何使用它
这个 Doom Emacs 模块是用来“驯服临时窗口”的:把各类不那么重要、短暂查看的缓冲区(Help、Completions、编译输出、Org capture 等)统一当作 popup,在侧边打开、按 ESC/C-g 一键关闭、需要时可恢复,并且能自动清理你标记为“短暂”的缓冲区。
如何理解与启用
- 在 init.el 的 doom! 中启用 :ui popup;可选加旗标:
- +defaults:启用一组合理的默认规则(常见 Help/Completions 等)。
- +all:兜底,把名称以空格或星号开头的“特殊缓冲区”都视为 popup。
- +defaults:启用一组合理的默认规则(常见 Help/Completions 等)。
- 核心原理:通过 display-buffer-alist 定规则,拦截 display-buffer 的行为,把匹配的缓冲区以指定方式在侧窗显示。少数包若用 switch-to-buffer/switch-to-window 会绕过它(README 里提到 org 有额外兼容)。
常用操作
- C-x p:在普通窗口与 popup 窗口之间切换(+popup/other)。
- 还有:+popup/toggle、+popup/close、+popup/close-all、+popup/restore、+popup/raise 等命令可用(可自行绑键)。
- 在 popup 中按 ESC 或 C-g 通常会关闭它(受 :quit 规则影响)。
如何写规则
- 用 set-popup-rule! 或 set-popup-rules! 在 $DOOMDIR/config.el 定义匹配规则。按缓冲区名(正则)或谓词匹配。
- 关键参数(简要):
- :side ‘left/‘right/‘above/‘below:在哪一侧开窗。
- :size/:width/:height:窗口大小(比例或像素/列行)。
- :select t:打开后选中该窗口。
- :quit t:允许用 ESC/C-g 关闭。
- :ttl:控制自动销毁缓冲区的“存活时间”:
- 0 立即杀掉(关闭时立刻 kill-buffer)。
- 数字 N 表示在 N 秒后自动杀掉。
- t 表示不自动杀(持久)。
- 0 立即杀掉(关闭时立刻 kill-buffer)。
- :slot/:vslot:在侧窗口里的排序位置。
- :modeline t/nil:是否显示模式行(默认隐藏,可覆盖)。
- 其他 ACTIONS/PARAMETERS 会透传到 display-buffer 的动作与参数。
- :side ‘left/‘right/‘above/‘below:在哪一侧开窗。
- 示例(可直接粘到 config.el):
- 基础多条规则:
(set-popup-rules! '(("^ \\*" :slot -1) ; 兜底:特殊缓冲区 ("^\\*" :select t) ("^\\*Completions" :slot -1 :ttl 0) ("^\\*$?:scratch\\|Messages$" :ttl t) ("^\\*Help" :slot -1 :size 0.2 :select t) ("^\\*doom:" :size 0.35 :select t :modeline t :quit t :ttl t))) - 给 Help/compile 放在底部、可 ESC 关闭:
(set-popup-rule! "^\\*Help" :side 'bottom :size 0.25 :select t :quit t) (set-popup-rule! "^\\*compilation\\*" :side 'bottom :size 0.25 :quit t :ttl 5) - 给 Org capture 做成右侧持久窗:
(set-popup-rule! "^\\*Org Capture\\*" :side 'right :width 0.4 :select t :ttl t)
- 基础多条规则:
配置细节
- 默认 popup 隐藏 mode-line,如需显示:
- 全局改默认: (plist-put +popup-defaults :modeline t)
- 或完全禁用 mode-line 管理: (remove-hook ‘+popup-buffer-mode-hook #‘+popup-set-modeline-on-enable-h)
- 全局改默认: (plist-put +popup-defaults :modeline t)
- 宏与函数:
- without-popups!:在一段代码里暂时禁用 popup 管理。
- save-popups!:暂存并恢复当前 popup 状态。
- +popup-window-p / +popup-buffer-p 等可在自定义逻辑里判断。
- without-popups!:在一段代码里暂时禁用 popup 管理。
注意与排错
- 规则顺序很重要;越具体的规则应放在前面。
- 有些包用 switch-to-buffer 绕过规则(尤其 org 的部分场景),README 已做了一些兼容;若仍无效,尝试为该包的命令写专门规则,或查其显示函数。
- 用 M-: (pp display-buffer-alist) 查看当前规则是否已生效。
- 若希望“所有特殊缓冲区都侧开”,启用 +all 作为兜底。
总之:启用 :ui popup →(可选)+defaults/+all → 在 config.el 写 set-popup-rule!/set-popup-rules! → 用 C-x p 和相关命令管理 → 按需调大小、侧边、是否可一键关闭与是否自动清理。这样就能把临时窗口的体验统一、可控。
- 在 init.el 的 doom! 中启用 :ui popup;可选加旗标:
workspace
突然发现这东西很好用
使用的前缀是 SPC TAB
详见 doom-leader-workspace-map
依赖的是 persp-mode 这个包
完全符合我的想象!
他们的 buffer 共享策略是这样的
SPC b b 不显示其他 workspace 的 buffer
SPC b B 则显示其他 workspace 的 buffer
和 doom 自带的 session 管理不能兼容…
也就是不能 save 和 load,那这有点难受了
smooth-scroll
使用的是 ultra-scroll 和 good-scroll.el
平滑滚动的逻辑和我习惯的不一样,所以我自己写了一个 neoscroll.el
现在已经弃用了,自适应了
treemacs
SPC o p
-
突然发现可以直接跳到 org 文件的标题
但是刚才出现了这个报错
[Treemacs] Something went wrong when finding tag ‘long form’: (wrong-type-argument integer-or-marker-p nil)暂时没有发现什么特殊的触发条件
vc-gutter
实际的依赖是
有一个很好用的 +vc-gutter/next-hunk
:app
calendar
用的是
用的是 https://github.com/kiwanami/emacs-calfw
everywhere
这是 tecosaur 写的模块
理所当然地正在等待 wayland support
tecosaur/emacs-everywhere#50 Wayland support
IRC
使用的是 circe 这个包
我暂时还没搞懂 irc 到底是怎么连的
:editor
multiple-cursors
<:editor multiple-cursors>
- g z z to toggle new (frozen) cursors at point.
- g z t to toggle mirroring on and off (or switch to insert mode to activate
them). - g z A to place cursors at the end of each selected line.
- g z I will place them at the beginning.
我的评价就完全没法用,多选下的 x 然后 p 一下直接没了,只会粘贴一个
snippet
:lang org
终于把 org-roam v1 移除了
https://github.com/doomemacs/doomemacs/commit/d92883bff8ff5457faa09b41a1e8e404c3693594
doomemacs 的 org-link 预设
-
fn var
这两种链接的
:follow绑上了 describe-function describe-variable ,非常好用
-
kbd
我发现我把 kbd: 的写法写错了,doom文档里是这么写的
[[kbd:][h d d]]=,我是这么写的 =[[kbd:h d d]]。。。
其实问题不大,目的就是想要有一个特殊的高亮。我希望 kbd: 链接可以直接跳转到对应的 describe-key 去,
我觉得如果想要支持这个功能,还是不应该写到 describe 里去的。
事实上这没有意义,因为你想要描述的大多数时候不是当前 mode 的快捷键。
:lang latex
:email mu4e
mu4e
<:email mu4e> 这里的文档应该算挺全的了
我应该使用 set-email-account! 吗?
和 :ui workspace 合作的有一个问题
退出的时候他会直接删除那个 workspace
需要注意在打开一个 mu4e-update-mail-and-index window 的时候,不要退出
profiles管理
想要给 meow 开一个profile,结果出现了问题
❯ doom sync --profile meow
Error: Failed to load Doom from /home/_WD_/.config/emacs/early-init.el搞不懂了
doom —doomdir ~/.config/doom-meow sync
这是有用的
最后放弃了
内置宏
map!
我已完全掌握!
在这里贴上文档
"A convenience macro for defining keybinds, powered by `general'.
If evil isn't loaded, evil-specific bindings are ignored.
Properties
:leader [...] an alias for (:prefix doom-leader-key ...)
:localleader [...] bind to localleader; requires a keymap
:mode [MODE(s)] [...] inner keybinds are applied to major MODE(s)
:map [KEYMAP(s)] [...] inner keybinds are applied to KEYMAP(S)
:prefix [PREFIX] [...] set keybind prefix for following keys. PREFIX
can be a cons cell: (PREFIX . DESCRIPTION)
:prefix-map [PREFIX] [...] same as :prefix, but defines a prefix keymap
where the following keys will be bound. DO NOT
USE THIS IN YOUR PRIVATE CONFIG.
:after [FEATURE] [...] apply keybinds when [FEATURE] loads
:textobj KEY INNER-FN OUTER-FN define a text object keybind pair
:when [CONDITION] [...]
:unless [CONDITION] [...]
Any of the above properties may be nested, so that they only apply to a
certain group of keybinds.
States
:n normal
:v visual
:i insert
:e emacs
:o operator
:m motion
:r replace
:g global (binds the key without evil `current-global-map')
These can be combined in any order, e.g. :nvi will apply to normal, visual and
insert mode. The state resets after the following key=>def pair. If states are
omitted the keybind will be global (no emacs state; this is different from
evil's Emacs state and will work in the absence of `evil-mode').
These must be placed right before the key string.
Do
(map! :leader :desc \"Description\" :n \"C-c\" #'dosomething)
Don't
(map! :n :leader :desc \"Description\" \"C-c\" #'dosomething)
(map! :leader :n :desc \"Description\" \"C-c\" #'dosomething)"属性继承规则
(map! :leader ; 设置 leader 属性
"a" #'func-a ; 继承 :leader
:prefix "f" ; 新增 prefix 属性
"f" #'find-file ; 继承 :leader + :prefix "f"
"r" #'recent-files ; 继承 :leader + :prefix "f"
:map org-mode-map ; 新增 map 属性
"l" #'org-insert-link ; 继承 :leader + :prefix "f" + :map org-mode-map
:prefix "b" ; 覆盖之前的 prefix
"b" #'switch-buffer) ; 继承 :leader + :prefix "b" + :map org-mode-map-
状态的特殊性
状态标记 (:n, :v, :i 等) 有特殊规则:
(map! :leader :n "a" #'func-a ; normal 模式 :v "b" #'func-b ; visual 模式 "c" #'func-c ; 全局 (状态重置) :nv "d" #'func-d) ; normal + visual 模式关键点:
- 状态在每个键绑定后 重置
- 其他属性 持续继承 直到被新值覆盖
- 嵌套块内的属性只在该块内有效
- 状态在每个键绑定后 重置
实际示例
(map! :leader ; 全局设置
(:prefix "f" ; 嵌套块开始
"f" #'find-file ; :leader + :prefix "f"
:n "n" #'new-file) ; :leader + :prefix "f" + normal 模式
"g" #'magit-status ; 只继承 :leader,prefix "f" 已结束
:map org-mode-map ; 新增 map 属性
"l" #'org-store-link) ; :leader + :map org-mode-mapuse-package!
:custom 在有些时候可以替代
:init (setq xx xx)
要求这个变量是一个可以可自定义变量
setq!
setq! 是 Doom Emacs 提供的一个宏,用来“更聪明地”设置可自定义变量(即 Emacs 的 customizable variables)。
它的作用与 setq 类似:批量给变量赋值。但与 setq 和 setopt 有重要区别:
与 setq 不同:setq! 在设置变量时会触发该变量的自定义 setter(即通过 defcustom 定义时的 :set 函数等),因此能正确应用变量的副作用或验证逻辑。setq 只是简单赋值,不会调用这些机制。
与 setopt 不同:setq! 不会为了设置变量而加载相关的自定义库或包,避免不必要的依赖加载,更轻量。
简单理解:
如果你只是给普通变量赋值,用 setq 就行。
如果你要设置的是通过 defcustom 定义的“可自定义变量”,并希望它的 setter/副作用生效,但又不想像 setopt 那样引入额外依赖,建议用 setq!。
用法与 setq 一样: (setq! var1 val1 var2 val2 …)
示例:
(setq! tab-width 4) 会触发 tab-width 的 setter,确保相关行为正确更新。
(setq tab-width 4) 只改变量,不一定更新相关状态。
(setopt tab-width 4) 也会触发 setter,但可能会加载定制相关库;Doom 更推荐用 setq!。
Issues
doomemacs/doomemacs#8003 Failed `doom upgrade` - fatal: the requested upstrea…
我遇到过好多次这个问题了,我还以为是我的网络问题