分享:在eglot中执行LSP Server支持的command

有部分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)))

注意:这个函数是同步执行的,而且只支持无参命令,有参命令可以自行修改

使用效果如下:

5 个赞