Eric J.M. Ritz has an excellent post on indenting Elisp code. Say what? Isn’t that what Emacs is for? Yes but there’s a corner case when you’re writing macros.
Here’s a macro that I use to make my Elisp code work on a region if one’s defined or on the whole buffer if not.
(defmacro with-region-or-buffer (args &rest body) "Execute BODY with BEG and END bound to the beginning and end of the current region if one exists or the current buffer if not." `(let ((,(car args) (if (use-region-p) (region-beginning) (point-min))) (,(cadr args) (if (use-region-p) (region-end) (point-max)))) ,@body))
As it stands, a call to that macro would get formatted as
(with-region-or-buffer (start end) (blah start end) (more blahs start end))
but that’s not what we want. We’d like it to get formatted as
(with-region-or-buffer (start end) (blah start end) (more blahs start end))
The easy way to get Emacs to indent it properly is with the declare
declaration as shown in the slightly revised version of with-region-or-buffer
shown below.
(defmacro with-region-or-buffer (args &rest body) "Execute BODY with BEG and END bound to the beginning and end of the current region if one exists or the current buffer if not." (declare (indent 1)) `(let ((,(car args) (if (use-region-p) (region-beginning) (point-min))) (,(cadr args) (if (use-region-p) (region-end) (point-max)))) ,@body))
It’s really hard to find the documentation for this (at least I always find it hard) so I’m glad to have Ritz’s post for bookmarking purposes. The post has a link to the documentation for declare
so you can see what other arguments to the indent
declaration are possible.
Update: what’s → what