Backquote and Unquote
Knowing that limited-save-excursion
must be a macro function, all we have to do is imagine how a call to limited-save-excursion
should expand. Here's a start:
(limited-save-excursion subexpr1 subexpr2 ...)
expands to
(let ((orig-point (point))) subexpr1 subexpr2 ... (goto-char orig-point))
Here's how to write that as a Lisp macro function:
(defmacro limited-save-excursion (&rest subexprs) "Like save-excursion, but only restores point." (append '(let ((orig-point (point)))) subexprs '((goto-char orig-point))))
Remember that append
works by effectively stripping off the outer parentheses of each list, gluing the results together, and putting a new pair of parentheses around the result. So this call to append
takes three lists:
(let ((orig-point (point))))
(subexpr1 subexpr2 ...)
((goto-char orig-point))
strips off their outer parentheses:
let ((orig-point (point)))
subexpr1 subexpr2 ...
(goto-char orig-point)
and surrounds the result with new parentheses:
(let ((orig-point (point))) subexpr1 subexpr2 ... (goto-char orig-point))
That's the expansion of the macro, which then gets evaluated.
That would do the trick, but it's hard to read the macro definition and understand what's going on. Fortunately, there's a better way. It turns out that nearly all macros recombine their arguments with calls to such functions as list
and append
, with some expressions quoted and others not. In fact, that's so common that Emacs Lisp has a special syntax making it possible to write templates ...
Get Writing GNU Emacs Extensions now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.