aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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