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?

3 Answers 3

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.

4
  • 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, 2017 at 15:16
  • mouse-drag-region gets an event which contains that information I think. Feb 19, 2017 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, 2017 at 17:40
  • 1
    I don't think so. See emacs.stackexchange.com/questions/967/… 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. Feb 19, 2017 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)
  ...
2
  • 1
    Could you add some explanatory text to explain what your code is doing, please?
    – Dan
    Jun 18, 2021 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, 2021 at 2: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.

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, 2017 at 14:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.