branch: master commit 0284f412dcdb40230fee72bcbe0efb68e9f08717 Merge: 63ab036 285419b Author: Dmitry Gutov <dgu...@yandex.ru> Commit: Dmitry Gutov <dgu...@yandex.ru>
Merge branch 'simpler-async' --- NEWS.md | 4 ++++ company.el | 34 +++++++++------------------------- test/async-tests.el | 26 ++++++++++++++------------ 3 files changed, 27 insertions(+), 37 deletions(-) diff --git a/NEWS.md b/NEWS.md index c6b8139..be28f60 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,10 @@ ## Next +* The most common case of tooltip flickering with asynchronous backend (and + built-in cache disabled) is fixed + ([#510](https://github.com/company-mode/company-mode/issues/510), + [#654](https://github.com/company-mode/company-mode/issues/654)). * Native line numbers compatibility fixes. * New feature `company-tng`. It contains a frontend and some helper code. The frontend triggers insertion of the candidate as soon as it's selected, so diff --git a/company.el b/company.el index 20e885e..2737a29 100644 --- a/company.el +++ b/company.el @@ -1220,36 +1220,20 @@ can retrieve meta-data for them." (let* ((non-essential (not (company-explicit-action-p))) (c (if company--manual-action (company-call-backend 'candidates prefix) - (company-call-backend-raw 'candidates prefix))) - res) + (company-call-backend-raw 'candidates prefix)))) (if (not (eq (car c) :async)) c - (let ((buf (current-buffer)) - (win (selected-window)) - (tick (buffer-chars-modified-tick)) - (pt (point)) - (backend company-backend)) + (let ((res 'none) + (inhibit-redisplay t)) (funcall (cdr c) (lambda (candidates) - (if (not (and candidates (eq res 'done))) - ;; There's no completions to display, - ;; or the fetcher called us back right away. - (setq res candidates) - (setq company-backend backend - company-candidates-cache - (list (cons prefix - (company--preprocess-candidates candidates)))) - (unwind-protect - (company-idle-begin buf win tick pt) - (unless company-candidates - (setq company-backend nil - company-candidates-cache nil))))))) - ;; FIXME: Relying on the fact that the callers - ;; will interpret nil as "do nothing" is shaky. - ;; A throw-catch would be one possible improvement. - (or res - (progn (setq res 'done) nil))))) + (when (eq res 'none) + (push 'company-dummy-event unread-command-events)) + (setq res candidates))) + (while (and (eq res 'none) + (sit-for 0.5))) + (and (consp res) res))))) (defun company--preprocess-candidates (candidates) (cl-assert (cl-every #'stringp candidates)) diff --git a/test/async-tests.el b/test/async-tests.el index 48ebdfb..277a91d 100644 --- a/test/async-tests.el +++ b/test/async-tests.el @@ -65,27 +65,28 @@ (company-mode) (let (company-frontends company-transformers - (company-backends (list 'company-async-backend))) + (company-backends (list 'company-async-backend)) + unread-command-events + noninteractive + (start-time (current-time))) (company-idle-begin (current-buffer) (selected-window) (buffer-chars-modified-tick) (point)) - (should (null company-candidates)) - (sleep-for 0.1) + (should (< (time-to-seconds + (time-subtract (current-time) start-time)) + 0.1)) (should (equal "foo" company-prefix)) (should (equal '("abc" "abd") company-candidates))))) -(ert-deftest company-idle-begin-cancels-async-candidates-if-buffer-changed () +(ert-deftest company-idle-begin-with-async-aborts-on-user-input () (with-temp-buffer (company-mode) (let (company-frontends - (company-backends (list 'company-async-backend))) + (company-backends (list 'company-async-backend)) + noninteractive + (unread-command-events (list 'company-dummy-event))) (company-idle-begin (current-buffer) (selected-window) (buffer-chars-modified-tick) (point)) - (should (null company-candidates)) - (insert "a") - (sleep-for 0.1) - (should (null company-candidates)) - (should (null company-candidates-cache)) - (should (null company-backend))))) + (should (null company-candidates))))) (ert-deftest company-idle-begin-async-allows-immediate-callbacks () (with-temp-buffer @@ -100,7 +101,8 @@ (cons :async (lambda (cb) (funcall cb c))))) (`no-cache t))))) - (company-minimum-prefix-length 0)) + (company-minimum-prefix-length 0) + (unread-command-events (list 'company-dummy-event))) (company-idle-begin (current-buffer) (selected-window) (buffer-chars-modified-tick) (point)) (should (equal '("abc" "def") company-candidates))