Clickable text is text that can be clicked, with either the mouse or via a keyboard command, to produce some result. Many major modes use clickable text to implement textual hyper-links, or links for short.
The easiest way to insert and manipulate links is to use the
button package. See Buttons. In this section, we will explain how to manually set up clickable text in a buffer, using text properties. For simplicity, we will refer to the clickable text as a link.
Implementing a link involves three separate steps: (1) indicating clickability when the mouse moves over the link; (2) making
mouse-2 on that link do something; and (3) setting up a
follow-link condition so that the link obeys
To indicate clickability, add the
mouse-face text property to the text of the link; then Emacs will highlight the link when the mouse moves over it. In addition, you should define a tooltip or echo area message, using the
help-echo text property. See Special Properties. For instance, here is how Dired indicates that file names are clickable:
help-echo "mouse-2: visit this file in other window")))
To make the link clickable, bind
mouse-2 to commands that perform the desired action. Each command should check to see whether it was called on a link, and act accordingly. For instance, Dired’s major mode keymap binds
mouse-2 to the following command:
(defun dired-mouse-find-file-other-window (event)
"In Dired, visit the file or directory name you click on."
(let ((window (posn-window (event-end event)))
(pos (posn-point (event-end event)))
(if (not (windowp window))
(error "No file chosen"))
(with-current-buffer (window-buffer window)
(setq file (dired-get-file-for-visit)))
(if (file-directory-p file)
(or (and (cdr dired-subdir-alist)
(find-file-other-window (file-name-sans-versions file t)))))
This command uses the functions
posn-point to determine where the click occurred, and
dired-get-file-for-visit to determine which file to visit.
Instead of binding the mouse command in a major mode keymap, you can bind it within the link text, using the
keymap text property (see Special Properties). For instance:
(let ((map (make-sparse-keymap)))
(define-key map [mouse-2] 'operate-this-button)
(put-text-property link-start link-end 'keymap map))
With this method, you can easily define different commands for different links. Furthermore, the global definition of
mouse-2 remain available for the rest of the text in the buffer.
The basic Emacs command for clicking on links is
mouse-2. However, for compatibility with other graphical applications, Emacs also recognizes
mouse-1 clicks on links, provided the user clicks on the link quickly without moving the mouse. This behavior is controlled by the user option
mouse-1-click-follows-link. See Mouse References in The GNU Emacs Manual.
To set up the link so that it obeys
mouse-1-click-follows-link, you must either (1) apply a
follow-link text or overlay property to the link text, or (2) bind the
follow-link event to a keymap (which can be a major mode keymap or a local keymap specified via the
keymap text property). The value of the
follow-link property, or the binding for the
follow-link event, acts as a condition for the link action. This condition tells Emacs two things: the circumstances under which a
mouse-1 click should be regarded as occurring inside the link, and how to compute an action code that says what to translate the
mouse-1 click into. The link action condition can be one of the following:
If the condition is the symbol
mouse-face, a position is inside a link if there is a non-
mouse-face property at that position. The action code is always
For example, here is how Info mode handles
(define-key Info-mode-map [follow-link] 'mouse-face)
If the condition is a function,
func, then a position
pos is inside a link if
(func pos) evaluates to non-
nil. The value returned by
func serves as the action code.
For example, here is how pcvs enables
mouse-1 to follow links on file names only:
(define-key map [follow-link]
(eq (get-char-property pos 'face) 'cvs-filename-face)))
If the condition value is anything else, then the position is inside a link and the condition itself is the action code. Clearly, you should specify this kind of condition only when applying the condition via a text or property overlay on the link text (so that it does not apply to the entire buffer).
The action code tells
mouse-1 how to follow the link:
a string or vector
If the action code is a string or vector, the
mouse-1 event is translated into the first element of the string or vector; i.e., the action of the
mouse-1 click is the local or global binding of that character or symbol. Thus, if the action code is
mouse-1 translates into
f. If it is
mouse-1 translates into
For any other non-
nil action code, the
mouse-1 event is translated into a
mouse-2 event at the same position.
mouse-1 to activate a button defined with
define-button-type, give the button a
follow-link property. The property value should be a link action condition, as described above. See Buttons. For example, here is how Help mode handles
mouse-1 on a widget defined with
define-widget, give the widget a
:follow-link property. The property value should be a link action condition, as described above. For example, here is how the
link widget specifies that a
mouse-1 click shall be translated to
(define-widget 'link 'item
"An embedded link."
:help-echo "Follow the link."
function mouse-on-link-p pos
This function returns non-
nil if position
pos in the current buffer is on a link.
pos can also be a mouse event location, as returned by
event-start (see Accessing Mouse).