1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-10 00:00:39 -08:00

Fix lisp-indent-region and indent-sexp (Bug#26619)

The new lisp-indent-region introduced in 2017-04-22 "Add new
`lisp-indent-region' that doesn't reparse the code." is broken because
it doesn't save the calculated indent amounts for already seen sexp
depths.  Fix this by unifying the indent-sexp and lisp-indent-region
code.  Furthermore, only preserve position 2 of the running parse
when the depth doesn't change.
* lisp/emacs-lisp/lisp-mode.el (lisp-ppss): Use an OLDSTATE that
corresponds with the start point when calling parse-partial-sexp.
(lisp-indent-state): New struct.
(lisp-indent-calc-next): New function, extracted from indent-sexp.
(indent-sexp, lisp-indent-region): Use it.
(lisp-indent-line): Take indentation, instead of parse state.
* test/lisp/emacs-lisp/lisp-mode-tests.el
(lisp-mode-tests--correctly-indented-sexp): New constant.
(lisp-indent-region, lisp-indent-region-defun-with-docstring):
(lisp-indent-region-open-paren, lisp-indent-region-in-sexp): New
tests.
This commit is contained in:
Noam Postavsky 2017-04-23 10:43:05 -04:00
parent 17e540aa42
commit e7b6751c0a
2 changed files with 171 additions and 90 deletions

View file

@ -21,10 +21,7 @@
(require 'cl-lib)
(require 'lisp-mode)
(ert-deftest indent-sexp ()
"Test basics of \\[indent-sexp]."
(with-temp-buffer
(insert "\
(defconst lisp-mode-tests--correctly-indented-sexp "\
\(a
(prog1
(prog1
@ -42,9 +39,14 @@ noindent\" 3
2) ; comment
;; comment
b)")
(ert-deftest indent-sexp ()
"Test basics of \\[indent-sexp]."
(with-temp-buffer
(insert lisp-mode-tests--correctly-indented-sexp)
(goto-char (point-min))
(let ((indent-tabs-mode nil)
(correct (buffer-string)))
(correct lisp-mode-tests--correctly-indented-sexp))
(dolist (mode '(fundamental-mode emacs-lisp-mode))
(funcall mode)
(indent-sexp)
@ -97,5 +99,78 @@ noindent\" 3
(indent-sexp)
(should (equal (buffer-string) correct)))))
(ert-deftest lisp-indent-region ()
"Test basics of `lisp-indent-region'."
(with-temp-buffer
(insert lisp-mode-tests--correctly-indented-sexp)
(goto-char (point-min))
(let ((indent-tabs-mode nil)
(correct lisp-mode-tests--correctly-indented-sexp))
(emacs-lisp-mode)
(indent-region (point-min) (point-max))
;; Don't mess up correctly indented code.
(should (string= (buffer-string) correct))
;; Correctly add indentation.
(save-excursion
(while (not (eobp))
(delete-horizontal-space)
(forward-line)))
(indent-region (point-min) (point-max))
(should (equal (buffer-string) correct))
;; Correctly remove indentation.
(save-excursion
(let ((n 0))
(while (not (eobp))
(unless (looking-at "noindent\\|^[[:blank:]]*$")
(insert (make-string n ?\s)))
(cl-incf n)
(forward-line))))
(indent-region (point-min) (point-max))
(should (equal (buffer-string) correct)))))
(ert-deftest lisp-indent-region-defun-with-docstring ()
"Test Bug#26619."
(with-temp-buffer
(insert "\
\(defun test ()
\"This is a test.
Test indentation in emacs-lisp-mode\"
(message \"Hi!\"))")
(let ((indent-tabs-mode nil)
(correct (buffer-string)))
(emacs-lisp-mode)
(indent-region (point-min) (point-max))
(should (equal (buffer-string) correct)))))
(ert-deftest lisp-indent-region-open-paren ()
(with-temp-buffer
(insert "\
\(with-eval-after-load 'foo
(setq bar `(
baz)))")
(let ((indent-tabs-mode nil)
(correct (buffer-string)))
(emacs-lisp-mode)
(indent-region (point-min) (point-max))
(should (equal (buffer-string) correct)))))
(ert-deftest lisp-indent-region-in-sexp ()
(with-temp-buffer
(insert "\
\(when t
(when t
(list 1 2 3)
'etc)
(quote etc)
(quote etc))")
(let ((indent-tabs-mode nil)
(correct (buffer-string)))
(emacs-lisp-mode)
(search-backward "1")
(indent-region (point) (point-max))
(should (equal (buffer-string) correct)))))
(provide 'lisp-mode-tests)
;;; lisp-mode-tests.el ends here