0

For many built-in commands that require user input in the minibuffer I can yank from the middle mouse button (mouse-yank-primary with <down-mouse-2>). Some examples where this works are rgrep, grep, query-replace, find-file, execute-extended-command.

However, for helm- related commands, I haven't found any where this works. For example, with helm-M-x, helm-swoop, and functions that are on the helm-completing-read-handlers-alist, if I try to yank from the mouse, I get the message:

<down-mouse-2> is undefined
<mouse-2> is undefined

in the minibuffer. Is there any way to use mouse-yank-primary in helm contexts?

The closest I have gotten is:

(define-key helm-map
  (kbd "<down-mouse-2>") 'mouse-yank-primary)

This works to yank the text into the minibuffer, but now it gives me an annoying <drag-mouse-2> is undefined message which I haven't been able to get rid of, and which doesn't appear with the built-in commands mentioned above. Any suggestions?

  • 1
    I have no experience with anything involving the mouse in Emacs, so I can't really help here, but have you tried binding <drag-mouse-2> to ignore in helm-map? That might get rid of your annoying message at least. – Aaron Harris Jan 27 '16 at 19:52
  • I am very new to elisp programming and haven't come across ignore yet, but your suggestion actually worked perfectly when combined with what I already had. I was hoping that there was some helm mode configuration to just use the mouse-2 the way the built-in commands do, but since I haven't gotten any answer yet, it seems like I will have to go with the solution I mentioned above combined with your suggestion. If you convert your comment to an answer, I would accept it. – elethan Jan 27 '16 at 19:56
  • As part of the comment-to-answer conversion, I figured I'd do my due diligence and see if there was some easy configuration setting I had missed. As it turns out, you do have some other options, though I'm not sure any of them are better than my original idea. – Aaron Harris Jan 28 '16 at 0:01
2

After poking around the helm source code a bit, it looks like helm tries to temporarily override all the mouse commands using the minor mode helm--remap-mouse-mode, and this is most likely the source of your issues.

With the caveat that I don't have any experience with using the mouse in Emacs, there are several solutions that occur to me here, in increasing order of sophistication/precision:


Solution #1: The reason helm is trying to disable the mouse here is because by default helm won't let you leave the minibuffer when it's active. If you're fine with being able to leave the minibuffer (including with commands like other-window), you can set helm-prevent-escaping-from-minibuffer to nil.


Solution #2: You can just disable helm--remap-mouse-mode entirely. Here's some advice to just prevent it from ever being turned on.

(advice-add #'helm--remap-mouse-mode :override #'ignore)

Solution #3: Apparently bindings in helm-map will shadow those in helm--remap-mouse-mode-map, as you've already discovered. Together with your binding for <mouse-2>, you can bind <drag-mouse-2> to ignore in helm-map to get rid of the annoying message you mentioned.


(Non-)Solution #4: The ideal solution here would be to adjust the bindings in helm--remap-mouse-mode-map directly. However helm is doing something weird (and possibly buggy?) here that I don't fully understand. Here's the full definition of the mode, including its keymap:

(defvar helm--remap-mouse-mode-map
  (let ((map (make-sparse-keymap)))
    (cl-loop for k in '([mouse-1] [mouse-2] [mouse-3]
                        [down-mouse-1] [down-mouse-2] [down-mouse-3]
                        [drag-mouse-1] [drag-mouse-2] [drag-mouse-3]
                        [double-mouse-1] [double-mouse-2] [double-mouse-3]
                        [triple-mouse-1] [triple-mouse-2] [triple-mouse-3])
             do (define-key map k 'undefined))
    map))

(define-minor-mode helm--remap-mouse-mode
    "[INTERNAL] Prevent escaping helm minibuffer with mouse clicks.
Do nothing when used outside of helm context.

WARNING: Do not use this mode yourself, it is internal to helm."
  :group 'helm
  :global t
  :keymap helm--remap-mouse-mode-map
  (unless helm-alive-p
    (setq helm--remap-mouse-mode-map nil)))

The body here is run whenever the mode is enabled or disabled, and as far as I can tell helm-alive-p will be false under normal use during the disabling call. Thus after the first time the mode is used, helm--remap-mouse-mode-map gets set to nil (which isn't even a valid keymap!) and never gets set back. The baffling part is that the mode still somehow works, since the advice from solution #2 successfully re-enables the mouse.


Final note: When checking to see if there was an enlightening bug report dealing with the issues from solution #4, I found two issues (#501 and #622) in which the implementation of this feature was discussed. I figured I'd pass them on for additional context in case anyone is interested.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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