记一个 Emacs 26 Keyboard Macro 输入字符重复的 Bug


工作中不时地会使用 Emacs keyboard macro 来解决重复性的编辑任务, 但有时录制了再重放却出现输入的字符被重复了,导致出现非预期的结果。 一般此时为了赶进度,只好忍了,放弃使用 keyboard macro ,改用其他方式编辑代码。

如果你不知道或者没怎么用 emacs keyboard macro ,以下这个视频演示了如何用它来快速制作大块的有序列表,让你有个更直观的了解:

诡异的是等到有空闲的时候尝试重现却又重现不了,还一度以为是由于 keyboard macro 不支持输入 M-x 命令导致的, 但又没看到其他 Emacser 提到有此限制。

问题虽然偶尔才出现,但是一旦出现,工作流会被打断,很让人苦恼。 好在春节期间终于被我重现出来了,这个问题在启用 pyim 输入法的情况下必现,比如在录制时输入 nihao 得到了 你好 , 但是在 replay keyboard macro 的时候,得到的效果却相当于人工输入了 nniihhaaoo ,每个输入字符都被重复了一次, 自然就没法得到 你好 二字,详细的重现步骤见这个 pyim issue

pyim 维护者 @tumashu 帮忙确认了 Emacs 自带的 quail-chinese 输入法也有此问题,建议我去 mailing list 问下看看。 最后 Emacs maintainer Eli Zaretskii 在 这个 thread 告知半年前已经有人在 Bug #32108 中报告了, 且已经在 master 中修复了( commit 03e3440dbbfea40b449a9f6f23a3630664275d11 ),将会包含在 Emacs 27 发布中。

修复原理大致是在内核中增加一个标记 inhibit--record-char ,由输入法根据情况设置为 t/nil , 当值为 t 时内核不会把事件记录到 last-kbd-macro 中(见 record-char 函数), 这样输入法出于实现需要重放的用户输入字符,就不会被重复记录到 keyboard macro 中。

Emacs 自带的输入法虽然已经解决了问题,但是 pyim 还没解决,接下来如果有时间再研究下如何解决( Emacs 27 已经编译好了 :) ), 在彻底解决之前,如果在录制 keyboard macro 时不需要输入中文,可以通过 M-x toggle-input-method 切换回英文输入来 workaround , 这样就能避开这个 bug ,继续用 keyboard macro 来编辑文本。

Emacs 

也可以看看

comments powered by Disqus