how do I improve indentation of reify methods in clojure-mode

125 views
Skip to first unread message

B Smith-Mannschott

unread,
Jan 8, 2011, 4:24:10 PM1/8/11
to clo...@googlegroups.com
I'm using (emacs) clojure-mode 1.7.1 and I'm not happy with the how it
indents method definitions, e.g. in reify:


| (reify ItemListener
| (itemStateChanged
| [this e]
| (f (selected? e))))

The fact that Protocols method name, arg list and method body are all
indented to nearly the same level makes multiple methods and even
multiple protocols all kind of mush together visually. Is there any
way to hack or customize clojure-mode to get something like this:

| (reify ItemListener
| (itemStateChanged
| [this e]
| (f (selected? e))))

or (even nicer)

| (reify ItemListener
| (itemStateChanged [this e]
| (f (selected? e))))

I also have my troubles with letfn such that I find myself just always
using let as a result. (i.e. my editor's ugly indentation defaults
drive my choice of construct -- how demented is that?)

Any tips?

// Ben

Stuart Sierra

unread,
Jan 8, 2011, 5:17:20 PM1/8/11
to clo...@googlegroups.com
This is an unfortunate problem with clojure-mode being based on older Lisp modes for Emacs. It doesn't really know how to read Clojure code, just how to parse Lispy expressions in general.

Phil Hagelberg's fork of clojure-mode [1] has experimental support for better indentation in forms like reify.

-Stuart Sierra

Eric Schulte

unread,
Jan 9, 2011, 1:19:32 PM1/9/11
to clo...@googlegroups.com
Hi,

Even using Phil's clojure-mode I find myself often editing the source
code of clojure-mode to add custom indentation or fontification for my
own macros or for forms I feel have been missed. Perhaps some of the
lists of function/marco-names in clojure-mode could be tucked behind
user-configurable variables to allow personalization without editing of
the source file.

When writing emacs-lisp it is possible to include indentation
information into a definition e.g.

(defmacro do-something-to-something (thing &rest stuff-to-do)
(declare (indent 1))
...)

the `(declare (indent 1))' ensures that it will be indented as follows

(do-something-to-something thing
(stuff-to-do))

perhaps something similar could be done in Clojure using meta
information, although that may be asking for far too much Clojure/e-lisp
interaction?

I'd have to think this issue has been addressed by the CL community.

Cheers -- Eric

Eric Schulte

unread,
Jan 11, 2011, 2:12:28 AM1/11/11
to clo...@googlegroups.com
As an example of a user-accessible function for customizing indentation,
the following can be used with the latest clojure-mode either
interactively or from a user's config.

(defun clojure-new-indent (&optional func level)
"Set the indentation level of FUNC to LEVEL."
(interactive)
(let ((func (or func
(read-from-minibuffer "function name: "
(condition-case nil
(which-function) (error nil)))))
(level (or level (read-from-minibuffer "indent (number): " "1")))))
(put (if (stringp func) (intern func) func)
'clojure-indent-function
(if (stringp level) (string-to-number level) level)))

e.g. (clojure-new-indent 'while-let 1) will result in

(while-let [something stuff]
(body))

rather than

(while-let [something stuff]
(body))

Cheers -- Eric

B Smith-Mannschott

unread,
Jan 11, 2011, 12:57:21 PM1/11/11
to clo...@googlegroups.com

I'll give that a try. Thanks!

// ben

Reply all
Reply to author
Forward
0 new messages