Go to the first, previous, next, last section, table of contents.


Defining Clickable Text

There are two ways to set up clickable text in a buffer. There are typically two parts of this: to make the text highlight when the mouse is over it, and to make a mouse button do something when you click it on that part of the text.

Highlighting is done with the mouse-face text property. Here is an example of how Dired does it:

(condition-case nil
    (if (dired-move-to-filename)
        (put-text-property (point)
                           (save-excursion
                             (dired-move-to-end-of-filename)
                             (point))
                           'mouse-face 'highlight))
  (error nil))

The first two arguments to put-text-property specify the beginning and end of the text.

The usual way to make the mouse do something when you click it on this text is to define mouse-2 in the major mode's keymap. The job of checking whether the click was on clickable text is done by the command definition. Here is how Dired does it:

(defun dired-mouse-find-file-other-window (event)
  "In dired, visit the file or directory name you click on."
  (interactive "e")
  (let (file)
    (save-excursion
      (set-buffer (window-buffer (posn-window (event-end event))))
      (save-excursion
        (goto-char (posn-point (event-end event)))
        (setq file (dired-get-filename))))
    (select-window (posn-window (event-end event)))
    (find-file-other-window (file-name-sans-versions file t))))

The reason for the outer save-excursion construct is to avoid changing the current buffer; the reason for the inner one is to avoid permanently altering point in the buffer you click on. In this case, Dired uses the function dired-get-filename to determine which file to visit, based on the position found in the event.

Instead of defining a mouse command for the major mode, you can define a key binding for the clickable text itself, using the local-map text property:

(let ((map (make-sparse-keymap)))
  (define-key-binding map [mouse-2] 'operate-this-button)
  (put-text-property (point)
                     (save-excursion
                       (dired-move-to-end-of-filename)
                       (point))
                     'local-map map))

This method makes it possible to define different commands for various clickable pieces of text. Also, the major mode definition (or the global definition) remains available for the rest of the text in the buffer.


Go to the first, previous, next, last section, table of contents.