]> git.eshelyaron.com Git - emacs.git/commitdiff
Reinstate the catch/loop/throw idiom in eglot-request
authorJoão Távora <joaotavora@gmail.com>
Sun, 13 May 2018 01:39:32 +0000 (02:39 +0100)
committerJoão Távora <joaotavora@gmail.com>
Sun, 13 May 2018 01:44:05 +0000 (02:44 +0100)
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

index 13f6f61d5814008e5e17f4d85de03277fcb552e7..6f9034942d58709bfcbc3926bbae3016e80b5a06 100644 (file)
@@ -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"