aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeo Liu2018-09-14 22:31:50 +0800
committerLeo Liu2018-09-14 22:38:58 +0800
commit1e3b3fa6159db837fca2f2d564e51b01048a906f (patch)
tree405eb6253616b634f29433c33fbe560054bcf7d7
parent219893a519e57a53425ea2c821ef0781f9642771 (diff)
downloademacs-1e3b3fa6159db837fca2f2d564e51b01048a906f.tar.gz
emacs-1e3b3fa6159db837fca2f2d564e51b01048a906f.zip
Fix (thing-at-point 'list) regression (Bug#31772)
* lisp/thingatpt.el (thing-at-point-bounds-of-list-at-point): Revert to pre 26.1 behavior. Return whole sexp at point if no enclosing list. (list-at-point): New optional arg to ignore comments and strings. * test/lisp/thingatpt-tests.el (thing-at-point-bounds-of-list-at-point): Fix and augment tests.
-rw-r--r--lisp/thingatpt.el27
-rw-r--r--test/lisp/thingatpt-tests.el72
2 files changed, 52 insertions, 47 deletions
diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el
index 6a978fe96ef..79f0230a20a 100644
--- a/lisp/thingatpt.el
+++ b/lisp/thingatpt.el
@@ -219,17 +219,15 @@ The bounds of THING are determined by `bounds-of-thing-at-point'."
219 219
220(defun thing-at-point-bounds-of-list-at-point () 220(defun thing-at-point-bounds-of-list-at-point ()
221 "Return the bounds of the list at point. 221 "Return the bounds of the list at point.
222Prefer the enclosing list with fallback on sexp at point.
222\[Internal function used by `bounds-of-thing-at-point'.]" 223\[Internal function used by `bounds-of-thing-at-point'.]"
223 (save-excursion 224 (save-excursion
224 (let* ((st (parse-partial-sexp (point-min) (point))) 225 (if (ignore-errors (up-list -1))
225 (beg (or (and (eq 4 (car (syntax-after (point)))) 226 (ignore-errors (cons (point) (progn (forward-sexp) (point))))
226 (not (nth 8 st)) 227 (let ((bound (bounds-of-thing-at-point 'sexp)))
227 (point)) 228 (and bound
228 (nth 1 st)))) 229 (<= (car bound) (point)) (< (point) (cdr bound))
229 (when beg 230 bound)))))
230 (goto-char beg)
231 (forward-sexp)
232 (cons beg (point))))))
233 231
234;; Defuns 232;; Defuns
235 233
@@ -608,8 +606,13 @@ Signal an error if the entire string was not used."
608 606
609(put 'number 'thing-at-point 'number-at-point) 607(put 'number 'thing-at-point 'number-at-point)
610;;;###autoload 608;;;###autoload
611(defun list-at-point () 609(defun list-at-point (&optional ignore-comment-or-string)
612 "Return the Lisp list at point, or nil if none is found." 610 "Return the Lisp list at point, or nil if none is found.
613 (form-at-point 'list 'listp)) 611If IGNORE-COMMENT-OR-STRING is non-nil comments and strings are
612treated as white space."
613 (let ((ppss (and ignore-comment-or-string (syntax-ppss))))
614 (save-excursion
615 (goto-char (or (nth 8 ppss) (point)))
616 (form-at-point 'list 'listp))))
614 617
615;;; thingatpt.el ends here 618;;; thingatpt.el ends here
diff --git a/test/lisp/thingatpt-tests.el b/test/lisp/thingatpt-tests.el
index cfb57de6189..1d80519fe74 100644
--- a/test/lisp/thingatpt-tests.el
+++ b/test/lisp/thingatpt-tests.el
@@ -84,41 +84,43 @@ position to retrieve THING.")
84 (goto-char (nth 1 test)) 84 (goto-char (nth 1 test))
85 (should (equal (thing-at-point (nth 2 test)) (nth 3 test)))))) 85 (should (equal (thing-at-point (nth 2 test)) (nth 3 test))))))
86 86
87;; These tests reflect the actual behavior of 87;; See bug#24627 and bug#31772.
88;; `thing-at-point-bounds-of-list-at-point'. 88(ert-deftest thing-at-point-bounds-of-list-at-point ()
89(ert-deftest thing-at-point-bug24627 () 89 (cl-macrolet ((with-test-buffer (str &rest body)
90 "Test for https://debbugs.gnu.org/24627 ." 90 `(with-temp-buffer
91 (let ((string-result '(("(a \"b\" c)" . (a "b" c)) 91 (emacs-lisp-mode)
92 (";(a \"b\" c)") 92 (insert ,str)
93 ("(a \"b\" c\n)" . (a "b" c)) 93 (search-backward "|")
94 ("\"(a b c)\"") 94 (delete-char 1)
95 ("(a ;(b c d)\ne)" . (a e)) 95 ,@body)))
96 ("(foo\n(a ;(b c d)\ne) bar)" . (a e)) 96 (let ((tests1
97 ("(foo\na ;(b c d)\ne bar)" . (foo a e bar)) 97 '(("|(a \"b\" c)" (a "b" c))
98 ("(foo\n(a \"(b c d)\"\ne) bar)" . (a "(b c d)" e)) 98 (";|(a \"b\" c)" (a "b" c) nil)
99 ("(b\n(a ;(foo c d)\ne) bar)" . (a e)) 99 ("|(a \"b\" c\n)" (a "b" c))
100 ("(princ \"(a b c)\")" . (princ "(a b c)")) 100 ("\"|(a b c)\"" (a b c) nil)
101 ("(defun foo ()\n \"Test function.\"\n ;;(a b)\n nil)" . (defun foo nil "Test function." nil)))) 101 ("|(a ;(b c d)\ne)" (a e))
102 (file 102 ("(foo\n|(a ;(b c d)\ne) bar)" (foo (a e) bar))
103 (expand-file-name "lisp/thingatpt.el" source-directory)) 103 ("(foo\n|a ;(b c d)\ne bar)" (foo a e bar))
104 buf) 104 ("(foo\n|(a \"(b c d)\"\ne) bar)" (foo (a "(b c d)" e) bar))
105 ;; Test for `thing-at-point'. 105 ("(b\n|(a ;(foo c d)\ne) bar)" (b (a e) bar))
106 (when (file-exists-p file) 106 ("(princ \"|(a b c)\")" (a b c) (princ "(a b c)"))
107 (unwind-protect 107 ("(defun foo ()\n \"Test function.\"\n ;;|(a b)\n nil)"
108 (progn 108 (defun foo nil "Test function." nil)
109 (setq buf (find-file file)) 109 (defun foo nil "Test function." nil))))
110 (goto-char (point-max)) 110 (tests2
111 (forward-line -1) 111 '(("|list-at-point" . "list-at-point")
112 (should-not (thing-at-point 'list))) 112 ("list-|at-point" . "list-at-point")
113 (kill-buffer buf))) 113 ("list-at-point|" . nil)
114 ;; Tests for `list-at-point'. 114 ("|(a b c)" . "(a b c)")
115 (dolist (str-res string-result) 115 ("(a b c)|" . nil))))
116 (with-temp-buffer 116 (dolist (test tests1)
117 (emacs-lisp-mode) 117 (with-test-buffer (car test)
118 (insert (car str-res)) 118 (should (equal (list-at-point) (cl-second test)))
119 (re-search-backward "\\((a\\|^a\\)") 119 (when (cddr test)
120 (should (equal (list-at-point) 120 (should (equal (list-at-point t) (cl-third test))))))
121 (cdr str-res))))))) 121 (dolist (test tests2)
122 (with-test-buffer (car test)
123 (should (equal (thing-at-point 'list) (cdr test))))))))
122 124
123(ert-deftest thing-at-point-url-in-comment () 125(ert-deftest thing-at-point-url-in-comment ()
124 (with-temp-buffer 126 (with-temp-buffer