Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

elisp macro to write a function?

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!

like image 487
Anycorn Avatar asked Mar 13 '10 04:03

Anycorn


People also ask

Does emacs Lisp have macros?

14 Macros. Macros enable you to define new control constructs and other language features. A macro is defined much like a function, but instead of telling how to compute a value, it tells how to compute another Lisp expression which will in turn compute the value.

How do Lisp macros work?

The Common Lisp macro facility allows the user to define arbitrary functions that convert certain Lisp forms into different forms before evaluating or compiling them. This is done at the expression level, not at the character-string level as in most other languages.

What is defun?

defun is the usual way to define new Lisp functions. It defines the symbol name as a function with argument list args (see Features of Argument Lists) and body forms given by body . Neither name nor args should be quoted.

How does let work in Lisp?

The let expression is a special form in Lisp that you will need to use in most function definitions. let is used to attach or bind a symbol to a value in such a way that the Lisp interpreter will not confuse the variable with a variable of the same name that is not part of the function.


2 Answers

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.

like image 143
Sean Avatar answered Oct 21 '22 03:10

Sean


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:

alt text

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.

like image 3
Cheeso Avatar answered Oct 21 '22 03:10

Cheeso