Let's say I have a function that looks like the following (as is often the case when printing elisp output).

(defun my-example-function () (let ((a (do-something)) (b (do-something))) (setq someone me) (with-current-buffer b (do-that (or this (and that those))) (format "%s" a))))

I would like a command that can turn that into something a human would write, such as the following.

(defun my-example-function ()
  (let ((a (do-something))
        (b (do-something)))
    (setq someone me)
    (with-current-buffer b
      (do-that (or this (and that those)))
      (format "%s" a))))

I understand that there's more than one way to format a piece of elisp code, and different human beings do it differently. Furthermore, I understand it's somewhat subjective. But it should be fairly easy to come up with a set of rules that results in code that is at least decent.

I actually tought of doing this myself a while ago, but I figured it's better to ask before I reinvent the wheel.

Note, I'm aware of the pp function, but it doesn't quite get there:

(defun my-example-function nil
    (setq someone me)
    (with-current-buffer b
       (or this
           (and that those)))
      (format "%s" a))))
  • 5
    Does this help? Elisp Formatting – Luke Shimkus Sep 25 '14 at 22:23
  • Formatting is necessarily subjective. I'm not sure you could do better than a slightly better version of pp. – shosti Sep 25 '14 at 22:27
  • @King Thanks, it's certainly relevant. – Malabarba Sep 25 '14 at 23:22

Here's how lispy re-formatted it for me (by pressing M at either end of the expression):

(defun my-example-function ()
  (let ((a (do-something))
        (b (do-something)))
    (setq someone me)
    (with-current-buffer b (do-that (or this (and that those)))
                         (format "%s" a))))

To get from this to the formatting that you specified, press qk C-m [.

  • (local-set-key (kbd "s-8") #'lispy-multiline) (local-set-key (kbd "s-*") #'lispy-oneline) – grettke Mar 28 '18 at 2:57
  • Why is pressing M does different formatting from directly executing lispy-multiline? – Yuki Feb 12 at 19:40

As others have suggested in comments, "formatting" can mean different things.

For indentation that is pretty conventional, try using C-M-q (command indent-pp-sexp in Lisp modes) with the cursor somewhere inside the top-level sexp that you want to re-indent (e.g. the defun sexp).

No, this is not "automatic" indentation, but it can become a habit to use it. ;-)

For things other than indentation you will need to either do it manually or roll your own "formatting" command(s) or find some existing such.

See also the Emacs manual, node Multi-line Indent and the Elisp manual, node Mode-Specific Indent.

  • 3
    Thanks, I'm quite happy with elisp indentation, I'm looking for something that knows when to break lines. :-) And yes I understand it's subjective. :-( – Malabarba Sep 25 '14 at 23:06
  • M-q (fill-paragraph) can sometimes be useful for line-breaking in Emacs-Lisp mode, depending on the context. But you are probably looking for alignment as well... – Drew Sep 25 '14 at 23:16
  • @Malabarba see elisp-autofmt in my answer, this wraps/unwraps lines, respecting the fill column. – ideasman42 Apr 7 at 3:32

Listing lisp formatting tools here for completeness:

  • Elisp-Autofmt Emacs integration to run on-save.
    Uses strict 2 space indentation for parenthesis depth (not on melpa, usable via striaght).
  • lispy includes auto-formatting functionality (lispy on melpa)
  • ElispFormat produces idiomatic elisp, but seems to have right-shift problems - going over the fill column width (elisp-format on melpa).
  • Grind no Emacs integration (not on melpa).
  • Semantic Refactor (srefactor on melpa)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.