Subject: Re: bug#78106: [Feature Request] EGLOT: Optionally make code action indications use mouse clicks

From: Elijah Gabe Pérez <[email-masked]>
Date: Thu, 01 May 2025 18:04:26 -0600

João Távora <[email-masked]> writes:

> Elijah Gabe Pérez <[email-masked]> writes:
> Your ideas are good, but did you test your patch thoroughly?  I did, see
> comments below.
>
>>                 (overlay-buffer eglot--suggestion-overlay))
>> -      (overlay-get eglot--suggestion-overlay 'eglot--suggestion-tooltip)))
>> +      (eglot--mode-line-props
>> +       eglot-code-action-indicator
>> +       'help-echo
>> +       `((mouse-1
>> +          eglot-code-actions-at-mouse
>> +          ,(plist-get (aref (overlay-get eglot--suggestion-overlay 'eglot--actions) 0) :title)))
>> +       "Execute code actions at point\n")))
>
> This removes the face from the mode-line indication and uses 'help-echo.
> Probably should be eglot-code-action-indicator-face.

Oops, sorry, I thought that function was a kind of `propertize'.

> Also the blurb looks like.
>
>    Execute code actions at point. mouse-1: extract subexpression to variable
>
> Maybe it should be:
>
>    mouse-1: execute code actions at point
>
> since your second sentence is misleading, as it will actually pop a
> menu, not execute the actual action right away.

I agree, fixed.

>>  (add-to-list
>> @@ -4130,7 +4136,7 @@ eglot-code-action-suggestion
>>             (when (cl-plusp (length actions))
>>               (setq blurb
>>                     (substitute-command-keys
>> -                    (eglot--format "\\[eglot-code-actions]: %s"
>> +                    (eglot--format "\\[eglot-code-actions] or
>>  \\[eglot-code-actions-at-mouse]: %s"
>
> This isn't right, did you test this?  The second part shows the user
> instructions that when followed do not do what they say they do.  For me
> it says:
>
>    <f2> or M-x eglot-code-actions-at-mouse: extract subexpression to variable
>
> I have M-x eglot-code-actions bound to <f2> of course.  In my case it
> should say 'mouse-2' as that is the (default) button that pops up a
> menu.  So it should be
>
>   <f2>: extract subexpression to variable, mouse-2: execute code actions
>   at point
>
> Needless to say if I press 'M-x eglot-code-actions-at-mouse' it doesn't
> work, and I get an error saying there is no mouse event when invoking
> the command.  So substitute-command-keys might not be a solution here,
> as you can't easily get it to be aware of the special map and not say
> anything if nothing is bound there.
>
> Even more problematic is the fact that it shows the changed blurb in the
> ElDoc area, in situations where the mouse (if there even is one!) is not
> hovering on the margin or fringe (if there even are fringes).
>
> So this isn't a straightforward problem to solve, which probably
> explains why I left this minor detail out.
>
> I also feel that if the code to do this grows too complicated, it's
> better to add generic utility to Emacs to solve these problems and
> conditionally use it in eglot.el with a 'fboundp' check.

A way I found for achieve this is only (re)propertizing the blurb
help-echo for `margin' and `nearby' options (like the patch below).
This let eldoc area unchanged (i tested it).

I used `substitute-command-keys' only for get the mouse-1/2/3 button for
margin, but since i see this is problematic, I've changed it to only
display `mouse-2'.

The help-echo for `margin' and `nearby' now should be displayed as:
"M-x eglot-code-actions: remove #include directive (and 1 more actions),
mouse-2: execute code actions at point"

and for the mode-line: "mouse-1: Execute code actions at point."

>From bf06dd9db04e433f72f635cd18e64443ce29c0b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <[email-masked]>
Date: Wed, 30 Apr 2025 13:21:29 -0600
Subject: [PATCH] Add keybinding to eglot code actions help-echo.

* lisp/progmodes/eglot.el (eglot-mode-line-action-suggestion):
Allow mouse-clicks in mode line for code actions.
(eglot-code-action-suggestion): Add "mouse-1" to help-echo only
in `margin' and `nearby' options.
---
 lisp/progmodes/eglot.el | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 530fd4aa5b8..ff8769dd5d2 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -2531,7 +2531,11 @@ eglot-mode-line-action-suggestion
   '(:eval
     (when (and (memq 'mode-line eglot-code-action-indications)
                (overlay-buffer eglot--suggestion-overlay))
-      (overlay-get eglot--suggestion-overlay 'eglot--suggestion-tooltip)))
+      (eglot--mode-line-props
+       eglot-code-action-indicator 'eglot-code-action-indicator-face
+       `((mouse-1
+          eglot-code-actions-at-mouse
+          "execute code actions at point")))))
   "Eglot mode line construct for at-point code actions.")
 
 (add-to-list
@@ -4143,19 +4147,25 @@ eglot-code-action-suggestion
                                'keymap eglot-diagnostics-map))
              (save-excursion
                (goto-char (car bounds))
-               (let ((ov (make-overlay (car bounds) (cadr bounds))))
+               (let ((ov (make-overlay (car bounds) (cadr bounds)))
+                     (tooltip-1 (propertize
+                                 tooltip
+                                 'help-echo
+                                 (concat
+                                  blurb
+                                  ",\nmouse-2: execute code actions at point"))))
                  (overlay-put ov 'eglot--actions actions)
                  (overlay-put ov 'eglot--suggestion-tooltip tooltip)
                  (overlay-put
                   ov
                   'before-string
                   (cond ((memq 'nearby eglot-code-action-indications)
-                         tooltip)
+                         tooltip-1)
                         ((memq 'margin eglot-code-action-indications)
                          (propertize "⚡"
                                      'display
                                      `((margin left-margin)
-                                       ,tooltip)))))
+                                       ,tooltip-1)))))
                  (setq eglot--suggestion-overlay ov)))))
          (when use-text-p (funcall cb blurb)))
        :hint :textDocument/codeAction)
-- 
2.49.0

-- 
                                          - E.G via GNU Emacs and Org.