tags:

views:

38

answers:

1

I've been using kmacro commands such as kmacro-name-last-macro to save keyboard macros. The problem is that after I have saved a macro and even added it to my .emacs file, I come across an error and want to edit the macro using kmacro-step-edit-macro. If my named macro is no longer in the macro ring (the default kmacro-ring-max is 8) I can't use any of the editing or macro ring commands on that macro. After learning that name-last-kbd-macro will save the symbol form which is easier to edit, I regret using kmacro-name-last-macro and wonder why it is the new default.

Is there are way to add a previously defined macro to the macro ring so I can edit it with kmacro-step-edit-macro?

+1  A: 

Yes, there is a way to add a previously defined macro to the macro ring so you can edit it with kmacro-step-edit-macro :

Imagine you have named a keyboard macro tata using name-last-kbd-macro, and done a insert-kbd-macro for tata. For example :

(fset 'tata
   [return return ?f ?o ?o return])

You can store this macro definition into your .emacs for later use. On a new emacs session, you can use the following lisp code to put back your macro into your kmacro-ring :

(kmacro-push-ring (list 'tata 0 "%d"))
(kmacro-pop-ring)

After that, you can do a kmacro-step-edit-macro on it.

If you have named your macro using kmacro-name-last-macro instead of name-last-kbd-macro, the call to insert-kbd-macro will insert a different definition for your macro, using a lambda function instead of a vector or a string (to be able to store the current counter), for example :

(fset 'tata
   (lambda (&optional arg) "Keyboard macro." (interactive "p")
   (kmacro-exec-ring-item
      (quote ([return return 102 111 111 return] 0 "%d")) arg)))

In this case, kmacro-step-edit-macro raises an error as this is not a vector or a string. To solve this problem you can :

  • either transform your lambda function to a classic vector macro definition (like, for example, the top definition of tata above). It is normally always possible to do this kind of transformation.

  • or define a macro that calls your lambda function macro, for example : (fset 'foo [?\M-x ?t ?a ?t ?a return]) And then you can place this foo macro into the kmacro ring as said before. But in this case, you could have some side-effects at the end of the macro execution.

Jérôme Radix
Reed G. Law
I don't know if it's possible for your case, but you could modify your macro definition macroname to a vector by removing all the command statements and leaving only [1342...25 return]One other solution is to define a vector calling your macro, for example :(fset 'foo [?\M-x ?m ?a ?c ?r ?o ?n ?a ?m ?e return])
Jérôme Radix