9

I would like some Emacs Lisp forms to be indented like Common Lisp. For instance, in Emacs Lisp, if is indented like this:

(if COND
    THEN
  ELSE)

whilst I would prefer it like this:

(if COND
    THEN
    ELSE)

I could do this:

(setq lisp-indent-function #'common-lisp-indent-function)

But this impacts all forms, thus breaking the indentation of Emacs Lisp macros, like cl-letf and any user-defined macro.

phils
  • 48,657
  • 3
  • 76
  • 115
Eleno
  • 1,428
  • 11
  • 17

2 Answers2

16

Answer:

Symbols for functions and macros have a lisp-indent-function property which you can set with declare or in your case, since if is already defined, you can just use put.

You can read about the possible property values here:

M-: (info "(elisp) Indenting Macros") return

if's default setting is 2 which means the second form get's special treatment and is offset.

You can change the property value to 'defun and all the body forms will line up.

(put 'if 'lisp-indent-function 'defun)

Best Practice:

It is important to note that there is a reason for the indentation style. if in Elisp is NOT like if in Common Lisp.

Note the different signatures:

Common Lisp: (if TEST THEN &OPTIONAL ELSE)

Emacs Lisp: (if COND THEN ELSE...)

In Emacs lisp, you can have as many forms after the condition as you want but only the first form is the THEN clause, all other forms are part of the ELSE clause.

This is a valid Elisp if form that is not valid in CL:

(if something
    (message "THEN")
  (message "all")
  (message "these")
  (message "run")
  (message "on")
  (message "ELSE"))

This shows why it is important that the THEN clause is indented more, it is to make it stand out against all the ELSE forms.

In addition to the indentation being important to the users ability to parse the code, it would also go against the accepted styling patterns of elisp. 99.99999% (carfefully calculated) of elisp code you encounter will use the exact same default indentation scheme. Changing the indentation of if for you own use will make it hard for you to work on other peoples elisp and make it hard for others to work on yours.

Jordon Biondo
  • 12,332
  • 2
  • 41
  • 62
2

I actually use Common Lisp indent, with the Elisp indent for if. You could customize some code similar to mine:

(setq lisp-indent-function 'common-lisp-indent-function)
(eval-after-load 'cl-indent
  `(progn
     (put 'cl-flet 'common-lisp-indent-function
          (get 'flet 'common-lisp-indent-function))
     (put 'cl-labels 'common-lisp-indent-function
          (get 'labels 'common-lisp-indent-function))
     (put 'if 'common-lisp-indent-function 2)))
abo-abo
  • 13,943
  • 1
  • 29
  • 43
  • Thanks, but this would require me to fix the indentation of all user-defined macros, too. I would rather follow the opposite route and fix just the indentation of `if` as performed by `lisp-indent-function`. – Eleno Jun 16 '15 at 12:32
  • I've had this config for years. There are zero other macros that I needed to "fix". Just remember to put a `declare` statement in each new macro, which is good to do in any case. – abo-abo Jun 16 '15 at 14:18