上下文
我正在使用after-make-frame-functions
挂钩在emacs客户端/服务器配置中正确加载主题。具体来说,这是我用来创建代码段(基于此SO答案):
(if (daemonp)
(add-hook 'after-make-frame-functions
(lambda (frame)
(select-frame frame)
(load-theme 'monokai t)
;; setup the smart-mode-line and its theme
(sml/setup)))
(progn (load-theme 'monokai t)
(sml/setup)))
问题
当emacsclient -c/t
开始新的会话时,不仅在新框架中,而且还在所有先前存在的框架(其他emacsclient会话)中执行挂钩,这会产生非常烦人的视觉效果(在所有那些框架中再次加载主题)。更糟糕的是,在终端中已经打开的客户端的主题颜色就完全混乱了。显然,这仅在连接到同一emacs服务器的emacs客户端上发生。出现这种现象的原因很明显,该挂钩在服务器上运行,并且其所有客户端都受到影响。
问题
有什么方法可以只执行一次此功能,也可以不使用钩子而获得相同的结果吗?
部分解决方案
由于@Drew的回答,我现在有了这段代码。但是仍然存在问题,一旦在终端中启动客户端会话,GUI将无法正确加载主题,反之亦然。经过大量测试,我意识到其行为取决于首先启动哪个emacsclient,并且丢弃各种东西后,我认为它可能与所加载的调色板有关。如果您手动重新加载主题,那么一切都可以正常工作,这就是为什么每次在钩子上调用函数时都不会出现此行为的原因,就像在我的初始配置中一样。
(defun emacsclient-setup-theme-function (frame)
(progn
(select-frame frame)
(load-theme 'monokai t)
;; setup the smart-mode-line and its theme
(sml/setup)
(remove-hook 'after-make-frame-functions 'emacsclient-setup-theme-function)))
(if (daemonp)
(add-hook 'after-make-frame-functions 'emacsclient-setup-theme-function)
(progn (load-theme 'monokai t)
(sml/setup)))
最终的解决方案
最后,我有完全有效的代码来解决部分解决方案中出现的行为,为实现此目的,我在首次启动相关emacsclient时通过模式(终端或gui)运行了一次功能,然后从挂钩中删除了该功能,因为不再需要了。现在,我很高兴!:)再次感谢@Drew!
代码:
(setq myGraphicModeHash (make-hash-table :test 'equal :size 2))
(puthash "gui" t myGraphicModeHash)
(puthash "term" t myGraphicModeHash)
(defun emacsclient-setup-theme-function (frame)
(let ((gui (gethash "gui" myGraphicModeHash))
(ter (gethash "term" myGraphicModeHash)))
(progn
(select-frame frame)
(when (or gui ter)
(progn
(load-theme 'monokai t)
;; setup the smart-mode-line and its theme
(sml/setup)
(sml/apply-theme 'dark)
(if (display-graphic-p)
(puthash "gui" nil myGraphicModeHash)
(puthash "term" nil myGraphicModeHash))))
(when (not (and gui ter))
(remove-hook 'after-make-frame-functions 'emacsclient-setup-theme-function)))))
(if (daemonp)
(add-hook 'after-make-frame-functions 'emacsclient-setup-theme-function)
(progn (load-theme 'monokai t)
(sml/setup)))