Fix wrong indentation after string literal (Bug#27306)

* lisp/emacs-lisp/lisp-mode.el (lisp-indent-state)
(lisp-indent-calc-next): Remove `depth' field, use (car ppss) instead.
* test/lisp/emacs-lisp/lisp-mode-tests.el
(lisp-indent-region-after-string-literal): New test.
This commit is contained in:
Noam Postavsky 2017-06-10 09:50:48 -04:00
parent 9af2ab68ca
commit cc8aa484cd
2 changed files with 26 additions and 14 deletions

View file

@ -773,11 +773,9 @@ complete sexp in the innermost containing list at position
(:constructor lisp-indent-initial-state
(&aux (ppss (lisp-ppss))
(ppss-point (point))
(depth (car ppss))
(stack (make-list (1+ depth) nil)))))
(stack (make-list (1+ (car ppss)) nil)))))
stack ;; Cached indentation, per depth.
ppss
depth
ppss-point)
(defun lisp-indent-calc-next (state)
@ -785,9 +783,11 @@ complete sexp in the innermost containing list at position
STATE is updated by side effect, the first state should be
created by `lisp-indent-initial-state'. This function may move
by more than one line to cross a string literal."
(pcase-let (((cl-struct lisp-indent-state
(stack indent-stack) ppss depth ppss-point)
state))
(pcase-let* (((cl-struct lisp-indent-state
(stack indent-stack) ppss ppss-point)
state)
(indent-depth (car ppss)) ; Corresponding to indent-stack.
(depth indent-depth))
;; Parse this line so we can learn the state to indent the
;; next line.
(while (let ((last-sexp (nth 2 ppss)))
@ -799,22 +799,22 @@ by more than one line to cross a string literal."
(if (and (not (nth 2 ppss)) (= depth (car ppss)))
(setf (nth 2 ppss) last-sexp)
(setq last-sexp (nth 2 ppss)))
(setq depth (car ppss))
;; Skip over newlines within strings.
(nth 3 ppss))
(let ((string-start (nth 8 ppss)))
(setq ppss (parse-partial-sexp (point) (point-max)
nil nil ppss 'syntax-table))
(setf (nth 2 ppss) string-start)) ; Finished a complete string.
(setq ppss (parse-partial-sexp (point) (point-max)
nil nil ppss 'syntax-table))
(setf (nth 2 ppss) string-start) ; Finished a complete string.
(setq depth (car ppss)))
(setq ppss-point (point)))
(setq ppss-point (point))
(let* ((next-depth (car ppss))
(depth-delta (- next-depth depth)))
(let* ((depth-delta (- depth indent-depth)))
(cond ((< depth-delta 0)
(setq indent-stack (nthcdr (- depth-delta) indent-stack)))
((> depth-delta 0)
(setq indent-stack (nconc (make-list depth-delta nil)
indent-stack))))
(setq depth next-depth))
indent-stack)))))
(prog1
(let (indent)
(cond ((= (forward-line 1) 1) nil)
@ -826,7 +826,6 @@ by more than one line to cross a string literal."
;; This only happens if we're in a string.
(t (error "This shouldn't happen"))))
(setf (lisp-indent-state-stack state) indent-stack)
(setf (lisp-indent-state-depth state) depth)
(setf (lisp-indent-state-ppss-point state) ppss-point)
(setf (lisp-indent-state-ppss state) ppss))))

View file

@ -185,6 +185,19 @@ Test indentation in emacs-lisp-mode\"
(indent-region (point) (point-max))
(should (equal (buffer-string) correct)))))
(ert-deftest lisp-indent-region-after-string-literal ()
(with-temp-buffer
(insert "\
\(user-error \"Unexpected initialization file: `%s'
Expected initialization file: `%s'\"
(abbreviate-file-name user-init-file)
(abbreviate-file-name this-init-file))")
(let ((indent-tabs-mode nil)
(correct (buffer-string)))
(emacs-lisp-mode)
(indent-region (point-min) (point-max))
(should (equal (buffer-string) correct)))))
(provide 'lisp-mode-tests)
;;; lisp-mode-tests.el ends here