在 Android Emacs 中使用 doom-emacs

本文目标:在一个安卓设备上,成功安装GUI Emacs且能使用 Termux 管理 Emacs 所用的 git 等工具。同时,成功加载 doom-emacs 配置。

2023 年初,即将发布的 Emacs 30.1 将对 Android GUI 的支持包括其中。这意味着除了桌面端,移动端也有原生的 Emacs 体验了。(当然,iOS由于其自身特性,未来也不可能支持 Emacs。)

与常规安卓应用不同的是,要想更好的在安卓平台使用 Emacs,直接安装 APK 远远不足,还需要进行额外配置。

此外,因为 doom-emacs 的配置涉及到调用 Emacs 本身,但是安卓系统又没有提供现成的 emacs 可执行命令,配置起来不如桌面端顺畅。在此分享我的配置经验,希望多少能帮到一些朋友。

在此特别感谢 oldosfan,ta 是 Android Port 主要贡献者,并且在如何在 Android Emacs 配置 doom-emacs 对我帮助良多。

1. 安装 Android Emacs

最佳方式是安装特定版本的Emacs和Termux,二者共享相同的 sharedUserId manifest attribute 和签名,这意味着二者可以互相访问对方的数据文件夹( /data/data/org.gnu.emacs//data/data/com.termux/ ),这样使用 Termux 来安装 GNU/Linux 应用程序后,Emacs 中就可以运行这些应用程序。


  1. Emacs 和 termux 必须按照特定的顺序安装特定的版本,如果之前已经安装过,请先卸载,以避免 sharedUserId 或签名冲突。
  2. ​安装特定版本的 Termux,从 Android ports for GNU Emacs - Browse /termux at SourceForge.net 下载APK文件进行安装。安装完成先不要打开 Termux。
  3. ​从上一个网址中选择合适版本的 Emacs 来安装。
    • 👎 不推荐F-Droid 的版本,因为:
      • 版本并非最新:缺少错误修复和新功能。
      • 缺少许多依赖包:GnuTLS, image libraries, tree-sitter
    • 挑选主要依据​安卓系统版本​和​芯片CPU架构​。例如 emacs-30.0.50-29-arm64-v8a.apk 适用于运行 Android 10.0 或更高版本的 aarch64 设备,是一个常见的选择。如果安装的版本不匹配,将无法正常执行。
  4. 两个都安装完成,打开 Termux,执行以下命令,安装并更新所有应用程序。

    pkg update && pkg upgrade
    
    • 如果太慢,可以考虑Termux换成国内镜像源。
  5. 打开 Emacs,在 ~/.emacs.d/early-init.el 中加入:

    1
    2
    3
    4
    5
    (when (string-equal system-type "android")
    ;; Add Termux binaries to PATH environment
    (let ((termuxpath "/data/data/com.termux/files/usr/bin"))
    (setenv "PATH" (concat (getenv "PATH") ":" termuxpath))
    (setq exec-path (append exec-path (list termuxpath)))))

    • 该代码将 Emacs 与 Termux 文件系统绑定,从而让 Emacs 访问通过 Termux 安装的程序。
    • 🤔 官方文档还对 LD_LIBRARY_PATH 环境变量进行了配置。但是配置之后,在 Emacs 中运行 mpv 会出现问题,不配置这个变量也暂未发现问题。留待观察。
  6. 重启 Emacs,应用配置。如果你在 Termux 中已经安装了 git,可以尝试在 Emacs 执行 (executable-find "git") 。如果返回git的路径,说明配置成功。

2. 使用 doom-emacs 配置

因为,Android 中没有 Emacs 可执行文件,shell 路径也不同,因此需要一定的修改才能进行 doom install。以下操作​请注意区分​,是在Termux中运行,还是在 Emacs Shell 中运行。


  1. 在 Termux 中安装 Git

    pkg install git
    
  2. 在 Termux 中,=git clone= doom-emacs 到 Emacs 主目录

    git clone --depth 1 https://github.com/hlissner/doom-emacs /data/data/org.gnu.emacs/files/.emacs.d.doom
    
  3. 在 Android Emacs 的 shell 环境中,软链接 emacs 可执行文件:

    ln -s /data/data/org.gnu.emacs/lib/libandroid-emacs.so /data/data/com.termux/files/usr/bin/emacs
    
    • 链接成功后,在Android Emacs中运行 emacs --version 应该可以看到:

      emacs –version GNU Emacs 30.0.50 Copyright (C) 2024 Free Software Foundation, Inc. GNU Emacs comes with ABSOLUTELY NO WARRANTY. You may redistribute copies of GNU Emacs under the terms of the GNU General Public License. For more information about these matters, see the file named COPYING.

    • 否则,在执行doom时会报错:

      Error: failed to run Emacs with command 'emacs'

      Are you sure Emacs is installed and in your $PATH?

  4. 编辑 .emacs.d.doom/bin/doom ,修改 Shebang:​#!/usr/bin/env sh#!/system/bin/sh
    • hlissner 建议不要修改doom Shebang,直接在执行命令时指定 shell,例如 sh ~/.emacs.d/bin/doom install=。很遗憾,由于 cache 机制该方案并不生效,必须修改 doom Shebang。升级doom需要使用 =doom upgrade --force 并再次修改 Shebang。
  5. ~/.emacs.d/early-init.el 中的内容添加到 ~/.doom.d/init.el​,以便生成 doom env 文件的时候把 Termux 路径加入到 PATH 环境变量。
  6. 在 Android Emacs 的 shell 环境​中执行 doom install
    • 在Android Emacs 的 shell 环境中执行 doom install 非常慢,可以考虑把其他环境的 repos 文件夹复制到 ~/.emacs.d.doom/.local/straight/repos 再执行 doom install,跳过 git clone,加快速度。
    • 如果提示 error ("Failed to run \"git\"; see buffer *straight-process*") ,可以尝试:
      • 检查 doom 的 env 文件是否把 Termux 路径加入到 PATH
      • 在 eshell中执行命令,不要在 shell 中执行
      • 执行 (setq android-use-exec-loader nil)
  7. 安装完成之后,把 .emacs.d.doom 软链接为 .emacs.d=。建议不要直接改名,这样未来改变 =.emacs.d 指向的路径就可以切换配置,进行debug。
  8. 重新启动,Emacs 应该可以加载 doom-emacs 配置了。由于 Android 和桌面端的路径以及支持的功能并不完全一致。一般需要对 doom-emacs 配置进行调整。享受在 Android 上使用 Emacs 的快乐吧。

3. 更新历史

  • [2024-03-09 六] 编辑文件从 .emacs.d.doom/early-init.el → =~/.doom.d/init.el=,减少对 doom-emacs repo 的修改,感谢 hlissner
  • [2024-02-04 日] 初稿

Date: 2024-02-04 日 00:00

Validate

版权声明

本文由宇晨创作,采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

首发于跬步,转载或引用请注明出处,本文永久链接:在 Android Emacs 中使用 doom-emacs

知识共享许可协议