Skip to content
  • Sponsor clojure-emacs/clojure-mode

  • Notifications You must be signed in to change notification settings
  • Fork 247

Commit e201ed6

Browse files
plexusbbatsov
authored andcommittedFeb 13, 2024
Make it possible to get uniform indentation
While Emacs and clojure-mode have good support for "lisp-style" indentation, and provided fine-grained customization via indent-specs, some prefer "dumb" indentation where every single form gets the same level of indent, regardless of whether it's a macro, whether there are arguments on the same line as the function name, etc. Currently this is not possible without redefining certain functions because of hard-coded values that handle specific cases, namely the indent-spec case, and the keyword invocation case (`(:require ...)`). This introduces two new defcustoms, one allows completely disabling the indent-spec handling, so the first hard-coded case is skipped, the second allows specifically customizing the second case. This should allow "tonsky style" formatting with ``` (setq clojure-indent-style 'always-indent clojure-indent-keyword-style 'always-indent clojure-enable-indent-specs nil) ```
1 parent c66ada8 commit e201ed6

File tree

1 file changed

+58
-2
lines changed

1 file changed

+58
-2
lines changed
 

‎clojure-mode.el

+58-2
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@
100100

101101
(defcustom clojure-indent-style 'always-align
102102
"Indentation style to use for function forms and macro forms.
103+
For forms that start with a keyword see `clojure-indent-keyword-style'.
104+
103105
There are two cases of interest configured by this variable.
104106
105107
- Case (A) is when at least one function argument is on the same
@@ -147,6 +149,51 @@ to indent function forms.
147149
align-arguments))
148150
:package-version '(clojure-mode . "5.2.0"))
149151

152+
(defcustom clojure-indent-keyword-style 'always-align
153+
"Indentation style to use for forms that start with a keyword.
154+
For function/macro forms, see `clojure-indent-style'.
155+
There are two cases of interest configured by this variable.
156+
157+
- Case (A) is when at least one argument following the keyword is
158+
on the same line as the keyword.
159+
- Case (B) is the opposite (no arguments are on the same line as
160+
the keyword).
161+
162+
The possible values for this variable are keywords indicating how
163+
to indent keyword invocation forms.
164+
165+
`always-align' - Follow the same rules as `lisp-mode'. All
166+
args are vertically aligned with the first arg in case (A),
167+
and vertically aligned with the function name in case (B).
168+
For instance:
169+
(:require [foo.bar]
170+
[bar.baz])
171+
(:require
172+
[foo.bar]
173+
[bar.baz])
174+
175+
`always-indent' - All args are indented like a macro body.
176+
(:require [foo.bar]
177+
[bar.baz])
178+
(:x
179+
location
180+
0)
181+
182+
`align-arguments' - Case (A) is indented like `lisp', and
183+
case (B) is indented like a macro body.
184+
(:require [foo.bar]
185+
[bar.baz])
186+
(:x
187+
location
188+
0)
189+
"
190+
:safe #'symbolp
191+
:type '(choice (const :tag "Same as `lisp-mode'" 'always-align)
192+
(const :tag "Indent like a macro body" 'always-indent)
193+
(const :tag "Indent like a macro body unless first arg is on the same line"
194+
'align-arguments))
195+
:package-version '(clojure-mode . "5.14.0"))
196+
150197
(defcustom clojure-use-backtracking-indent t
151198
"When non-nil, enable context sensitive indentation."
152199
:type 'boolean
@@ -1686,7 +1733,8 @@ This function also returns nil meaning don't specify the indentation."
16861733
(1+ (current-column))
16871734
;; Function or macro call.
16881735
(forward-char 1)
1689-
(let ((method (clojure--find-indent-spec))
1736+
(let ((method (and clojure-enable-indent-specs
1737+
(clojure--find-indent-spec)))
16901738
(last-sexp calculate-lisp-indent-last-sexp)
16911739
(containing-form-column (1- (current-column))))
16921740
(pcase method
@@ -1723,7 +1771,7 @@ This function also returns nil meaning don't specify the indentation."
17231771
(cond
17241772
;; Preserve useful alignment of :require (and friends) in `ns' forms.
17251773
((and function (string-match "^:" function))
1726-
(clojure--normal-indent last-sexp 'always-align))
1774+
(clojure--normal-indent last-sexp clojure-indent-keyword-style))
17271775
;; This should be identical to the :defn above.
17281776
((and function
17291777
(string-match "\\`\\(?:\\S +/\\)?\\(def[a-z]*\\|with-\\)"
@@ -1802,6 +1850,14 @@ Requires the macro's NAME and a VALUE."
18021850
(put-clojure-indent x 'defun))
18031851
value))
18041852

1853+
(defcustom clojure-enable-indent-specs t
1854+
"Honor indent specs, either set via metadata on the
1855+
function/macro, or via `define-clojure-indent'. Set this to `nil'
1856+
to get uniform formatting of all forms."
1857+
:type 'boolean
1858+
:safe #'booleanp
1859+
:package-version '(clojure-mode . "5.14.0"))
1860+
18051861
(defcustom clojure-defun-indents nil
18061862
"List of additional symbols with defun-style indentation in Clojure.
18071863

0 commit comments

Comments
 (0)