From 76cdf293c480c3825eb99eae0ab863d185cf6570 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Wed, 20 Sep 2023 11:00:19 +0100 Subject: [PATCH] Eglot: better consider diagnostics at point on code action requests * lisp/progmodes/eglot.el (eglot--code-action-bounds): Rename from eglot--code-action-bounds. Rework to consider diagnostics. (eglot-code-actions): Use new eglot--code-action-bounds. (eglot--code-action): Use new eglot--code-action-bounds. * etc/EGLOT-NEWS: mention change. GitHub-reference: https://github.com/joaotavora/eglot/discussions/1295 --- etc/EGLOT-NEWS | 7 +++++++ lisp/progmodes/eglot.el | 21 ++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/etc/EGLOT-NEWS b/etc/EGLOT-NEWS index ffc8095f752..f5f78ccd483 100644 --- a/etc/EGLOT-NEWS +++ b/etc/EGLOT-NEWS @@ -43,6 +43,13 @@ For 'newline' commands, Eglot sometimes sent the wrong character code to the server. Also made this feature less chatty in the mode-line and messages buffer. +** Improve mouse invocation of code actions + +When invoking code actions by middle clicking with the mouse on +Flymake diagnostics, it was often the case that Eglot didn't request +code actions correctly and thus no actions were offered to the user. +This has been fixed. github#1295 + * Changes in Eglot 1.15 (29/4/2023) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 79b3dbb2994..e511df01850 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -3579,11 +3579,18 @@ edit proposed by the server." :newName ,newname)) this-command)) -(defun eglot--region-bounds () - "Region bounds if active, else bounds of things at point." - (if (use-region-p) `(,(region-beginning) ,(region-end)) - (let ((boftap (bounds-of-thing-at-point 'sexp))) - (list (car boftap) (cdr boftap))))) +(defun eglot--code-action-bounds () + "Calculate appropriate bounds depending on region and point." + (let (diags) + (cond ((use-region-p) `(,(region-beginning) ,(region-end))) + ((setq diags (flymake-diagnostics (point))) + (cl-loop for d in diags + minimizing (flymake-diagnostic-beg d) into beg + maximizing (flymake-diagnostic-end d) into end + finally (cl-return (list beg end)))) + (t + (let ((boftap (bounds-of-thing-at-point 'sexp))) + (list (car boftap) (cdr boftap))))))) (defun eglot-code-actions (beg &optional end action-kind interactive) "Find LSP code actions of type ACTION-KIND between BEG and END. @@ -3593,7 +3600,7 @@ Interactively, default BEG and END to region's bounds else BEG is point and END is nil, which results in a request for code actions at point. With prefix argument, prompt for ACTION-KIND." (interactive - `(,@(eglot--region-bounds) + `(,@(eglot--code-action-bounds) ,(and current-prefix-arg (completing-read "[eglot] Action kind: " '("quickfix" "refactor.extract" "refactor.inline" @@ -3656,7 +3663,7 @@ at point. With prefix argument, prompt for ACTION-KIND." "Define NAME to execute KIND code action." `(defun ,name (beg &optional end) ,(format "Execute `%s' code actions between BEG and END." kind) - (interactive (eglot--region-bounds)) + (interactive (eglot--code-action-bounds)) (eglot-code-actions beg end ,kind t))) (eglot--code-action eglot-code-action-organize-imports "source.organizeImports") -- 2.39.2