]> rtime.felk.cvut.cz Git - sojka/company-mode.git/commitdiff
company-sort-by-occurrence: allow customizing the weighing logic
authorDmitry Gutov <dgutov@yandex.ru>
Sun, 20 Jul 2014 02:49:03 +0000 (05:49 +0300)
committerDmitry Gutov <dgutov@yandex.ru>
Sun, 20 Jul 2014 05:52:04 +0000 (08:52 +0300)
Closes #152

NEWS.md
company.el

diff --git a/NEWS.md b/NEWS.md
index e547f796831b9053ebd12e6371430d9fcf6ed7df..d5184c3c31c0a37381669efcb8d7325ce0f21708 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -2,6 +2,8 @@
 
 ## Next
 
+* New user option `company-occurrence-weight-function`, allowing to tweak the
+  behavior of the transformer `company-sort-by-occurrence`.
 * Setting `company-idle-delay` to `t` is deprecated. Use the value 0 instead.
 
 ## 2014-07-01 (0.8.1)
index ceb815a541823377603f10c58cab3a3bc3e2120f..662a2200f578d4977ba31d9266277d7942a96866 100644 (file)
@@ -1191,11 +1191,31 @@ can retrieve meta-data for them."
       (setq c (funcall tr c)))
     c))
 
+(defcustom company-occurrence-weight-function
+  #'company-occurrence-prefer-closest-above
+  "Function to weigh matches in `company-sort-by-occurrence'.
+It's called with two arguments: the beginning and the end of the match."
+  :type '(choice
+          (const :tag "First above point, then below point"
+                 company-occurrence-prefer-closest-above)
+          (const :tag "Prefer closest in any direction"
+                 company-occurrence-prefer-any-closest)))
+
+(defun company-occurrence-prefer-closest-above (match-beg match-end)
+  "Give priority to the matches above point, then those below point."
+  (if (< match-beg (point))
+      (- (point) match-end)
+    (- match-beg (window-start))))
+
+(defun company-occurrence-prefer-any-closest (_match-beg match-end)
+  "Give priority to the matches closest to the point."
+  (abs (- (point) match-end)))
+
 (defun company-sort-by-occurrence (candidates)
   "Sort CANDIDATES according to their occurrences.
 Searches for each in the currently visible part of the current buffer and
-gives priority to the closest ones above point, then closest ones below
-point. The rest of the list is appended unchanged.
+prioritizes the matches according to `company-occurrence-weight-function'.
+The rest of the list is appended unchanged.
 Keywords and function definition names are ignored."
   (let* (occurs
          (noccurs
@@ -1203,8 +1223,8 @@ Keywords and function definition names are ignored."
            (lambda (candidate)
              (when (or
                     (save-excursion
-                      (progn (forward-char (- (length company-prefix)))
-                             (search-backward candidate (window-start) t)))
+                      (forward-char (- (length company-prefix)))
+                      (search-backward candidate (window-start) t))
                     (save-excursion
                       (search-forward candidate (window-end) t)))
                (let ((beg (match-beginning 0))
@@ -1218,10 +1238,10 @@ Keywords and function definition names are ignored."
                                              (company-call-backend 'prefix))))
                                 (and (stringp prefix)
                                      (= (length prefix) (- end beg))))))
-                   (push (cons candidate (if (< beg (point))
-                                             (- (point) end)
-                                           (- beg (window-start))))
-                         occurs)
+                   (push
+                    (cons candidate
+                          (funcall company-occurrence-weight-function beg end))
+                    occurs)
                    t))))
            candidates)))
     (nconc