emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Jim Porter <jporterbugs@gmail.com>
To: Ihor Radchenko <yantar92@posteo.net>, eliz@gnu.org
Cc: emacs-devel@gnu.org, emacs-orgmode@gnu.org
Subject: Re: Adding custom providers for thingatpt.el (was: [PATCH] Add support for 'thing-at-point' to get URL at point)
Date: Sun, 28 Apr 2024 21:26:32 -0700	[thread overview]
Message-ID: <0c66ae28-7088-3ac7-be39-7714b8f80455@gmail.com> (raw)
In-Reply-To: <673a0f71-c91f-8461-7388-9efbed6ba24f@gmail.com>

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

On 4/12/2024 3:30 PM, Jim Porter wrote:
> On 4/12/2024 5:41 AM, Ihor Radchenko wrote:
>> Jim Porter <jporterbugs@gmail.com> writes:
>>
>>> That sounds reasonable enough to me; does anyone else have opinions on
>>> this? Otherwise, I'll get to work on a patch (though probably not for a
>>> couple weeks).
>>
>> It has been a while since the last message in this thread.
>> Jim, may I know if you had a chance to work on the patch?
> 
> Sorry about that. I'm currently extremely swamped with real life, but 
> most of that should be wrapped up by the end of the month, at which 
> point I'll be able to devote some time to Emacs again.

Ihor, Eli: What do you think of the attached patch? I added variables to 
let modes define custom providers for 'bounds-of-thing-at-point' and 
'forward-thing'. (Notably, I avoided adding vars for the 
'beginning-of-thing' and 'end-of-thing' functions, since those just call 
'bounds-of-thing-at-point' anyway.)

If this looks like a reasonable way to go, I'll continue work on this 
patch by adding entries to 'bounds-of-thing-at-point-provider-alist' and 
'forward-thing-provider-alist' in the appropriate places (i.e. wherever 
we already add to 'thing-at-point-provider-alist', like in EWW).

[-- Attachment #2: 0001-Allow-defining-custom-providers-for-more-thingatpt-f.patch --]
[-- Type: text/plain, Size: 6486 bytes --]

From a0ed62aa42fa47043511ba814cf5ce8419e9d03f Mon Sep 17 00:00:00 2001
From: Jim Porter <jporterbugs@gmail.com>
Date: Sun, 28 Apr 2024 21:19:53 -0700
Subject: [PATCH] Allow defining custom providers for more "thingatpt"
 functions

* lisp/thingatpt.el (bounds-of-thing-at-point-provider-alist)
(forward-thing-provider-alist): New variables...
(forward-thing, bounds-of-thing-at-point): ... use them.
* test/lisp/thingatpt-tests.el (thing-at-point-providers)
(forward-thing-providers, bounds-of-thing-at-point-providers): New
tests.

* etc/NEWS: Announce this change.
---
 etc/NEWS                     | 18 +++++++++++++-----
 lisp/thingatpt.el            | 35 ++++++++++++++++++++++++++++++-----
 test/lisp/thingatpt-tests.el | 31 +++++++++++++++++++++++++++++++
 3 files changed, 74 insertions(+), 10 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 7efb4110bcd..2480f0d096d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1591,19 +1591,27 @@ of the currently existing keyboards macros using the new mode
 duplicating them, deleting them, and editing their counters, formats,
 and keys.
 
-** Miscellaneous
+** thingatpt.el
 
 ---
-*** Webjump now assumes URIs are HTTPS instead of HTTP.
-For links in 'webjump-sites' without an explicit URI scheme, it was
-previously assumed that they should be prefixed with "http://".  Such
-URIs are now prefixed with "https://" instead.
+*** New variables for providing custom thingatpt implementations.
+The new variables 'bounds-of-thing-at-point-provider-alist' and
+'forward-thing-provider-alist' now allow defining custom implementations
+of 'bounds-of-thing-at-point' and 'forward-thing', respectively.
 
 ---
 *** 'bug-reference-mode' now supports 'thing-at-point'.
 Now, calling '(thing-at-point 'url)' when point is on a bug reference
 will return the URL for that bug.
 
+** Miscellaneous
+
+---
+*** Webjump now assumes URIs are HTTPS instead of HTTP.
+For links in 'webjump-sites' without an explicit URI scheme, it was
+previously assumed that they should be prefixed with "http://".  Such
+URIs are now prefixed with "https://" instead.
+
 +++
 *** New user option 'rcirc-log-time-format'
 This allows for rcirc logs to use a custom timestamp format, than the
diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el
index 7896ad984df..d5f71e3c6a8 100644
--- a/lisp/thingatpt.el
+++ b/lisp/thingatpt.el
@@ -75,6 +75,22 @@ thing-at-point-provider-alist
 `existing-filename', `url', `email', `uuid', `word', `sentence',
 `whitespace', `line', `face' and `page'.")
 
+(defvar bounds-of-thing-at-point-provider-alist nil
+  "Alist of providers to return the bounds of a \"thing\" at point.
+This variable can be set globally, or appended to buffer-locally by
+modes, to provide functions that will return the bounds of a \"thing\"
+at point.  The first provider for the \"thing\" that returns a non-nil
+value wins.  You can use this in much the same way as
+`thing-at-point-provider-alist' (which see).")
+
+(defvar forward-thing-provider-alist nil
+  "Alist of providers for moving forward to the end of a \"thing\".
+This variable can be set globally, or appended to buffer-locally by
+modes, to provide functions that will move forward to the end of a
+\"thing\" at point.  The first provider for the \"thing\" that returns a
+non-nil value wins.  You can use this in much the same way as
+`thing-at-point-provider-alist' (which see).")
+
 ;; Basic movement
 
 ;;;###autoload
@@ -84,11 +100,16 @@ forward-thing
 Possibilities include `symbol', `list', `sexp', `defun', `number',
 `filename', `url', `email', `uuid', `word', `sentence', `whitespace',
 `line', and `page'."
-  (let ((forward-op (or (get thing 'forward-op)
-			(intern-soft (format "forward-%s" thing)))))
-    (if (functionp forward-op)
-	(funcall forward-op (or n 1))
-      (error "Can't determine how to move over a %s" thing))))
+  (setq n (or n 1))
+  (or (seq-some (lambda (elt)
+                  (and (eq (car elt) thing)
+                       (funcall (cdr elt) n)))
+                forward-thing-provider-alist)
+      (let ((forward-op (or (get thing 'forward-op)
+			    (intern-soft (format "forward-%s" thing)))))
+        (if (functionp forward-op)
+	    (funcall forward-op n)
+          (error "Can't determine how to move over a %s" thing)))))
 
 ;; General routines
 
@@ -106,6 +127,10 @@ bounds-of-thing-at-point
 Return a cons cell (START . END) giving the start and end
 positions of the thing found."
   (cond
+   ((seq-some (lambda (elt)
+                (and (eq (car elt) thing)
+                     (funcall (cdr elt))))
+                bounds-of-thing-at-point-provider-alist))
    ((get thing 'bounds-of-thing-at-point)
     (funcall (get thing 'bounds-of-thing-at-point)))
    ;; If the buffer is totally empty, give up.
diff --git a/test/lisp/thingatpt-tests.el b/test/lisp/thingatpt-tests.el
index e50738f1122..4aacd776176 100644
--- a/test/lisp/thingatpt-tests.el
+++ b/test/lisp/thingatpt-tests.el
@@ -258,4 +258,35 @@ test-numbers-hex-c
   (should (equal (test--number "0xf00" 2) 3840))
   (should (equal (test--number "0xf00" 3) 3840)))
 
+(ert-deftest thing-at-point-providers ()
+  (with-temp-buffer
+    (setq-local thing-at-point-provider-alist
+                `((url . ,(lambda () "test"))))
+    (insert "hello")
+    (should (equal (thing-at-point 'url) "test"))
+    (should (equal (thing-at-point 'word) "hello"))))
+
+(ert-deftest forward-thing-providers ()
+  (with-temp-buffer
+    (setq-local forward-thing-provider-alist
+                `((url . ,(lambda (n) (goto-char 4)))))
+    (insert "hello there")
+    (goto-char (point-min))
+    (should (eq (save-excursion (forward-thing 'url) (point)) 4))
+    (should (eq (save-excursion (forward-thing 'word) (point)) 6))))
+
+(ert-deftest bounds-of-thing-at-point-providers ()
+  (with-temp-buffer
+    (setq-local bounds-of-thing-at-point-provider-alist
+                `((url . ,(lambda () '(2 . 3)))))
+    (insert "hello")
+    ;; Look for a "URL", using our provider above.
+    (should (equal (bounds-of-thing-at-point 'url) '(2 . 3)))
+    (should (eq (save-excursion (beginning-of-thing 'url)) 2))
+    (should (eq (save-excursion (end-of-thing 'url)) 3))
+    ;; Look for a word, which should *not* use our provider above.
+    (should (equal (bounds-of-thing-at-point 'word) '(1 . 6)))
+    (should (eq (save-excursion (beginning-of-thing 'word)) 1))
+    (should (eq (save-excursion (end-of-thing 'word)) 6))))
+
 ;;; thingatpt-tests.el ends here
-- 
2.25.1


  reply	other threads:[~2024-04-29  4:39 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-06 19:45 [PATCH] Add support for 'thing-at-point' to get URL at point Jim Porter
2023-11-06 19:56 ` Jim Porter
2023-11-06 20:11 ` Adding custom providers for thingatpt.el (was: [PATCH] Add support for 'thing-at-point' to get URL at point) Ihor Radchenko
2023-11-06 20:53   ` Jim Porter
2024-02-05 15:07     ` Ihor Radchenko
2024-02-05 22:44       ` Jim Porter
2024-02-05 22:56         ` Ihor Radchenko
2024-02-06 12:26           ` Eli Zaretskii
2024-02-06 12:38             ` Ihor Radchenko
2024-02-06 12:47               ` Eli Zaretskii
2024-04-12 12:41         ` Ihor Radchenko
2024-04-12 22:30           ` Jim Porter
2024-04-29  4:26             ` Jim Porter [this message]
2024-04-29 18:14               ` Ihor Radchenko
2024-04-30  4:42                 ` Jim Porter
2024-04-30 11:39                   ` Ihor Radchenko
2024-04-30 18:27                     ` Jim Porter
2024-04-30 21:10                       ` [External] : " Drew Adams
2024-05-07  1:08                         ` Jim Porter
2024-05-07  1:52                           ` Drew Adams
2024-05-07 12:20                             ` Eli Zaretskii
2024-05-07 15:16                               ` Drew Adams
2024-05-07 16:10                               ` Jim Porter
2024-05-07 18:01                                 ` Eli Zaretskii

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

  List information: https://www.orgmode.org/

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

  git send-email \
    --in-reply-to=0c66ae28-7088-3ac7-be39-7714b8f80455@gmail.com \
    --to=jporterbugs@gmail.com \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    --cc=emacs-orgmode@gnu.org \
    --cc=yantar92@posteo.net \
    /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 public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).