From ff607912cd7b3a771eae85e54be24fc21668b2e9 Mon Sep 17 00:00:00 2001
From: Hugo Duncan <hugo@hugoduncan.org>
Date: Fri, 19 Feb 2021 16:29:58 -0500
Subject: [PATCH 1/2] feat: make indentation of special arguments customisable

Allow control of the indentation of special arguments through a defcustom.

- introduces clojure-special-arg-indent-factor, which is used as a factor of
lisp-body-ident to indent special arguments.  Defaults to 2, the currently hard
coded value for this.
---
 CHANGELOG.md                          |  1 +
 README.md                             |  4 +++
 clojure-mode.el                       | 10 +++++-
 test/clojure-mode-indentation-test.el | 45 +++++++++++++++++++++++++++
 4 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 33dd1b81..de40c06a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
 * [#571](https://github.com/clojure-emacs/clojure-mode/issues/571): Remove `project.el` integration.
 * [#574](https://github.com/clojure-emacs/clojure-mode/issues/574): Remove `clojure-view-grimoire` command.
 * Stop `clojure-sort-ns` from calling `redisplay`
+* Add 'clojure-special-arg-indent-factor' to control special argument indentation.
 
 ## 5.12.0 (2020-08-13)
 
diff --git a/README.md b/README.md
index 675877b0..0905c262 100644
--- a/README.md
+++ b/README.md
@@ -216,6 +216,10 @@ For instructions on how to write these specifications, see
 [this document](https://docs.cider.mx/cider/indent_spec.html).
 The only difference is that you're allowed to use lists instead of vectors.
 
+The indentation of special arguments is controlled by
+`clojure-special-arg-indent-factor`, which by default indents special arguments
+a further `lisp-body-indent` when compared to ordinary arguments.
+
 ### Indentation of Comments
 
 `clojure-mode` differentiates between comments like `;`, `;;`, etc.
diff --git a/clojure-mode.el b/clojure-mode.el
index 53f0bb6c..a9ca793f 100644
--- a/clojure-mode.el
+++ b/clojure-mode.el
@@ -1136,6 +1136,13 @@ will align the values like this:
   :safe #'listp
   :type '(repeat string))
 
+(defcustom clojure-special-arg-indent-factor
+  2
+  "Factor of the 'lisp-body-indent' used to indent special arguments."
+  :package-version '(clojure-mode . "5.13")
+  :type 'integer
+  :safe 'integerp)
+
 (defvar clojure--beginning-of-reader-conditional-regexp
   "#\\?@(\\|#\\?("
   "Regexp denoting the beginning of a reader conditional.")
@@ -1503,7 +1510,8 @@ This function also returns nil meaning don't specify the indentation."
              (clojure--normal-indent last-sexp 'always-align))
             ;; Special arg. Rigidly indent with a large indentation.
             (t
-             (+ (* 2 lisp-body-indent) containing-form-column)))))
+             (+ (* clojure-special-arg-indent-factor lisp-body-indent)
+                containing-form-column)))))
         (`:defn
          (+ lisp-body-indent containing-form-column))
         ((pred functionp)
diff --git a/test/clojure-mode-indentation-test.el b/test/clojure-mode-indentation-test.el
index abbb3507..b9081721 100644
--- a/test/clojure-mode-indentation-test.el
+++ b/test/clojure-mode-indentation-test.el
@@ -233,6 +233,51 @@ DESCRIPTION is a string with the description of the spec."
       (ala/bala top
         |one)"))
 
+  (describe "specify an indentation for symbol"
+    (put-clojure-indent 'cala 1)
+
+    (when-indenting-with-point-it "should handle a symbol with ns"
+      "
+      (cala top
+      |one)"
+      "
+      (cala top
+        |one)")
+    (when-indenting-with-point-it "should handle special arguments"
+      "
+      (cala
+       |top
+        one)"
+      "
+      (cala
+          |top
+        one)"))
+  (describe "should respect special argument indentation"
+    :var (clojure-special-arg-indent-factor)
+    (before-each
+     (setq clojure-special-arg-indent-factor 1))
+    (after-each
+     (setq clojure-special-arg-indent-factor 2))
+
+    (put-clojure-indent 'cala 1)
+
+    (when-indenting-with-point-it "should handle a symbol with ns"
+      "
+      (cala top
+      |one)"
+      "
+      (cala top
+        |one)")
+    (when-indenting-with-point-it "should handle special arguments"
+      "
+      (cala
+       |top
+        one)"
+      "
+      (cala
+        |top
+        one)"))
+
   (describe "we can pass a lambda to explicitly set the column"
     (put-clojure-indent 'arsymbol (lambda (indent-point state) 0))
 

From 6994e28cc7f0ece58b16cab242147794f3c99322 Mon Sep 17 00:00:00 2001
From: Hugo Duncan <hugo@hugoduncan.org>
Date: Tue, 23 Feb 2021 08:42:08 -0500
Subject: [PATCH 2/2] Add example in README

---
 README.md | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/README.md b/README.md
index 0905c262..2aa8cd3c 100644
--- a/README.md
+++ b/README.md
@@ -220,6 +220,20 @@ The indentation of special arguments is controlled by
 `clojure-special-arg-indent-factor`, which by default indents special arguments
 a further `lisp-body-indent` when compared to ordinary arguments.
 
+An example of the default formatting is:
+
+```clojure
+(defrecord MyRecord
+    [my-field])
+```
+
+Setting `clojure-special-arg-indent-factor` to 1, results in:
+
+```clojure
+(defrecord MyRecord
+  [my-field])
+```
+
 ### Indentation of Comments
 
 `clojure-mode` differentiates between comments like `;`, `;;`, etc.