这两天受到 @SteamedFish 和@Locez 的鼓动,而且本人的 doom 配置也积累到一定程度了,是时候把自己的 doom-private-config进行模块化拆分,以方便管理维护了。
本来预想是挺简单的事,把集中在一起的配置,按照不同的类型,新建对应的 module 目录,然后建立 config.el 和 packages.el,把配置代码对应部分剪切过来就行了。结果拆分完毕一启动,一堆报错信息。汗~
冷静,冷静。查看错误信息,发现都是无效函数和参数为空的信息。这就怪了,配置代码完全没变,只是放在了不同的位置。莫非……跟执行的顺序有关?尝试把所有与已有 package 有关的配置代码都用 after! 括起来,确保配置代码在对应的 package 加载之后才执行。再次重新启动,果然可以了!看来之前的 ~/.doom.d/config.el 文件里的代码是在各个 modules 加载之后才执行的。
至此以为,万事大吉。而且可喜的是, emacs 的启动时间竟然减少了 1 秒,真是意外的收获。可运行一段时间以后,总觉得有些不对劲,仔细观察发现是 theme 的部分颜色有异常,由于我是使用 theme-changer 包根据日出日落时间自动切换 theme 的,已经在 use-package! 的 :after 中指定在 doom-themes 和 solaire-mode 之后加载了,怎么还会有问题呢?
没有出错提示,那就说明是正常执行了,还有异常说明有些配置被别的代码修改了,应该还是执行顺序的问题。我尝试让此 package 延迟 5 秒加载,发现问题依旧,那看来最后执行是不可以的,肯定在这之前 doom 有一些 ui 方面的处理。从 ~/.emacs.d/init.el 开始查找,在 core.el 里的 doom-initialize 函数中找到了说明, doom 的加载顺序为:
1
2
3
4
5
6
7
8
9
10
11
12
| ~/.emacs.d/init.el
~/.emacs.d/core/core.el
~/.doom.d/init.el
Module init.el files
`doom-before-init-modules-hook'
Module config.el files
~/.doom.d/config.el
`doom-init-modules-hook'
`after-init-hook'
`emacs-startup-hook'
`doom-init-ui-hook'
`window-setup-hook'
|
果然发现有一个 doom-init-ui-hook,这个 hook 看名字就是和 ui 初始化有关,加上看到 ~/.doom.d/config.el 的次序也在它之前,八成是这样没跑了。最后选中 emacs-startup-hook 作为注入点,再次重新启动。
完美~
[1月13日更新]
无意中发现 tabnine 没生效,根据前一日的经验,应该也是执行顺序的事, tabnine 要修改 company-backends 的值,估计是 doom 里的 company 之后又有修改company-backends 的操作,哪怕是在 tabnine 中指定 after company 也不行。依据前述办法,把增加 company-backends 操作加在后面次序的 hook 中,我选定的是after-init-hook,重启后生效。最终 tabnine 的配置代码是:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| (use-package! company-tabnine
:when (featurep! :completion company)
:hook
(kill-emacs . company-tabnine-kill-process)
(lsp-after-open . (lambda ()
(add-to-list 'company-transformers 'company//sort-by-tabnine t)
(add-to-list 'company-backends '(company-lsp :with company-tabnine :separate))))
(after-init . (lambda ()
(add-to-list 'company-backends #'company-tabnine)
(set-company-backend! 'text-mode
'company-tabnine 'company-dabbrev 'company-yasnippet 'company-ispell)
(set-company-backend! 'conf-mode
'company-tabnine 'company-capf 'company-dabbrev-code 'company-yasnippet)
(set-company-backend! 'prog-mode
'company-tabnine 'company-capf 'company-yasnippet)))
:config
(set company-idle-delay 1)
(map! (:leader
:desc "Use company default backend" "clo" #'company-other-backend
:desc "Use company tabnine backend" "clt" #'company-tabnine))
;; Integrate company-tabnine with lsp-mode
(defun company//sort-by-tabnine (candidates)
(if (or (functionp company-backend)
(not (and (listp company-backend) (memq 'company-tabnine company-backend))))
candidates
(let ((candidates-table (make-hash-table :test #'equal))
candidates-lsp
candidates-tabnine)
(dolist (candidate candidates)
(if (eq (get-text-property 0 'company-backend candidate)
'company-tabnine)
(unless (gethash candidate candidates-table)
(push candidate candidates-tabnine))
(push candidate candidates-lsp)
(puthash candidate t candidates-table)))
(setq candidates-lsp (nreverse candidates-lsp))
(setq candidates-tabnine (nreverse candidates-tabnine))
(nconc (seq-take candidates-tabnine 3)
(seq-take candidates-lsp 6))))))
|