A few notes on Elisp indentation
28 Jan 2015I sure do like to keep my Elisp code nice and indented. But sometimes the indentation engine just won't listen.
lisp-indent-function
By default, the indentation is handled as if:
(setq lisp-indent-function 'lisp-indent-function)
At least in one case, it looks horrible:
(cl-labels ((square (x)
(* x x)))
(mapcar #'square '(0 1 2 3 4 5)))
;; => (0 1 4 9 16 25)
That's why I have:
(setq lisp-indent-function 'common-lisp-indent-function)
which leads to this indentation:
(cl-labels ((square (x)
(* x x)))
(mapcar #'square '(0 1 2 3 4 5)))
;; => (0 1 4 9 16 25)
Ah, much better. The indentation does change a bit in other places as a result of this. To my experience, it can be fixed on a case-by-case basis by declaring the indent level for the offending function or macro.
Declaring indent level
Here's how it looks like
(defmacro lispy-save-excursion (&rest body)
"More intuitive (`save-excursion' BODY)."
(declare (indent 0))
`(let ((out (save-excursion
,@body)))
(when (bolp)
(back-to-indentation))
out))
By default, functions behave as if their indent
was declared to nil
.
Zero here means that we expect zero arguments on the same line, so that this indentation follows:
(lispy-save-excursion
(lispy--out-forward arg)
(backward-list)
(indent-sexp))
The indentation above is just like the one that the original save-excursion
has.
Note that if I hadn't declared the indent, it would look like this:
(lispy-save-excursion
(lispy--out-forward arg)
(backward-list)
(indent-sexp))
The impact is much larger for statements that require an indent
of 1:
Compare the proper thing:
(lispy-dotimes arg
(when (= (point) (point-max))
(error "Reached end of buffer"))
(forward-list))
to this horror:
(lispy-dotimes arg
(when (= (point) (point-max))
(error "Reached end of buffer"))
(forward-list))
Outro
I've shown two things you can try if you find your Elisp indentation annoying. If you know of more, let me know.