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?
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.
Related
I have never written an emacs function before and was wondering if anyone could help me get started. I would like to have a function that takes a highlighted region parses it (by ",") then evaluates each chunk with another function already built into emacs.
The highlighted code may look something like this: x <- function(w=NULL,y=1,z=20){} (r code), and I would like to scrape out w=NULL, y=1, and z=20 then pass each one a function already included with emacs. Any suggestions on how to get started?
A lisp function is defined using defun (you really should read the elisp intro, it will save you a lot of time - "a pint of sweat saves a gallon of blood").
To turn a mere function into an interactive command (which can be called using M-x or bound to a key), you use interactive.
To pass the region (selection) to the function, you use the "r" code:
(defun my-command (beg end)
"Operate on each word in the region."
(interactive "r")
(mapc #'the-emacs-function-you-want-to-call-on-each-arg
;; split the string on any sequence of spaces and commas
(split-string (buffer-substring-no-properties beg end) "[ ,]+")))
Now, copy the form above to the *scratch* emacs buffer, place the point (cursor) on a function, say, mapc or split-string, then hit C-h f RET and you will see a *Help* buffer explaining what the function does.
You can evaluate the function definition by hitting C-M-x while the point is on it (don't forget to replace the-emacs-function-you-want-to-call-on-each-arg with something meaningful), and then test is by selecting w=NULL,y=1,z=20 and hitting M-x my-command RET.
Incidentally, C-h f my-command RET will now show Operate on each word in the region in the *Help* buffer.
I'm trying to figure out where M-m is bound to back-to-indentation function. When I issue C-h k M-m (describe-key), I get the following output
M-m runs the command back-to-indentation, which is an interactive
compiled Lisp function in `simple.el'.
It is bound to M-m.
(back-to-indentation)
Move point to the first non-whitespace character on this line.
When I look at simple.el, I'm seeing only the definition of function back-to-indentation. I searched throughout the file and I didn't see any keybinding done for that function using define-key. I'm assuming that it happens elsewhere.
How can I identify the location where the function is bound to M-m key?
Emacs version: GNU Emacs 24.2.1 (x86_64-apple-darwin12.2.0, NS apple-appkit-1187.34)
I don't know if that's possible in general, but my guess would be that Emacs doesn't remember where the code was that defined a given key.
C-hb will show the current bindings, from which you can establish which keymap you're interested in, and work from there. For most major or minor mode maps, it won't be too difficult to find the code.
Your specific example is a global binding which Emacs configures in bindings.el.
Adding this at the beginning of my .emacs did the trick for me:
(let ((old-func (symbol-function 'define-key))
(bindings-buffer (get-buffer-create "*Bindings*")))
(defun define-key (keymap key def)
(with-current-buffer bindings-buffer
(insert (format "%s -> %s\n" key def))
(mapbacktrace (lambda (evald func args flags)
(insert (format "* %s\n" (cons func args))))))
(funcall old-func keymap key def)))
The idea is that I redefine the define-key function (which is used to bind key within keymap to def) to first log its arguments to a buffer *Bindings*, together with the stacktrace of where it's being called from. After that it calls the old version of the function.
This creates a closure to store the old value of define-key, so it depends of lexical-bindings being t. In retrospect, I think it would have been possible to use function advising instead; but using a closure felt simpler.
Since I had this at the beginning of my .emacs, this recorded all calls to define-key during initialization. So I just had to switch to that buffer once initialization finished, find the call where the particular key was bound, and then inspect the backtrace to find the site from which that happened.
I have a program that takes as inputs a chunk of data and a list of rules, applying both a set of standard rules and the rules given as input to the chunk of data. The size of both inputs may vary.
I want to be able to write a list of rules like this:
(rule-generating-macro
(rule-1-name rule-1-target
(rule-action-macro (progn actions more-actions)))
(rule-2-name rule-2-target
(rule-action-macro (or (action-2) (default-action))))
;; more rules
)
Right now, rules are more verbose -- they look more like
(defvar rule-list
`((rule-1-name rule-1-target
,#(rule-action-macro (progn actions more-actions)))
(rule-2-name rule-2-target
,#(rule-action-macro (or (action-2) (default-action))))
;; more rules
)
The latter form looks uglier to me, but I can't figure out how to write a macro that can handle a variable-length &rest argument, iterate over it, and return the transformed structure. Using a defun instead of a defmacro isn't really on the table because (as hopefully the example shows) I'm trying to control evaluation of the list of rules instead of evaluating the list when my program first sees it, and once you need to control evaluation, you're in defmacro territory. In this case, the thorny point is the rule-action-macro part - getting the interpreter to read that and use its expanded value has been problematic.
How can I create a macro that handles a variable-length argument so that I can write rule lists in a concise way?
defmacro will happily accept a &rest argument
(see Defining Macros for Emacs Lisp and Macro Lambda Lists for Common Lisp).
Then you can do pretty much anything you want with it in the macro body - e.g., iterate over it. Remember, macro is much more than just backquote!
E.g.:
(defmacro multidefvar (&rest vars)
(let ((forms (mapcar (lambda (var) `(defvar ,var)) vars)))
`(progn ,#forms)))
(macroexpand '(multidefvar a b c d))
==> (PROGN (DEFVAR A) (DEFVAR B) (DEFVAR C) (DEFVAR D))
I want to bind customize-option for a certain variable to a key, since I need to change it rather often. I have two options:
(global-set-key (kbd "<f12>") '(lambda() (interactive) (customize-option 'my-variable) ) )
(global-set-key (kbd "<f12>") '(customize-option 'my-variable )
The first one works, the second does not, because commandp complains that customize-option is not a command. Why? As far as I know, customize-option is an interactive function, so commandp should be t:
customize-option is an interactive compiled Lisp function.
It is bound to .
(customize-option SYMBOL)
Customize SYMBOL, which must be a user option variable.
It is the form (customize-option 'my-variable) which is not a command. You cannot bind to an arbitrary quoted form, any more than you can bind to a literal string or an unbound symbol. Some of those would be useful to bind to, but it's not hard to work around the limitations. Write a macro if you find it hard to live with. (As the saying goes, now you have two problems.)
The second argument to global-set-key must be a command definition, typically a symbol naming an interactive function. An interactive function is a function that begins with the (interactive) form. For example:
(defun delete-to-end ()
"Delete text from point to the end of buffer."
(interactive)
(delete-region (point) (point-max)))
This defines an interactive function and assigns it to the symbol delete-to-end. After that, delete-to-end is a valid command that you can pass to global-set-key:
(global-set-key [f12] 'delete-to-end)
Without the (interactive) line, delete-to-end would still name a function callable from Lisp programs, but it would not be a "command". Since it is marked interactive, (commandp 'delete-to-end) returns true, and M-x delete-to-end works.
Interactive functions don't need to be bound to a symbol, they can be anonymous. Like any other anonymous functions, they are created using a lambda form, except that for commands it must also include (interactive). Anonymous commands can be passed as the second argument to global-set-key without assigning them to a symbol, so the following definition is equivalent to the one above:
(global-set-key [f12]
(lambda ()
"Delete text from point to the end of buffer."
(interactive)
(delete-region (point) (point-max))))
...except it's somewhat less readable, and looks uglier when inspected with C-h c
or C-h k.
In your case, the first call to global-set-key is given a valid command (a quoted lambda form is itself a valid function), but the second one isn't, it is given a two-element list that can neither be called nor satisfies the requirement of being marked "interactive".
I have written a few nearly identical functions, except for their names. For example:
; x is name, such as function/paragraph/line/etc.
(defun my-x-function
(interactive)
(mark-x) (do-more-stuff) (modify-x))
Is there a way to automatically generate such functions? I have a feeling this is what macros do, but I am not sure how to use them. Any help, maybe including a small example would be great.
Thanks!
Yep, that's exactly what macros do. Here's a straightforward macro that builds functions according to the pattern you specified:
(defmacro make-my-function (name)
(list 'defun (intern (format "my-%s-function" name)) ()
(list 'interactive)
(list (intern (format "mark-%s" name)))
(list 'do-more-stuff)
(list (intern (format "modify-%s" name)))))
You can copy this macro to a *scratch* buffer in Emacs and evaluate it, and then check that it works like this:
(make-my-function x) ; type control-J here
my-x-function ; <-- Emacs's output
(symbol-function 'my-x-function) ; type control-J here
(lambda nil (interactive) (mark-x) (do-more-stuff) (modify-x)) ; <-- Emacs's output
More commonly one would use the backquote facility to write macros more concisely, but all macros essentially work in the same manner as the above example.
Macros can do that, but there are lots of template modules for emacs to do similar work. I use a thing called yasnippet.el to do quick code-generation things. For example, in a C-source file, if I type for<TAB>, I get a for loop template; it allows me to fill in the template, setting the variable name, limits, and internal loop contents.
looks like this:
You can set up templates for anything you like. Function definitions, if statements, switch statements, whatever. Set up different templates for different modes. The template for a for loop in C is different than the template for a for loop in C#, and so on. Very handy.