From bb08431bca7475dffdc3f37a97e4aea468a83641 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Sun, 13 May 2018 02:39:32 +0100 Subject: [PATCH] Reinstate the catch/loop/throw idiom in eglot-request This reverts parts of commit fabee14ed5b32c30c6ac5cb1ce88f387522a6a1e. Unfortunately, this may cause problems when calling the error callbacks directly as in the process sentinel. In that particular scenario the accept-process-output won't have return, because no output has is being handled. Consequently, if we're unlucky, we have another 30 seconds to way before the flag is tested and the loop exits. * eglot.el (eglot-request): Use catch/loop/throw again --- lisp/progmodes/eglot.el | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 13f6f61d581..6f9034942d5 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -651,20 +651,25 @@ DEFERRED is passed to `eglot--async-request', which see." ;; bad idea, since that might lead to the request never having a ;; chance to run, because `eglot--ready-predicates'. (when deferred (eglot--signal-textDocument/didChange)) - (let ((retval)) - (eglot--async-request - proc method params - :success-fn (lambda (&rest args) - (setq retval `(done ,(if (vectorp (car args)) - (car args) args)))) - :error-fn (eglot--lambda (&key code message &allow-other-keys) - (setq retval `(error ,(format "Oops: %s: %s" code message)))) - :timeout-fn (lambda () - (setq retval '(error "Timed out"))) - :deferred deferred) - (while (not retval) (accept-process-output nil 30)) - (when (eq 'error (car retval)) (eglot--error (cadr retval))) - (cadr retval))) + (let* ((done (make-symbol "eglot--request-catch-tag")) + (res + (catch done (eglot--async-request + proc method params + :success-fn (lambda (&rest args) + (throw done (if (vectorp (car args)) + (car args) args))) + :error-fn (eglot--lambda + (&key code message &allow-other-keys) + (throw done + `(error ,(format "Oops: %s: %s" + code message)))) + :timeout-fn (lambda () + (throw done '(error "Timed out"))) + :deferred deferred) + ;; now spin, baby! + (while t (accept-process-output nil 0.01))))) + (when (and (listp res) (eq 'error (car res))) (eglot--error (cadr res))) + res)) (cl-defun eglot--notify (process method params) "Notify PROCESS of something, don't expect a reply.e" -- 2.39.2