]> git.eshelyaron.com Git - emacs.git/commitdiff
Be more careful about indent-sexp going over eol (Bug#35286)
authorNoam Postavsky <npostavs@gmail.com>
Mon, 15 Apr 2019 22:49:57 +0000 (18:49 -0400)
committerNoam Postavsky <npostavs@gmail.com>
Mon, 22 Apr 2019 16:49:36 +0000 (12:49 -0400)
* lisp/emacs-lisp/lisp-mode.el (indent-sexp): Only go over multiple
sexps if the end of line is within a sexp.
* test/lisp/emacs-lisp/lisp-mode-tests.el
(indent-sexp-stop-before-eol-comment)
(indent-sexp-stop-before-eol-non-lisp): New tests.

lisp/emacs-lisp/lisp-mode.el
test/lisp/emacs-lisp/lisp-mode-tests.el

index 57f57175c51f1bceba0ba64fd5781fe2336e5d29..74bf0c87c53835ed2a1e2342c8e688581bb2a5b9 100644 (file)
@@ -1205,19 +1205,25 @@ ENDPOS is encountered."
                     ;; Get error now if we don't have a complete sexp
                     ;; after point.
                     (save-excursion
+                      (forward-sexp 1)
                       (let ((eol (line-end-position)))
-                        (forward-sexp 1)
                         ;; We actually look for a sexp which ends
                         ;; after the current line so that we properly
                         ;; indent things like #s(...).  This might not
                         ;; be needed if Bug#15998 is fixed.
-                        (condition-case ()
-                            (while (and (< (point) eol) (not (eobp)))
-                              (forward-sexp 1))
-                          ;; But don't signal an error for incomplete
-                          ;; sexps following the first complete sexp
-                          ;; after point.
-                          (scan-error nil)))
+                        (when (and (< (point) eol)
+                                   ;; Check if eol is within a sexp.
+                                   (> (nth 0 (save-excursion
+                                               (parse-partial-sexp
+                                                (point) eol)))
+                                      0))
+                          (condition-case ()
+                              (while (< (point) eol)
+                                (forward-sexp 1))
+                            ;; But don't signal an error for incomplete
+                            ;; sexps following the first complete sexp
+                            ;; after point.
+                            (scan-error nil))))
                       (point)))))
     (save-excursion
       (while (let ((indent (lisp-indent-calc-next parse-state))
index a6370742ab47734362af78c70ea322de8bb1fbca..63632449ca5576d2597f857d6f9000147028560e 100644 (file)
@@ -136,6 +136,34 @@ noindent\" 3
     (indent-sexp)
     (should (equal (buffer-string) "(())"))))
 
+(ert-deftest indent-sexp-stop-before-eol-comment ()
+  "`indent-sexp' shouldn't look for more sexps after an eol comment."
+  ;; See https://debbugs.gnu.org/35286.
+  (with-temp-buffer
+    (emacs-lisp-mode)
+    (let ((str "() ;;\n  x"))
+      (insert str)
+      (goto-char (point-min))
+      (indent-sexp)
+      ;; The "x" is in the next sexp, so it shouldn't get indented.
+      (should (equal (buffer-string) str)))))
+
+(ert-deftest indent-sexp-stop-before-eol-non-lisp ()
+  "`indent-sexp' shouldn't be too agressive in non-Lisp modes."
+  ;; See https://debbugs.gnu.org/35286#13.
+  (with-temp-buffer
+    (prolog-mode)
+    (let ((str "\
+x(H) -->
+    {y(H)}.
+a(A) -->
+    b(A)."))
+      (insert str)
+      (search-backward "{")
+      (indent-sexp)
+      ;; There's no line-spanning sexp, so nothing should be indented.
+      (should (equal (buffer-string) str)))))
+
 (ert-deftest lisp-indent-region ()
   "Test basics of `lisp-indent-region'."
   (with-temp-buffer