aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorNoam Postavsky2017-03-05 00:16:13 -0500
committerNoam Postavsky2017-03-12 20:08:32 -0400
commit3ee3995d105ff02f0fac540757431d36cb45c6c7 (patch)
tree2ef4b94411b15cc051d264990a2a4ba441be86db /lisp
parent1b424533675341a2090b79a6ffc420ac6b179ce7 (diff)
downloademacs-3ee3995d105ff02f0fac540757431d36cb45c6c7.tar.gz
emacs-3ee3995d105ff02f0fac540757431d36cb45c6c7.zip
* lisp/emacs-lisp/lisp-mode.el (indent-sexp): Simplify.
* test/lisp/emacs-lisp/lisp-mode-tests.el (indent-sexp): (indent-subsexp, indent-sexp-in-string): New tests.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/emacs-lisp/lisp-mode.el168
1 files changed, 72 insertions, 96 deletions
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index c2f5f42ace8..5faa6a50ae5 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -1069,103 +1069,79 @@ Lisp function does not specify a special indentation."
1069If optional arg ENDPOS is given, indent each line, stopping when 1069If optional arg ENDPOS is given, indent each line, stopping when
1070ENDPOS is encountered." 1070ENDPOS is encountered."
1071 (interactive) 1071 (interactive)
1072 (let ((indent-stack (list nil)) 1072 (let* ((indent-stack (list nil))
1073 (next-depth 0) 1073 ;; If ENDPOS is non-nil, use beginning of defun as STARTING-POINT.
1074 ;; If ENDPOS is non-nil, use nil as STARTING-POINT 1074 ;; If ENDPOS is nil, it is safe not to scan before point
1075 ;; so that calculate-lisp-indent will find the beginning of 1075 ;; since every line we indent is more deeply nested than point is.
1076 ;; the defun we are in. 1076 (starting-point (save-excursion (if endpos (beginning-of-defun))
1077 ;; If ENDPOS is nil, it is safe not to scan before point 1077 (point)))
1078 ;; since every line we indent is more deeply nested than point is. 1078 (state nil)
1079 (starting-point (if endpos nil (point))) 1079 (init-depth 0)
1080 (last-point (point)) 1080 (next-depth 0)
1081 last-depth bol outer-loop-done inner-loop-done state this-indent) 1081 (last-depth 0)
1082 (or endpos 1082 (last-syntax-point (point)))
1083 ;; Get error now if we don't have a complete sexp after point. 1083 (unless endpos
1084 (save-excursion (forward-sexp 1))) 1084 ;; Get error now if we don't have a complete sexp after point.
1085 (save-excursion (forward-sexp 1)
1086 ;; We need a marker because we modify the buffer
1087 ;; text preceding endpos.
1088 (setq endpos (point-marker))))
1085 (save-excursion 1089 (save-excursion
1086 (setq outer-loop-done nil) 1090 (while (< (point) endpos)
1087 (while (if endpos (< (point) endpos) 1091 ;; Parse this line so we can learn the state to indent the
1088 (not outer-loop-done)) 1092 ;; next line.
1089 (setq last-depth next-depth 1093 (while (progn
1090 inner-loop-done nil) 1094 (setq state (parse-partial-sexp
1091 ;; Parse this line so we can learn the state 1095 last-syntax-point (progn (end-of-line) (point))
1092 ;; to indent the next line. 1096 nil nil state))
1093 ;; This inner loop goes through only once 1097 ;; Skip over newlines within strings.
1094 ;; unless a line ends inside a string. 1098 (nth 3 state))
1095 (while (and (not inner-loop-done) 1099 (setq state (parse-partial-sexp (point) (point-max)
1096 (not (setq outer-loop-done (eobp)))) 1100 nil nil state 'syntax-table))
1097 (setq state (parse-partial-sexp (point) (progn (end-of-line) (point)) 1101 (setq last-syntax-point (point)))
1098 nil nil state)) 1102 (setq next-depth (car state))
1099 (setq next-depth (car state)) 1103 ;; If the line contains a comment indent it now with
1100 ;; If the line contains a comment other than the sort 1104 ;; `indent-for-comment'.
1101 ;; that is indented like code, 1105 (when (nth 4 state)
1102 ;; indent it now with indent-for-comment. 1106 (indent-for-comment)
1103 ;; Comments indented like code are right already. 1107 (end-of-line))
1104 ;; In any case clear the in-comment flag in the state 1108 (setq last-syntax-point (point))
1105 ;; because parse-partial-sexp never sees the newlines. 1109 (when (< next-depth init-depth)
1106 (if (car (nthcdr 4 state)) 1110 (setq indent-stack (nconc indent-stack
1107 (progn (indent-for-comment) 1111 (make-list (- init-depth next-depth) nil))
1108 (end-of-line) 1112 last-depth (- last-depth next-depth)
1109 (setcar (nthcdr 4 state) nil))) 1113 next-depth init-depth))
1110 ;; If this line ends inside a string, 1114 (forward-line 1)
1111 ;; go straight to next line, remaining within the inner loop, 1115 (when (< (point) endpos)
1112 ;; and turn off the \-flag. 1116 (let ((depth-delta (- next-depth last-depth)))
1113 (if (car (nthcdr 3 state)) 1117 (cond ((< depth-delta 0)
1114 (progn 1118 (setq indent-stack (nthcdr (- depth-delta) indent-stack)))
1115 (forward-line 1) 1119 ((> depth-delta 0)
1116 (setcar (nthcdr 5 state) nil)) 1120 (setq indent-stack (nconc (make-list depth-delta nil)
1117 (setq inner-loop-done t))) 1121 indent-stack))))
1118 (and endpos 1122 (setq last-depth next-depth))
1119 (<= next-depth 0) 1123 ;; Now indent the next line according
1120 (progn 1124 ;; to what we learned from parsing the previous one.
1121 (setq indent-stack (nconc indent-stack 1125 (skip-chars-forward " \t")
1122 (make-list (- next-depth) nil)) 1126 ;; But not if the line is blank, or just a comment (we
1123 last-depth (- last-depth next-depth) 1127 ;; already called `indent-for-comment' above).
1124 next-depth 0))) 1128 (unless (or (eolp) (eq (char-syntax (char-after)) ?<))
1125 (forward-line 1) 1129 (let ((this-indent (car indent-stack)))
1126 ;; Decide whether to exit. 1130 (when (listp this-indent)
1127 (if endpos 1131 (let ((val (calculate-lisp-indent
1128 ;; If we have already reached the specified end, 1132 (or (car this-indent) starting-point))))
1129 ;; give up and do not reindent this line. 1133 (setq
1130 (if (<= endpos (point)) 1134 this-indent
1131 (setq outer-loop-done t)) 1135 (cond ((integerp val)
1132 ;; If no specified end, we are done if we have finished one sexp. 1136 (setf (car indent-stack) val))
1133 (if (<= next-depth 0) 1137 ((consp val) ; (COLUMN CONTAINING-SEXP-START)
1134 (setq outer-loop-done t))) 1138 (setf (car indent-stack) (cdr val))
1135 (unless outer-loop-done 1139 (car val))
1136 (while (> last-depth next-depth) 1140 ;; `calculate-lisp-indent' only returns nil
1137 (setq indent-stack (cdr indent-stack) 1141 ;; when we're in a string, but this won't
1138 last-depth (1- last-depth))) 1142 ;; happen because we skip strings above.
1139 (while (< last-depth next-depth) 1143 (t (error "This shouldn't happen!"))))))
1140 (setq indent-stack (cons nil indent-stack) 1144 (indent-line-to this-indent))))))))
1141 last-depth (1+ last-depth)))
1142 ;; Now indent the next line according
1143 ;; to what we learned from parsing the previous one.
1144 (setq bol (point))
1145 (skip-chars-forward " \t")
1146 ;; But not if the line is blank, or just a comment
1147 ;; (except for double-semi comments; indent them as usual).
1148 (if (or (eobp) (looking-at "\\s<\\|\n"))
1149 nil
1150 (if (and (car indent-stack)
1151 (>= (car indent-stack) 0))
1152 (setq this-indent (car indent-stack))
1153 (let ((val (calculate-lisp-indent
1154 (if (car indent-stack) (- (car indent-stack))
1155 starting-point))))
1156 (if (null val)
1157 (setq this-indent val)
1158 (if (integerp val)
1159 (setcar indent-stack
1160 (setq this-indent val))
1161 (setcar indent-stack (- (car (cdr val))))
1162 (setq this-indent (car val))))))
1163 (if (and this-indent (/= (current-column) this-indent))
1164 (progn (delete-region bol (point))
1165 (indent-to this-indent)))))
1166 (or outer-loop-done
1167 (setq outer-loop-done (= (point) last-point))
1168 (setq last-point (point)))))))
1169 1145
1170(defun indent-pp-sexp (&optional arg) 1146(defun indent-pp-sexp (&optional arg)
1171 "Indent each line of the list starting just after point, or prettyprint it. 1147 "Indent each line of the list starting just after point, or prettyprint it.