[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
js2025 7d328eaca7e 1/4: Eglot: introduce eglot-advertise-cancellation
From: |
João Távora |
Subject: |
js2025 7d328eaca7e 1/4: Eglot: introduce eglot-advertise-cancellation |
Date: |
Fri, 17 Jan 2025 08:33:00 -0500 (EST) |
branch: js2025
commit 7d328eaca7e1b4f701d3cff14b0b377a542ab7cc
Author: João Távora <joaotavora@gmail.com>
Commit: João Távora <joaotavora@gmail.com>
Eglot: introduce eglot-advertise-cancellation
Setting this variable to true causes Eglot to send special
cancellation notification for certain stale client request.
This may improve the performance of some LSP servers, who might
be able to avoid doing costly but ultimately useless work on
behalf of the client.
Request cancellation is described in
https://microsoft.github.io/language-server-protocol/
specifications/lsp/3.17/specification/#cancelRequest
* lisp/jsonrpc.el (jsonrpc-request): Accept function as value for
CANCEL-ON-INPUT.
* lisp/progmodes/eglot.el (eglot--request): Rework.
* doc/misc/eglot.texi (Customizing Eglot): Mention
eglot-advertise-cancellation.
---
doc/misc/eglot.texi | 8 ++++++++
lisp/jsonrpc.el | 12 ++++++++----
lisp/progmodes/eglot.el | 16 +++++++++++++++-
3 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/doc/misc/eglot.texi b/doc/misc/eglot.texi
index af38adc094a..b2cbb795429 100644
--- a/doc/misc/eglot.texi
+++ b/doc/misc/eglot.texi
@@ -983,6 +983,14 @@ from the language server to be handled as Emacs's progress
reporting
facilities.
@end table
+@vindex eglot-advertise-cancellation
+@cindex request cancellation
+@item eglot-advertise-cancellation
+Setting this variable to true causes Eglot to send special cancellation
+notification for certain stale client request. This may improve the
+performance of some LSP servers, who might be able to avoid doing costly
+but ultimately useless work on behalf of the client.
+
@node Advanced server configuration
@chapter Advanced server configuration
diff --git a/lisp/jsonrpc.el b/lisp/jsonrpc.el
index 1d3a983d41e..92d31bf4429 100644
--- a/lisp/jsonrpc.el
+++ b/lisp/jsonrpc.el
@@ -399,10 +399,12 @@ error of type `jsonrpc-error'.
DEFERRED and TIMEOUT as in `jsonrpc-async-request', which see.
-If CANCEL-ON-INPUT is non-nil and the user inputs something while
-the function is waiting, then it exits immediately, returning
-CANCEL-ON-INPUT-RETVAL. Any future replies (normal or error) are
-ignored."
+If CANCEL-ON-INPUT is non-nil and the user inputs something while the
+function is waiting, then any future replies to the request by the
+remote endpoint (normal or error) are ignored and the function exits
+returning CANCEL-ON-INPUT-RETVAL. If CANCEL-ON-INPUT is a function, it
+is invoked with one argument an integer identifying the cancelled
+request as specified in the JSONRPC 2.0 spec."
(let* ((tag (cl-gensym "jsonrpc-request-catch-tag")) id-and-timer
canceled
(throw-on-input nil)
@@ -435,6 +437,8 @@ ignored."
(unwind-protect
(let ((inhibit-quit t)) (while (sit-for 30)))
(setq canceled t))
+ (when (functionp cancel-on-input)
+ (funcall cancel-on-input (car id-and-timer)))
`(canceled ,cancel-on-input-retval))
(t (while t (accept-process-output nil 30)))))
;; In normal operation, continuations for error/success is
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 3c9644568ef..9ed36e39e65 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -573,6 +573,15 @@ under cursor."
(const :tag "Execute custom commands" :executeCommandProvider)
(const :tag "Inlay hints" :inlayHintProvider)))
+
+(defcustom eglot-advertise-cancellation nil
+ "If non-nil, Eglot attemps to inform server of cancelled requests.
+This is done by sending an additional '$/cancelRequest' notification
+every time Eglot decides to forget a request. The effect of this
+notification is implementation defined, and is only useful for some
+servers."
+ :type 'boolean)
+
(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.")
@@ -1739,7 +1748,12 @@ Unless IMMEDIATE, send pending changes before making
request."
(unless immediate (eglot--signal-textDocument/didChange))
(jsonrpc-request server method params
:timeout timeout
- :cancel-on-input cancel-on-input
+ :cancel-on-input
+ (cond ((and cancel-on-input
+ eglot-advertise-cancellation)
+ (lambda (id)
+ (jsonrpc-notify server '$/cancelRequest `(:id
,id))))
+ (cancel-on-input))
:cancel-on-input-retval cancel-on-input-retval))