工作中不时地会使用 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 来编辑文本。