Indentation
CIDER relies on clojure-mode to do the indentation of Clojure code. While clojure-mode
will generally indent code "the right way", from time to time you might want to teach it
how to indent certain macros.
There are two ways to do this - you can either add some indentation configuration in your Emacs config
or you can add it to your Clojure code and let CIDER generate the necessary configuration for
clojure-mode automatically. We’ll refer to the first approach as "static indentation" and to the second
one as "dynamic indentation".
Static Indentation
| Everything in this section will work as described even if CIDER is not present/active. Static indentation doesn’t require a REPL to work. |
clojure-mode is smart enough to indent most Clojure code correctly out-of-the-box, but it can’t know
if something is a macro and its body should be indented differently.
clojure-mode is very flexible when it comes to indentation configuration and here we are going to go over the basics.
Indentation Modes
There are a few common ways to indent Clojure code and all of them are supported by clojure-mode.
The indentation of function forms is configured by the variable
clojure-indent-style. It takes three possible values:
-
always-align(the default)
(some-function
10
1
2)
(some-function 10
1
2)
-
always-indent
(some-function
10
1
2)
(some-function 10
1
2)
-
align-arguments
(some-function
10
1
2)
(some-function 10
1
2)
You can read more about the indentation options in clojure-mode here.
|
Macro Indentation
As mentioned earlier, clojure-mode can’t know if something in your code is a macro that has to be indented
differently from a regular function invocation (most likely because the macro takes some forms as parameters).
In such a situation you need to
teach clojure-mode how to indent the macro in question. Consider this simple example:
(defmacro with-in-str
"[DOCSTRING]"
{:style/indent 1}
[s & body]
...cut for brevity...)
;; Target indentation
(with-in-str str
(foo)
(bar)
(baz))
To get clojure-mode to indent it properly you’ll need to add the following code to your Emacs config:
(put-clojure-indent 'with-in-str 1)
;; or
(define-clojure-indent
(with-in-str 1)
| You can find more details here. |
Dynamic Indentation
It is common for macros to require special indentation mechanisms. This is most
common in macros that start with do, def, or with-. CIDER has some
heuristics to detect these macros, but it also lets you explicitly specify how
a macro should be indented.
Here’s a simple example of how someone would specify the indent spec for a macro they’ve written (using an example in core):
(defmacro with-in-str
"[DOCSTRING]"
{:style/indent 1}
[s & body]
...cut for brevity...)
;; Target indentation
(with-in-str str
(foo)
(bar)
(baz))
And here’s a more complex one:
(defmacro letfn
"[DOCSTRING]"
{:style/indent [1 [[:defn]] :form]}
[fnspecs & body]
...cut for brevity...)
;; Target indentation
(letfn [(six-times [y]
(* (twice y) 3))
(twice [x]
(* x 2))]
(println "Twice 15 =" (twice 15))
(println "Six times 15 =" (six-times 15)))
Don’t worry if this looks intimidating. For most macros the indent spec should
be either just a number, or one of the keywords :defn or :form. A full
description of the spec is provided in the
indent spec section of the manual.
If you don’t want to use this feature, you can disable it by setting
cider-dynamic-indentation to nil in your Emacs init file.
(setq cider-dynamic-indentation nil)