9

Is there a way, via some command that can be invoked by the keyboard, of making Emacs think that I clicked at a particular point (so that it does whatever it would have done if I clicked there, e.g. follow link or pop up a menu)? Or that I hovered mouse at point (so that tool tip pops up)?

[Motivation: Some modes decorate the buffer, turning some text into links and so on. I may know how to do something with the mouse (e.g. click on it), but not the equivalent keyboard shortcut/command to invoke. Of course I should read documentation for the mode and learn it, but thought it's an interesting question.]

Malabarba
  • 22,878
  • 6
  • 78
  • 163
ShreevatsaR
  • 880
  • 6
  • 19
  • 2
    I am especially interested in whether you can simulate a hover with the keyboard. It is not uncommon for a tool-tip to be the easiest place to find the information I am looking for. – nispio Oct 09 '14 at 19:20
  • @nispio you can preview the tooltip at point with [display-local-help](http://doc.endlessparentheses.com/Fun/display-local-help) – Malabarba Oct 10 '14 at 01:19
  • @Malabarba: Thanks very much; that seems to work! – ShreevatsaR Oct 10 '14 at 01:46

1 Answers1

6

Often, navigating to a location and pressing some key will have the same effect as clicking at that location. There's no built-in mechanism that ensures this, it's just that modes are typically written that way.

You can generate mouse events (click, double/triple/… click, button down/up, drag, motion). All mouse events have the form (TYPE POSITION . EXTRA-DATA) where TYPE is a symbol that encodes the mouse button, the nature of the action (click, drag, etc.), and the modifiers. TYPE is mouse-movement for a motion event. Call posn-at-point to generate the POSITION for the location of the point in the current buffer.

Here's some proof-of-concept code that simulates a mouse click at the cursor position when you press f11 followed by a digit. Modifiers are taken into account.

(defun make-mouse-event-at-point (base-event)
  (let ((posn (posn-at-point))
        (prefix "")
        (basic-type (event-basic-type base-event))
        (modifiers (event-modifiers base-event)))
    (cond
     ((and (integerp basic-type) (>= basic-type ?0) (<= basic-type ?9))
      ;; click
      (let* ((mouse-type (intern (format "%smouse-%d" prefix (- basic-type ?0))))
             (click-count 1)
             (type (event-convert-list (append modifiers (list mouse-type)))))
        (list type posn click-count)))
     (t
      (error "Unsupported key for mouse event: %s" (event-basic-type base-event))))))
(defun simulate-mouse-event-at-point ()
  (interactive)
  (let ((event (make-mouse-event-at-point last-input-event)))
    (setq unread-command-events (cons event unread-command-events))))

(defvar simulate-mouse-event-map (make-sparse-keymap))
(global-set-key [f11] simulate-mouse-event-map)
(define-key simulate-mouse-event-map [t] 'simulate-mouse-event-at-point)

Simulating hover looks more difficult.

  • 2
    This doesn't simulate hover, but if all you want is to see a tooltip, you can preview the tooltip at point with [display-local-help](http://doc.endlessparentheses.com/Fun/display-local-help) – Malabarba Oct 10 '14 at 01:20
  • I'm still trying this out, but in response to the first couple of sentences: the reason I asked this question is that I'm working in a mode where the "some key" is not clear (it happens to be `C-c C-, RET`, but I had to look up the mode's documentation for that). – ShreevatsaR Oct 10 '14 at 01:45
  • Actually this doesn't quite work. In the mode I'm working in, some piece of code is turned into a link, and clicking with the mouse opens up a menu at the point. Doing the above with `f11 1` doesn't do that (it prints something in the minibuffer but it's not the equivalent of a mouse click on the link) though `f11 3` does seem to be equivalent to `` and so on. – ShreevatsaR Oct 10 '14 at 01:52
  • @ShreevatsaR Maybe the mouse click action you want is bound to `down-mouse-1` and not `mouse-1`? [How can I find out in which keymap a key is bound?](http://emacs.stackexchange.com/questions/653/how-can-i-find-out-in-which-keymap-a-key-is-bound/654#654) may help investigate this. – Gilles 'SO- stop being evil' Oct 10 '14 at 07:46