emacs-lsp / lsp-ui

UI integrations for lsp-mode
https://emacs-lsp.github.io/lsp-ui
GNU General Public License v3.0
1.03k stars 141 forks source link

isearch mode is cancelled when moving mouse #532

Open xdai opened 3 years ago

xdai commented 3 years ago

After entering isearch mode by pressing ctrl-s, if you move the mouse then isearch mode will be cancelled. This is frustrating because following key strokes meant to be made under isearch mode just creates chaos in current buffer.

The issue goes away if I uninstall lsp-ui.

How to reproduce:

  1. Press ctrl-s
  2. Move mouse

I am running

Here is my lsp config:

(use-package lsp-mode
  :init
  (setq lsp-keymap-prefix "C-c l")
  (setq lsp-clients-clangd-executable "~/app/clangd_11.0.0-rc1/bin/clangd.exe")
  (setq lsp-clients-clangd-args '("--clang-tidy" "--header-insertion=never"))

  :config
  (setq lsp-headerline-breadcrumb-enable t)
  (setq lsp-headerline-breadcrumb-segments '(symbols))
  (setq lsp-lens-enable t)
  (setq lsp-enable-snippet nil)

  :hook
  ((c-mode   . lsp-deferred)
   (c++-mode . lsp-deferred))

  :commands
  (lsp lsp-deferred))
jcs090218 commented 3 years ago

I can reproduce this issue, yet I am not sure about what causes this issue. You don't have to uninstall lsp-ui; due if lsp-ui is not loaded then this behaviour wouldn't be occurred.

Anyway, thanks for reporting this issue to us. I will mark this with bug label for now!

danielmartin commented 3 years ago

Thanks for the report. From a buffer where you can reproduce the bug, could you do C-h k and then move the mouse pointer? It will open a Help buffer with documentation about the function that is running when the mouse moves and cancels the isearch.

xdai commented 3 years ago

I think C-h k only describes mouse click but not mouse movement.

I don't know Emacs well enough to know how to register a hook to mouse movement. But the almighty StackOverflow suggests post-command-hook. Not sure if it helps, but here it is:

post-command-hook is a variable defined in ‘C source code’.
Its value is
(lsp-ui-doc--make-request lsp-ui-sideline flycheck-perform-deferred-syntax-check flycheck-error-list-update-source flycheck-error-list-highlight-errors flycheck-maybe-display-error-at-point-soon flycheck-hide-error-buffer lsp--post-command eldoc-schedule-timer jit-lock--antiblink-post-command t)
Local in buffer stdfu_Api.cpp; global value is 
(global-font-lock-mode-check-buffers global-eldoc-mode-check-buffers global-hi-lock-mode-check-buffers ibuffer-auto-update-changed beacon--post-command sml/generate-position-help global-hl-line-maybe-unhighlight global-hl-line-highlight)
danielmartin commented 3 years ago

I think C-h k only describes mouse click but not mouse movement.

If I'm not mistaken, it should describe mouse movement as well, as it's an event like any other (<mouse-movement>).

Switch to an affected buffer.
M-x describe-key (C-h k).
Move the mouse pointer and click somewhere.

You should see a Help buffer like

There were several key-sequences:

\<mouse-movement> runs the command dap-tooltip-mouse-motion \<down-mouse-1> at that spot runs the command mouse-drag-region \<mouse-1> at that spot runs the command mouse-set-point

They're all described below.

BTW, I can reproduce this inconvenience if dap-tooltip-mode is enabled (from the dap-mode package). This minor mode wires command dap-tooltip-mouse-motion to <mouse-movement>.

It also happens if lsp-ui-doc-mode is enabled. That wires lsp-ui-doc--handle-mouse-movement to <mouse-movement>. Could you try disabling lsp-ui-doc-mode if you have it enabled?

One possible workaround to make isearch and lsp-ui-doc-mode work in tandem could be something like:

(put 'lsp-ui-doc--handle-mouse-movement 'isearch-scroll t)

That requires you add (setq isearch-allow-scroll t) to your Emacs configuration.

xdai commented 3 years ago

Thanks @danielmartin. Interestingly C-h k shows only <down-mouse-1> <mouse-1>, but M-x describe-key shows <mouse-movement> <down-mouse-1> <mouse-1>:

Enabled minor modes: Abbrev Auto-Composition Auto-Compression Auto-Encryption Beacon Blink-Cursor Column-Number Company Delete-Selection Desktop-Save Eldoc Electric-Indent File-Name-Shadow Flycheck Font-Lock Global-Eldoc Global-Font-Lock Global-Hi-Lock Global-Hl-Line Hi-Lock Line-Number Lsp Lsp-Completion Lsp-Diagnostics Lsp-Headerline-Breadcrumb Lsp-Lens Lsp-Managed Lsp-Modeline-Code-Actions Lsp-Modeline-Diagnostics Lsp-Modeline-Workspace-Status Lsp-Ui Lsp-Ui-Doc Lsp-Ui-Sideline Mouse-Wheel Rainbow-Delimiters Save-Place Show-Paren Tooltip Transient-Mark

\<mouse-movement> runs the command lsp-ui-doc--handle-mouse-movement \<down-mouse-1> at that spot runs the command mouse-drag-region \<mouse-1> at that spot runs the command mouse-set-point

Disabling lsp-ui-doc-mode doesn't solve the issue:

Enabled minor modes: Abbrev Auto-Composition Auto-Compression Auto-Encryption Beacon Blink-Cursor Column-Number Company Delete-Selection Desktop-Save Eldoc Electric-Indent File-Name-Shadow Flycheck Font-Lock Global-Eldoc Global-Font-Lock Global-Hi-Lock Global-Hl-Line Hi-Lock Line-Number Lsp Lsp-Completion Lsp-Diagnostics Lsp-Headerline-Breadcrumb Lsp-Lens Lsp-Managed Lsp-Modeline-Code-Actions Lsp-Modeline-Diagnostics Lsp-Modeline-Workspace-Status Lsp-Ui Lsp-Ui-Sideline Mouse-Wheel Rainbow-Delimiters Save-Place Show-Paren Tooltip Transient-Mark

\<mouse-movement> runs the command ignore \<down-mouse-1> at that spot runs the command mouse-drag-region \<mouse-1> at that spot runs the command mouse-set-point

In a C++ buffer where none of lsp modes are enabled (and the issue doesn't exist):

Enabled minor modes: Abbrev Auto-Composition Auto-Compression Auto-Encryption Beacon Blink-Cursor Column-Number Delete-Selection Desktop-Save Electric-Indent File-Name-Shadow Font-Lock Global-Eldoc Global-Font-Lock Global-Hi-Lock Global-Hl-Line Hi-Lock Line-Number Mouse-Wheel Rainbow-Delimiters Save-Place Show-Paren Tooltip Transient-Mark

\<down-mouse-1> at that spot runs the command mouse-drag-region \<mouse-1> at that spot runs the command mouse-set-point

The workaround you mentioned works unreliably. When lsp-ui-doc-mode is enabled and the workaround is applied (through running in scratch buffer), the Regexp I-search: prompt blinks but don't get cancelled when moving the mouse gently. However, if the mouse is moved quickly, or moved to (but doesn't click on) a different buffer, then isearch is likely being cancelled.

(put 'lsp-ui-doc--handle-mouse-movement 'isearch-scroll t)
(setq isearch-allow-scroll t)
danielmartin commented 3 years ago

Ender Dai notifications@github.com writes:

The workaround you mentioned works unreliably. When lsp-ui-doc-mode is enabled and the workaround is applied (through running in scratch buffer), the Regexp I-search: prompt blinks but don't get cancelled when moving the mouse gently. However, if the mouse is moved quickly, or moved to (but doesn't click on) a different buffer, then isearch is likely being cancelled.

(put 'lsp-ui-doc--handle-mouse-movement 'isearch-scroll t)
(setq isearch-allow-scroll t)

I think we may need to add the 'isearch-scroll property to more commands. Could you try evaluating the following two forms and see if it improves the situation?

(put 'dap-tooltip-mouse-motion 'isearch-scroll t) (put 'handle-switch-frame 'isearch-scroll t)

xdai commented 3 years ago

I don't have dap but I evaluated all 4 forms nevertheless. The situation is the same: isearch will be cancelled if mouse is moved over doc frame or a different buffer.

danielmartin commented 3 years ago

Very curious, I can't reproduce isearch exiting after applying those changes. Are you using a single Emacs frame or more than one? After you move the cursor and reproduce the problem, press C-h l (view-lossage) and paste the contents here.

xdai commented 3 years ago

issue-532

macd commented 3 years ago

I was having the same (and more) problems. The proposed fix for the mouse movement seems to work for me. However, my current problem is that the isearch is canceled on certain search strings in a very non repeatable manner. I tried to narrow it down, but seems to be very non-deterministic. But it happens enough to make lsp-mode unusable for me. This is with c++ and clangd. Sorry I cannot be more helpful. Here is the output of C h l when this happened in isearch after keying in only a 'd' and a 'u'

 C-p                        ;; previous-line
 C-p                        ;; previous-line
 C-p                        ;; previous-line
 C-s                        ;; isearch-forward
 d                          ;; isearch-printing-char
 u                          ;; isearch-printing-char
 <switch-frame>             ;; handle-switch-frame
 <switch-frame>             ;; handle-switch-frame
 C-h <switch-frame> l       ;; view-lossage

Don't know where those <switch-frame> s came from. Some of the pop up info stuff? Edit: confirming problem goes away when lsp-ui in uninstalled

rvl commented 3 years ago

It's not just isearch which is affected by this issue. I have also found that with lsp-ui, mouse movement interrupts key sequences such as C-x C-s.

I worked around the problem with (setq lsp-ui-doc-enable nil).

Is there some better way of detecting mouse hover events than binding to <mouse-movement>? Can the keymap binding be conditional on lsp-ui-doc-show-with-mouse?

Personally, I would be happy with just a key shortcut to show documentation.

hectorhon commented 3 years ago

I don't have lsp-ui installed, but experienced isearch being cancelled as well when using the rustic package. Using C-h k from above, I was able to pinpoint it to dap-tooltip-mouse-motion. In my case, dap-mode was installed as a dependency of lsp-java. After uninstalling lsp-java, I no longer face the issue.

emenel commented 1 year ago

I don't have lsp-ui installed, but experienced isearch being cancelled as well when using the rustic package. Using C-h k from above, I was able to pinpoint it to dap-tooltip-mouse-motion. In my case, dap-mode was installed as a dependency of lsp-java. After uninstalling lsp-java, I no longer face the issue.

This solved the issue for me as well, but no idea why it was happening. Luckily I don't write much java or rely on dap for it, but if you do this will be an issue.

braoult commented 1 year ago

It's not just isearch which is affected by this issue. I have also found that with lsp-ui, mouse movement interrupts key sequences such as C-x C-s.

Breaking a sequence may do some damage: In my case, I have tons of "b" inserted in my source code when I try to C-x b to switch buffer (my right hand being on the mouse and left one typing the sequence). A small mouse movement between the C-x and the b breaks the "C-x" and a "b" is simply inserted.

cdfh commented 11 months ago

This was causing me pain as well. I fixed by preventing dap-tooltip-mode from running with:

(custom-set-variables
  ...
  '(dap-auto-configure-features '(sessions locals breakpoints expressions controls)))
AlexanderArvidsson commented 6 months ago

The reason this happens is not because of lsp-ui directly, but lsp-ui sets track-mouse t when it sets up the mouse for lsp-ui-doc-mode, but in doing so, emacs will cancel key sequences when you move your mouse.

Give it a try, open up a no-config emacs and do (setq-local track-mouse t), then initiate a keystroke and move your mouse, it will be canceled.

This affects both I-Search and key-sequences. The only fix is to not set track-mouse t, but that will probably make hover docs not work.

cdfh commented 6 months ago

Ah, that's handy to know, thanks for sharing. Another fix might be to set track-mouse to nil upon a key press and reset it to t upon a chord's completion. I confess, I've not missed dap-tooltip-mode too much since disabling it and am no longer affected by the issue so doubt I'll get round to trying the above, bit will post if I do.

braoult commented 6 months ago

The reason this happens is not because of lsp-ui directly, but lsp-ui sets track-mouse t when it sets up the mouse for lsp-ui-doc-mode, but in doing so, emacs will cancel key sequences when you move your mouse. [...] This affects both I-Search and key-sequences. The only fix is to not set track-mouse t, but that will probably make hover docs not work.

Good catch. This would be nice to have a workaround for lsp-ui, maybe without tracking the mouse ?

For example, would it be possible to get mouse position when requested to do so (like a keyboard shortcut) ? I am thinking about something like a function that would (1) find mouse position (2) do what is currently done on hover.

AlexanderArvidsson commented 6 months ago

More importantly, disabling lsp-ui-doc-mode does not reset track-mouse back to nil, if that was the previous setting. It should remember what the previous setting was and then reset it back once the mode is turned off.

I am more in favor of turning track-mouse to nil while in the middle of a key sequence or isearch, but I am not sure how to accomplish this. I gave it a try but came up empty. There could be way more edge cases as well though. For isearch-like prompts, we could check if we're currently being prompted, should catch most cases I think.

Regarding keyboard shortcut, I currently have a function that shows the popup at a specific point (default cursor), perhaps if there's a function that returns the mouse point it would be easy to pipe that into there. I'll give it a try next year 😁!

Finally, perhaps there's some magic to be done with mouse-face instead? Perhaps there's a way to show the popup through mouse-face instead, since it doesn't rely on track-mouse.