如何在emacs中撤消call-last-kbd-macro

Dov*_*eld 7 emacs undo

在emacs中,我有时会错误地调用call-last-kbd-macro.在撤消时我会预期撤销以原子方式撤消键盘宏的整个效果,但这不会发生.相反,我发现自己必须一次撤消宏的每一步.如何在执行宏之前让emacs返回缓冲区状态?

Tre*_*son 3

恐怕仅使用内置'undo机制无法做到这一点。Emacs 中的宏系统实际上会回放内容,就像用户实际键入击键(或鼠标事件)一样,因此撤消历史记录( buffer-undo-list) 会正常更新。

以下是有关如何扩展当前undo机制以实现您想要的功能的建议。

  1. 扩展'undo以了解撤消列表中的新条目、macro-begin标记和macro-end元素

  2. 建议/更改宏播放以在宏播放的开头/结尾插入标记

  3. undo代码将两个标记之间的所有撤消事件视为一个单元并撤消所有事件(并在撤消历史记录的末尾添加适当的标记,这样当您redo进行操作时,它们仍然被视为单个块)

注意事项:

  • 这仅适用于在单个缓冲区中运行的宏,如果您的宏切换缓冲区(或在其他缓冲区中产生副作用),则这些更改不会被视为块。
  • 如果您的宏在与开始时不同的缓冲区中结束,那么您必须干净地处理它 - 您不希望撤消列表中出现“不平衡”macro-begin和标记。macro-end

不用说,这是一项复杂的工作。祝你好运。

  • 沿着这些思路,http://www.panix.com/~harley/elisp/undo-group.el 添加了一个标记,即两个“nil”,然后将其用作“undo-group”命令的边界。 (4认同)
  • 谢谢特雷。确实是一个复杂的答案。本着同样的精神,一个更简单但更黑客的解决方案是让 call-last-kbd-macro (或包装器)在撤消列表中插入某种无操作标记。然后创建一个新的函数clear-to-macro-marker,它将撤消所有更改,直到命中该标记。 (2认同)