Subject: bug#68762: 30.0.50; thing-at-point for an e-mail adress stops at "."

From: Eshel Yaron <[email-masked]>
Date: Sun, 28 Jan 2024 06:58:19 +0100

Eli Zaretskii <[email-masked]> writes:

>> From: Titus Müller <[email-masked]>
>> Date: Sat, 27 Jan 2024 14:25:08 +0100
>>
>>
>> When I use (thing-at-point 'email) and point is on an e-mail adress
>> like [email-masked], thing-at-point only gets [email-masked]
>> and loses the first part before the "." character. This happens
>> after I upgraded from 29.1 to emacs 30.0.50.
>
> Philip, is this because of the changes in commit ff20898dad?
>
> Could you please look into this?

FWIW, AFAICT this is introduced by 03cfede8f0 (which fixed Bug#61519).

I think the real issue resides in `thing-at-point-looking-at`, though:
It stops extending the match backwards when it first encounters a
non-match.  The following change solves this for me, and keeps all the
tests happy:

diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el
index 323d3d1cf6c..6f7532f9b0f 100644
--- a/lisp/thingatpt.el
+++ b/lisp/thingatpt.el
@@ -621,34 +621,22 @@ thing-at-point-looking-at
 back from point."
   (save-excursion
     (let ((old-point (point))
-	  (forward-bound (and distance (+ (point) distance)))
-	  (backward-bound (and distance (- (point) distance)))
-	  match prev-pos new-pos)
-      (and (looking-at regexp)
-	   (>= (match-end 0) old-point)
-	   (setq match (point)))
-      ;; Search back repeatedly from end of next match.
-      ;; This may fail if next match ends before this match does.
-      (re-search-forward regexp forward-bound 'limit)
-      (setq prev-pos (point))
-      (while (and (setq new-pos (re-search-backward regexp backward-bound t))
-                  ;; Avoid inflooping with some regexps, such as "^",
-                  ;; matching which never moves point.
-                  (< new-pos prev-pos)
-		  (or (> (match-beginning 0) old-point)
-		      (and (looking-at regexp)	; Extend match-end past search start
-			   (>= (match-end 0) old-point)
-			   (setq match (point))))))
-      (if (not match) nil
-	(goto-char match)
-	;; Back up a char at a time in case search skipped
-	;; intermediate match straddling search start pos.
-	(while (and (not (bobp))
-		    (progn (backward-char 1) (looking-at regexp))
-		    (>= (match-end 0) old-point)
-		    (setq match (point))))
-	(goto-char match)
-	(looking-at regexp)))))
+          prev-point match)
+      (goto-char (if distance
+                     (max (point-min) (- old-point distance))
+                   (point-min)))
+      (while (and (setq prev-point (point))
+                  (setq match
+                        (re-search-forward regexp
+                                           (and distance
+                                                (min (point-max)
+                                                     (+ old-point distance)))
+                                           t))
+                  (< (match-end 0) old-point))
+        (unless (< prev-point (point))
+          (forward-char)))
+      (and match (<= (match-beginning 0) old-point (match-end 0))))))
+

 ;;   Email addresses
 (defvar thing-at-point-email-regexp