all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Drew Adams <drew.adams@oracle.com>
To: Lars Ingebrigtsen <larsi@gnus.org>
Cc: 9454@debbugs.gnu.org
Subject: bug#9454: 24.0.50; thingatpt.el should be updated to respect field boundaries
Date: Tue, 20 Aug 2019 08:26:34 -0700 (PDT)	[thread overview]
Message-ID: <ebf3f2eb-b71e-4b87-9e48-68884c0115b6@default> (raw)
In-Reply-To: <87pnl0zh7f.fsf@mouse.gnus.org>

[-- Attachment #1: Type: text/plain, Size: 786 bytes --]

> Do you have a test case to reproduce this bug?

No.

See the original report.  It points you to my
code that fixes the problem by sprinkling
`constrain-to-field' everywhere.

To give an idea, attached are two functions,
my version and the vanilla version.  Ediff
them.  See the additions of this:

 (constrain-to-field nil orig)

I believe that the vanilla function needs
similar protection.  For you to decide.

That's just one thingatpt.el function.  I
also added `constraint-to-field to other
such functions.

See thingatpt+.el if you want to see the
occurrences, to maybe save some time when
checking where thingatpt.el might need the
same treatment.

I think you get the idea.  Thing-at-point
should respect fields.  Do it or don't do
it; your choice.

[-- Attachment #2: throw-my-thg.el --]
[-- Type: application/octet-stream, Size: 2701 bytes --]

(defun tap-bounds-of-thing-at-point-1 (thing)
  "Helper for `tap-bounds-of-thing-at-point'.
Do everything except handle the optional SYNTAX-TABLE arg."
  (let ((bounds-fn  (or (get thing 'tap-bounds-of-thing-at-point)
                        (get thing 'bounds-of-thing-at-point))))
    (if bounds-fn
        (funcall bounds-fn)
      (let ((orig  (point)))
        (condition-case nil
            (save-excursion
              ;; Try moving forward, then back.
              (funcall (or (get thing 'end-op) ; Move to end.
                           (lambda () (forward-thing thing 1))))
              (constrain-to-field nil orig)
              (funcall (or (get thing 'beginning-op) ; Move to beg.
                           (lambda () (forward-thing thing -1))))
              (constrain-to-field nil orig)
              (let ((beg  (point)))
                (if (<= beg orig)
                    ;; If that brings us all the way back to ORIG,
                    ;; it worked.  But END may not be the real end.
                    ;; So find the real end that corresponds to BEG.
                    ;; FIXME: in which cases can `real-end' differ from `end'?
                    (let ((real-end  (progn (funcall
                                             (or (get thing 'end-op)
                                                 (lambda () (forward-thing thing 1))))
                                            (constrain-to-field nil orig)
                                            (point))))
                      (and (< orig real-end)  (< beg real-end)
                           (cons beg real-end)))
                  (goto-char orig)
                  ;; Try a second time, moving first backward and then forward,
                  ;; so that we can find a thing that ends at ORIG.
                  (funcall (or (get thing 'beginning-op) ; Move to beg.
                               (lambda () (forward-thing thing -1))))
                  (constrain-to-field nil orig)
                  (funcall (or (get thing 'end-op) ; Move to end.
                               (lambda () (forward-thing thing 1))))
                  (constrain-to-field nil orig)
                  (let ((end       (point))
                        (real-beg  (progn (funcall
                                           (or (get thing 'beginning-op)
                                               (lambda () (forward-thing thing -1))))
                                          (constrain-to-field nil orig)
                                          (point))))
                    (and (<= real-beg orig)  (< orig end)  (< real-beg end)
                         (cons real-beg end))))))
          (error nil))))))

[-- Attachment #3: throw-vanilla-thg.el --]
[-- Type: application/octet-stream, Size: 2034 bytes --]

(defun bounds-of-thing-at-point (thing)
  "Determine the start and end buffer locations for the THING at point.
THING should be a symbol specifying a type of syntactic entity.
Possibilities include `symbol', `list', `sexp', `defun',
`filename', `url', `email', `word', `sentence', `whitespace',
`line', and `page'.

See the file `thingatpt.el' for documentation on how to define a
valid THING.

Return a cons cell (START . END) giving the start and end
positions of the thing found."
  (if (get thing 'bounds-of-thing-at-point)
      (funcall (get thing 'bounds-of-thing-at-point))
    (let ((orig (point)))
      (ignore-errors
	(save-excursion
	  ;; Try moving forward, then back.
	  (funcall ;; First move to end.
	   (or (get thing 'end-op)
	       (lambda () (forward-thing thing 1))))
	  (funcall ;; Then move to beg.
	   (or (get thing 'beginning-op)
	       (lambda () (forward-thing thing -1))))
	  (let ((beg (point)))
	    (if (<= beg orig)
		;; If that brings us all the way back to ORIG,
		;; it worked.  But END may not be the real end.
		;; So find the real end that corresponds to BEG.
		;; FIXME: in which cases can `real-end' differ from `end'?
		(let ((real-end
		       (progn
			 (funcall
			  (or (get thing 'end-op)
			      (lambda () (forward-thing thing 1))))
			 (point))))
		  (when (and (<= orig real-end) (< beg real-end))
		    (cons beg real-end)))
	      (goto-char orig)
	      ;; Try a second time, moving backward first and then forward,
	      ;; so that we can find a thing that ends at ORIG.
	      (funcall ;; First, move to beg.
	       (or (get thing 'beginning-op)
		   (lambda () (forward-thing thing -1))))
	      (funcall ;; Then move to end.
	       (or (get thing 'end-op)
		   (lambda () (forward-thing thing 1))))
	      (let ((end (point))
		    (real-beg
		     (progn
		       (funcall
			(or (get thing 'beginning-op)
			    (lambda () (forward-thing thing -1))))
		       (point))))
		(if (and (<= real-beg orig) (<= orig end) (< real-beg end))
		    (cons real-beg end))))))))))

  reply	other threads:[~2019-08-20 15:26 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-06 23:14 bug#9454: 24.0.50; thingatpt.el should be updated to respect field boundaries Drew Adams
2019-08-20  2:47 ` Lars Ingebrigtsen
2019-08-20 15:26   ` Drew Adams [this message]
2019-08-21 20:11     ` Lars Ingebrigtsen
2021-08-25 16:05       ` Lars Ingebrigtsen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ebf3f2eb-b71e-4b87-9e48-68884c0115b6@default \
    --to=drew.adams@oracle.com \
    --cc=9454@debbugs.gnu.org \
    --cc=larsi@gnus.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.