NixOS 下 Emacs 声明式管理第三方库配置的坑

用的 NixOS, 使用 emacs-overlay

之前和现在的配置:

diff --git a/home/modules/applications/misc/emacs.nix b/home/modules/applications/misc/emacs.nix
index 4360950e23..7e581a2b49 100644
--- a/home/modules/applications/misc/emacs.nix
+++ b/home/modules/applications/misc/emacs.nix
@@ -13,10 +13,11 @@
 
   config = lib.mkIf cfg.enable {
     home.packages = with pkgs; [
-      emacs-pgtk
+      ((emacsPackagesFor emacs-pgtk).emacsWithPackages (epkgs: with epkgs; [
+        jinx
+        mu4e
+      ]))
       emacs-lsp-booster
-      emacsPackages.jinx
-      emacsPackages.mu4e
       sqlite # ekg needs it
 
       # wakatime # wakatime plugin needs it (it calls wakatime-cli)

之前一直有 compatSymbols function definition is void 的问题,我用的是 把 compat 加入 native-comp 的禁止名单中解决的,所以一直以为是 内置的compat 库在最新的 master 分支上存在问题:

今天我查了下 emacs bug archive, 纳闷为什么还没有人提这个 bug, 便检查了下配置,发现是版本不对应的问题,就进行了修改。想到坛友也可能遇到这个问题,遂分享。


我还以为加了Emacs Overlay 之后第三方 Emacs 库中的 Emacs 依赖也会随之更改,没想到不会 :sweat:

熟悉的 emacsPackagesFor emacs-pgtk

不过你都既然这样用了,像我一样就只用 nixpkgs 不导入 emacs-overlay 了

我猜 emacs-overlay 的主要目的是通过 elisp 安装 melpa package ,提供 emacs-git 和 emacs-unstable

我在macOS上遇到过,某些包通过nix 声明式安装会导致找不到autoloads,例如 diff-hl,不知道有没有大佬遇到过,有没有解决方法(纯萌新,就喜欢瞎折腾 :rofl:),感谢任何建议

你提的 autoloads 是指 emacs 下找不到依赖的 bin 程序吗?

如果是这样,检查 emacs 里 exec-path 变量的值与 shell 里是否有差异。

通过图形环境启动的 emacs 不一定会去读 .bashrc 里的 PATH 配置。

我用 emacs-overlay 主要是为了能体验到最新版本的 emacs。emacs-overlay 提供了挺多包的: emacs-overlay/overlays/emacs.nix at dfbc53025ea2527fbf2aca46be92cf725360f4a9 · nix-community/emacs-overlay · GitHub

我用 Nix 安装 Emacs,但是基本不用 Nix 管理 Emacs package,原因是:

  • Nix 的只读特性使得我遇到上游 bug 时想微调一个 package 变得很困难。
  • 新增/升级/删除一个包需要重新构建 Nix profile,相对来说比较麻烦。
  • 版本可控性没有那么自由。

只有 gn-mode-from-source 这种找不到对应 git 仓库也不在 Melpa 上的包我才会用 Nix 管理。

如果楼主不那么追求 Nix 一统全局,不妨考虑一下,没必要给自己增加很多额外的麻烦。

我也基本不用 Nix 管理 Emacs 包,除了几个像jinx, mu4e这种包,他们需要编译一些C文件。如果引用了第三方库的头文件,在nix环境下编译就比较麻烦了,需要修改环境变量LD_LIBRARY_PATH来让 ld linker 能够找到文件,或者用 patchelf 来把第三方库打包进可执行文件中。而 jinx 就用到了 enchant 库。对于这种包,在 nix 环境下,还是用nixpkgs的版本比较好。

Jinx, Vterm 这种我也是优先自己写 default.nix 来打包,其实并不复杂,你可以直接抄 Nixpkgs 里面的源码

1 个赞

给一个参考:

我是直接将他们加到 home.packages 下,这样可以在 ~/.nix-profiles/share/emacs/site-lisp 目录下找到。然后 Emacs 端加入配置:

这段代码用于处理 NIX_PROFILES 环境变量,并添加相关路径到 load-path。逻辑基本是从 site-start.el(如果你是 Nix 安装的 Emacs,这个文件里应该有一些 Nix 相关的处理逻辑)里面抄的。

1 个赞

这样做感觉有点复杂了,还是 nixpkgs 的方法方便。<3

1 个赞