mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-22 07:09:54 +00:00
Eglot: Handle LSP progress with Emacs progress reporters (bug#59149)
Co-authored-by: João Távora <joaotavora@gmail.com> * lisp/progmodes/eglot.el (eglot-report-progress): New custom variable. (eglot-lsp-server): New slot for tracking active progress reporters. (eglot-handle-notification (eql $/progress)): New method. The LSP spec describes methods for reporting progress on long running jobs to the client: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#progress https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workDoneProgress This change reports those notifications in the minibuffer as they come in. It shows a percent indicator (if the server provides theme), or a spinner. This change could open the door for writing a "cancel long running request" command, which are identified by these progress notifications. See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#window_workDoneProgress_cancel * doc/misc/eglot.texi (Customizing Eglot): Describe new variable.
This commit is contained in:
parent
0cfeb1c2bc
commit
74a009dd96
@ -955,6 +955,13 @@ Note that you can still configure the excluded Emacs features manually
|
||||
to use Eglot in your @code{eglot-managed-mode-hook} or via some other
|
||||
mechanism.
|
||||
|
||||
@vindex eglot-report-progress
|
||||
@cindex progress
|
||||
@item eglot-report-progress
|
||||
Set this variable to true if you'd like progress notifications coming
|
||||
from the LSP server to be handled as Emacs's progress reporting
|
||||
facilities.
|
||||
|
||||
@vindex eglot-workspace-configuration
|
||||
@cindex server workspace configuration
|
||||
@item eglot-workspace-configuration
|
||||
|
@ -387,6 +387,11 @@ done by `eglot-reconnect'."
|
||||
"String displayed in mode line when Eglot is active."
|
||||
:type 'string)
|
||||
|
||||
(defcustom eglot-report-progress t
|
||||
"If non-nil, show progress of long running LSP server work"
|
||||
:type 'boolean
|
||||
:version "29.1")
|
||||
|
||||
(defvar eglot-withhold-process-id nil
|
||||
"If non-nil, Eglot will not send the Emacs process id to the language server.
|
||||
This can be useful when using docker to run a language server.")
|
||||
@ -471,6 +476,7 @@ This can be useful when using docker to run a language server.")
|
||||
(TextDocumentEdit (:textDocument :edits) ())
|
||||
(TextEdit (:range :newText))
|
||||
(VersionedTextDocumentIdentifier (:uri :version) ())
|
||||
(WorkDoneProgress (:kind) (:title :message :percentage :cancellable))
|
||||
(WorkspaceEdit () (:changes :documentChanges))
|
||||
(WorkspaceSymbol (:name :kind) (:containerName :location :data)))
|
||||
"Alist (INTERFACE-NAME . INTERFACE) of known external LSP interfaces.
|
||||
@ -832,6 +838,9 @@ treated as in `eglot--dbind'."
|
||||
(project
|
||||
:documentation "Project associated with server."
|
||||
:accessor eglot--project)
|
||||
(progress-reporters
|
||||
:initform (make-hash-table :test #'equal) :accessor eglot--progress-reporters
|
||||
:documentation "Maps LSP progress tokens to progress reporters.")
|
||||
(inhibit-autoreconnect
|
||||
:initform t
|
||||
:documentation "Generalized boolean inhibiting auto-reconnection if true."
|
||||
@ -2050,6 +2059,27 @@ COMMAND is a symbol naming the command."
|
||||
(_server (_method (eql telemetry/event)) &rest _any)
|
||||
"Handle notification telemetry/event.") ;; noop, use events buffer
|
||||
|
||||
(cl-defmethod eglot-handle-notification
|
||||
(server (_method (eql $/progress)) &key token value)
|
||||
"Handle $/progress notification identified by TOKEN from SERVER."
|
||||
(when eglot-report-progress
|
||||
(cl-flet ((fmt (&rest args) (mapconcat #'identity args " ")))
|
||||
(eglot--dbind ((WorkDoneProgress) kind title percentage message) value
|
||||
(pcase kind
|
||||
("begin"
|
||||
(let* ((prefix (format (concat "[eglot] %s %s:" (when percentage " "))
|
||||
(eglot-project-nickname server) token))
|
||||
(pr (puthash token
|
||||
(if percentage
|
||||
(make-progress-reporter prefix 0 100 percentage 1 0)
|
||||
(make-progress-reporter prefix nil nil nil 1 0))
|
||||
(eglot--progress-reporters server))))
|
||||
(progress-reporter-update pr percentage (fmt title message))))
|
||||
("report"
|
||||
(when-let ((pr (gethash token (eglot--progress-reporters server))))
|
||||
(progress-reporter-update pr percentage (fmt title message))))
|
||||
("end" (remhash token (eglot--progress-reporters server))))))))
|
||||
|
||||
(cl-defmethod eglot-handle-notification
|
||||
(_server (_method (eql textDocument/publishDiagnostics)) &key uri diagnostics
|
||||
&allow-other-keys) ; FIXME: doesn't respect `eglot-strict-mode'
|
||||
|
Loading…
Reference in New Issue
Block a user