ShannonMax:一个利用信息论优化 Emacs 键绑定的库
Source: Hacker News
ShannonMax 使用信息论来 分析你的 Emacs 使用情况 并 建议更好的键绑定。
它帮助你找到那些通过更改键绑定可以显著减少敲击次数的命令。

警告: 使用键盘记录器时,请注意不要记录任何敏感信息!
引用此软件
Straus, S. (2024). Better Keybindings with Information Theory [Computer software]. Retrieved from https://github.com/sstraust/shannonmax
原始演讲 – Better Keybindings with Information Theory – YouTube
Source: …
如何使用
-
下载所需文件
shannon-max.eltarget/emacskeys-0.1.0‑SNAPSHOT‑standalone.jar
-
将它们放在同一目录,该目录需在你的 Emacs
load‑path中,例如:~/.emacs.d/custom/shannon-max.el ~/.emacs.d/custom/target/emacskeys-0.1.0-SNAPSHOT-standalone.jar -
在你的
~/.emacs(或init.el)中添加以下内容:;; 将目录加入 Emacs 的 load‑path (add-to-list 'load-path "~/.emacs.d/custom") ;; 加载 shannon‑max 包 (require 'shannon-max) ;; 告诉包 JAR 文件所在位置 (setq shannon-max-jar-file (expand-file-name "~/.emacs.d/custom/target/emacskeys-0.1.0-SNAPSHOT-standalone.jar")) -
确保你的机器已安装 Java(JVM),并且 JAR 文件具有可执行权限:
chmod +x ~/.emacs.d/custom/target/emacskeys-0.1.0-SNAPSHOT-standalone.jar -
开始收集按键记录数据
在你的 Emacs 配置中添加以下行(或手动求值):
(shannon-max-start-logger)运行几分钟后,检查
~/emacs-logged-keys是否已有数据写入。 -
分析收集到的数据
当样本足够时,执行:
M-x shannon-max-analyze该命令将显示你在 Emacs 中键位使用的 Shannon 熵分析结果。
查看输出
您可以随时调用分析:
M-x shannon-max-analyze
在结果缓冲区中可以使用以下键绑定:
| 键 | 操作 |
|---|---|
C-c C-n | 向下滚动一页结果 |
C-c C-p | 向上滚动一页结果 |
C-c C-e | 调用 keymap-global-set 在全局绑定键(仅限 Emacs 29+) |
解释结果
Shannonmax 将键绑定的 实际 长度(例如 "x e" 的长度为 2)与其 理论 长度进行比较——理论长度是基于您使用该命令的频率应当拥有的长度。
理论长度来源于对您记录的命令使用情况进行的信息论分析。
- 常用命令 → 应该拥有 更短 的键绑定。
- 不常用命令 → 可以容忍 更长 的键绑定。
典型工作流程
- 找出 对常用命令来说过长 的键绑定。
- 将它们重新绑定为更短、更方便的组合。
- 如果便利的键位用尽,考虑 解除对不常用命令的过短键绑定,以释放空间。
想要观看可视化演示,请观看教程视频:
Shannonmax Overview (YouTube)
自定义行为
shannon-max-custom-keypress-cost
默认情况下,shannon‑max 假设每一次按键的成本为 1。
包含控制字符的序列会为每个控制字符额外增加 1 的成本。
示例
| 序列 | 成本 |
|---|---|
a | 1 |
a b | 2 |
C-a | 2 |
C-M-a | 3 |
C-x C-s | 4 |
如果你想使用不同的成本模型,可以提供自己的成本函数并相应地调整字母表大小(见下文)。
shannon-max-alphabet-size
该变量表示 单次按键可以产生多少种不同的命令。
它用于计算给定键命令的理论长度。
- 当只有 2 个键 时,键绑定必须相对较长才能编码所有可能的命令。
- 当有 100 个键 时,键绑定可以更短。
默认假设 52 个键(A–Z 和 a–z),且每次按键的成本为 1。
如果你更改了成本函数,请为新的成本加权“键盘”重新计算合适的字母表大小。正确的做法是求解 Shannon 论文中描述的特征方程(见第 3 页):
未来的工作将自动化此计算。
在此期间,你可以尝试不同的取值,直到结果看起来合理为止;你仍然会得到有用且可操作的输出。
shannon-max-filtered-commands
一个要在输出中 忽略 的 Emacs 命令列表。
默认情况下,匹配 "lambda"、"(" 或 "[" 的命令会被过滤掉——这对于排除自插入命令及类似项目很有用。
shannon-max-filter-commands-fn
一个执行与 shannon-max-filtered-commands 相同过滤操作的函数,但允许你实现自定义的排除逻辑。
已知限制
键盘记录器的限制
某些包会干扰键盘记录器正确记录命令的能力。
shannonmax 在 post-command-hook 中使用 real-last-command 和 this-command-keys-vector 来确定要记录的键/命令。像 ido-mode 这样的包可能会破坏这些值。
我们使用 post-command-hook(而不是 pre-command-hook),以便在 god-mode 激活时能够正确捕获记录的键。
如果你有想法或解决方案,欢迎告诉我!
对主/次模式的更好支持
有些键绑定仅在特定的主模式或次模式下有效。
理想情况下我们会为每个模式计算单独的键映射,但要正确且保持实用性地实现这一点,需要精心设计。
对多命令 / 算术编码的支持
为了生成最优的输出,我们希望能够识别常用 Emacs 命令的 对 或 序列,并将它们折叠为单一的逻辑键绑定。
更多待办事项
- 通过 MELPA 实现更简便的安装
- 为重新绑定键提供更友好的 UI 菜单(而不是使用
keymap-global-set) - 改进对大写字母的处理
还有其他想法吗? 欢迎在仓库中打开 issue! :D