This is something I discovered during development of beeminder.el version 1.2. I wanted to have some text in the buffer saying “View all data” that would perform an action when clicked or when the user pressed RET on it.
I tried a couple of approaches, such as setting text properties in the buffer and then searching at the current point when RET was pressed. But those solutions didn’t feel right.
Finally, I discovered the
insert-button function which does what I wanted.
The previous code looked a little like this:
(insert "View all data") (put-text-property (line-beginning-position) (line-end-position) 'beeminder-is-read-more t) (defun beeminder-handle-view-all-data-link () "Handle a click on the 'Read more data' text." (when (get-text-property (point) 'beeminder-is-read-more) (beeminder-view-data-for-current-goal))) ;; Bind to <RET> (define-key beeminder-mode-map (kbd "<RET>") #'beeminder-handle-view-all-data-link)
It’s not the cleanest code ever, and it’s a lot of effort for a simple button. By using
insert-button, it now looks like this:
(insert-button "View all data" 'action (lambda (_arg) (beeminder-view-data-for-current-goal)))
Read more: Buttons - GNU Emacs Lisp Reference Manual.