Next: , Previous: Clickable Text, Up: Text Properties


32.19.10 Links and Mouse-1

The normal Emacs command for activating text in read-only buffers is <Mouse-2>, which includes following textual links. However, most graphical applications use <Mouse-1> for following links. For compatibility, <Mouse-1> follows links in Emacs too, when you click on a link quickly without moving the mouse. The user can customize this behavior through the variable mouse-1-click-follows-link.

To define text as a link at the Lisp level, you should bind the mouse-2 event to a command to follow the link. Then, to indicate that <Mouse-1> should also follow the link, you should specify a follow-link condition either as a text property or as a key binding:

follow-link property
If the clickable text has a non-nil follow-link text or overlay property, that specifies the condition.
follow-link event
If there is a binding for the follow-link event, either on the clickable text or in the local keymap, the binding is the condition.

Regardless of how you set the follow-link condition, its value is used as follows to determine whether the given position is inside a link, and (if so) to compute an action code saying how <Mouse-1> should handle the link.

mouse-face
If the condition is mouse-face, a position is inside a link if there is a non-nil mouse-face property at that position. The action code is always t.

For example, here is how Info mode handles <Mouse-1>:

          (define-key Info-mode-map [follow-link] 'mouse-face)
     

a function
If the condition is a valid 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]
            (lambda (pos)
              (eq (get-char-property pos 'face) 'cvs-filename-face)))
     

anything else
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 only specify this kind of condition on the text that constitutes a link.

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 "foo", <Mouse-1> translates into f. If it is [foo], <Mouse-1> translates into <foo>.
anything else
For any other non-nil action code, the mouse-1 event is translated into a mouse-2 event at the same position.

To define <Mouse-1> to activate a button defined with define-button-type, give the button a follow-link property with a value as specified above to determine how to follow the link. For example, here is how Help mode handles <Mouse-1>:

     (define-button-type 'help-xref
       'follow-link t
       'action #'help-button-action)

To define <Mouse-1> on a widget defined with define-widget, give the widget a :follow-link property with a value as specified above to determine how to follow the link.

For example, here is how the link widget specifies that a <Mouse-1> click shall be translated to <RET>:

     (define-widget 'link 'item
       "An embedded link."
       :button-prefix 'widget-link-prefix
       :button-suffix 'widget-link-suffix
       :follow-link "\C-m"
       :help-echo "Follow the link."
       :format "%[%t%]")
— 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 Events).