diff options
| author | Leo Liu | 2018-09-14 22:31:50 +0800 |
|---|---|---|
| committer | Leo Liu | 2018-09-14 22:38:58 +0800 |
| commit | 1e3b3fa6159db837fca2f2d564e51b01048a906f (patch) | |
| tree | 405eb6253616b634f29433c33fbe560054bcf7d7 | |
| parent | 219893a519e57a53425ea2c821ef0781f9642771 (diff) | |
| download | emacs-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.el | 27 | ||||
| -rw-r--r-- | test/lisp/thingatpt-tests.el | 72 |
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. |
| 222 | Prefer 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)) | 611 | If IGNORE-COMMENT-OR-STRING is non-nil comments and strings are |
| 612 | treated 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 |