有部分LSP服务器需要额外进行 :workspace/executeCommand
,比如 metals
就需要执行 build-import
等,lsp-metals
内置了对这些命令的支持:
这里我在 eglot
上包装了一下,使其能够选择需要执行的命令:
(defun my/eglot-enable-command-provider (orig-fn server)
"Unconditionally add :executeCommandProvider to Eglot client capabilities."
(let ((original-capabilities (funcall orig-fn server)))
;; Add or update :executeCommandProvider at the top level
(plist-put original-capabilities
:executeCommandProvider '(:commands (:dynamicRegistration :json-false)))))
(advice-add 'eglot-client-capabilities :around #'my/eglot-enable-command-provider)
(defun my/eglot-execute-command (command)
"Interactively execute a COMMAND supported by the current Eglot LSP server.
COMMAND is a string as advertised by the server. No arguments are passed."
(interactive
(let* ((server (eglot-current-server))
(caps (eglot--capabilities server))
(provider (plist-get caps :executeCommandProvider))
(commands (and provider (plist-get provider :commands))))
(list (completing-read "LSP Command: "
(or (cl-coerce commands 'list) '())
nil nil))))
(eglot-execute (eglot-current-server) (list :command command)))
注意:这个函数是同步执行的,而且只支持无参命令,有参命令可以自行修改
使用效果如下: