@@ -950,25 +950,47 @@ spec."
950950 (let ((function (thing-at-point 'symbol )))
951951 (clojure--get-indent-method function))))
952952
953- (defun clojure--normal-indent (last-sexp )
953+ (defun clojure--normal-indent (last-sexp indent-mode )
954954 " Return the normal indentation column for a sexp.
955- LAST-SEXP is the start of the previous sexp."
955+ Point should be after the open paren of the _enclosing_ sexp, and
956+ LAST-SEXP is the start of the previous sexp (immediately before
957+ the sexp being indented). INDENT-MODE is any of the values
958+ accepted by `clojure-indent-style' ."
956959 (goto-char last-sexp)
957960 (forward-sexp 1 )
958961 (clojure-backward-logical-sexp 1 )
959962 (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 )))
963+ (if (ignore-errors
964+ ; ; `backward-sexp' until we reach the start of a sexp that is the
965+ ; ; first of its line (the start of the enclosing sexp).
966+ (while (string-match
967+ " [^[:blank:]]"
968+ (buffer-substring (line-beginning-position ) (point )))
969+ (setq last-sexp-start (prog1 (point )
970+ (forward-sexp -1 ))))
971+ t )
972+ ; ; Here we have found an arg before the arg we're indenting which is at
973+ ; ; the start of a line. Every mode simply aligns on this case.
974+ (current-column )
975+ ; ; Here we have reached the start of the enclosing sexp (point is now at
976+ ; ; the function name), so the behaviour depends on INDENT-MODE and on
977+ ; ; whether there's also an argument on this line (case A or B).
978+ (let ((case-a ; The meaning of case-a is explained in `clojure-indent-style' .
979+ (and last-sexp-start
980+ (< last-sexp-start (line-end-position )))))
981+ (cond
982+ ; ; For compatibility with the old `clojure-defun-style-default-indent' , any
983+ ; ; value other than these 3 is equivalent to `always-body' .
984+ ((not (memq indent-mode '(:lisp :body-unless-same-line nil )))
985+ (+ (current-column ) lisp-body-indent -1 ))
986+ ; ; There's an arg after the function name, so align with it.
987+ (case-a (goto-char last-sexp-start)
988+ (current-column ))
989+ ; ; Not same line.
990+ ((eq indent-mode :body-unless-same-line )
991+ (+ (current-column ) lisp-body-indent -1 ))
992+ ; ; Finally, just align with the function name.
993+ (t (current-column )))))))
972994
973995(defun clojure--not-function-form-p ()
974996 " Non-nil if form at point doesn't represent a function call."
@@ -982,6 +1004,9 @@ LAST-SEXP is the start of the previous sexp."
9821004 ; ; Car of form is not a symbol.
9831005 (not (looking-at " .\\ (?:\\ sw\\ |\\ s_\\ )" ))))
9841006
1007+ ; ; Check the general context, and provide indentation for data structures and
1008+ ; ; special macros. If current form is a function (or non-special macro),
1009+ ; ; delegate indentation to `clojure--normal-indent' .
9851010(defun clojure-indent-function (indent-point state )
9861011 " When indenting a line within a function call, indent properly.
9871012
@@ -1013,6 +1038,7 @@ This function also returns nil meaning don't specify the indentation."
10131038 ; ; Function or macro call.
10141039 (forward-char 1 )
10151040 (let ((method (clojure--find-indent-spec))
1041+ (last-sexp calculate-lisp-indent-last-sexp)
10161042 (containing-form-column (1- (current-column ))))
10171043 (pcase method
10181044 ((or (pred integerp) `(, method ))
@@ -1028,10 +1054,13 @@ This function also returns nil meaning don't specify the indentation."
10281054 ; ; indentation as if there were an extra sexp at point.
10291055 (scan-error (cl-incf pos)))
10301056 (cond
1057+ ; ; The first non-special arg. Rigidly reduce indentation.
10311058 ((= pos (1+ method))
10321059 (+ lisp-body-indent containing-form-column))
1060+ ; ; Further non-special args, align with the arg above.
10331061 ((> pos (1+ method))
1034- (clojure--normal-indent calculate-lisp-indent-last-sexp))
1062+ (clojure--normal-indent last-sexp :lisp ))
1063+ ; ; Special arg. Rigidly indent with a large indentation.
10351064 (t
10361065 (+ (* 2 lisp-body-indent) containing-form-column)))))
10371066 (`:defn
@@ -1044,15 +1073,18 @@ This function also returns nil meaning don't specify the indentation."
10441073 (cond
10451074 ; ; largely to preserve useful alignment of :require, etc in ns
10461075 ((and function (string-match " ^:" function))
1047- (let ((clojure-defun-style-default-indent nil ))
1048- (clojure--normal-indent calculate-lisp-indent-last-sexp)))
1049- ((or clojure-defun-style-default-indent
1050- (and function
1051- (string-match " \\ `\\ (?:\\ S +/\\ )?\\ (def[a-z]*\\ |with-\\ )"
1052- function)
1053- (not (string-match " \\ `default" (match-string 1 function)))))
1076+ (clojure--normal-indent last-sexp :body-unless-same-line ))
1077+ ; ; This is should be identical to the :defn above.
1078+ ((and function
1079+ (string-match " \\ `\\ (?:\\ S +/\\ )?\\ (def[a-z]*\\ |with-\\ )"
1080+ function)
1081+ (not (string-match " \\ `default" (match-string 1 function))))
10541082 (+ lisp-body-indent containing-form-column))
1055- (t (clojure--normal-indent calculate-lisp-indent-last-sexp)))))))))
1083+ ; ; Finally, nothing special here, just respect the user's
1084+ ; ; preference.
1085+ (t (clojure--normal-indent last-sexp (if clojure-defun-style-default-indent
1086+ :always-body
1087+ :lisp ))))))))))
10561088
10571089; ;; Setting indentation
10581090(defun put-clojure-indent (sym indent )
0 commit comments