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
This commit is contained in:
João Távora 2023-09-20 11:00:19 +01:00
parent f0794ac9ca
commit 76cdf293c4
2 changed files with 21 additions and 7 deletions

View file

@ -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)

View file

@ -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")