10

Classic use-case:

  1. You start recording a macro: C-x (
  2. You do some stuff, let's say hello.
  3. You run a command that throws an error, let's say C-g (e.g. you mistakenly run C-s and you have to cancel that with C-g, now your work is lost).

Now your recording so far is lost.

I would like to resume where I left off before I ran a command which interrupted my recording. I looked at C-h f start-kbd-macro, but it's written in C, so I can't tweak it. I also hunted around for a variable like current-kbd-macro, but found none so far.

Can it be recovered?

Update:

I couldn't figure out why C-u C-x ( wasn't working for me, but I've discovered it's because I was testing with C-g.

It turns out that C-g is special -- if you trigger a different kind of error e.g.

C-x ( M-: (signal 'quit nil) 

Then this will stop the recording, but last-kbd-macro will contain "M-: M-( signal 'quit nil", but with

C-x ( C-g

This stops recording and discards anything recorded. As a C-g-happy user (as are at least two of my friends), this is a rather unfortunate distinction. I tried editing keyboard-quit, but there's nothing I can do in there.

It looks like the only way to recover this is via recent-keys and automatically figuring out where a start-kbd-macro (or similar) was called, as in kmacro-edit-lossage.

8

I started an implementation here which lets you rebind your C-x ( to resmacro-start-macro.

Now, suppose you get half way through a macro and make a mistake and hit C-g, e.g. you run C-s by mistake and so you hit C-g to cancel it, or w/e.

C-x ( hello C-s C-g 

Now run C-u C-x ( which will prompt in the minibuffer with:

Resume macro with (RET: continue, DEL: remove last): h e l l o C-s

So you hit backspace (DEL) to delete the C-s and then RET to proceed. Now it says:

Appending to kbd macro...

And you can continue.

In total:

C-x (      -- start macro
hello
C-s        -- mistake
C-g        -- cancel mistake (and macro)
C-u C-x (  -- recover lost macro
DEL        -- remove mistake
RET        -- continue recording
world!

Convenient, no context switch, minimum keybindings to achieve task, automatically figures out where your macro started (at C-x () from (recent-keys).

  • 1
    Hey, that sounds really nice. Care to submit it as a patch to Emacs? – Stefan Nov 7 '14 at 14:17
  • You're welcome to do so/relicense as you like! I'm going to trial it for a while locally before announcing it anywhere, so that I can know it's reliable. The Emacs maintainers might think it's too hacky, though. ;-) – Christopher Done Nov 7 '14 at 18:12
  • To include it in Emacs we need the author to sign copyright paperwork (the same paperwork would also cover god-mode, of course). – Stefan Nov 7 '14 at 21:12
  • The link is broken now :( – DirtY iCE May 13 '18 at 15:14
2

Execute kmacro-start-macro-or-insert-counter with prefix (C-u) to append to the previous macro.

  • 2
    The docstring doesn't say so, but a double prefix arg (C-u C-u) sets both the APPEND and NO-EXEC arguments to start-kbd-macro, which lets you append without the initial replay of the macro-so-far. This behaviour is documented in the manual, however: (emacs) Basic Keyboard Macro – phils Nov 7 '14 at 2:42
  • Try this with the example in my question, does not work. – Christopher Done Nov 7 '14 at 13:20
2

Combining the good answers from stsquad and artagnon gives (to my mind) a total solution to the problem which is entirely reasonable:

  • C-xC-keC-hl to edit a macro generated from the lossage
  • edit the macro, to reduce it to the original recording
  • C-cC-c to store the edited macro
  • Either C-u<f3> to firstly replay that macro, and then continue recording subsequent keystrokes which will be appended to the macro definition
  • ...or C-uC-u<f3> to continue recording without the initial replay of the macro-thus-far.

Maybe the need to edit the lossage-as-macro isn't ideal, but (a) you were bound to need to edit the macro regardless, if you aborted the recording, and (b) this shouldn't be happening very often, if you just remember how to stop the macro normally (e.g. with <f4> rather than C-g).

None of which is to say that it wouldn't be useful if the aborted macro was stored somewhere; it's just that I don't think this actually happens. It would probably be worth M-x report-emacs-bug to suggest this feature.

  • This does not address the problem. With your solution half of the time it would be easier to just start the macro over again. I've posted an answer elsewhere which does solve the problem nicely. – Christopher Done Nov 7 '14 at 13:22
  • 1
    Sure, for simple cases starting over would be easier. It's still useful for the remainder, though, which means some people will find it helpful; especially as it's available by default. As I indicated, I think the idea of a more automated approach is a good one, so I'm happy to see you working on a solution, and have certainly up-voted your answer. – phils Nov 7 '14 at 13:34
0

The canonical solution is C-x C-k C-e (kmacro-edit-macro) which will allow you to step through each key-press and insert/delete whatever you want. The command syntax for the editor is a little terse but ? will bring up a guide. There is a more natural editor bound to C-x C-k e (edit-kbd-macro) which gives a plain text macro editor with commentary.

Another option is M-x insert-kbd-macro which will allow you to edit the macro as Lisp but it's not the most readable thing in the world.

As far as variables are concerned you are looking for last-kbd-macro and kmacro-ring.

As you mention you haven't completed your macro, you can just create it from your lossage. C-x C-k e C-h l and delete up to 300 preceding characters.

  • This is a bad answer I'd downvote if I could. You either didn't read the question or are ignoring it. Neither last-kbd-macro nor kmacro-ring contain the keys pressed before C-g or an error happened. I specifically put INCOMPLETE in all-caps in my title anticipating such bad answers. Thanks for trying to help, though. – Christopher Done Nov 6 '14 at 23:09
  • 1
    @ChristopherDone: sure you can - I've added a note at the bottom to mention the lossage. You can create a macro from up to 300 of your previously typed characters. – stsquad Nov 6 '14 at 23:22
  • Yeah, someone mentioned lossage on #emacs. I just want to resume where I left off. I don't want to have to open the editor and start deleting things from that when I'm in the middle of doing something. – Christopher Done Nov 6 '14 at 23:34
  • 2
    The combination of this and artagnon's answers give a fine solution: C-x C-k e C-h l, edit, C-c C-c, then C-u f3 to carry on recording (noting that that last f3 will firstly play the macro-thus-far before awaiting further input). Maybe the need to edit the lossage-as-macro isn't ideal, but (a) you were bound to need to edit the macro regardless, if you aborted the recording, and (b) this shouldn't be happening very often, if you just remember how to stop the macro normally. – phils Nov 7 '14 at 2:32
  • 1
    @phils +1 Maybe you should turn that into a separate answer. – itsjeyd Nov 7 '14 at 8:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.