Skip to content

Commit

Permalink
Per joaotavora#1070: Make eglot-code-actions usable non-interactively
Browse files Browse the repository at this point in the history
* eglot.el (eglot--read-execute-code-action): New helper.
(eglot-code-actions): Use new helper.  Offer non-interactive version.
  • Loading branch information
joaotavora committed Oct 5, 2022
1 parent cc5c8fc commit 2599cd0
Showing 1 changed file with 23 additions and 13 deletions.
36 changes: 23 additions & 13 deletions eglot.el
Original file line number Diff line number Diff line change
Expand Up @@ -3124,8 +3124,9 @@ Returns a list as described in docstring of `imenu--index-alist'."
(let ((boftap (bounds-of-thing-at-point 'sexp)))
(list (car boftap) (cdr boftap)))))

(defun eglot-code-actions (beg &optional end action-kind)
"Offer to execute actions of ACTION-KIND between BEG and END.
(defun eglot-code-actions (beg &optional end action-kind interactive)
"Find LSP code actions of type ACTION-KIND between BEG and END.
Interactively, offer to execute them.
If ACTION-KIND is nil, consider all kinds of actions.
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
Expand All @@ -3135,8 +3136,10 @@ at point. With prefix argument, prompt for ACTION-KIND."
,(and current-prefix-arg
(completing-read "[eglot] Action kind: "
'("quickfix" "refactor.extract" "refactor.inline"
"refactor.rewrite" "source.organizeImports")))))
(unless (eglot--server-capable :codeActionProvider)
"refactor.rewrite" "source.organizeImports")))
t))
(unless (or (not interactive)
(eglot--server-capable :codeActionProvider))
(eglot--error "Server can't execute code actions!"))
(let* ((server (eglot--current-server-or-lose))
(actions
Expand All @@ -3154,13 +3157,20 @@ at point. With prefix argument, prompt for ACTION-KIND."
collect it)]
,@(when action-kind `(:only [,action-kind]))))
:deferred t))
(menu-items
(or (cl-loop for action across actions
;; Do filtering ourselves, in case the `:only'
;; didn't go through.
when (or (not action-kind)
(equal action-kind (plist-get action :kind)))
collect (cons (plist-get action :title) action))
;; Redo filtering, in case the `:only' didn't go through.
(actions (cl-loop for a across actions
when (or (not action-kind)
(equal action-kind (plist-get a :kind)))
collect a)))
(if interactive
(eglot--read-execute-code-action actions server action-kind)
actions)))

(defun eglot--read-execute-code-action (actions server &optional action-kind)
"Helper for interactive calls to `eglot-code-actions'"
(let* ((menu-items
(or (cl-loop for a in actions
collect (cons (plist-get a :title) a))
(apply #'eglot--error
(if action-kind `("No \"%s\" code actions here" ,action-kind)
`("No code actions here")))))
Expand All @@ -3169,7 +3179,7 @@ at point. With prefix argument, prompt for ACTION-KIND."
(plist-get (cdr menu-item) :isPreferred))
menu-items))
(default-action (car (or preferred-action (car menu-items))))
(action (if (and action-kind (null (cadr menu-items)))
(chosen (if (and action-kind (null (cadr menu-items)))
(cdr (car menu-items))
(if (listp last-nonmenu-event)
(x-popup-menu last-nonmenu-event `("Eglot code actions:"
Expand All @@ -3179,7 +3189,7 @@ at point. With prefix argument, prompt for ACTION-KIND."
default-action)
menu-items nil t nil nil default-action)
menu-items))))))
(eglot--dcase action
(eglot--dcase chosen
(((Command) command arguments)
(eglot-execute-command server (intern command) arguments))
(((CodeAction) edit command)
Expand Down

0 comments on commit 2599cd0

Please sign in to comment.