Skip to content

Commit 93912ba

Browse files
committed
Be more careful about indent-sexp going over eol (Bug#35286)
* 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.
1 parent 3988e93 commit 93912ba

File tree

2 files changed

+42
-8
lines changed

2 files changed

+42
-8
lines changed

lisp/emacs-lisp/lisp-mode.el

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,19 +1205,25 @@ ENDPOS is encountered."
12051205
;; Get error now if we don't have a complete sexp
12061206
;; after point.
12071207
(save-excursion
1208+
(forward-sexp 1)
12081209
(let ((eol (line-end-position)))
1209-
(forward-sexp 1)
12101210
;; We actually look for a sexp which ends
12111211
;; after the current line so that we properly
12121212
;; indent things like #s(...). This might not
12131213
;; be needed if Bug#15998 is fixed.
1214-
(condition-case ()
1215-
(while (and (< (point) eol) (not (eobp)))
1216-
(forward-sexp 1))
1217-
;; But don't signal an error for incomplete
1218-
;; sexps following the first complete sexp
1219-
;; after point.
1220-
(scan-error nil)))
1214+
(when (and (< (point) eol)
1215+
;; Check if eol is within a sexp.
1216+
(> (nth 0 (save-excursion
1217+
(parse-partial-sexp
1218+
(point) eol)))
1219+
0))
1220+
(condition-case ()
1221+
(while (< (point) eol)
1222+
(forward-sexp 1))
1223+
;; But don't signal an error for incomplete
1224+
;; sexps following the first complete sexp
1225+
;; after point.
1226+
(scan-error nil))))
12211227
(point)))))
12221228
(save-excursion
12231229
(while (let ((indent (lisp-indent-calc-next parse-state))

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,34 @@ noindent\" 3
136136
(indent-sexp)
137137
(should (equal (buffer-string) "(())"))))
138138

139+
(ert-deftest indent-sexp-stop-before-eol-comment ()
140+
"`indent-sexp' shouldn't look for more sexps after an eol comment."
141+
;; See https://debbugs.gnu.org/35286.
142+
(with-temp-buffer
143+
(emacs-lisp-mode)
144+
(let ((str "() ;;\n x"))
145+
(insert str)
146+
(goto-char (point-min))
147+
(indent-sexp)
148+
;; The "x" is in the next sexp, so it shouldn't get indented.
149+
(should (equal (buffer-string) str)))))
150+
151+
(ert-deftest indent-sexp-stop-before-eol-non-lisp ()
152+
"`indent-sexp' shouldn't be too agressive in non-Lisp modes."
153+
;; See https://debbugs.gnu.org/35286#13.
154+
(with-temp-buffer
155+
(prolog-mode)
156+
(let ((str "\
157+
x(H) -->
158+
{y(H)}.
159+
a(A) -->
160+
b(A)."))
161+
(insert str)
162+
(search-backward "{")
163+
(indent-sexp)
164+
;; There's no line-spanning sexp, so nothing should be indented.
165+
(should (equal (buffer-string) str)))))
166+
139167
(ert-deftest lisp-indent-region ()
140168
"Test basics of `lisp-indent-region'."
141169
(with-temp-buffer

0 commit comments

Comments
 (0)