(should (null company-candidates))
(should (null (company-explicit-action-p))))))
+(ert-deftest company-ignore-case-replaces-prefix ()
+ (with-temp-buffer
+ (company-mode)
+ (let (company-frontends
+ (company-backends
+ (list (lambda (command &optional arg)
+ (case command
+ (prefix (buffer-substring (point-min) (point)))
+ (candidates '("abcd" "abef"))
+ (ignore-case t))))))
+ (insert "A")
+ (let (this-command)
+ (company-complete))
+ (should (string= "ab" (buffer-string)))
+ (delete-char -2)
+ (insert "AB") ; hack, to keep it in one test
+ (company-complete-selection)
+ (should (string= "abcd" (buffer-string))))))
+
+(ert-deftest company-ignore-case-with-keep-prefix ()
+ (with-temp-buffer
+ (insert "AB")
+ (company-mode)
+ (let (company-frontends
+ (company-backends
+ (list (lambda (command &optional arg)
+ (case command
+ (prefix (buffer-substring (point-min) (point)))
+ (candidates '("abcd" "abef"))
+ (ignore-case 'keep-prefix))))))
+ (let (this-command)
+ (company-complete))
+ (company-complete-selection)
+ (should (string= "ABcd" (buffer-string))))))
+
+(ert-deftest company-non-prefix-completion ()
+ (with-temp-buffer
+ (insert "tc")
+ (company-mode)
+ (let (company-frontends
+ company-end-of-buffer-workaround
+ (company-backends
+ (list (lambda (command &optional arg)
+ (case command
+ (prefix (buffer-substring (point-min) (point)))
+ (candidates '("tea-cup" "teal-color")))))))
+ (let (this-command)
+ (company-complete))
+ (should (string= "tc" (buffer-string))))))
+
+(ert-deftest company-non-prefix-completion ()
+ (with-temp-buffer
+ (insert "tc")
+ (company-mode)
+ (let (company-frontends
+ company-end-of-buffer-workaround
+ (company-backends
+ (list (lambda (command &optional arg)
+ (case command
+ (prefix (buffer-substring (point-min) (point)))
+ (candidates '("tea-cup" "teal-color")))))))
+ (let (this-command)
+ (company-complete))
+ (should (string= "tc" (buffer-string)))
+ (company-complete-selection)
+ (should (string= "tea-cup" (buffer-string))))))
+
(ert-deftest company-pseudo-tooltip-does-not-get-displaced ()
:tags '(interactive)
(with-temp-buffer
(defsubst company-strip-prefix (str)
(substring str (length company-prefix)))
+(defun company--insert-candidate (candidate)
+ ;; XXX: Return value we check here is subject to change.
+ (set-text-properties 0 (length candidate) nil candidate)
+ (if (eq (company-call-backend 'ignore-case) 'keep-prefix)
+ (insert (company-strip-prefix candidate))
+ (delete-region (- (point) (length company-prefix)) (point))
+ (insert candidate)))
+
(defmacro company-with-candidate-inserted (candidate &rest body)
"Evaluate BODY with CANDIDATE temporarily inserted.
This is a tool for back-ends that need candidates inserted before they
`(let ((inhibit-modification-hooks t)
(inhibit-point-motion-hooks t)
(modified-p (buffer-modified-p)))
- (insert (company-strip-prefix ,candidate))
+ (company--insert-candidate ,candidate)
(unwind-protect
(progn ,@body)
(delete-region company-point (point)))))
(defun company-reformat (candidate)
;; company-ispell needs this, because the results are always lower-case
;; It's mory efficient to fix it only when they are displayed.
- (concat company-prefix (substring candidate (length company-prefix))))
+ ;; FIXME: Adopt the current text's capitalization instead?
+ (if (eq (company-call-backend 'ignore-case) 'keep-prefix)
+ (concat company-prefix (substring candidate (length company-prefix)))
+ candidate))
(defun company--should-complete ()
(and (not (or buffer-read-only overriding-terminal-local-map
;; Save in cache:
(push (cons company-prefix company-candidates) company-candidates-cache)
;; Calculate common.
- (let ((completion-ignore-case (company-call-backend 'ignore-case)))
- (setq company-common (company--safe-candidate
- (try-completion company-prefix company-candidates))))
- (when (eq company-common t)
- (setq company-candidates nil)))
+ (let ((completion-ignore-case (company-call-backend 'ignore-case))
+ ;; We want to support non-prefix completion, so filtering is the
+ ;; responsibility of each respective backend, not ours.
+ ;; On the other hand, we don't want to replace non-prefix input in
+ ;; `company-complete-common'.
+ (common (try-completion company-prefix company-candidates)))
+ (setq company-common (company--safe-candidate common))))
(defun company--safe-candidate (str)
(or (company-call-backend 'crop str)
(setq company-point (point)))
(defun company-finish (result)
- (insert (company-strip-prefix result))
+ (company--insert-candidate result)
(company-cancel result)
;; Don't start again, unless started manually.
(setq company-point (point)))
(if (and (not (cdr company-candidates))
(equal company-common (car company-candidates)))
(company-complete-selection)
- (insert (company-strip-prefix company-common)))))
+ (when company-common
+ (company--insert-candidate company-common)))))
(defun company-complete ()
"Complete the common part of all candidates or the current selection.
(defun company-pseudo-tooltip-unless-just-one-frontend (command)
"`company-pseudo-tooltip-frontend', but not shown for single candidates."
(unless (and (eq command 'post-command)
- (not (cdr company-candidates)))
+ (company--show-inline-p))
(company-pseudo-tooltip-frontend command)))
;;; overlay ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun company-preview-if-just-one-frontend (command)
"`company-preview-frontend', but only shown for single candidates."
- (unless (and (eq command 'post-command)
- (cdr company-candidates))
+ (when (or (not (eq command 'post-command))
+ (company--show-inline-p))
(company-preview-frontend command)))
+(defun company--show-inline-p ()
+ (and (not (cdr company-candidates))
+ company-common
+ (string-prefix-p company-prefix company-common
+ (company-call-backend 'ignore-case))))
+
;;; echo ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar company-echo-last-msg nil)