branch: externals/company
commit 703a9f892d25a4455abfcd0dfc7fe8b61c397a44
Author: Dmitry Gutov <dmi...@gutov.dev>
Commit: Dmitry Gutov <dmi...@gutov.dev>

    company-capf--candidates: Abort when the underlying capf changes
    
    That cancels completion, forcing the re-fetching of data (after the idle 
delay).
    
    Making sure that completions from one capf aren's displayed where another 
capf
    is in force (when that choice is done based on buffer contents). This is
    probably only relevant with "asynchronous" sources, where the frontends are
    repainted in the middle of fetching the updated completions.
---
 company-capf.el    |  9 ++++++---
 test/capf-tests.el | 29 +++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/company-capf.el b/company-capf.el
index 7ef9df0ba6..fc2cebcbd9 100644
--- a/company-capf.el
+++ b/company-capf.el
@@ -193,15 +193,17 @@ so we can't just use the preceding variable instead.")
       annotation)))
 
 (defun company-capf--candidates (input suffix)
-  (let* ((res (company--capf-data))
+  (let* ((current-capf (car company-capf--current-completion-data))
+         (res (company--capf-data))
          (table (nth 3 res))
          (pred (plist-get (nthcdr 4 res) :predicate))
          (meta (and res
                     (completion-metadata
                      (buffer-substring (nth 1 res) (nth 2 res))
                      table pred))))
-    (company-capf--save-current-data res meta)
-    (when res
+    (when (and res
+               (or (not current-capf)
+                   (equal current-capf (car res))))
       (let* ((interrupt (plist-get (nthcdr 4 res) :company-use-while-no-input))
              (all-result (company-capf--candidates-1 input suffix
                                                      table pred
@@ -212,6 +214,7 @@ so we can't just use the preceding variable instead.")
              (candidates (assoc-default :completions all-result)))
         (setq company-capf--sorted (functionp sortfun))
         (when candidates
+          (company-capf--save-current-data res meta)
           (setq company-capf--current-boundaries
                 (company--capf-boundaries-markers
                  (assoc-default :boundaries all-result)
diff --git a/test/capf-tests.el b/test/capf-tests.el
index 06437c92a6..0a646e6bbe 100644
--- a/test/capf-tests.el
+++ b/test/capf-tests.el
@@ -166,5 +166,34 @@
         (company-capf 'candidates "b" "")))
     '("be"))))
 
+(ert-deftest company-capf-changed-source ()
+  (company-capf-with-buffer
+   "abc|"
+   (let* ((cc1 '("abczzzzzz" "abcdef" "abc123"))
+          (comp1
+           (lambda ()
+             (let ((len (length (thing-at-point 'word))))
+               (when (< len 4)
+                 (list (- (point) len) (point) cc1)))))
+          (cc2 '("abcz" "abczdef" "abcz123"))
+          (comp2
+           (lambda ()
+             (list (pos-bol) (point)
+                   (mapcar
+                    (lambda (s)
+                      (concat (buffer-substring (pos-bol) (+ (pos-bol) 
(current-indentation)))
+                              s))
+                    cc2)))))
+
+     (setq-local completion-at-point-functions
+                 (list comp1 comp2))
+
+     (should (equal (company-capf 'prefix) '("abc" "" nil)))
+     (should (equal (company-capf 'candidates "abc" "") cc1))
+     (insert "z")
+     (should (null (company-capf 'candidates "abcz" "")))
+     (delete-char -2)
+     (should (equal (company-capf 'candidates "ab" "") cc1)))))
+
 (provide 'capf-tests)
 ;;; capf-tests.el ends here

Reply via email to