branch: externals/cape commit 3b019d5dea5346571926fa9d508a9879243be36a Author: Daniel Mendler <m...@daniel-mendler.de> Commit: Daniel Mendler <m...@daniel-mendler.de>
cape--company-call: Use polling if throw-on-input=nil --- cape.el | 57 +++++++++++++++++++++++++++------------------------------ 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/cape.el b/cape.el index 9cba1e18ff..184d584bbd 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))))