;; Author: Nikolaj Schumacher
;; Maintainer: Dmitry Gutov <dgutov@yandex.ru>
;; URL: http://company-mode.github.io/
-;; Version: 0.9.0-cvs
+;; Version: 0.9.0
;; Keywords: abbrev, convenience, matching
;; Package-Requires: ((emacs "24.1") (cl-lib "0.5"))
cases (except for `duplicates' and `sorted'), the first non-nil value among
all the backends is returned.
-The group can also contain keywords. Currently, `:with' and `:sorted'
+The group can also contain keywords. Currently, `:with' and `:separate'
keywords are defined. If the group contains keyword `:with', the backends
listed after this keyword are ignored for the purpose of the `prefix'
-command. If the group contains keyword `:sorted', the final list of
-candidates is not sorted after concatenation.
+command. If the group contains keyword `:separate', the candidates that
+come from different backends are sorted separately in the combined list.
Asynchronous backends
=====================
(let ((backends (cl-loop for b in backends
when (not (and (symbolp b)
(eq 'failed (get b 'company-init))))
- collect b)))
+ collect b))
+ (separate (memq :separate backends)))
(when (eq command 'prefix)
(setq backends (butlast backends (length (member :with backends)))))
- (unless (memq command '(sorted))
- (setq backends (cl-delete-if #'keywordp backends)))
+ (setq backends (cl-delete-if #'keywordp backends))
(pcase command
(`candidates
- (company--multi-backend-adapter-candidates backends (car args)))
- (`sorted (memq :sorted backends))
- (`duplicates t)
+ (company--multi-backend-adapter-candidates backends (car args) separate))
+ (`sorted separate)
+ (`duplicates (not separate))
((or `prefix `ignore-case `no-cache `require-match)
(let (value)
(cl-dolist (backend backends)
(car backends))))
(apply backend command args))))))))
-(defun company--multi-backend-adapter-candidates (backends prefix)
- (let ((pairs (cl-loop for backend in (cdr backends)
+(defun company--multi-backend-adapter-candidates (backends prefix separate)
+ (let ((pairs (cl-loop for backend in backends
when (equal (company--prefix-str
(funcall backend 'prefix))
prefix)
collect (cons (funcall backend 'candidates prefix)
- (let ((b backend))
- (lambda (candidates)
- (mapcar
- (lambda (str)
- (propertize str 'company-backend b))
- candidates)))))))
- (when (equal (company--prefix-str (funcall (car backends) 'prefix)) prefix)
- ;; Small perf optimization: don't tag the candidates received
- ;; from the first backend in the group.
- (push (cons (funcall (car backends) 'candidates prefix)
- 'identity)
- pairs))
+ (company--multi-candidates-mapper
+ backend
+ separate
+ ;; Small perf optimization: don't tag the
+ ;; candidates received from the first
+ ;; backend in the group.
+ (not (eq backend (car backends))))))))
(company--merge-async pairs (lambda (values) (apply #'append values)))))
+(defun company--multi-candidates-mapper (backend separate tag)
+ (lambda (candidates)
+ (when separate
+ (let ((company-backend backend))
+ (setq candidates
+ (company--preprocess-candidates candidates))))
+ (when tag
+ (setq candidates
+ (mapcar
+ (lambda (str)
+ (propertize str 'company-backend backend))
+ candidates)))
+ candidates))
+
(defun company--merge-async (pairs merger)
(let ((async (cl-loop for pair in pairs
thereis
(or (not b1) (not (memq b1 low-priority)))))))))))
(defun company-sort-prefer-same-case-prefix (candidates)
- "Prefer CANDIDATES with the same case sensitive prefix.
+ "Prefer CANDIDATES with the exact same prefix.
If a backend returns case insensitive matches, candidates with the an exact
-prefix match will be prioritized even if this changes the lexical order."
+prefix match (same case) will be prioritized."
(cl-loop for candidate in candidates
if (string-prefix-p company-prefix candidate)
collect candidate into same-case