summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mendler <mail@daniel-mendler.de>2022-01-19 09:03:16 +0100
committerDaniel Mendler <mail@daniel-mendler.de>2022-01-19 09:29:04 +0100
commit3b019d5dea5346571926fa9d508a9879243be36a (patch)
treeebb97d449d1e6fd4dbb4109815c82c1e0d4c80a2
parentfa38c165d80535fea9aaa261be5301299f30a38e (diff)
cape--company-call: Use polling if throw-on-input=nil
-rw-r--r--cape.el57
1 files changed, 27 insertions, 30 deletions
diff --git a/cape.el b/cape.el
index 9cba1e1..184d584 100644
--- a/cape.el
+++ b/cape.el
@@ -60,10 +60,6 @@
"Dictionary word list file."
:type 'string)
-(defcustom cape-company-timeout 5.0
- "Company asynchronous timeout."
- :type '(choice nil float))
-
(defcustom cape-dabbrev-min-length 4
"Minimum length of dabbrev expansions."
:type 'integer)
@@ -878,32 +874,33 @@ If INTERACTIVE is nil the function acts like a capf."
(pcase (apply app)
;; Handle async future return values.
(`(:async . ,fetch)
- (let ((res 'cape--waiting)
- (start (time-to-seconds)))
- (unwind-protect
- (progn
- (funcall fetch (lambda (arg)
- (when (eq res 'cape--waiting)
- (push 'cape--done unread-command-events))
- (setq res arg)))
- ;; Force synchronization.
- (while (eq res 'cape--waiting)
- ;; When we've got input, interrupt the computation.
- (when (and unread-command-events toi)
- (throw toi nil))
- (when (and cape-company-timeout
- (> (- (time-to-seconds) start) cape-company-timeout))
- (error "Cape company backend async timeout"))
- (sit-for 0.1 'noredisplay)))
- ;; Remove cape--done introduced by future callback.
- ;; NOTE: `sit-for' converts cape--done to (t . cape--done).
- ;; It seems that `sit-for' does not use a robust method to
- ;; reinject inputs, maybe the implementation will change in
- ;; the future.
- (setq unread-command-events
- (delq 'cape--done
- (delete '(t . cape--done)
- unread-command-events))))
+ (let ((res 'cape--waiting))
+ (if toi
+ (unwind-protect
+ (progn
+ (funcall fetch (lambda (arg)
+ (when (eq res 'cape--waiting)
+ (push 'cape--done unread-command-events))
+ (setq res arg)))
+ ;; Force synchronization, interruptible!
+ (while (eq res 'cape--waiting)
+ ;; When we've got input, interrupt the computation.
+ (when unread-command-events (throw toi nil))
+ (sit-for 0.1 'noredisplay)))
+ ;; Remove cape--done introduced by future callback.
+ ;; NOTE: `sit-for' converts cape--done to (t . cape--done).
+ ;; It seems that `sit-for' does not use a robust method to
+ ;; reinject inputs, maybe the implementation will change in
+ ;; the future.
+ (setq unread-command-events (delq 'cape--done
+ (delete '(t . cape--done)
+ unread-command-events))))
+ (funcall fetch (lambda (arg) (setq res arg)))
+ ;; Force synchronization, not interruptible! We use polling
+ ;; here and ignore pending input since we don't use
+ ;; `sit-for'. This is the same method used by Company itself.
+ (while (eq res 'cape--waiting)
+ (sleep-for 0.01)))
res))
;; Plain old synchronous return value.
(res res))))