Created
July 19, 2024 01:06
-
-
Save jefftrull/10cae87ce38bdf6655b30af5891b0fa6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
** Jeff Trull: thing-at-point | |
*** Generalizes "things" - parseable elements in a buffer | |
- words, lines, sentences | |
- symbols and sexps | |
- emails and urls | |
- uuids | |
Imagine anything that might come after ~forward-~ | |
**** Example | |
#+begin_src elisp | |
(with-temp-buffer | |
(save-excursion (insert "foo")) | |
(forward-word) | |
(point)) | |
#+end_src | |
#+begin_src elisp | |
(with-temp-buffer | |
(save-excursion (insert "foo")) | |
(forward-thing 'word) | |
(point)) | |
#+end_src | |
There's also motion commands ~beginning-of-thing~ and ~end-of-thing~ that work similarly. | |
*** Getting the thing | |
#+begin_src elisp | |
(with-temp-buffer | |
(save-excursion (insert "foo")) | |
(thing-at-point 'word)) ;; there is also "thing-at-mouse"! | |
#+end_src | |
*** Getting the boundaries of the thing | |
#+begin_src elisp | |
(with-temp-buffer | |
(save-excursion (insert "foo_")) | |
(bounds-of-thing-at-point 'word)) | |
#+end_src | |
#+begin_src elisp | |
(with-temp-buffer | |
(save-excursion (insert "foo_")) | |
(bounds-of-thing-at-point 'symbol)) | |
#+end_src | |
*** Writing your own thing-at-point provider | |
Let's make a thing called ~coord~, a comma-separated pair of coordinates in parentheses | |
**** Parser | |
#+begin_src elisp | |
(defun jet/parse-coord () | |
(with-peg-rules | |
((number (and (opt (char ?-)) (+ [digit]))) | |
(coord (and (char ?\() number (char ?,) number (char ?\))))) | |
(peg-run (peg (region coord) eob)))) | |
#+end_src | |
**** thing-at-point Provider | |
#+begin_src elisp | |
(defun jet/bounds-of-coord-at-point () | |
(save-excursion | |
(let ((pt (point)) | |
(lim (point-max))) | |
;; search forward for parens | |
(skip-chars-forward "^()") | |
(if (and (eq (char-after) ?\() (eq (point) pt)) | |
;; we began at a left paren. attempt to parse a coord | |
(jet/parse-coord) ;; returns bounds | |
(if (eq (point) lim) | |
;; we found no right parens | |
nil | |
(if (eq (char-after) ?\() | |
;; we found a left paren after our start point | |
nil | |
;; go to the start of this parenthesized expression | |
(backward-up-list) | |
(jet/parse-coord) ;; and return bounds (or nil) | |
)))))) | |
#+end_src | |
**** Installation | |
#+begin_src elisp | |
(put 'coord 'bounds-of-thing-at-point 'jet/bounds-of-coord-at-point) | |
#+end_src |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment