Open jkitchin opened 6 years ago
Hi!
Indeed, that's the right approach, since when the callback happens, its knowledge is pretty much limited to the fact that the user clicked a mouse-button.
Button-lock buttons can respond to clicks other than mouse-1, so the value of (point)
doesn't always change in tandem with the click. Thus consulting the mouse event directly is more general. So I usually write the above more like
(setq hashtag-regexp "\\(^\\|[[:space:]]\\|\\s(\\)\\(?2:#\\(?1:[[:alnum:]]*\\)\\)")
(defun hashtag-mouse-action (event)
"Callback for clicks on hashtags."
(interactive "e")
(let ((click-pos (posn-point (event-end event))))
(save-mark-and-excursion
(save-match-data
(goto-char (1- (previous-single-property-change click-pos 'hashtag)))
(when (looking-at hashtag-regexp)
(message "%s" (match-string-no-properties 1)))))))
(setq hashtag-button
(button-lock-set-button hashtag-regexp
#'hashtag-mouse-action
:grouping 2
:additional-property 'hashtag ; custom property
:face (list 'link)
:help-echo "Click me to open the hashtag."))
;; (button-lock-unset-button hashtag-button)
(The regular expression confused me at first, perhaps because it was simplified for the sake of the example? It could be more like \\(?:^\\|[[:space:]]\\|\\s(\\)\\(#\\([[:alnum:]]+\\)\\)
, reversing the group numbers.)
Thanks for the confirmation, and improvement.
The regexp is just something that worked. The ?2: syntax just lets you number the groups the way you want. Once groups get nested, and there are many of them, I find it confusing to remember/figure out which group I need, so I just number them explicitly.
I find myself doing something like this a lot lately. I have a regexp with some groups in it that match text I want to make a button of, but in the action I only need to use part of the text. For example below will make a #hashtag into a button, but in the action I only need the "hashtag", e.g. to open the hashtag on Twitter or something.
The most robust way I have found so far is via property searching to get to the beginning of the match, and then "look at it" again. Is this the right approach to doing this?