【求助】如何配置 GUI 插件在 Daemon 时不加载,当 emacsclient 连接时再判断是否加载。

普通设置,如

(push '(menu-bar-lines . 0) default-frame-alist)
(push '(tool-bar-lines . 0) default-frame-alist)

需求:系统启动 daemon ,无 GUI ,相关 GUI 设置不执行;其他方式启动 Emacs ,判断是否为 GUI 如果是则加载相关 GUI 设置,如果不是则不加载。

方案:将界面设置定义到函数中,通过 after-make-frame-functions 这个 Hook 触发函数。另外再写一段配置判断当前是否为 daemon , 如果是 daemon 则不执行设置 GUI 的函数,等待 Hook 触发,如果不是 daemon ,则触发函数加载 GUI 配置。

问题:如何配置 GUI 插件在 Daemon 时不加载,当 emacsclient 连接时再判断是否加载。

需求:比如 fontaine 在 daemon 时不加载,但在 emacsclient -c 后就需要立即加载, 使用其他方式打开 Emacs 则判断是否为 GUI 如果是则加载,如果不是则不加载。

区别:use-package 的 :if(display-graphic-p) 只判断一次,其他方式打开 Emacs 也只需要这一次的判断, 而连接 daemon 则是,daemon 已经判断不加载相关配置后,需要去再一次的判断是否需要加载。

坛友们有什么好的方案,以及这方面的各种建议吗?

系统环境:NixOS+niri+Emacs30.2

server-after-make-frame-hook 可以解决。

4 个赞

函数写成类似下面这样可以吗?主要利用use-package把相关的GUI插件defer,再通过函数被触发运行插件的关键命令来自动加载。

(when sys/nixosp
  ;; 加载 Emacs 的内置 GUI 设置选项
  (defun sys/setup-nixos-gui-frame (&optional frame)   ;; 判断是否图形界面,统一加载 Emacs 内置的 GUI 设置,通过钩子 server-after-make-frame-hook 触发
    (let ((current-frame (or frame (selected-frame))))
      (when (sys/nixos-gui-p current-frame)
        (push '(menu-bar-lines . 0) default-frame-alist)
        (push '(tool-bar-lines . 0) default-frame-alist))))
  (add-hook 'server-after-make-frame-hook #'sys/setup-nixos-gui-frame)

  ;; 加载 Emacs 的 GUI 相关插件包
  (defun sys/load-nixos-gui-plugin (&optional frame)   ;; 判断是否图形界面,统一加载 Emacs 插件的 GUI 设置,通过钩子 server-after-make-frame-hook 触发
    (let ((current-frame (or frame (selected-frame))))
      (when (sys/nixos-gui-p current-frame)
        (fontaine-mode +1))))
  (add-hook 'server-after-make-frame-hook #'sys/load-nixos-gui-plugin))

(when sys/nixosp
  (unless (daemonp) ; 检查当前 Emacs 实例是否是 daemon 如果不是则执行函数
    (sys/setup-nixos-gui-frame))
  (unless (daemonp) ; 检查当前 Emacs 实例是否是 daemon 如果不是则执行函数
    (sys/load-nixos-gui-plugin)))