Emacs 远程开发利器:TRAMP-RPC 极速体验
如果你曾尝试在 Emacs 中通过 TRAMP 打开远程项目、浏览目录、编辑文件、或使用 magit 管理代码,你大概率经历过这种感受:卡。
一个简单的 find-file 要等上好几秒, dired 列个目录像在拨号上网, magit-status 打开后先去接杯水,回来可能还没渲染完。
这不是你的网络问题,是 TRAMP 的实现方式决定的。
TRAMP 是什么
TRAMP(Transparent Remote Access, Multiple Protocol)是 Emacs 内置的远程文件访问层。它让你可以像操作本地文件一样操作远程文件:
;; 通过 SSH 打开远程文件
C-x C-f /ssh:user@remote-host:/path/to/file
;; 打开远程目录
C-x C-f /ssh:user@remote-host:/home/user/project/
TRAMP 让你无需 scp、无需 SSH 登录,直接在 Emacs 中编辑远程服务器上的代码——这对开发和运维来说是非常丝滑的体验。
**但其底层原理存在性能瓶颈**:
传统 TRAMP 通过 SSH 登录到远程机 → 执行 shell 命令(如 ls 、 stat 、 cat ) → 解析 shell 输出的文本。每一个文件操作都可能触发多轮 SSH 往返。每轮往返产生数十毫秒延迟,操作多了后感受会非常明显。
TRAMP-RPC:用二进制 RPC 替换 Shell 解析
emacs-tramp-rpc 是 ArthurHeymans 开发的高性能 TRAMP 后端。它用一个轻量的 Rust 服务端替代了 shell 命令解析,通过 MessagePack-RPC 协议与 Emacs 通信。目前已获得 270+ GitHub stars。
**核心区别**:
| 维度 | 传统 TRAMP | TRAMP-RPC |
|---|---|---|
| 通信方式 | Shell 命令 + 文本解析 | MessagePack 二进制 RPC |
| 单次操作延迟 | 多次 SSH 往返 | 单次往返 |
| 批量操作 | 不支持 | 原生支持,一次请求搞定 |
| 远程依赖 | 需要 shell 环境 | 无需 shell |
| 二进制体积 | 无 | Rust 编译后 ~850KB |
**实测性能对比**(来自官方 benchmark):
| 操作 | RPC 耗时 | SSH 耗时 | 加速比 |
|---|---|---|---|
| connection-setup | 31 ms | 1.17 s | 38.2x |
| file-exists | 3.3 ms | 38.8 ms | 11.9x |
| dir-files-and-attrs | 3.5 ms | 95.9 ms | 27.1x |
| directory-files | 12.1 ms | 37.2 ms | 3.1x |
| copy-file | 43.1 ms | 192.0 ms | 4.5x |
| 批量 10x file-attributes | 37.6 ms | 304.7 ms | 8.1x |
批量请求还可叠加 2-4 倍提升(如 10x stat 从 37.6ms 降至 9.1ms)。
架构:Emacs + Rust 的完美协作
┌─────────────┐ SSH/MessagePack-RPC ┌──────────────────┐
│ Emacs │ ◄────────────────────► │ tramp-rpc-server │
│ (tramp-rpc) │ │ (Rust) │
└─────────────┘ └──────────────────┘
Emacs Lisp 客户端负责 TRAMP 文件操作协议层的对接,Rust 服务端运行在远程主机上,负责实际文件系统操作。两者通过 SSH 建立连接,使用 MessagePack 二进制编码,支持请求批处理(batch)和命令并行执行。
Emacs Lisp 端模块划分:
| 模块 | 职责 |
|---|---|
| tramp-rpc.el | 核心 RPC 通信与文件操作处理器 |
| tramp-rpc-process.el | 异步进程与 PTY 支持(vterm/eat) |
| tramp-rpc-magit.el | Magit/Projectile 优化与缓存 |
| tramp-rpc-deploy.el | 二进制自动部署与版本管理 |
| tramp-rpc-advice.el | 进程 I/O 与 VC 集成的 advice 函数 |
| tramp-rpc-protocol.el | MessagePack-RPC 协议实现 |
安装
-
环境要求
- Emacs 30.1 或更高版本
- Tramp 2.8.1.4 或更高
- SSH 可访问远程主机
- 远程主机:Linux 或 macOS(x86_64 / aarch64)
-
在 Neo Emacs(Doom 系)中的配置
第一步,在 packages.el 中添加依赖:
(package! msgpack) (package! tramp-rpc :recipe (:host github :repo "ArthurHeymans/emacs-tramp-rpc" :files ("lisp/*.el")))第二步,在 config.el 中配置:
(use-package! msgpack) (use-package! tramp-rpc) ;; 构建策略:优先从 GitHub Release 下载(最快) (setq tramp-rpc-deploy-git-build-policy 'release) ;; 本地缓存目录(建议放在 doom 配置目录下) (setq tramp-rpc-deploy-local-cache-directory "~/.doom.d/neoemacs/tramp-rpc-binaries") ;; 远程安装目录 (setq tramp-rpc-deploy-remote-directory "~/.cache/emacs/tramp-rpc")配置说明:
- tramp-rpc-deploy-git-build-policy :设为 ’release 时,优先下载预编译 GitHub Release 版本(~850KB),仅在下载失败时才尝试本地编译。
- tramp-rpc-deploy-local-cache-directory :本地存储二进制文件的路径,缓存后可复用,避免重复下载。
- tramp-rpc-deploy-remote-directory :服务端二进制存放路径。
连接远程主机
使用 rpc 方法前缀代替原来的 ssh :
C-x C-f /rpc:user@host:/path/to/file
首次连接时,TRAMP-RPC 会自动完成部署流程:
用户连接 /rpc:host:/path
│
▼
远程已有二进制?── yes ──► 启动就绪
│ no
▼
检查本地缓存
│
├─ 命中 ────────► 传输到远程
│
▼
从 GitHub Releases 下载
│
└─ 成功 ────────► 缓存 + 传输到远程
整个过程全自动,你只需等待数秒。
总结
TRAMP-RPC 是对 Emacs TRAMP 系统的一次本质性升级。它用 Rust 服务端 + MessagePack 二进制协议替换了传统 shell 文本解析,将远程文件操作的速度提升了数倍到数十倍。
对于像 essayWorkFlow 这样需要频繁与远程服务器交互的项目,TRAMP-RPC 让日常的远程文件操作、代码编辑、Git 管理变得流畅高效,真正实现了“远程如本地”的开发体验。
| 项目 | |
|---|---|
| 仓库地址 | github.com/ArthurHeymans/emacs-tramp-rpc |
| 许可协议 | GPL-3.0 |
| 技术栈 | Emacs Lisp + Rust + MessagePack |
| 当前版本 | 0.9.1 |