4

I want to move point to where the mouse is pointing. This is easy to do interactively: just click and point will move to where the mouse is pointing.

However, I need to do this inside elisp code. I tried to find a nice way by inspecting the source for mouse-drag-region and by reading the manual on Mouse Position but did not manage :-(

Anyone has an elegant solution?

phs
  • 1,095
  • 6
  • 13

3 Answers3

2

You can do something like this:

(defun jump-to-cursor ()
  "Jump to the position under the mouse cursor if possible."
  (interactive)
  (when-let ((cursor-pos (mouse-position))
         (line (cddr cursor-pos))
         (col  (cadr cursor-pos))
         (p (save-excursion
          (goto-char (window-start))
          (forward-line line)
          (if (> (- (line-end-position) (line-beginning-position)) col)
              (progn  (move-to-column col) (1- (point)))
            nil))))
    (goto-char p)))

That function tries to compute the position under the cursor and then go to it if it can.

John Kitchin
  • 11,555
  • 1
  • 19
  • 41
  • 1
    Thanks a lot for your answer. Actually it provides a good example of the difficulties we face. Your code "tries" to compute the position because `(mouse-position)` does not provide actual values for line+column when character sizes change. I still wonder how mouse-drag-region does the trick... – phs Feb 19 '17 at 15:16
  • mouse-drag-region gets an event which contains that information I think. – John Kitchin Feb 19 '17 at 15:57
  • Is there an easy way to create, in elisp code, such an event without actually clicking on the mouse? – phs Feb 19 '17 at 17:40
  • 1
    I don't think so. See http://emacs.stackexchange.com/questions/967/simulating-mouse-operations-with-keyboard for an example to simulate a mouse-click at the current position. The problem is you don't know the position of the mouse cursor. I think you can only get it from the actual event, or by approximating it like my function does. – John Kitchin Feb 19 '17 at 17:49
2
(mouse-set-point last-input-event)
(redisplay t)

As MT indicates, this moves the point (aka caret) to the mouse pointer (aka cursor) the purpose being to then perform point operations. For example, I have bound C-S-leftClick to a function that, depending on text in the line at the pointer, invokes another function or opens a context menu.

  (global-set-key [C-S-mouse-1]#'lxa-mouse-open)
...
(defun lxa-mouse-open()
"Move cursor to mouse position and invoke `lxa-open'"
  (interactive) ; Required for binding to mouse button
  (mouse-set-point last-input-event)
  (redisplay t)
  (lxa-open)
  ...
  • 1
    Could you add some explanatory text to explain what your code is doing, please? – Dan Jun 18 '21 at 17:47
  • This solved my specific issue, which was reassigning click to a function. This makes sure the movement of point takes place before I do the rest of my stuff. – MT. Jul 28 '21 at 02:55
1

(mouse-position) returns line+column relative to the frame, not the window. You need to subtract window-top-line and window-left-column to get line+column relative to window.

tinlyx
  • 1,276
  • 1
  • 12
  • 27
Ray Wang
  • 46
  • 1
  • Yes, eventually I'll also want point to move to the right window in the right frame. And that these window and frame become selected. But let's assume for the moment that there is only one window and one frame. – phs Feb 20 '17 at 14:37