tags:

views:

37

answers:

1

In emacs, I sometimes invoke call-last-kbd-macro by mistake. When undoing I would have expected undo to undo the entire effect of the keyboard macro atomically, but that does not happen. Instead I find myself having to undo each step of the macro one at a time. How can I get emacs to return to the buffer state before the execution of the macro?

A: 

I'm afraid you can't do that with just the built-in 'undo mechanism. The macro system in Emacs actually plays things back as though the user were actually typing in the keystrokes (or mouse events), and so the undo history (buffer-undo-list) gets updated as normal.

Here's a suggestion of how to extend the current undo mechanism to do what you want.

  1. extend 'undo to understand a new entry in the undo list, a macro-begin marker and a macro-end element

  2. advise/change the macro playback to insert the markers at the beginning/end of the macro playback

  3. have the undo code treat all undo events between the two markers as a unit and undo them all (and add the appropriate markers on the end of the undo history so when you redo things, they're still treated as a single block)

Caveats:

  • This would only work for macros that operate in a single buffer, if your macro switched buffers (or had side effects in other buffers), those changes would not be treated as a block.
  • If your macro ended in a different buffer than it started, then you'd have to handle that cleanly - you don't want "unbalanced" macro-begin and macro-end markers in the undo list.

Needless to say, this is a complicated endeavor. I wish you luck.

Trey Jackson
Thanks Trey. Indeed a complex answer. A simpler but more hackish solution in the same spirit would be to make call-last-kbd-macro (or a wrapper) insert some kind of no-op marker in the undo list. And then create a new function clear-to-macro-marker that would undo all changes until the marker was hit.
dov