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.
The recommended way to install elmacro is through MELPA.
Otherwise, simply add elmacro.el
to your load-path and then (require 'elmacro)
.
To enable elmacro, do M-x elmacro-mode or enable it from your config file like this:
(elmacro-mode)
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 kmacro-edit-lossage
.
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.
Default value: (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.
Default value: 30
Number of commands shown by default in elmacro-show-last-commands.
Default value: (copy-file copy-directory rename-file delete-file make-directory)
List of non-interactive functions that you also want to be recorded.
For example, dired-copy-file
(C
key in dired)
doesn't reads its arguments as an interactive specification, and
thus the file name is never stored.
Default value: ("^(ido.*)$" "^(smex)$")
Regexps used to filter unwanted commands.
Default value:
'(("#<frame [^0]+\\(0x[0-9a-f]+\\)>" ",(elmacro-get-frame \"\\1\")")
("#<window \\([0-9]+\\)[^>]+>" ",(elmacro-get-window \\1)")
("#<buffer \\([^>]+\\)>" ",(get-buffer \"\\1\")"))
List of (regexp replacement)
for special objects.
This will be used as arguments for replace-regexp-in-string
.
Default value: nil
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 self-insert-command
into insert
.
This filter should be not be enabled with packages that
advice self-insert-command
, see the FAQ for more information.
Before:
(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)
After:
(insert "a")
(insert "b")
(insert "ccc")
Concatenate multiple text insertion together.
Before:
(insert "a")
(insert "b")
(insert "c")
After:
(insert "abc")
Turn special objects into usable objects using elmacro-special-objects.
Normally elmacro
works reasonably well with these, but if you want to ensure the most accurate experience you should
disable the elmacro-processor-prettify-inserts processor (see elmacro-processors).
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
instead (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.