From 9e5c05a5cff6ab4eea5667792cf277c020b95426 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 10 Jun 2017 09:50:48 -0400 Subject: [PATCH v1] 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. --- lisp/emacs-lisp/lisp-mode.el | 27 +++++++++++++-------------- test/lisp/emacs-lisp/lisp-mode-tests.el | 13 +++++++++++++ 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 1e38d44e1b..59db00d5f9 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -773,11 +773,9 @@ (cl-defstruct (lisp-indent-state (: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 @@ (defun lisp-indent-calc-next (state) 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 @@ (defun lisp-indent-calc-next (state) (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 @@ (defun lisp-indent-calc-next (state) ;; 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)))) diff --git a/test/lisp/emacs-lisp/lisp-mode-tests.el b/test/lisp/emacs-lisp/lisp-mode-tests.el index f2fe7a6cf4..582041cfc2 100644 --- a/test/lisp/emacs-lisp/lisp-mode-tests.el +++ b/test/lisp/emacs-lisp/lisp-mode-tests.el @@ -185,6 +185,19 @@ (ert-deftest lisp-indent-region-in-sexp () (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 -- 2.11.1