求教如何在nixos下安装emacs rime

折腾了下没能成功,特来请教各位大佬们~

我按照这个贴子配置成功了emacs vterm,但是rime还是不行,尝试了

        ((emacsPackagesNgGen emacs).emacsWithPackages
          (epkgs: [ epkgs.vterm epkgs.rime ]))

加上copy 了nixos安装的librime到~/emacs.d/librime里,cp -r /nix/store/lmyqq18a3ns3gl6pcrjdh3mcpffg5dmc-librime-1.5.3/* ~/.emacs.d/librime/

.emacs.d/librime on  develop [?]
➜ ll
dr-xr-xr-x - ztlevi users 20 Jun 20:28 bin
dr-xr-xr-x - ztlevi users 20 Jun 20:28 include
dr-xr-xr-x - ztlevi users 20 Jun 20:28 lib
dr-xr-xr-x - ztlevi users 20 Jun 20:28 share

但是编译rime还是报错了

gcc lib.c -o librime-emacs.so -fPIC -O2 -Wall -I /home/ztlevi/.emacs.d/librime/include/ -shared -L /home/ztlevi/.emacs.d/librime/lib/ -Wl,-rpath /home/ztlevi/.emacs.d/librime/lib/ -lrime
lib.c:23:10: fatal error: emacs-module.h: No such file or directory
   23 | #include <emacs-module.h>
      |          ^~~~~~~~~~~~~~~~
compilation terminated.
make: *** [Makefile:40: lib] Error 1
rime-compile-module: Compile Rime dynamic module failed

设置变量

(rime-emacs-module-header-root(concat(shell-command-to-string "nix eval --raw '(let pkgs = import <nixpkgs> {}; in with pkgs; lib.getLib emacs)'") "/include"))
(rime-librime-root (shell-command-to-string "nix eval --raw '(let pkgs = import <nixpkgs> {}; in with pkgs; lib.getLib librime)'"))
(rime-share-data-dir (concat (shell-command-to-string "nix eval --raw '(let pkgs = import <nixpkgs> {}; in with pkgs; lib.getLib brise)'") "/share/rime-data"))
4 个赞

works like a charm!

参考了你的设置,在 Mac 上 使用 Nix 只要设置以下两个变量就可以自动编译 emacs-rime。

(when (eq system-type 'darwin)
    (setq rime-librime-root  "~/emacs-data/librime/dist") ;; 从 librime 仓库下载相应的预编译包
    (setq rime-emacs-module-header-root "~/.nix-profile/include"))

现在 nixpkg 里已经有 emacs-rime 了 , 用 nix-env -iA nixpkgs.emacs26Packages.rime 就能用。(不知道 mac 会不会有问题。(可能会写错,因为我现在不用 nix 了。

现在有 librime,是最新的 1.7.3 版本,但是只支持 Linux,不支持 darwin。 所以在 Mac 平台还是需要到官方仓库下载最新的Release,

rime-with-plugins-1.7.3-osx.zip 这个是带插件的,支持 lua。

通过 nix eval --raw '(let pkgs = import <nixpkgs> {}; in with pkgs; lib.getLib emacs)' 获取路径并不靠谱,当更新过 channel 或者升级过 nix 之后,获得的路径可能就实效了:

⋊> nix eval --raw '(let pkgs = import <nixpkgs> {}; in with pkgs; lib.getLib emacs)'
/nix/store/gkvj9d90wjrp69vbnnqp6496cc996dkf-emacs-27.2

⋊> ls /nix/store/gkvj9d90wjrp69vbnnqp6496cc996dkf-emacs-27.2
ls: cannot access '/nix/store/gkvj9d90wjrp69vbnnqp6496cc996dkf-emacs-27.2': No such file or directory

readlink 获取到的路径才是有效的,也是 wiki 推荐的方法:

⋊> readlink -f ~/.nix-profile/bin/emacs
/nix/store/nycbav7by9ii4l62scwsn952hpxbpak1-emacs-27.2/bin/emacs

⋊> ls /nix/store/nycbav7by9ii4l62scwsn952hpxbpak1-emacs-27.2/
Applications  bin  include  lib  libexec  share

而且 readlink 耗时极少。


EDIT:

更可靠的方法应该是获取当前 Emacs 路径:

(file-truename (concat invocation-directory invocation-name))
;; => "/nix/store/nycbav7by9ii4l62scwsn952hpxbpak1-emacs-27.2/bin/emacs-27.2"
2 个赞

请教下这个命令得到的 Emacs 路径,怎么得到 /nix/store/nycbav7by9ii4l62scwsn952hpxbpak1-emacs-27.2/include 这个路径?

(epkgs.melpaPackages.rime.overrideAttrs (old: {
  recipe = pkgs.writeText "recipe" ''
    (rime :repo "DogLooksGood/emacs-rime"
          :files (:defaults "lib.c" "Makefile" "librime-emacs.so")
          :fetcher github)
  '';
  postPatch = old.postPatch or "" + ''
    emacs --batch -Q -L . \
        --eval "(progn (require 'rime) (rime-compile-module))"
  '';
  buildInputs = old.buildInputs ++ (with pkgs; [ librime ]);
}))

(file-truename (concat (file-name-directory (directory-file-name (file-truename invocation-directory))) “include”))

我已经不用 Nix 和 emacs-rime 了。

不过 emacs-rime 的作者 @DogLooksGood 目前好像是用 Nix的,在 Nix 上安装 emacs-rime 应该不是问题了吧?

在非 nixos 下用 nix 安装的 emacs 和 librime,得手动设置 rime-emacs-module-header 和 rime-librime-root, header 还好说楼上大佬给我的代码能很快获取到,但是我还不知道怎么快速获取 librime 在 /nix/store 中的 path

不过不太理解为什么用 nix 装的 emacs 要手动设置这两个不能像正常使用 emacs 一样直接获取。。

我是用的 home-manager 安装了 gcc13, gnumake, librimeemacs-nox 然后配置是这样写的

(setq rime-emacs-module-header-root "~/.nix-profile/include"
        rime-librime-root "~/.nix-profile"
        rime-share-data-dir "/mnt/c/Program Files (x86)/Rime/weasel-0.15.0/data")
1 个赞

我是这样设置之后在 nixos 上不用设置 rime-emacs-module-header-root 和 rime-librime-root 就可以直接 compile 了

奇怪我是装的 emacs29-pgtk 但是 ~/.nix-profile/include 下没有 emacs_module.h,设置了 rime-librime-root 也找不到 rime_api.h

今天又解决了一下我 C-\ 启动 rime 的时候一直报 rime-activate: Wrong type argument: stringp, nil 的这个问题。

发现 rime-share-data-dirnil

这个变量在 Linux 下获取默认值时会搜索 xdg-data-dirs

~/.nix-profile/share 又在 xdg-data-dirs 里面。

只要在 home-manager 的 home.packages 里面加上 rime-data

这样 ~/.nix-profile/share 里面就有 rime-data

rime-share-data-dir 的默认值也能自动获取了。

1 个赞

我是手动设置了 /usr/share/rime/data,话说我不知道这个 share dir 是干什么的。。是不是放一些预定义的 schema 的?我的 schema 直接是在我 data dir 中的所以就随便设置了个

对,跟 rime-user-data-dir 不同。

终于知道怎么在 Nix 上安装 rime lua 扩展了

nixpkgs.overlays = [
  (final: prev: {
    librime = (prev.librime.override {
      plugins = [
        (pkgs.fetchFromGitHub {
          owner = "hchunhui";
          repo = "librime-lua";
          rev = "7c297e4d2e08fcdd3e9b2dcae2a42317b9a217ff";
          sha256 = "sha256-GVfr2fzaQYyfNnjN20YcNfBVB144gZKVEunbX10Mgeg=";
        })
      ];
    }).overrideAttrs (old: {
      buildInputs = (old.buildInputs or []) ++ [pkgs.luajit];
    });
  })
];
1 个赞