Shows keyboard macros or latest interactive commands as emacs lisp.
Say you have the following text:
violets are blue roses are red
With the cursor somewhere on the first line. Press the following keys:
F3 C-e M-b M-u C-a C-n F4
Then doing M-x elmacro-show-last-macro upcase-last-word RET produces a buffer with:
(defun upcase-last-word () (interactive) (move-end-of-line 1) (backward-word 1) (upcase-word 1) (move-beginning-of-line 1) (next-line 1 1))
You can now do M-x eval-buffer followed by M-x upcase-last-word or call it from your emacs lisp code.
Table of Contents
- Contributions welcome!
The recommended way to install elmacro is through MELPA.
Otherwise, simply add
elmacro.el to your load-path and then
To enable elmacro, do M-x elmacro-mode or enable it from your config file like this:
M-x elmacro-show-last-macro shows your latest macro as emacs lisp.
In order to use this, you must first record a keyboard macro. Then, when you do M-x elmacro-show-last-macro it will ask you for a defun name and show the latest macro as emacs lisp.
M-x elmacro-show-last-commands shows your latest emacs activity as emacs lisp.
This is basically a better version of
The default number of commands shown is modifiable in variable elmacro-show-last-commands-default.
You can also modify this number by using a numeric prefix argument or by using the universal argument, in which case it’ll ask for how many in the minibuffer.
Clears the list of recorded commands.
(elmacro-processor-filter-unwanted elmacro-processor-prettify-inserts elmacro-processor-concatenate-inserts elmacro-processor-handle-special-objects)
List of processors functions used to improve code listing.
Each function is passed the list of commands meant to be displayed and is expected to return a modified list of commands.
Number of commands shown by default in elmacro-show-last-commands.
(copy-file copy-directory rename-file delete-file make-directory)
List of non-interactive functions that you also want to be recorded.
C key in dired)
doesn't reads its arguments as an interactive specification, and
thus the file name is never stored.
Regexps used to filter unwanted commands.
'(("#<frame [^0]+\\(0x[0-9a-f]+\\)>" ",(elmacro-get-frame \"\\1\")") ("#<window \\([0-9]+\\)[^>]+>" ",(elmacro-get-window \\1)") ("#<buffer \\([^>]+\\)>" ",(get-buffer \"\\1\")"))
(regexp replacement) for special objects.
This will be used as arguments for
Set to true to turn debugging in buffer
* elmacro debug *.
The way elmacro processes commands can be modified using processors.
A processor is an emacs lisp function that takes a list the commands meant to be displayed and is expected to return a modified list of commands.
For example, a simple processor that filters anything you insert in a buffer:
(defun filter-insert-processor (commands) (--remove (eq 'insert (car it)) commands))
Remove unwanted commands using elmacro-unwanted-commands-regexps.
Transform all occurences of
This filter should be not be enabled with packages that
self-insert-command, see the FAQ for more information.
(setq last-command-event 97) (self-insert-command 1) (setq last-command-event 98) (self-insert-command 1) (setq last-command-event 99) (self-insert-command 3)
(insert "a") (insert "b") (insert "ccc")
Concatenate multiple text insertion together.
(insert "a") (insert "b") (insert "c")
Turn special objects into usable objects using elmacro-special-objects.
org-mode, smartparens, etc
This is necessary because these packages usually advice
self-insert-command, and by transforming
it into an
insert the advice does not run and we miss functionnality.
A nice addition to normal macros is that mouse events (clicks / scroll) are also recorded and elmacro can figure which emacs window / frame was the target.
For example, by default clicking in a window will generate code like:
(mouse-set-point '(mouse-1 (#<window 75 on foo.el> 913 (90 . 286) 185432429 nil 913 (10 . 15) nil (90 . 1) (9 . 19))))
We see that the
<#window 75 on foo.el> part is not very useful.
Thanks to the processor elmacro-processor-handle-special-objects, the following code is generated
elmacro-get-window is a helper that returns the correct emacs window object):
(mouse-set-point `(mouse-1 (,(elmacro-get-window 75) 913 (90 . 286) 185432429 nil 913 (10 . 15) nil (90 . 1) (9 . 19))))
Either as suggestions or as pull requests by opening tickets on the issue tracker.