]> code.delx.au - gnu-emacs-elpa/commitdiff
Remove completions without annotations when considering duplicates
authorDmitry Gutov <dgutov@yandex.ru>
Sun, 20 Dec 2015 22:16:54 +0000 (00:16 +0200)
committerDmitry Gutov <dgutov@yandex.ru>
Sun, 20 Dec 2015 22:16:54 +0000 (00:16 +0200)
Closes #432.

NEWS.md
company.el
test/core-tests.el

diff --git a/NEWS.md b/NEWS.md
index b3ab1236819f2023122d7c96730a996d2b68100b..a32baded2b8c3a0ea6cf5b860dc0c1d9fb1d3707 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -2,6 +2,9 @@
 
 ## Next
 
+* When duplicates are removed, completions without annotations are also removed
+  in favor of completions with equal names that have annotations (experimental
+  change) ([#432](https://github.com/company-mode/company-mode/issues/432)).
 * New user option `company-etags-everywhere`.
 * `company-yasnippet` supports `yas-key-syntaxes` better. But we use them in the
   reverse order, preferring the longest key prefix that matches anything. And we
index 48f41d49e10b7c08e19b771873ecda6f4a3935d7..8d416de92381b1720f73dee8595648e7c37d71e4 100644 (file)
@@ -1199,7 +1199,7 @@ can retrieve meta-data for them."
   (unless (company-call-backend 'sorted)
     (setq candidates (sort candidates 'string<)))
   (when (company-call-backend 'duplicates)
-    (company--strip-duplicates candidates))
+    (setq candidates (company--strip-duplicates candidates)))
   candidates)
 
 (defun company--postprocess-candidates (candidates)
@@ -1210,27 +1210,37 @@ can retrieve meta-data for them."
   (company--transform-candidates candidates))
 
 (defun company--strip-duplicates (candidates)
-  (let ((c2 candidates)
-        (annos 'unk))
-    (while c2
-      (setcdr c2
-              (let ((str (pop c2)))
-                (while (let ((str2 (car c2)))
-                         (if (not (equal str str2))
-                             (progn
-                               (setq annos 'unk)
-                               nil)
-                           (when (eq annos 'unk)
-                             (setq annos (list (company-call-backend
-                                                'annotation str))))
-                           (let ((anno2 (company-call-backend
-                                         'annotation str2)))
-                             (if (member anno2 annos)
-                                 t
-                               (push anno2 annos)
-                               nil))))
-                  (pop c2))
-                c2)))))
+  (let* ((annos 'unk)
+         (str (car candidates))
+         (ref (cdr candidates))
+         res str2 anno2)
+    (while ref
+      (setq str2 (pop ref))
+      (if (not (equal str str2))
+          (progn
+            (push str res)
+            (setq str str2)
+            (setq annos 'unk))
+        (setq anno2 (company-call-backend
+                     'annotation str2))
+        (cond
+         ((null anno2))             ; Skip it.
+         ((when (eq annos 'unk)
+            (let ((ann1 (company-call-backend 'annotation str)))
+              (if (null ann1)
+                  ;; No annotation on the earlier element, drop it.
+                  t
+                (setq annos (list ann1))
+                nil)))
+          (setq annos (list anno2))
+          (setq str str2))
+         ((member anno2 annos))     ; Also skip.
+         (t
+          (push anno2 annos)
+          (push str res)            ; Maintain ordering.
+          (setq str str2)))))
+    (push str res)
+    (nreverse res)))
 
 (defun company--transform-candidates (candidates)
   (let ((c candidates))
index 13e547e3d36b15ac566ad3dcc9119ea675a7c580..dcadfd3ab70f6f74d5da8fe592948748a251ebe4 100644 (file)
                 ("a" . "b")
                 ("a" . "c")
                 ("a" . "b")
-                ("b" . "c")
                 ("b" . nil)
-                ("a" . "b")))
+                ("b" . "c")
+                ("a" . "b")
+                ("c" . nil)
+                ("c" . nil)))
          (fn (lambda (kvs)
                (mapcar (lambda (kv) (propertize (car kv) 'ann (cdr kv)))
                        kvs)))
               (`duplicates t)
               (`annotation (get-text-property 0 'ann arg)))))
          (reference '(("a" . "b")
-                      ("a" . nil)
                       ("a" . "c")
                       ("b" . "c")
-                      ("b" . nil)
-                      ("a" . "b"))))
+                      ("a" . "b")
+                      ("c" . nil))))
     (let ((ct-sorted t))
       (should (ct-equal-including-properties
                (company--preprocess-candidates (funcall fn kvs))
                (funcall fn reference))))
     (should (ct-equal-including-properties
              (company--preprocess-candidates (funcall fn kvs))
-             (funcall fn (butlast reference))))))
+             (funcall fn (append (butlast reference 2)
+                                 (last reference)))))))
 
 ;;; Row and column