在emacs中,我有时会错误地调用call-last-kbd-macro。在撤消时我会预期撤销以原子方式撤消键盘宏的整个效果,但这不会发生。相反,我发现自己必须一次撤消宏的每一步。如何在执行宏之前让emacs返回缓冲区状态?
答案 0 :(得分:3)
我担心你只能使用内置的'undo
机制来做到这一点。 Emacs中的宏系统实际上回放的东西就像用户实际键入击键(或鼠标事件)一样,因此undo history(buffer-undo-list
)正常更新。
以下是如何扩展当前undo
机制以执行您想要的操作的建议。
延长'undo
以了解撤消列表中的新条目,macro-begin
标记和macro-end
元素
建议/更改宏播放以在宏播放的开头/结尾插入标记
让undo
代码将两个标记之间的所有撤消事件视为一个整体并将其全部撤消(并在撤消历史记录末尾添加相应的标记,以便redo
事情,他们仍然被视为一个单独的块)
警告:
macro-begin
和macro-end
标记。 毋庸置疑,这是一项复杂的工作。祝你好运。
答案 1 :(得分:1)
例如,可以通过覆盖undo-boundary
来轻松完成此操作。 noflet
包。
给出如下的宏定义(由insert-kbd-macro
生成):
(fset 'my-macro
[... keys ...])
或:
(fset 'my-macro
(lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ([...keys...] 0 "%d")) arg)))
这样编辑它:
(require 'noflet)
(fset 'my-macro
(lambda (&optional arg) "Keyboard macro." (interactive "p")
(undo-boundary)
(noflet ((undo-boundary ()))
(kmacro-exec-ring-item (quote ([...keys...] 0 "%d")) arg))
(undo-boundary)))
如果您不想编辑所有的宏定义,则可以选择添加一个包装器,该包装器调用作为参数指定的宏,同时如上所述创建/抑制撤消边界。