95
95
" Face used to font-lock interop method names (camelCase)."
96
96
:package-version '(clojure-mode . " 3.0.0" ))
97
97
98
- (defcustom clojure-defun-style-default-indent nil
99
- " When non-nil, use default indenting for functions and macros.
100
- Otherwise check `define-clojure-indent' and `put-clojure-indent' ."
101
- :type 'boolean
102
- :safe 'booleanp )
98
+ (defcustom clojure-indent-style :always-align
99
+ " Indentation style to use for function forms and macro forms.
100
+ There are two cases of interest configured by this variable.
101
+
102
+ - Case (A) is when at least one function argument is on the same
103
+ line as the function name.
104
+ - Case (B) is the opposite (no arguments are on the same line as
105
+ the function name). Note that the body of macros is not
106
+ affected by this variable, it is always indented by
107
+ `lisp-body-indent' (default 2) spaces.
108
+
109
+ Note that this variable configures the indentation of function
110
+ forms (and function-like macros), it does not affect macros that
111
+ already use special indentation rules.
112
+
113
+ The possible values for this variable are keywords indicating how
114
+ to indent function forms.
115
+
116
+ `:always-align' - Follow the same rules as `lisp-mode' . All
117
+ args are vertically aligned with the first arg in case (A),
118
+ and vertically aligned with the function name in case (B).
119
+ For instance:
120
+ (reduce merge
121
+ some-coll)
122
+ (reduce
123
+ merge
124
+ some-coll)
125
+
126
+ `:always-indent' - All args are indented like a macro body.
127
+ (reduce merge
128
+ some-coll)
129
+ (reduce
130
+ merge
131
+ some-coll)
132
+
133
+ `:align-arguments' - Case (A) is indented like `lisp' , and
134
+ case (B) is indented like a macro body.
135
+ (reduce merge
136
+ some-coll)
137
+ (reduce
138
+ merge
139
+ some-coll)"
140
+ :type '(choice (const :tag " Same as `lisp-mode' " lisp)
141
+ (const :tag " Indent like a macro body" always-body)
142
+ (const :tag " Indent like a macro body unless first arg is on the same line"
143
+ body-unless-same-line))
144
+ :package-version '(clojure-mode . " 5.2.0" ))
145
+
146
+ (define-obsolete-variable-alias 'clojure-defun-style-default-indent
147
+ 'clojure-indent-style " 5.2.0" )
103
148
104
149
(defcustom clojure-use-backtracking-indent t
105
150
" When non-nil, enable context sensitive indentation."
@@ -950,25 +995,47 @@ spec."
950
995
(let ((function (thing-at-point 'symbol )))
951
996
(clojure--get-indent-method function))))
952
997
953
- (defun clojure--normal-indent (last-sexp )
998
+ (defun clojure--normal-indent (last-sexp indent-mode )
954
999
" Return the normal indentation column for a sexp.
955
- LAST-SEXP is the start of the previous sexp."
1000
+ Point should be after the open paren of the _enclosing_ sexp, and
1001
+ LAST-SEXP is the start of the previous sexp (immediately before
1002
+ the sexp being indented). INDENT-MODE is any of the values
1003
+ accepted by `clojure-indent-style' ."
956
1004
(goto-char last-sexp)
957
1005
(forward-sexp 1 )
958
1006
(clojure-backward-logical-sexp 1 )
959
1007
(let ((last-sexp-start nil ))
960
- (unless (ignore-errors
961
- (while (string-match
962
- " [^[:blank:]]"
963
- (buffer-substring (line-beginning-position ) (point )))
964
- (setq last-sexp-start (prog1 (point )
965
- (forward-sexp -1 ))))
966
- t )
967
- ; ; If the last sexp was on the same line.
968
- (when (and last-sexp-start
969
- (> (line-end-position ) last-sexp-start))
970
- (goto-char last-sexp-start)))
971
- (current-column )))
1008
+ (if (ignore-errors
1009
+ ; ; `backward-sexp' until we reach the start of a sexp that is the
1010
+ ; ; first of its line (the start of the enclosing sexp).
1011
+ (while (string-match
1012
+ " [^[:blank:]]"
1013
+ (buffer-substring (line-beginning-position ) (point )))
1014
+ (setq last-sexp-start (prog1 (point )
1015
+ (forward-sexp -1 ))))
1016
+ t )
1017
+ ; ; Here we have found an arg before the arg we're indenting which is at
1018
+ ; ; the start of a line. Every mode simply aligns on this case.
1019
+ (current-column )
1020
+ ; ; Here we have reached the start of the enclosing sexp (point is now at
1021
+ ; ; the function name), so the behaviour depends on INDENT-MODE and on
1022
+ ; ; whether there's also an argument on this line (case A or B).
1023
+ (let ((case-a ; The meaning of case-a is explained in `clojure-indent-style' .
1024
+ (and last-sexp-start
1025
+ (< last-sexp-start (line-end-position )))))
1026
+ (cond
1027
+ ; ; For compatibility with the old `clojure-defun-style-default-indent' , any
1028
+ ; ; value other than these 3 is equivalent to `always-body' .
1029
+ ((not (memq indent-mode '(:always-align :align-arguments nil )))
1030
+ (+ (current-column ) lisp-body-indent -1 ))
1031
+ ; ; There's an arg after the function name, so align with it.
1032
+ (case-a (goto-char last-sexp-start)
1033
+ (current-column ))
1034
+ ; ; Not same line.
1035
+ ((eq indent-mode :align-arguments )
1036
+ (+ (current-column ) lisp-body-indent -1 ))
1037
+ ; ; Finally, just align with the function name.
1038
+ (t (current-column )))))))
972
1039
973
1040
(defun clojure--not-function-form-p ()
974
1041
" Non-nil if form at point doesn't represent a function call."
@@ -982,6 +1049,9 @@ LAST-SEXP is the start of the previous sexp."
982
1049
; ; Car of form is not a symbol.
983
1050
(not (looking-at " .\\ (?:\\ sw\\ |\\ s_\\ )" ))))
984
1051
1052
+ ; ; Check the general context, and provide indentation for data structures and
1053
+ ; ; special macros. If current form is a function (or non-special macro),
1054
+ ; ; delegate indentation to `clojure--normal-indent' .
985
1055
(defun clojure-indent-function (indent-point state )
986
1056
" When indenting a line within a function call, indent properly.
987
1057
@@ -1013,6 +1083,7 @@ This function also returns nil meaning don't specify the indentation."
1013
1083
; ; Function or macro call.
1014
1084
(forward-char 1 )
1015
1085
(let ((method (clojure--find-indent-spec))
1086
+ (last-sexp calculate-lisp-indent-last-sexp)
1016
1087
(containing-form-column (1- (current-column ))))
1017
1088
(pcase method
1018
1089
((or (pred integerp) `(, method ))
@@ -1028,26 +1099,35 @@ This function also returns nil meaning don't specify the indentation."
1028
1099
; ; indentation as if there were an extra sexp at point.
1029
1100
(scan-error (cl-incf pos)))
1030
1101
(cond
1102
+ ; ; The first non-special arg. Rigidly reduce indentation.
1031
1103
((= pos (1+ method))
1032
1104
(+ lisp-body-indent containing-form-column))
1105
+ ; ; Further non-special args, align with the arg above.
1033
1106
((> pos (1+ method))
1034
- (clojure--normal-indent calculate-lisp-indent-last-sexp))
1107
+ (clojure--normal-indent last-sexp :always-align ))
1108
+ ; ; Special arg. Rigidly indent with a large indentation.
1035
1109
(t
1036
1110
(+ (* 2 lisp-body-indent) containing-form-column)))))
1037
1111
(`:defn
1038
1112
(+ lisp-body-indent containing-form-column))
1039
1113
((pred functionp)
1040
1114
(funcall method indent-point state))
1041
- ((and `nil
1042
- (guard (let ((function (thing-at-point 'sexp )))
1043
- (or (and clojure-defun-style-default-indent
1044
- ; ; largely to preserve useful alignment of :require, etc in ns
1045
- (not (string-match " ^:" function)))
1046
- (and (string-match " \\ `\\ (?:\\ S +/\\ )?\\ (def[a-z]*\\ |with-\\ )"
1047
- function)
1048
- (not (string-match " \\ `default" (match-string 1 function))))))))
1049
- (+ lisp-body-indent containing-form-column))
1050
- (_ (clojure--normal-indent calculate-lisp-indent-last-sexp))))))
1115
+ ; ; No indent spec, do the default.
1116
+ (`nil
1117
+ (let ((function (thing-at-point 'symbol )))
1118
+ (cond
1119
+ ; ; Preserve useful alignment of :require (and friends) in `ns' forms.
1120
+ ((and function (string-match " ^:" function))
1121
+ (clojure--normal-indent last-sexp :align-arguments ))
1122
+ ; ; This is should be identical to the :defn above.
1123
+ ((and function
1124
+ (string-match " \\ `\\ (?:\\ S +/\\ )?\\ (def[a-z]*\\ |with-\\ )"
1125
+ function)
1126
+ (not (string-match " \\ `default" (match-string 1 function))))
1127
+ (+ lisp-body-indent containing-form-column))
1128
+ ; ; Finally, nothing special here, just respect the user's
1129
+ ; ; preference.
1130
+ (t (clojure--normal-indent last-sexp clojure-indent-style)))))))))
1051
1131
1052
1132
; ;; Setting indentation
1053
1133
(defun put-clojure-indent (sym indent )
0 commit comments