]> code.delx.au - gnu-emacs-elpa/commitdiff
Merge commit 'eb0d8d9e687e1364098f9abc6f9281fcbc0d3abd' from company
authorDmitry Gutov <dgutov@yandex.ru>
Tue, 13 Jan 2015 02:44:02 +0000 (05:44 +0300)
committerDmitry Gutov <dgutov@yandex.ru>
Tue, 13 Jan 2015 02:44:02 +0000 (05:44 +0300)
21 files changed:
1  2 
packages/company/.elpaignore
packages/company/Makefile
packages/company/NEWS.md
packages/company/company-bbdb.el
packages/company/company-capf.el
packages/company/company-clang.el
packages/company/company-cmake.el
packages/company/company-etags.el
packages/company/company-files.el
packages/company/company-semantic.el
packages/company/company-tests.el
packages/company/company.el
packages/company/test/all.el
packages/company/test/async-tests.el
packages/company/test/clang-tests.el
packages/company/test/core-tests.el
packages/company/test/elisp-tests.el
packages/company/test/frontends-tests.el
packages/company/test/keywords-tests.el
packages/company/test/template-tests.el
packages/company/test/transformers-tests.el

index 0000000000000000000000000000000000000000,9f31d8a765cf08a222f29fd6ba49568096795be8..9f31d8a765cf08a222f29fd6ba49568096795be8
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,5 +1,5 @@@
+ .travis.yml
+ .gitignore
+ Makefile
+ test/
+ company-tests.el
index c52be4be3873cffc3d0bd7d024d3cd3bb8d84baf,fada44430ca0c322e89974b367aeec13ba15eec5..fada44430ca0c322e89974b367aeec13ba15eec5
@@@ -20,11 -20,11 +20,11 @@@ clean
        @rm -rf company-*/ company-*.tar company-*.tar.bz2 *.elc ert.el
  
  test:
-       ${EMACS} -Q -nw -L . -l company-tests.el -l company-elisp-tests.el \
+       ${EMACS} -Q -nw -L . -l test/all.el \
        --eval "(let (pop-up-windows) (ert t))"
  
  test-batch:
-       ${EMACS} -Q --batch -L . -l company-tests.el -l company-elisp-tests.el \
+       ${EMACS} -Q --batch -L . -l test/all.el \
        --eval "(ert-run-tests-batch-and-exit '(not (tag interactive)))"
  
  compile:
diff --combined packages/company/NEWS.md
index 56bebb657a7aecca393e3dfa9b3935c24faf76eb,553155e35cb127690ec1d01ceb9878c02fcb0530..553155e35cb127690ec1d01ceb9878c02fcb0530
@@@ -1,5 -1,22 +1,22 @@@
  # History of user-visible changes
  
+ ## Next
+ * Pressing `M-n` or `M-p` doesn't quit the search mode.
+ * New command `company-complete-common-or-cycle`. No default binding.
+ * `company-search-toggle-filtering` replaced `company-search-kill-others`.
+ * Quitting the search mode resets the filtering.
+ * Pressing `backspace` in the search mode deletes the character at the end of
+   the search string.
+ * `company-semantic` displays function arguments as annotations.
+ * New user option, `company-bbdb-modes`.
+ * `company-show-numbers` and `company-complete-number` now use visual numbering
+   of the candidates, taking into account only the ones currently displayed.
+ * `company-complete-number` can be bound to keypad numbers directly, with or
+   without modifiers.
+ * `company-cmake` expands `<LANG>` and `<CONFIG>` placeholders inside variable
+   names.
  ## 2014-10-15 (0.8.6)
  
  * `company-clang` and `company-template-c-like-templatify` support templated
@@@ -14,7 -31,7 +31,7 @@@
  * `company-ropemacs` is only used when `ropemacs-mode` is on.
  * `company-gtags` is enabled in all `prog-mode` derivatives by default.
  * `company-end-of-buffer-workaround` is not used anymore.
- * `company-begin-commands` includes several `cc-mode` commands.
+ * `company-begin-commands` includes some of `cc-mode` commands.
  
  ## 2014-08-27 (0.8.3)
  
index 22741a2051664a3c01c48b2238de652aa2c802fe,58be84c77ac3aee1a4b577f0f87a13d6c0598a70..58be84c77ac3aee1a4b577f0f87a13d6c0598a70
  (declare-function bbdb-dwim-mail "bbdb-com")
  (declare-function bbdb-search "bbdb-com")
  
+ (defgroup company-bbdb nil
+   "Completion back-end for BBDB."
+   :group 'company)
+ (defcustom company-bbdb-modes '(message-mode)
+   "Major modes in which `company-bbdb' may complete."
+   :type '(repeat (symbol :tag "Major mode"))
+   :package-version '(company . "0.8.8"))
  (defun company-bbdb--candidates (arg)
    (cl-mapcan (lambda (record)
                 (mapcar (lambda (mail) (bbdb-dwim-mail record mail))
  
  ;;;###autoload
  (defun company-bbdb (command &optional arg &rest ignore)
-   "`company-mode' completion back-end for `bbdb'."
+   "`company-mode' completion back-end for BBDB."
    (interactive (list 'interactive))
    (cl-case command
      (interactive (company-begin-backend 'company-bbdb))
-     (prefix (and (eq major-mode 'message-mode)
+     (prefix (and (memq major-mode company-bbdb-modes)
                   (featurep 'bbdb-com)
-                  (looking-back "^\\(To\\|Cc\\|Bcc\\):.*"
+                  (looking-back "^\\(To\\|Cc\\|Bcc\\): *\\(.*\\)"
                                 (line-beginning-position))
-                  (company-grab-symbol)))
+                  (match-string-no-properties 2)))
      (candidates (company-bbdb--candidates arg))
      (sorted t)
      (no-cache t)))
index b630025690f498063f554fb75463d2c07fa0f678,4962a26c0d8a4e1ac6512ba0c8f3247b48f7b54c..4962a26c0d8a4e1ac6512ba0c8f3247b48f7b54c
      (`init nil)      ;Don't bother: plenty of other ways to initialize the code.
      (`post-completion
       (let* ((res (company--capf-data))
-             (exit-function (plist-get (nthcdr 4 res) :exit-function)))
+             (exit-function (plist-get (nthcdr 4 res) :exit-function))
+             (table (nth 3 res))
+             (pred (plist-get (nthcdr 4 res) :predicate)))
         (if exit-function
-            (funcall exit-function arg 'finished))))
+            ;; Follow the example of `completion--done'.
+            (funcall exit-function arg
+                     (if (eq (try-completion arg table pred) t)
+                         'finished 'sole)))))
      ))
  
  (provide 'company-capf)
index 90757a84b957f52a05111d8ddf4333d67f1b7220,8114b3b5bb0a145239a039dc8fa5d8233a785d08..8114b3b5bb0a145239a039dc8fa5d8233a785d08
@@@ -110,7 -110,7 +110,7 @@@ or automatically through a custom `comp
  ;; TODO: Handle Pattern (syntactic hints would be neat).
  ;; Do we ever see OVERLOAD (or OVERRIDE)?
  (defconst company-clang--completion-pattern
-   "^COMPLETION: \\_<\\(%s[a-zA-Z0-9_:<>]*\\)\\(?: : \\(.*\\)$\\)?$")
+   "^COMPLETION: \\_<\\(%s[a-zA-Z0-9_:]*\\)\\(?: : \\(.*\\)$\\)?$")
  
  (defconst company-clang--error-buffer-name "*clang-error*")
  
       ((string-match "[^:]:[^:]" meta)
        (substring meta (1+ (match-beginning 0))))
       ((string-match "\\((.*)[ a-z]*\\'\\)" meta)
-       (match-string 1 meta)))))
+       (let ((paren (match-beginning 1)))
+         (if (not (eq (aref meta (1- paren)) ?>))
+             (match-string 1 meta)
+           (with-temp-buffer
+             (insert meta)
+             (goto-char paren)
+             (substring meta (1- (search-backward "<"))))))))))
  
  (defun company-clang--strip-formatting (text)
    (replace-regexp-in-string
  
  (defun company-clang--start-process (prefix callback &rest args)
    (let ((objc (derived-mode-p 'objc-mode))
-         (buf (get-buffer-create "*clang-output*")))
+         (buf (get-buffer-create "*clang-output*"))
+         (process-adaptive-read-buffering nil))
      (with-current-buffer buf (erase-buffer))
      (if (get-buffer-process buf)
          (funcall callback nil)
index a466f60b7a75b5abdad3ec06a4fd3e367ca9a46f,e2962f5a1bf996640e2d83d850e95fb395e0c162..e2962f5a1bf996640e2d83d850e95fb395e0c162
@@@ -1,9 -1,9 +1,9 @@@
  ;;; company-cmake.el --- company-mode completion back-end for CMake
  
- ;; Copyright (C) 2013  Free Software Foundation, Inc.
+ ;; Copyright (C) 2013-2014  Free Software Foundation, Inc.
  
  ;; Author: Chen Bin <chenbin DOT sh AT gmail>
- ;; Version: 0.1
+ ;; Version: 0.2
  
  ;; This program is free software: you can redistribute it and/or modify
  ;; it under the terms of the GNU General Public License as published by
  They affect which types of symbols we get completion candidates for.")
  
  (defvar company-cmake--completion-pattern
-   "^\\(%s[a-zA-Z0-9_]%s\\)$"
+   "^\\(%s[a-zA-Z0-9_<>]%s\\)$"
    "Regexp to match the candidates.")
  
  (defvar company-cmake-modes '(cmake-mode)
    "Major modes in which cmake may complete.")
  
+ (defvar company-cmake--candidates-cache nil
+   "Cache for the raw candidates.")
  (defvar company-cmake--meta-command-cache nil
    "Cache for command arguments to retrieve descriptions for the candidates.")
  
- (defun company-cmake--parse-output (prefix cmd)
-   "Analyze the temp buffer and collect lines."
-   (goto-char (point-min))
-   (let ((pattern (format company-cmake--completion-pattern
+ (defun company-cmake--replace-tags (rlt)
+   (setq rlt (replace-regexp-in-string
+              "\\(.*?\\(IS_GNU\\)?\\)<LANG>\\(.*\\)"
+              (lambda (_match)
+                (mapconcat 'identity
+                           (if (match-beginning 2)
+                               '("\\1CXX\\3" "\\1C\\3" "\\1G77\\3")
+                             '("\\1CXX\\3" "\\1C\\3" "\\1Fortran\\3"))
+                           "\n"))
+              rlt t))
+   (setq rlt (replace-regexp-in-string
+              "\\(.*\\)<CONFIG>\\(.*\\)"
+              (mapconcat 'identity '("\\1DEBUG\\2" "\\1RELEASE\\2"
+                                     "\\1RELWITHDEBINFO\\2" "\\1MINSIZEREL\\2")
+                         "\n")
+              rlt))
+   rlt)
+ (defun company-cmake--fill-candidates-cache (arg)
+   "Fill candidates cache if needed."
+   (let (rlt)
+     (unless company-cmake--candidates-cache
+       (setq company-cmake--candidates-cache (make-hash-table :test 'equal)))
+     ;; If hash is empty, fill it.
+     (unless (gethash arg company-cmake--candidates-cache)
+       (with-temp-buffer
+         (let ((res (call-process company-cmake-executable nil t nil arg)))
+           (unless (zerop res)
+             (message "cmake executable exited with error=%d" res)))
+         (setq rlt (buffer-string)))
+       (setq rlt (company-cmake--replace-tags rlt))
+       (puthash arg rlt company-cmake--candidates-cache))
+     ))
+ (defun company-cmake--parse (prefix content cmd)
+   (let ((start 0)
+         (pattern (format company-cmake--completion-pattern
                           (regexp-quote prefix)
                           (if (zerop (length prefix)) "+" "*")))
-         (case-fold-search nil)
-         lines match)
-     (while (re-search-forward pattern nil t)
-       (setq match (match-string-no-properties 1))
-       (puthash match cmd company-cmake--meta-command-cache)
-       (push match lines))
-     lines))
+         (lines (split-string content "\n"))
+         match
+         rlt)
+     (dolist (line lines)
+       (when (string-match pattern line)
+         (let ((match (match-string 1 line)))
+           (when match
+             (puthash match cmd company-cmake--meta-command-cache)
+             (push match rlt)))))
+     rlt))
  
  (defun company-cmake--candidates (prefix)
-   (let ((res 0)
-         results
-         cmd)
-     (setq company-cmake--meta-command-cache (make-hash-table :test 'equal))
+   (let (results
+         cmd-opts
+         str)
+     (unless company-cmake--meta-command-cache
+       (setq company-cmake--meta-command-cache (make-hash-table :test 'equal)))
      (dolist (arg company-cmake-executable-arguments)
-       (with-temp-buffer
-         (setq res (call-process company-cmake-executable nil t nil arg))
-         (unless (eq 0 res)
-           (message "cmake executable exited with error=%d" res))
-         (setq cmd (replace-regexp-in-string "-list$" "" arg) )
-         (setq results (nconc results (company-cmake--parse-output prefix cmd)))))
+       (company-cmake--fill-candidates-cache arg)
+       (setq cmd-opts (replace-regexp-in-string "-list$" "" arg) )
+       (setq str (gethash arg company-cmake--candidates-cache))
+       (when str
+         (setq results (nconc results
+                              (company-cmake--parse prefix str cmd-opts)))))
      results))
  
- (defun company-cmake--meta (prefix)
-   (let ((cmd-opts (gethash prefix company-cmake--meta-command-cache))
+ (defun company-cmake--unexpand-candidate (candidate)
+   (cond
+    ((string-match "^CMAKE_\\(C\\|CXX\\|Fortran\\)\\(_.*\\)$" candidate)
+     (setq candidate (concat "CMAKE_<LANG>" (match-string 2 candidate))))
+    ;; C flags
+    ((string-match "^\\(.*_\\)IS_GNU\\(C\\|CXX\\|G77\\)$" candidate)
+     (setq candidate (concat (match-string 1 candidate) "IS_GNU<LANG>")))
+    ;; C flags
+    ((string-match "^\\(.*_\\)OVERRIDE_\\(C\\|CXX\\|Fortran\\)$" candidate)
+     (setq candidate (concat (match-string 1 candidate) "OVERRIDE_<LANG>")))
+    ((string-match "^\\(.*\\)\\(_DEBUG\\|_RELEASE\\|_RELWITHDEBINFO\\|_MINSIZEREL\\)\\(.*\\)$" candidate)
+     (setq candidate (concat (match-string 1 candidate)
+                             "_<CONFIG>"
+                             (match-string 3 candidate)))))
+   candidate)
+ (defun company-cmake--meta (candidate)
+   (let ((cmd-opts (gethash candidate company-cmake--meta-command-cache))
          result)
+     (setq candidate (company-cmake--unexpand-candidate candidate))
+     ;; Don't cache the documentation of every candidate (command)
+     ;; Cache in this case will cost too much memory.
      (with-temp-buffer
-       (call-process company-cmake-executable nil t nil cmd-opts prefix)
+       (call-process company-cmake-executable nil t nil cmd-opts candidate)
        ;; Go to the third line, trim it and return the result.
        ;; Tested with cmake 2.8.9.
        (goto-char (point-min))
        (setq result (replace-regexp-in-string "^[ \t\n\r]+" "" result))
        result)))
  
- (defun company-cmake--doc-buffer (prefix)
-   (let ((cmd-opts (gethash prefix company-cmake--meta-command-cache)))
+ (defun company-cmake--doc-buffer (candidate)
+   (let ((cmd-opts (gethash candidate company-cmake--meta-command-cache)))
+     (setq candidate (company-cmake--unexpand-candidate candidate))
      (with-temp-buffer
-       (call-process company-cmake-executable nil t nil cmd-opts prefix)
+       (call-process company-cmake-executable nil t nil cmd-opts candidate)
        ;; Go to the third line, trim it and return the doc buffer.
        ;; Tested with cmake 2.8.9.
        (goto-char (point-min))
index c7ba60870c48761034c1b40ff6f76f257cff9461,1c01c91673195c05d3662370b3854722c9cfc5e3..1c01c91673195c05d3662370b3854722c9cfc5e3
@@@ -54,7 -54,7 +54,7 @@@ buffer automatically.
    (let ((file (locate-dominating-file (or buffer-file-name
                                            default-directory)
                                        "TAGS")))
-     (when file
+     (when (and file (file-regular-p file))
        (list (expand-file-name file)))))
  
  (defun company-etags-buffer-table ()
index baaeaca4bd853650f670f1691d4f7e8b5a20dd79,7cfc500751a1c22a4eacc74afa0a29753b893b73..7cfc500751a1c22a4eacc74afa0a29753b893b73
@@@ -64,6 -64,7 +64,7 @@@
                      (expand-file-name dir)
                      (nth 5 (file-attributes dir))))
           (file (file-name-nondirectory prefix))
+          (completion-ignore-case read-file-name-completion-ignore-case)
           candidates directories)
      (unless (company-file--keys-match-p key (car company-files--completion-cache))
        (dolist (file (company-files--directory-files dir file))
index 6c020a30f70ba4eaed2730b0d1c1ea4549ca716e,a1c7d16c90af0abdf2888a36b9284ba16a468a6e..a1c7d16c90af0abdf2888a36b9284ba16a468a6e
        (push tag company-semantic--current-tags)))
    (delete "" (mapcar 'semantic-tag-name company-semantic--current-tags)))
  
+ (defun company-semantic-annotation (argument tags)
+   (let* ((tag (assoc argument tags))
+          (kind (when tag (elt tag 1))))
+     (cl-case kind
+       (function (let* ((prototype (semantic-format-tag-prototype tag nil nil))
+                        (par-pos (string-match "(" prototype)))
+                   (when par-pos (substring prototype par-pos)))))))
  (defun company-semantic--pre-prefix-length (prefix-length)
    "Sum up the length of all chained symbols before POS.
  Symbols are chained by \".\" or \"->\"."
                    (company-semantic-completions arg)))
      (meta (funcall company-semantic-metadata-function
                     (assoc arg company-semantic--current-tags)))
+     (annotation (company-semantic-annotation arg
+                                              company-semantic--current-tags))
      (doc-buffer (company-semantic-doc-buffer
                   (assoc arg company-semantic--current-tags)))
      ;; Because "" is an empty context and doesn't return local variables.
index 0663c71f9fef75159454d951d1565ae1cda9e5cc,f0d669d11e65dbbf4c95fe9f926495fef79243e5..f0d669d11e65dbbf4c95fe9f926495fef79243e5
@@@ -1,8 -1,8 +1,8 @@@
- ;;; company-tests.el --- company-mode tests  -*- lexical-binding: t -*-
+ ;;; company-tests.el --- company-mode test helpers  -*- lexical-binding: t -*-
  
  ;; Copyright (C) 2011, 2013-2014  Free Software Foundation, Inc.
  
- ;; Author: Nikolaj Schumacher
+ ;; Author: Dmitry Gutov
  
  ;; This file is part of GNU Emacs.
  
  ;; You should have received a copy of the GNU General Public License
  ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
  
- ;;; Commentary:
- ;;
- ;;; Code:
- (require 'ert)
  (require 'company)
- (require 'company-keywords)
- (require 'company-clang)
  
  (defun company--column (&optional pos)
    (car (company--col-row pos)))
  
- ;;; Core
- (ert-deftest company-sorted-keywords ()
-   "Test that keywords in `company-keywords-alist' are in alphabetical order."
-   (dolist (pair company-keywords-alist)
-     (when (consp (cdr pair))
-       (let ((prev (cadr pair)))
-         (dolist (next (cddr pair))
-           (should (not (equal prev next)))
-           (should (string< prev next))
-           (setq prev next))))))
- (ert-deftest company-good-prefix ()
-   (let ((company-minimum-prefix-length 5)
-         company-abort-manual-when-too-short
-         company--manual-action            ;idle begin
-         (company-selection-changed t))    ;has no effect
-     (should (eq t (company--good-prefix-p "!@#$%")))
-     (should (eq nil (company--good-prefix-p "abcd")))
-     (should (eq nil (company--good-prefix-p 'stop)))
-     (should (eq t (company--good-prefix-p '("foo" . 5))))
-     (should (eq nil (company--good-prefix-p '("foo" . 4))))
-     (should (eq t (company--good-prefix-p '("foo" . t))))))
- (ert-deftest company--manual-prefix-set-and-unset ()
-   (with-temp-buffer
-     (insert "ab")
-     (company-mode)
-     (let (company-frontends
-           (company-backends
-            (list (lambda (command &optional arg)
-                    (cl-case command
-                      (prefix (buffer-substring (point-min) (point)))
-                      (candidates '("abc" "abd")))))))
-       (company-manual-begin)
-       (should (equal "ab" company--manual-prefix))
-       (company-abort)
-       (should (null company--manual-prefix)))))
- (ert-deftest company-abort-manual-when-too-short ()
-   (let ((company-minimum-prefix-length 5)
-         (company-abort-manual-when-too-short t)
-         (company-selection-changed t))    ;has not effect
-     (let ((company--manual-action nil))   ;idle begin
-       (should (eq t (company--good-prefix-p "!@#$%")))
-       (should (eq t (company--good-prefix-p '("foo" . 5))))
-       (should (eq t (company--good-prefix-p '("foo" . t)))))
-     (let ((company--manual-action t)
-           (company--manual-prefix "abc")) ;manual begin from this prefix
-       (should (eq t (company--good-prefix-p "!@#$")))
-       (should (eq nil (company--good-prefix-p "ab")))
-       (should (eq nil (company--good-prefix-p 'stop)))
-       (should (eq t (company--good-prefix-p '("foo" . 4))))
-       (should (eq t (company--good-prefix-p "abcd")))
-       (should (eq t (company--good-prefix-p "abc")))
-       (should (eq t (company--good-prefix-p '("bar" . t)))))))
- (ert-deftest company-multi-backend-with-lambdas ()
-   (let ((company-backend
-          (list (lambda (command &optional arg &rest ignore)
-                  (cl-case command
-                    (prefix "z")
-                    (candidates '("a" "b"))))
-                (lambda (command &optional arg &rest ignore)
-                  (cl-case command
-                    (prefix "z")
-                    (candidates '("c" "d")))))))
-     (should (equal (company-call-backend 'candidates "z") '("a" "b" "c" "d")))))
- (ert-deftest company-multi-backend-filters-backends-by-prefix ()
-   (let ((company-backend
-          (list (lambda (command &optional arg &rest ignore)
-                  (cl-case command
-                    (prefix (cons "z" t))
-                    (candidates '("a" "b"))))
-                (lambda (command &optional arg &rest ignore)
-                  (cl-case command
-                    (prefix "t")
-                    (candidates '("c" "d"))))
-                (lambda (command &optional arg &rest ignore)
-                  (cl-case command
-                    (prefix "z")
-                    (candidates '("e" "f")))))))
-     (should (equal (company-call-backend 'candidates "z") '("a" "b" "e" "f")))))
- (ert-deftest company-multi-backend-remembers-candidate-backend ()
-   (let ((company-backend
-          (list (lambda (command &optional arg)
-                  (cl-case command
-                    (ignore-case nil)
-                    (annotation "1")
-                    (candidates '("a" "c"))
-                    (post-completion "13")))
-                (lambda (command &optional arg)
-                  (cl-case command
-                    (ignore-case t)
-                    (annotation "2")
-                    (candidates '("b" "d"))
-                    (post-completion "42")))
-                (lambda (command &optional arg)
-                  (cl-case command
-                    (annotation "3")
-                    (candidates '("e"))
-                    (post-completion "74"))))))
-     (let ((candidates (company-calculate-candidates nil)))
-       (should (equal candidates '("a" "b" "c" "d" "e")))
-       (should (equal t (company-call-backend 'ignore-case)))
-       (should (equal "1" (company-call-backend 'annotation (nth 0 candidates))))
-       (should (equal "2" (company-call-backend 'annotation (nth 1 candidates))))
-       (should (equal "13" (company-call-backend 'post-completion (nth 2 candidates))))
-       (should (equal "42" (company-call-backend 'post-completion (nth 3 candidates))))
-       (should (equal "3" (company-call-backend 'annotation (nth 4 candidates))))
-       (should (equal "74" (company-call-backend 'post-completion (nth 4 candidates)))))))
- (ert-deftest company-multi-backend-handles-keyword-with ()
-   (let ((primo (lambda (command &optional arg)
-                  (cl-case command
-                    (prefix "a")
-                    (candidates '("abb" "abc" "abd")))))
-         (secundo (lambda (command &optional arg)
-                    (cl-case command
-                      (prefix "a")
-                      (candidates '("acc" "acd"))))))
-     (let ((company-backend (list 'ignore 'ignore :with secundo)))
-       (should (null (company-call-backend 'prefix))))
-     (let ((company-backend (list 'ignore primo :with secundo)))
-       (should (equal "a" (company-call-backend 'prefix)))
-       (should (equal '("abb" "abc" "abd" "acc" "acd")
-                      (company-call-backend 'candidates "a"))))))
- (ert-deftest company-begin-backend-failure-doesnt-break-company-backends ()
-   (with-temp-buffer
-     (insert "a")
-     (company-mode)
-     (should-error
-      (company-begin-backend (lambda (command &rest ignore))))
-     (let (company-frontends
-           (company-backends
-            (list (lambda (command &optional arg)
-                    (cl-case command
-                      (prefix "a")
-                      (candidates '("a" "ab" "ac")))))))
-       (let (this-command)
-         (company-call 'complete))
-       (should (eq 3 company-candidates-length)))))
- (ert-deftest company-require-match-explicit ()
-   (with-temp-buffer
-     (insert "ab")
-     (company-mode)
-     (let (company-frontends
-           (company-require-match 'company-explicit-action-p)
-           (company-backends
-            (list (lambda (command &optional arg)
-                    (cl-case command
-                      (prefix (buffer-substring (point-min) (point)))
-                      (candidates '("abc" "abd")))))))
-       (let (this-command)
-         (company-complete))
-       (let ((last-command-event ?e))
-         (company-call 'self-insert-command 1))
-       (should (eq 2 company-candidates-length))
-       (should (eq 3 (point))))))
- (ert-deftest company-dont-require-match-when-idle ()
-   (with-temp-buffer
-     (insert "ab")
-     (company-mode)
-     (let (company-frontends
-           (company-minimum-prefix-length 2)
-           (company-require-match 'company-explicit-action-p)
-           (company-backends
-            (list (lambda (command &optional arg)
-                    (cl-case command
-                      (prefix (buffer-substring (point-min) (point)))
-                      (candidates '("abc" "abd")))))))
-       (company-idle-begin (current-buffer) (selected-window)
-                           (buffer-chars-modified-tick) (point))
-       (should (eq 2 company-candidates-length))
-       (let ((last-command-event ?e))
-         (company-call 'self-insert-command 1))
-       (should (eq nil company-candidates-length))
-       (should (eq 4 (point))))))
- (ert-deftest company-dont-require-match-if-old-prefix-ended-and-was-a-match ()
-   (with-temp-buffer
-     (insert "ab")
-     (company-mode)
-     (let (company-frontends
-           (company-require-match 'company-explicit-action-p)
-           (company-backends
-            (list (lambda (command &optional arg)
-                    (cl-case command
-                      (prefix (company-grab-word))
-                      (candidates '("abc" "ab" "abd"))
-                      (sorted t))))))
-       (let (this-command)
-         (company-complete))
-       (let ((last-command-event ?e))
-         (company-call 'self-insert-command 1))
-       (should (eq 3 company-candidates-length))
-       (should (eq 3 (point)))
-       (let ((last-command-event ? ))
-         (company-call 'self-insert-command 1))
-       (should (null company-candidates-length))
-       (should (eq 4 (point))))))
- (ert-deftest company-should-complete-whitelist ()
-   (with-temp-buffer
-     (insert "ab")
-     (company-mode)
-     (let (company-frontends
-           company-begin-commands
-           (company-backends
-            (list (lambda (command &optional arg)
-                    (cl-case command
-                      (prefix (buffer-substring (point-min) (point)))
-                      (candidates '("abc" "abd")))))))
-       (let ((company-continue-commands nil))
-         (let (this-command)
-           (company-complete))
-         (company-call 'backward-delete-char 1)
-         (should (null company-candidates-length)))
-       (let ((company-continue-commands '(backward-delete-char)))
-         (let (this-command)
-           (company-complete))
-         (company-call 'backward-delete-char 1)
-         (should (eq 2 company-candidates-length))))))
- (ert-deftest company-should-complete-blacklist ()
-   (with-temp-buffer
-     (insert "ab")
-     (company-mode)
-     (let (company-frontends
-           company-begin-commands
-           (company-backends
-            (list (lambda (command &optional arg)
-                    (cl-case command
-                      (prefix (buffer-substring (point-min) (point)))
-                      (candidates '("abc" "abd")))))))
-       (let ((company-continue-commands '(not backward-delete-char)))
-         (let (this-command)
-           (company-complete))
-         (company-call 'backward-delete-char 1)
-         (should (null company-candidates-length)))
-       (let ((company-continue-commands '(not backward-delete-char-untabify)))
-         (let (this-command)
-           (company-complete))
-         (company-call 'backward-delete-char 1)
-         (should (eq 2 company-candidates-length))))))
- (ert-deftest company-auto-complete-explicit ()
-   (with-temp-buffer
-     (insert "ab")
-     (company-mode)
-     (let (company-frontends
-           (company-auto-complete 'company-explicit-action-p)
-           (company-auto-complete-chars '(? ))
-           (company-backends
-            (list (lambda (command &optional arg)
-                    (cl-case command
-                      (prefix (buffer-substring (point-min) (point)))
-                      (candidates '("abcd" "abef")))))))
-       (let (this-command)
-         (company-complete))
-       (let ((last-command-event ? ))
-         (company-call 'self-insert-command 1))
-       (should (string= "abcd " (buffer-string))))))
- (ert-deftest company-no-auto-complete-when-idle ()
-   (with-temp-buffer
-     (insert "ab")
-     (company-mode)
-     (let (company-frontends
-           (company-auto-complete 'company-explicit-action-p)
-           (company-auto-complete-chars '(? ))
-           (company-minimum-prefix-length 2)
-           (company-backends
-            (list (lambda (command &optional arg)
-                    (cl-case command
-                      (prefix (buffer-substring (point-min) (point)))
-                      (candidates '("abcd" "abef")))))))
-       (company-idle-begin (current-buffer) (selected-window)
-                           (buffer-chars-modified-tick) (point))
-       (let ((last-command-event ? ))
-         (company-call 'self-insert-command 1))
-       (should (string= "ab " (buffer-string))))))
- (ert-deftest company-clears-explicit-action-when-no-matches ()
-   (with-temp-buffer
-     (company-mode)
-     (let (company-frontends
-           company-backends)
-       (company-call 'manual-begin) ;; fails
-       (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-end-of-buffer-workaround
-           (company-backends
-            (list (lambda (command &optional arg)
-                    (cl-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 "A") ; 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)
-                    (cl-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)
-                    (cl-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
-     (save-window-excursion
-       (set-window-buffer nil (current-buffer))
-       (save-excursion (insert " ff"))
-       (company-mode)
-       (let ((company-frontends '(company-pseudo-tooltip-frontend))
-             (company-begin-commands '(self-insert-command))
-             (company-backends
-              (list (lambda (c &optional arg)
-                      (cl-case c (prefix "") (candidates '("a" "b" "c")))))))
-         (let (this-command)
-           (company-call 'complete))
-         (company-call 'open-line 1)
-         (should (eq 1 (overlay-start company-pseudo-tooltip-overlay)))))))
- (ert-deftest company-pseudo-tooltip-show ()
-   :tags '(interactive)
-   (with-temp-buffer
-     (save-window-excursion
-     (set-window-buffer nil (current-buffer))
-     (insert "aaaa\n  bb\nccccccc\nddd")
-     (search-backward "bb")
-     (let ((col (company--column))
-           (company-candidates-length 2)
-           (company-candidates '("123" "45"))
-           (company-backend 'ignore))
-       (company-pseudo-tooltip-show (company--row) col 0)
-       (let ((ov company-pseudo-tooltip-overlay))
-         ;; With margins.
-         (should (eq (overlay-get ov 'company-width) 5))
-         ;; FIXME: Make it 2?
-         (should (eq (overlay-get ov 'company-height) company-tooltip-limit))
-         (should (eq (overlay-get ov 'company-column) col))
-         (should (string= (overlay-get ov 'company-display)
-                          "\n  123 \nc 45  c\nddd\n")))))))
- (ert-deftest company-pseudo-tooltip-edit-updates-width ()
-   :tags '(interactive)
-   (with-temp-buffer
-     (set-window-buffer nil (current-buffer))
-     (let ((company-candidates-length 5)
-           (company-candidates '("123" "45" "67" "89" "1011"))
-           (company-backend 'ignore)
-           (company-tooltip-limit 4)
-           (company-tooltip-offset-display 'scrollbar))
-       (company-pseudo-tooltip-show (company--row)
-                                    (company--column)
-                                    0)
-       (should (eq (overlay-get company-pseudo-tooltip-overlay 'company-width)
-                   6))
-       (company-pseudo-tooltip-edit 4)
-       (should (eq (overlay-get company-pseudo-tooltip-overlay 'company-width)
-                   7)))))
- (ert-deftest company-preview-show-with-annotations ()
-   :tags '(interactive)
-   (with-temp-buffer
-     (save-window-excursion
-       (set-window-buffer nil (current-buffer))
-       (save-excursion (insert "\n"))
-       (let ((company-candidates-length 1)
-             (company-candidates '("123")))
-         (company-preview-show-at-point (point))
-         (let* ((ov company-preview-overlay)
-                (str (overlay-get ov 'after-string)))
-           (should (string= str "123"))
-           (should (eq (get-text-property 0 'cursor str) t)))))))
- (ert-deftest company-pseudo-tooltip-show-with-annotations ()
-   :tags '(interactive)
-   (with-temp-buffer
-     (save-window-excursion
-       (set-window-buffer nil (current-buffer))
-       (insert " ")
-       (save-excursion (insert "\n"))
-       (let ((company-candidates-length 2)
-             (company-backend (lambda (action &optional arg &rest _ignore)
-                                (when (eq action 'annotation)
-                                  (cdr (assoc arg '(("123" . "(4)")))))))
-             (company-candidates '("123" "45"))
-             company-tooltip-align-annotations)
-         (company-pseudo-tooltip-show-at-point (point) 0)
-         (let ((ov company-pseudo-tooltip-overlay))
-           ;; With margins.
-           (should (eq (overlay-get ov 'company-width) 8))
-           (should (string= (overlay-get ov 'company-display)
-                            "\n 123(4) \n 45     \n")))))))
- (ert-deftest company-pseudo-tooltip-show-with-annotations-right-aligned ()
-   :tags '(interactive)
-   (with-temp-buffer
-     (save-window-excursion
-       (set-window-buffer nil (current-buffer))
-       (insert " ")
-       (save-excursion (insert "\n"))
-       (let ((company-candidates-length 3)
-             (company-backend (lambda (action &optional arg &rest _ignore)
-                                (when (eq action 'annotation)
-                                  (cdr (assoc arg '(("123" . "(4)")
-                                                    ("67" . "(891011)")))))))
-             (company-candidates '("123" "45" "67"))
-             (company-tooltip-align-annotations t))
-         (company-pseudo-tooltip-show-at-point (point) 0)
-         (let ((ov company-pseudo-tooltip-overlay))
-           ;; With margins.
-           (should (eq (overlay-get ov 'company-width) 13))
-           (should (string= (overlay-get ov 'company-display)
-                            "\n 123     (4) \n 45          \n 67 (891011) \n")))))))
- (ert-deftest company-create-lines-shows-numbers ()
-   (let ((company-show-numbers t)
-         (company-candidates '("x" "y" "z"))
-         (company-candidates-length 3)
-         (company-backend 'ignore))
-     (should (equal '(" x 1 " " y 2 " " z 3 ")
-                    (company--create-lines 0 999)))))
- (ert-deftest company-create-lines-truncates-annotations ()
-   (let* ((ww (company--window-width))
-          (data `(("1" . "(123)")
-                  ("2" . nil)
-                  ("3" . ,(concat "(" (make-string (- ww 2) ?4) ")"))
-                  (,(make-string ww ?4) . "<4>")))
-          (company-candidates (mapcar #'car data))
-          (company-candidates-length 4)
-          (company-tooltip-margin 1)
-          (company-backend (lambda (cmd &optional arg)
-                             (when (eq cmd 'annotation)
-                               (cdr (assoc arg data)))))
-          company-tooltip-align-annotations)
-     (should (equal (list (format " 1(123)%s " (company-space-string (- ww 8)))
-                          (format " 2%s " (company-space-string (- ww 3)))
-                          (format " 3(444%s " (make-string (- ww 7) ?4))
-                          (format " %s " (make-string (- ww 2) ?4)))
-                    (company--create-lines 0 999)))
-     (let ((company-tooltip-align-annotations t))
-       (should (equal (list (format " 1%s(123) " (company-space-string (- ww 8)))
-                            (format " 2%s " (company-space-string (- ww 3)))
-                            (format " 3 (444%s " (make-string (- ww 8) ?4))
-                            (format " %s " (make-string (- ww 2) ?4)))
-                      (company--create-lines 0 999))))))
- (ert-deftest company-create-lines-truncates-common-part ()
-   (let* ((ww (company--window-width))
-          (company-candidates-length 2)
-          (company-tooltip-margin 1)
-          (company-backend #'ignore))
-     (let* ((company-common (make-string (- ww 3) ?1))
-            (company-candidates `(,(concat company-common "2")
-                                  ,(concat company-common "3"))))
-       (should (equal (list (format " %s2 " (make-string (- ww 3) ?1))
-                            (format " %s3 " (make-string (- ww 3) ?1)))
-                      (company--create-lines 0 999))))
-     (let* ((company-common (make-string (- ww 2) ?1))
-            (company-candidates `(,(concat company-common "2")
-                                  ,(concat company-common "3"))))
-       (should (equal (list (format " %s " company-common)
-                            (format " %s " company-common))
-                      (company--create-lines 0 999))))
-     (let* ((company-common (make-string ww ?1))
-            (company-candidates `(,(concat company-common "2")
-                                  ,(concat company-common "3")))
-            (res (company--create-lines 0 999)))
-       (should (equal (list (format " %s " (make-string (- ww 2) ?1))
-                            (format " %s " (make-string (- ww 2) ?1)))
-                      res))
-       (should (eq 'company-tooltip-common-selection
-                     (get-text-property (- ww 2) 'face
-                                        (car res))))
-       (should (eq 'company-tooltip-selection
-                   (get-text-property (1- ww) 'face
-                                      (car res))))
-       )))
- (ert-deftest company-create-lines-clears-out-non-printables ()
-   :tags '(interactive)
-   (let (company-show-numbers
-         (company-candidates (list
-                              (decode-coding-string "avalis\351e" 'utf-8)
-                              "avatar"))
-         (company-candidates-length 2)
-         (company-backend 'ignore))
-     (should (equal '(" avalis‗e    "
-                      " avatar      ")
-                    (company--create-lines 0 999)))))
- (ert-deftest company-create-lines-handles-multiple-width ()
-   :tags '(interactive)
-   (let (company-show-numbers
-         (company-candidates '("蛙蛙蛙蛙" "蛙abc"))
-         (company-candidates-length 2)
-         (company-backend 'ignore))
-     (should (equal '(" 蛙蛙蛙蛙 "
-                      " 蛙abc    ")
-                    (company--create-lines 0 999)))))
- (ert-deftest company-column-with-composition ()
-   :tags '(interactive)
-   (with-temp-buffer
-     (save-window-excursion
-       (set-window-buffer nil (current-buffer))
-       (insert "lambda ()")
-       (compose-region 1 (1+ (length "lambda")) "\\")
-       (should (= (company--column) 4)))))
- (ert-deftest company-column-with-line-prefix ()
-   :tags '(interactive)
-   (with-temp-buffer
-     (save-window-excursion
-       (set-window-buffer nil (current-buffer))
-       (insert "foo")
-       (put-text-property (point-min) (point) 'line-prefix "  ")
-       (should (= (company--column) 5)))))
- (ert-deftest company-column-with-line-prefix-on-empty-line ()
-   :tags '(interactive)
-   (with-temp-buffer
-     (save-window-excursion
-       (set-window-buffer nil (current-buffer))
-       (insert "\n")
-       (forward-char -1)
-       (put-text-property (point-min) (point-max) 'line-prefix "  ")
-       (should (= (company--column) 2)))))
- (ert-deftest company-column-with-tabs ()
-   :tags '(interactive)
-   (with-temp-buffer
-     (save-window-excursion
-       (set-window-buffer nil (current-buffer))
-       (insert "|\t|\t|\t(")
-       (let ((tab-width 8))
-         (should (= (company--column) 25))))))
- (ert-deftest company-row-with-header-line-format ()
-   :tags '(interactive)
-   (with-temp-buffer
-     (save-window-excursion
-       (set-window-buffer nil (current-buffer))
-       (should (= (company--row) 0))
-       (setq header-line-format "aaaaaaa")
-       (should (= (company--row) 0)))))
- (ert-deftest company-plainify ()
-   (let ((tab-width 8))
-     (should (equal-including-properties
-              (company-plainify "\tabc\td\t")
-              (concat "        "
-                      "abc     "
-                      "d       "))))
-   (should (equal-including-properties
-            (company-plainify (propertize "foobar" 'line-prefix "-*-"))
-            "-*-foobar")))
- (ert-deftest company-buffer-lines-with-lines-folded ()
-   :tags '(interactive)
-   (with-temp-buffer
-     (insert (propertize "aaa\nbbb\nccc\nddd\n" 'display "aaa+\n"))
-     (insert "eee\nfff\nggg")
-     (should (equal (company-buffer-lines (point-min) (point-max))
-                    '("aaa" "eee" "fff" "ggg")))))
- (ert-deftest company-buffer-lines-with-multiline-display ()
-   :tags '(interactive)
-   (with-temp-buffer
-     (insert (propertize "a" 'display "bbb\nccc\ndddd\n"))
-     (insert "eee\nfff\nggg")
-     (should (equal (company-buffer-lines (point-min) (point-max))
-                    '("" "" "" "eee" "fff" "ggg")))))
- (ert-deftest company-modify-line ()
-   (let ((str "-*-foobar"))
-     (should (equal-including-properties
-              (company-modify-line str "zz" 4)
-              "-*-fzzbar"))
-     (should (equal-including-properties
-              (company-modify-line str "xx" 0)
-              "xx-foobar"))
-     (should (equal-including-properties
-              (company-modify-line str "zz" 10)
-              "-*-foobar zz"))))
- (ert-deftest company-scrollbar-bounds ()
-   (should (equal nil (company--scrollbar-bounds 0 3 3)))
-   (should (equal nil (company--scrollbar-bounds 0 4 3)))
-   (should (equal '(0 . 0) (company--scrollbar-bounds 0 1 2)))
-   (should (equal '(1 . 1) (company--scrollbar-bounds 2 2 4)))
-   (should (equal '(2 . 3) (company--scrollbar-bounds 7 4 12)))
-   (should (equal '(1 . 2) (company--scrollbar-bounds 3 4 12)))
-   (should (equal '(1 . 3) (company--scrollbar-bounds 4 5 11))))
- ;;; Async
- (defun company-async-backend (command &optional arg)
-   (pcase command
-     (`prefix "foo")
-     (`candidates
-      (cons :async
-            (lambda (cb)
-              (run-with-timer 0.05 nil
-                              #'funcall cb '("abc" "abd")))))))
- (ert-deftest company-call-backend-forces-sync ()
-   (let ((company-backend 'company-async-backend)
-         (company-async-timeout 0.1))
-     (should (equal '("abc" "abd") (company-call-backend 'candidates)))))
- (ert-deftest company-call-backend-errors-on-timeout ()
-   (with-temp-buffer
-     (let* ((company-backend (lambda (command &optional _arg)
-                               (pcase command
-                                 (`candidates (cons :async 'ignore)))))
-            (company-async-timeout 0.1)
-            (err (should-error (company-call-backend 'candidates "foo"))))
-       (should (string-match-p "async timeout" (cadr err))))))
- (ert-deftest company-call-backend-raw-passes-return-value-verbatim ()
-   (let ((company-backend 'company-async-backend))
-     (should (equal "foo" (company-call-backend-raw 'prefix)))
-     (should (equal :async (car (company-call-backend-raw 'candidates "foo"))))
-     (should (equal 'closure (cadr (company-call-backend-raw 'candidates "foo"))))))
- (ert-deftest company-manual-begin-forces-async-candidates-to-sync ()
-   (with-temp-buffer
-     (company-mode)
-     (let (company-frontends
-           company-transformers
-           (company-backends (list 'company-async-backend)))
-       (company-manual-begin)
-       (should (equal "foo" company-prefix))
-       (should (equal '("abc" "abd") company-candidates)))))
- (ert-deftest company-idle-begin-allows-async-candidates ()
-   (with-temp-buffer
-     (company-mode)
-     (let (company-frontends
-           company-transformers
-           (company-backends (list 'company-async-backend)))
-       (company-idle-begin (current-buffer) (selected-window)
-                           (buffer-chars-modified-tick) (point))
-       (should (null company-candidates))
-       (sleep-for 0.1)
-       (should (equal "foo" company-prefix))
-       (should (equal '("abc" "abd") company-candidates)))))
- (ert-deftest company-idle-begin-cancels-async-candidates-if-buffer-changed ()
-   (with-temp-buffer
-     (company-mode)
-     (let (company-frontends
-           (company-backends (list 'company-async-backend)))
-       (company-idle-begin (current-buffer) (selected-window)
-                           (buffer-chars-modified-tick) (point))
-       (should (null company-candidates))
-       (insert "a")
-       (sleep-for 0.1)
-       (should (null company-candidates)))))
- (ert-deftest company-idle-begin-async-allows-immediate-callbacks ()
-   (with-temp-buffer
-     (company-mode)
-     (let (company-frontends
-           (company-backends
-            (list (lambda (command &optional arg)
-                    (pcase command
-                      (`prefix (buffer-substring (point-min) (point)))
-                      (`candidates
-                       (let ((c (all-completions arg '("abc" "def"))))
-                         (cons :async
-                               (lambda (cb) (funcall cb c)))))
-                      (`no-cache t)))))
-           (company-minimum-prefix-length 0))
-       (company-idle-begin (current-buffer) (selected-window)
-                           (buffer-chars-modified-tick) (point))
-       (should (equal '("abc" "def") company-candidates))
-       (let ((last-command-event ?a))
-         (company-call 'self-insert-command 1))
-       (should (equal '("abc") company-candidates)))))
- (ert-deftest company-multi-backend-forces-prefix-to-sync ()
-   (with-temp-buffer
-     (let ((company-backend (list 'ignore
-                                  (lambda (command)
-                                    (should (eq command 'prefix))
-                                    (cons :async
-                                          (lambda (cb)
-                                            (run-with-timer
-                                             0.01 nil
-                                             (lambda () (funcall cb nil))))))
-                                  (lambda (command)
-                                    (should (eq command 'prefix))
-                                    "foo"))))
-       (should (equal "foo" (company-call-backend-raw 'prefix))))
-     (let ((company-backend (list (lambda (_command)
-                                    (cons :async
-                                          (lambda (cb)
-                                            (run-with-timer
-                                             0.01 nil
-                                             (lambda () (funcall cb "bar"))))))
-                                  (lambda (_command)
-                                    "foo"))))
-       (should (equal "bar" (company-call-backend-raw 'prefix))))))
- (ert-deftest company-multi-backend-merges-deferred-candidates ()
-   (with-temp-buffer
-     (let* ((immediate (lambda (command &optional arg)
-                         (pcase command
-                           (`prefix "foo")
-                           (`candidates
-                            (cons :async
-                                  (lambda (cb) (funcall cb '("f"))))))))
-            (company-backend (list 'ignore
-                                   (lambda (command &optional arg)
-                                     (pcase command
-                                       (`prefix "foo")
-                                       (`candidates
-                                        (should (equal arg "foo"))
-                                        (cons :async
-                                              (lambda (cb)
-                                                (run-with-timer
-                                                 0.01 nil
-                                                 (lambda () (funcall cb '("a" "b")))))))))
-                                   (lambda (command &optional arg)
-                                     (pcase command
-                                       (`prefix "foo")
-                                       (`candidates '("c" "d" "e"))))
-                                   immediate)))
-       (should (equal :async (car (company-call-backend-raw 'candidates "foo"))))
-       (should (equal '("a" "b" "c" "d" "e" "f")
-                      (company-call-backend 'candidates "foo")))
-       (let ((company-backend (list immediate)))
-         (should (equal '("f") (company-call-backend 'candidates "foo")))))))
- ;;; Transformers
- (ert-deftest company-occurrence-prefer-closest-above ()
-   (with-temp-buffer
-     (save-window-excursion
-       (set-window-buffer nil (current-buffer))
-       (insert "foo0
- foo1
- ")
-       (save-excursion
-         (insert "
- foo3
- foo2"))
-       (let ((company-backend 'company-dabbrev)
-             (company-occurrence-weight-function
-              'company-occurrence-prefer-closest-above))
-         (should (equal '("foo1" "foo0" "foo3" "foo2" "foo4")
-                        (company-sort-by-occurrence
-                         '("foo0" "foo1" "foo2" "foo3" "foo4"))))))))
- (ert-deftest company-occurrence-prefer-any-closest ()
-   (with-temp-buffer
-     (save-window-excursion
-       (set-window-buffer nil (current-buffer))
-       (insert "foo0
- foo1
- ")
-       (save-excursion
-         (insert "
- foo3
- foo2"))
-       (let ((company-backend 'company-dabbrev)
-             (company-occurrence-weight-function
-              'company-occurrence-prefer-any-closest))
-         (should (equal '("foo1" "foo3" "foo0" "foo2" "foo4")
-                        (company-sort-by-occurrence
-                         '("foo0" "foo1" "foo2" "foo3" "foo4"))))))))
- ;;; Template
- (ert-deftest company-template-removed-after-the-last-jump ()
-   (with-temp-buffer
-     (insert "{ }")
-     (goto-char 2)
-     (let ((tpl (company-template-declare-template (point) (1- (point-max)))))
-       (save-excursion
-         (dotimes (i 2)
-           (insert " ")
-           (company-template-add-field tpl (point) "foo")))
-       (company-call 'template-forward-field)
-       (should (= 3 (point)))
-       (company-call 'template-forward-field)
-       (should (= 7 (point)))
-       (company-call 'template-forward-field)
-       (should (= 11 (point)))
-       (should (zerop (length (overlay-get tpl 'company-template-fields))))
-       (should (null (overlay-buffer tpl))))))
- (ert-deftest company-template-removed-after-input-and-jump ()
-   (with-temp-buffer
-     (insert "{ }")
-     (goto-char 2)
-     (let ((tpl (company-template-declare-template (point) (1- (point-max)))))
-       (save-excursion
-         (insert " ")
-         (company-template-add-field tpl (point) "bar"))
-       (company-call 'template-move-to-first tpl)
-       (should (= 3 (point)))
-       (dolist (c (string-to-list "tee"))
-         (let ((last-command-event c))
-           (company-call 'self-insert-command 1)))
-       (should (string= "{ tee }" (buffer-string)))
-       (should (overlay-buffer tpl))
-       (company-call 'template-forward-field)
-       (should (= 7 (point)))
-       (should (null (overlay-buffer tpl))))))
  (defun company-call (name &rest args)
    (let* ((maybe (intern (format "company-%s" name)))
           (command (if (fboundp maybe) maybe name)))
      (let ((this-command command))
        (run-hooks 'post-command-hook))))
  
- (ert-deftest company-template-c-like-templatify ()
-   (with-temp-buffer
-     (let ((text "foo(int a, short b)"))
-       (insert text)
-       (company-template-c-like-templatify text)
-       (should (equal "foo(arg0, arg1)" (buffer-string)))
-       (should (looking-at "arg0"))
-       (should (equal "int a"
-                      (overlay-get (company-template-field-at) 'display))))))
- (ert-deftest company-template-c-like-templatify-trims-after-closing-paren ()
-   (with-temp-buffer
-     (let ((text "foo(int a, short b)!@ #1334 a"))
-       (insert text)
-       (company-template-c-like-templatify text)
-       (should (equal "foo(arg0, arg1)" (buffer-string)))
-       (should (looking-at "arg0")))))
- (ert-deftest company-template-c-like-templatify-generics ()
-   (with-temp-buffer
-     (let ((text "foo<TKey, TValue>(int i, Dict<TKey, TValue>, long l)"))
-       (insert text)
-       (company-template-c-like-templatify text)
-       (should (equal "foo<arg0, arg1>(arg2, arg3, arg4)" (buffer-string)))
-       (should (looking-at "arg0"))
-       (should (equal "TKey" (overlay-get (company-template-field-at) 'display)))
-       (search-forward "arg3")
-       (forward-char -1)
-       (should (equal "Dict<TKey, TValue>"
-                      (overlay-get (company-template-field-at) 'display))))))
- ;;; Clang
- (ert-deftest company-clang-objc-templatify ()
-   (with-temp-buffer
-     (let ((text "createBookWithTitle:andAuthor:"))
-       (insert text)
-       (company-clang-objc-templatify text)
-       (should (equal "createBookWithTitle:arg0 andAuthor:arg1" (buffer-string)))
-       (should (looking-at "arg0"))
-       (should (null (overlay-get (company-template-field-at) 'display))))))
+ (provide 'company-tests)
index cf88ddd30d0bf817e2adf3ef00f5f189c0eec14c,965800624cda44995276dcc18b6f28375af68937..965800624cda44995276dcc18b6f28375af68937
@@@ -1,11 -1,11 +1,11 @@@
  ;;; company.el --- Modular text completion framework  -*- lexical-binding: t -*-
  
- ;; Copyright (C) 2009-2014  Free Software Foundation, Inc.
+ ;; Copyright (C) 2009-2015  Free Software Foundation, Inc.
  
  ;; Author: Nikolaj Schumacher
  ;; Maintainer: Dmitry Gutov <dgutov@yandex.ru>
  ;; URL: http://company-mode.github.io/
- ;; Version: 0.8.7
+ ;; Version: 0.8.8
  ;; Keywords: abbrev, convenience, matching
  ;; Package-Requires: ((emacs "24.1") (cl-lib "0.5"))
  
@@@ -340,20 -340,20 +340,20 @@@ The first argument is the command reque
  of the following:
  
  `prefix': The back-end should return the text to be completed.  It must be
- text immediately before point.  Returning nil passes control to the next
back-end.  The function should return `stop' if it should complete but
- cannot (e.g. if it is in the middle of a string).  Instead of a string,
- the back-end may return a cons where car is the prefix and cdr is used in
- `company-minimum-prefix-length' test.  It must be either number or t, and
- in the latter case the test automatically succeeds.
+ text immediately before point.  Returning nil from this command passes
control to the next back-end.  The function should return `stop' if it
+ should complete but cannot (e.g. if it is in the middle of a string).
+ Instead of a string, the back-end may return a cons where car is the prefix
+ and cdr is used in `company-minimum-prefix-length' test.  It must be either
number or t, and in the latter case the test automatically succeeds.
  
  `candidates': The second argument is the prefix to be completed.  The
  return value should be a list of candidates that match the prefix.
  
  Non-prefix matches are also supported (candidates that don't start with the
  prefix, but match it in some backend-defined way).  Backends that use this
- feature must disable cache (return t to `no-cache') and should also respond
- to `match'.
+ feature must disable cache (return t to `no-cache') and might also want to
respond to `match'.
  
  Optional commands:
  
@@@ -384,10 -384,10 +384,10 @@@ be kept if they have different annotati
  backends should store the related information on candidates using text
  properties.
  
- `match': The second argument is a completion candidate.  Backends that
- provide non-prefix completions should return the position of the end of
- text in the candidate that matches `prefix'.  It will be used when
rendering the popup.
+ `match': The second argument is a completion candidate.  Return the index
+ after the end of text matching `prefix' within the candidate string.  It
+ will be used when rendering the popup.  This command only makes sense for
backends that provide non-prefix completion.
  
  `require-match': If this returns t, the user is not allowed to enter
  anything not offered as a candidate.  Use with care!  The default value nil
@@@ -449,9 -449,11 +449,11 @@@ even if the back-end uses the asynchron
  (put 'company-backends 'safe-local-variable 'company-safe-backends-p)
  
  (defcustom company-transformers nil
-   "Functions to change the list of candidates received from backends,
- after sorting and removal of duplicates (if appropriate).
- Each function gets called with the return value of the previous one."
+   "Functions to change the list of candidates received from backends.
+ Each function gets called with the return value of the previous one.
+ The first one gets passed the list of candidates, already sorted and
+ without duplicates."
    :type '(choice
            (const :tag "None" nil)
            (const :tag "Sort by occurrence" (company-sort-by-occurrence))
@@@ -767,10 -769,10 +769,10 @@@ means that `company-mode' is always tur
    (interactive)
    (setq this-command last-command))
  
- (global-set-key '[31415926] 'company-ignore)
+ (global-set-key '[company-dummy-event] 'company-ignore)
  
  (defun company-input-noop ()
-   (push 31415926 unread-command-events))
+   (push 'company-dummy-event unread-command-events))
  
  (defun company--posn-col-row (posn)
    (let ((col (car (posn-col-row posn)))
@@@ -978,8 -980,9 +980,9 @@@ Controlled by `company-auto-complete'."
    ;; XXX: Return value we check here is subject to change.
    (if (eq (company-call-backend 'ignore-case) 'keep-prefix)
        (insert (company-strip-prefix candidate))
-     (delete-region (- (point) (length company-prefix)) (point))
-     (insert candidate)))
+     (unless (equal company-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.
@@@ -1054,13 -1057,6 +1057,6 @@@ can retrieve meta-data for them.
                                                (symbol-name backend))))
            (setq company-lighter (format " company-<%s>" name)))))))
  
- (defun company-apply-predicate (candidates predicate)
-   (let (new)
-     (dolist (c candidates)
-       (when (funcall predicate c)
-         (push c new)))
-     (nreverse new)))
  (defun company-update-candidates (candidates)
    (setq company-candidates-length (length candidates))
    (if (> company-selection 0)
                                           company-selection)))))
      (setq company-selection 0
            company-candidates candidates))
-   ;; Save in cache:
-   (push (cons company-prefix company-candidates) company-candidates-cache)
    ;; Calculate common.
    (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'.
+     ;; `company-complete-common', unless there's only one candidate.
      (setq company-common
            (if (cdr company-candidates)
-               (let ((common (try-completion company-prefix company-candidates)))
-                 (if (eq common t)
-                     ;; Mulple equal strings, probably with different
-                     ;; annotations.
-                     company-prefix
+               (let ((common (try-completion "" company-candidates)))
+                 (when (string-prefix-p company-prefix common
+                                        completion-ignore-case)
                    common))
              (car company-candidates)))))
  
                                             company-candidates-cache)))
                  (setq candidates (all-completions prefix prev))
                  (cl-return t)))))
-         ;; no cache match, call back-end
-         (setq candidates
-               (company--process-candidates
-                (company--fetch-candidates prefix))))
-     (setq candidates (company--transform-candidates candidates))
+         (progn
+           ;; No cache match, call the backend.
+           (setq candidates (company--preprocess-candidates
+                             (company--fetch-candidates prefix)))
+           ;; Save in cache.
+           (push (cons prefix candidates) company-candidates-cache)))
+     ;; Only now apply the predicate and transformers.
+     (setq candidates (company--postprocess-candidates candidates))
      (when candidates
        (if (or (cdr candidates)
                (not (eq t (compare-strings (car candidates) nil nil
           (cdr c)
           (lambda (candidates)
             (if (not (and candidates (eq res 'done)))
-                ;; Fetcher called us back right away.
+                ;; There's no completions to display,
+                ;; or the fetcher called us back right away.
                 (setq res candidates)
               (setq company-backend backend
                     company-candidates-cache
                     (list (cons prefix
-                                (company--process-candidates
-                                 candidates))))
+                                (company--preprocess-candidates candidates))))
               (company-idle-begin buf win tick pt)))))
        ;; FIXME: Relying on the fact that the callers
        ;; will interpret nil as "do nothing" is shaky.
        (or res
            (progn (setq res 'done) nil)))))
  
- (defun company--process-candidates (candidates)
-   (when company-candidates-predicate
-     (setq candidates
-           (company-apply-predicate candidates
-                                    company-candidates-predicate)))
+ (defun company--preprocess-candidates (candidates)
    (unless (company-call-backend 'sorted)
      (setq candidates (sort candidates 'string<)))
    (when (company-call-backend 'duplicates)
      (company--strip-duplicates candidates))
    candidates)
  
+ (defun company--postprocess-candidates (candidates)
+   (when (or company-candidates-predicate company-transformers)
+     (setq candidates (copy-sequence candidates)))
+   (when company-candidates-predicate
+     (setq candidates (cl-delete-if-not company-candidates-predicate candidates)))
+   (company--transform-candidates candidates))
  (defun company--strip-duplicates (candidates)
-   (let ((c2 candidates))
+   (let ((c2 candidates)
+         (annos 'unk))
      (while c2
        (setcdr c2
-               (let ((str (car c2))
-                     (anno 'unk))
-                 (pop c2)
+               (let ((str (pop c2)))
                  (while (let ((str2 (car c2)))
                           (if (not (equal str str2))
-                              nil
-                            (when (eq anno 'unk)
-                              (setq anno (company-call-backend
-                                          'annotation str)))
-                            (equal anno
-                                   (company-call-backend
-                                    'annotation 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)))))
  
@@@ -1288,15 -1290,14 +1290,14 @@@ from the rest of the back-ends in the g
         (not company-candidates)
         (let ((company-idle-delay 'now))
           (condition-case-unless-debug err
-              (company--perform)
+              (progn
+                (company--perform)
+                ;; Return non-nil if active.
+                company-candidates)
             (error (message "Company: An error occurred in auto-begin")
                    (message "%s" (error-message-string err))
                    (company-cancel))
-            (quit (company-cancel)))))
-   (unless company-candidates
-     (setq company-backend nil))
-   ;; Return non-nil if active.
-   company-candidates)
+            (quit (company-cancel))))))
  
  (defun company-manual-begin ()
    (interactive)
    (setq company--manual-action t)
    (unwind-protect
        (let ((company-minimum-prefix-length 0))
-         (company-auto-begin))
+         (or company-candidates
+             (company-auto-begin)))
      (unless company-candidates
        (setq company--manual-action nil))))
  
       ((and (or (not (company-require-match-p))
                 ;; Don't require match if the new prefix
                 ;; doesn't continue the old one, and the latter was a match.
+                (not (stringp new-prefix))
                 (<= (length new-prefix) (length company-prefix)))
             (member company-prefix company-candidates))
        ;; Last input was a success,
  (defun company--perform ()
    (or (and company-candidates (company--continue))
        (and (company--should-complete) (company--begin-new)))
-   (when company-candidates
+   (if (not company-candidates)
+       (setq company-backend nil)
      (setq company-point (point)
            company--point-max (point-max))
      (company-ensure-emulation-alist)
  
  ;;; search ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
- (defvar-local company-search-string nil)
+ (defvar-local company-search-string "")
  
  (defvar-local company-search-lighter " Search: \"\"")
  
- (defvar-local company-search-old-map nil)
+ (defvar-local company-search-filtering nil
+   "Non-nil to filter the completion candidates by the search string")
  
- (defvar-local company-search-old-selection 0)
+ (defvar-local company--search-old-selection 0)
  
- (defun company-search (text lines)
+ (defun company--search (text lines)
    (let ((quoted (regexp-quote text))
          (i 0))
      (cl-dolist (line lines)
          (cl-return i))
        (cl-incf i))))
  
+ (defun company-search-keypad ()
+   (interactive)
+   (let* ((name (symbol-name last-command-event))
+          (last-command-event (aref name (1- (length name)))))
+     (company-search-printing-char)))
  (defun company-search-printing-char ()
    (interactive)
-   (company-search-assert-enabled)
-   (let* ((ss (concat company-search-string (string last-command-event)))
-          (pos (company-search ss (nthcdr company-selection company-candidates))))
+   (company--search-assert-enabled)
+   (let ((ss (concat company-search-string (string last-command-event))))
+     (when company-search-filtering
+       (company--search-update-predicate ss))
+     (company--search-update-string ss)))
+ (defun company--search-update-predicate (&optional ss)
+   (let* ((company-candidates-predicate
+           (and (not (string= ss ""))
+                company-search-filtering
+                (lambda (candidate) (string-match ss candidate))))
+          (cc (company-calculate-candidates company-prefix)))
+     (unless cc (error "No match"))
+     (company-update-candidates cc)))
+ (defun company--search-update-string (new)
+   (let* ((pos (company--search new (nthcdr company-selection company-candidates))))
      (if (null pos)
          (ding)
-       (setq company-search-string ss
-             company-search-lighter (concat " Search: \"" ss "\""))
+       (setq company-search-string new
+             company-search-lighter (format " %s: \"%s\""
+                                            (if company-search-filtering
+                                                "Filter"
+                                              "Search")
+                                            new))
        (company-set-selection (+ company-selection pos) t))))
  
+ (defun company--search-assert-input ()
+   (company--search-assert-enabled)
+   (when (string= company-search-string "")
+     (error "Empty search string")))
  (defun company-search-repeat-forward ()
    "Repeat the incremental search in completion candidates forward."
    (interactive)
-   (company-search-assert-enabled)
-   (let ((pos (company-search company-search-string
-                              (cdr (nthcdr company-selection
-                                           company-candidates)))))
+   (company--search-assert-input)
+   (let ((pos (company--search company-search-string
+                               (cdr (nthcdr company-selection
+                                            company-candidates)))))
      (if (null pos)
          (ding)
        (company-set-selection (+ company-selection pos 1) t))))
  (defun company-search-repeat-backward ()
    "Repeat the incremental search in completion candidates backwards."
    (interactive)
-   (company-search-assert-enabled)
-   (let ((pos (company-search company-search-string
-                              (nthcdr (- company-candidates-length
-                                         company-selection)
-                                      (reverse company-candidates)))))
+   (company--search-assert-input)
+   (let ((pos (company--search company-search-string
+                               (nthcdr (- company-candidates-length
+                                          company-selection)
+                                       (reverse company-candidates)))))
      (if (null pos)
          (ding)
        (company-set-selection (- company-selection pos 1) t))))
  
- (defun company-create-match-predicate ()
-   (let ((ss company-search-string))
-     (setq company-candidates-predicate
-           (when ss (lambda (candidate) (string-match ss candidate)))))
-   (company-update-candidates
-    (company-apply-predicate company-candidates company-candidates-predicate))
-   ;; Invalidate cache.
-   (setq company-candidates-cache (cons company-prefix company-candidates)))
- (defun company-filter-printing-char ()
-   (interactive)
-   (company-search-assert-enabled)
-   (company-search-printing-char)
-   (company-create-match-predicate)
-   (company-call-frontends 'update))
- (defun company-search-kill-others ()
-   "Limit the completion candidates to the ones matching the search string."
+ (defun company-search-toggle-filtering ()
+   "Toggle `company-search-filtering'."
    (interactive)
-   (company-search-assert-enabled)
-   (company-create-match-predicate)
-   (company-search-mode 0)
-   (company-call-frontends 'update))
+   (company--search-assert-enabled)
+   (setq company-search-filtering (not company-search-filtering))
+   (let ((ss company-search-string))
+     (company--search-update-predicate ss)
+     (company--search-update-string ss)))
  
  (defun company-search-abort ()
    "Abort searching the completion candidates."
    (interactive)
-   (company-search-assert-enabled)
-   (company-set-selection company-search-old-selection t)
-   (company-search-mode 0))
+   (company--search-assert-enabled)
+   (company-search-mode 0)
+   (company-set-selection company--search-old-selection t))
  
  (defun company-search-other-char ()
    (interactive)
-   (company-search-assert-enabled)
+   (company--search-assert-enabled)
    (company-search-mode 0)
    (company--unread-last-input))
  
+ (defun company-search-delete-char ()
+   (interactive)
+   (company--search-assert-enabled)
+   (if (string= company-search-string "")
+       (ding)
+     (let ((ss (substring company-search-string 0 -1)))
+       (when company-search-filtering
+         (company--search-update-predicate ss))
+       (company--search-update-string ss))))
  (defvar company-search-map
    (let ((i 0)
          (keymap (make-keymap)))
      (while (< i 256)
        (define-key keymap (vector i) 'company-search-printing-char)
        (cl-incf i))
+     (dotimes (i 10)
+       (define-key keymap (read (format "[kp-%s]" i)) 'company-search-keypad))
      (let ((meta-map (make-sparse-keymap)))
        (define-key keymap (char-to-string meta-prefix-char) meta-map)
        (define-key keymap [escape] meta-map))
      (define-key keymap (vector meta-prefix-char t) 'company-search-other-char)
+     (define-key keymap (kbd "M-n") 'company-select-next)
+     (define-key keymap (kbd "M-p") 'company-select-previous)
      (define-key keymap "\e\e\e" 'company-search-other-char)
      (define-key keymap [escape escape escape] 'company-search-other-char)
-     (define-key keymap (kbd "DEL") 'company-search-other-char)
+     (define-key keymap (kbd "DEL") 'company-search-delete-char)
+     (define-key keymap [backspace] 'company-search-delete-char)
      (define-key keymap "\C-g" 'company-search-abort)
      (define-key keymap "\C-s" 'company-search-repeat-forward)
      (define-key keymap "\C-r" 'company-search-repeat-backward)
-     (define-key keymap "\C-o" 'company-search-kill-others)
+     (define-key keymap "\C-o" 'company-search-toggle-filtering)
      keymap)
    "Keymap used for incrementally searching the completion candidates.")
  
@@@ -1695,15 -1728,19 +1728,19 @@@ Don't start this directly, use `company
    (if company-search-mode
        (if (company-manual-begin)
            (progn
-             (setq company-search-old-selection company-selection)
+             (setq company--search-old-selection company-selection)
              (company-call-frontends 'update))
          (setq company-search-mode nil))
      (kill-local-variable 'company-search-string)
      (kill-local-variable 'company-search-lighter)
-     (kill-local-variable 'company-search-old-selection)
+     (kill-local-variable 'company-search-filtering)
+     (kill-local-variable 'company--search-old-selection)
+     (when company-backend
+       (company--search-update-predicate "")
+       (company-call-frontends 'update))
      (company-enable-overriding-keymap company-active-map)))
  
- (defun company-search-assert-enabled ()
+ (defun company--search-assert-enabled ()
    (company-assert-enabled)
    (unless company-search-mode
      (company-uninstall-map)
  - `company-search-repeat-forward' (\\[company-search-repeat-forward])
  - `company-search-repeat-backward' (\\[company-search-repeat-backward])
  - `company-search-abort' (\\[company-search-abort])
+ - `company-search-delete-char' (\\[company-search-delete-char])
  
  Regular characters are appended to the search string.
  
- The command `company-search-kill-others' (\\[company-search-kill-others])
- uses the search string to limit the completion candidates."
+ The command `company-search-toggle-filtering' (\\[company-search-toggle-filtering])
+ uses the search string to filter the completion candidates."
    (interactive)
    (company-search-mode 1)
    (company-enable-overriding-keymap company-search-map))
  (defun company-filter-candidates ()
    "Start filtering the completion candidates incrementally.
  This works the same way as `company-search-candidates' immediately
- followed by `company-search-kill-others' after each input."
+ followed by `company-search-toggle-filtering'."
    (interactive)
    (company-search-mode 1)
-   (company-enable-overriding-keymap company-filter-map))
+   (setq company-search-filtering t))
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
@@@ -1843,6 -1881,16 +1881,16 @@@ and invoke the normal binding.
        (when company-common
          (company--insert-candidate company-common)))))
  
+ (defun company-complete-common-or-cycle ()
+   "Insert the common part of all candidates, or select the next one."
+   (interactive)
+   (when (company-manual-begin)
+     (let ((tick (buffer-chars-modified-tick)))
+       (call-interactively 'company-complete-common)
+       (when (eq tick (buffer-chars-modified-tick))
+         (let ((company-selection-wrap-around t))
+           (call-interactively 'company-select-next))))))
  (defun company-complete ()
    "Insert the common part of all candidates or the current selection.
  The first time this is called, the common part is inserted, the second
@@@ -1857,18 -1905,26 +1905,26 @@@ inserted.
        (setq this-command 'company-complete-common))))
  
  (defun company-complete-number (n)
-   "Insert the Nth candidate.
+   "Insert the Nth candidate visible in the tooltip.
  To show the number next to the candidates in some back-ends, enable
  `company-show-numbers'.  When called interactively, uses the last typed
  character, stripping the modifiers.  That character must be a digit."
    (interactive
-    (list (let ((n (- (event-basic-type last-command-event) ?0)))
+    (list (let* ((type (event-basic-type last-command-event))
+                 (char (if (characterp type)
+                           ;; Number on the main row.
+                           type
+                         ;; Keypad number, if bound directly.
+                         (car (last (string-to-list (symbol-name type))))))
+                 (n (- char ?0)))
             (if (zerop n) 10 n))))
    (when (company-manual-begin)
-     (and (or (< n 1) (> n company-candidates-length))
+     (and (or (< n 1) (> n (- company-candidates-length
+                              company-tooltip-offset)))
           (error "No candidate number %d" n))
      (cl-decf n)
-     (company-finish (nth n company-candidates))))
+     (company-finish (nth (+ n company-tooltip-offset)
+                          company-candidates))))
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
@@@ -2095,7 -2151,6 +2151,6 @@@ If SHOW-VERSION is non-nil, show the ve
                           (string-width company-common)
                         0)))
           (ann-ralign company-tooltip-align-annotations)
-          (value (company--clean-string value))
           (ann-truncate (< width
                            (+ (length value) (length annotation)
                               (if ann-ralign 1 0))))
                               mouse-face company-tooltip-mouse)
                             line))
      (when selected
-       (if (and company-search-string
+       (if (and (not (string= company-search-string ""))
                 (string-match (regexp-quote company-search-string) value
                               (length company-prefix)))
            (let ((beg (+ margin (match-beginning 0)))
                  (end (+ margin (match-end 0))))
              (add-text-properties beg end '(face company-tooltip-search)
-                                  line)
-             (when (< beg common)
-               (add-text-properties beg common
-                                    '(face company-tooltip-common-selection)
-                                    line)))
+                                  line))
          (add-text-properties 0 width '(face company-tooltip-selection
                                         mouse-face company-tooltip-selection)
                               line)
  (defun company-buffer-lines (beg end)
    (goto-char beg)
    (let (lines lines-moved)
-     (while (and (> (setq lines-moved (vertical-motion 1)) 0)
+     (while (and (not (eobp)) ; http://debbugs.gnu.org/19553
+                 (> (setq lines-moved (vertical-motion 1)) 0)
                  (<= (point) end))
        (let ((bound (min end (1- (point)))))
          ;; A visual line can contain several physical lines (e.g. with outline's
        (floor (window-screen-lines))
      (window-body-height)))
  
- (defsubst company--window-width ()
+ (defun company--window-width ()
    (let ((ww (window-body-width)))
      ;; Account for the line continuation column.
      (when (zerop (cadr (window-fringes)))
                 (let ((margins (window-margins)))
                   (+ (or (car margins) 0)
                      (or (cdr margins) 0)))))
+     (when (and word-wrap
+                (version< emacs-version "24.4.51.5"))
+       ;; http://debbugs.gnu.org/18384
+       (cl-decf ww))
      ww))
  
  (defun company--replacement-string (lines old column nl &optional align-top)
  
  (defun company--create-lines (selection limit)
    (let ((len company-candidates-length)
-         (numbered 99999)
          (window-width (company--window-width))
          lines
          width
      (dotimes (_ len)
        (let* ((value (pop lines-copy))
               (annotation (company-call-backend 'annotation value)))
-         (when (and annotation company-tooltip-align-annotations)
-           ;; `lisp-completion-at-point' adds a space.
-           (setq annotation (comment-string-strip annotation t nil)))
+         (setq value (company--clean-string value))
+         (when annotation
+           (when company-tooltip-align-annotations
+             ;; `lisp-completion-at-point' adds a space.
+             (setq annotation (comment-string-strip annotation t nil)))
+           (setq annotation (company--clean-string annotation)))
          (push (cons value annotation) items)
-         (setq width (max (+ (string-width value)
+         (setq width (max (+ (length value)
                              (if (and annotation company-tooltip-align-annotations)
                                  (1+ (length annotation))
                                (length annotation)))
  
      (setq width (min window-width
                       (max company-tooltip-minimum-width
-                           (if (and company-show-numbers
-                                    (< company-tooltip-offset 10))
+                           (if company-show-numbers
                                (+ 2 width)
                              width))))
  
-     ;; number can make tooltip too long
-     (when company-show-numbers
-       (setq numbered company-tooltip-offset))
-     (let ((items (nreverse items)) new)
+     (let ((items (nreverse items))
+           (numbered (if company-show-numbers 0 99999))
+           new)
        (when previous
          (push (company--scrollpos-line previous width) new))
  
@@@ -2414,7 -2469,7 +2469,7 @@@ Returns a negative number if the toolti
               (end (save-excursion
                      (move-to-window-line (+ row (abs height)))
                      (point)))
-              (ov (make-overlay (if nl beg (1- beg)) end nil t t))
+              (ov (make-overlay (if nl beg (1- beg)) end nil t))
               (args (list (mapcar 'company-plainify
                                   (company-buffer-lines beg end))
                           column nl above)))
  (defun company-preview-show-at-point (pos)
    (company-preview-hide)
  
-   (setq company-preview-overlay (make-overlay pos pos))
    (let ((completion (nth company-selection company-candidates)))
      (setq completion (propertize completion 'face 'company-preview))
      (add-text-properties 0 (length company-common)
  
      (and (equal pos (point))
           (not (equal completion ""))
-          (add-text-properties 0 1 '(cursor t) completion))
-     (let ((ov company-preview-overlay))
-       (overlay-put ov 'after-string completion)
-       (overlay-put ov 'window (selected-window)))))
+          (add-text-properties 0 1 '(cursor 1) completion))
+     (let* ((beg pos)
+            (pto company-pseudo-tooltip-overlay)
+            (ptf-workaround (and
+                             pto
+                             (char-before pos)
+                             (eq pos (overlay-start pto)))))
+       ;; Try to accomodate for the pseudo-tooltip overlay,
+       ;; which may start at the same position if it's at eol.
+       (when ptf-workaround
+         (cl-decf beg)
+         (setq completion (concat (buffer-substring beg pos) completion)))
+       (setq company-preview-overlay (make-overlay beg pos))
+       (let ((ov company-preview-overlay))
+         (overlay-put ov (if ptf-workaround 'display 'after-string)
+                      completion)
+         (overlay-put ov 'window (selected-window))))))
  
  (defun company-preview-hide ()
    (when company-preview-overlay
index 0000000000000000000000000000000000000000,6d64a62207327059ccbeae2606607046740aa9d3..6d64a62207327059ccbeae2606607046740aa9d3
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,28 +1,28 @@@
+ ;;; all-tests.el --- company-mode tests  -*- lexical-binding: t -*-
+ ;; Copyright (C) 2015  Free Software Foundation, Inc.
+ ;; Author: Dmitry Gutov
+ ;; This file is part of GNU Emacs.
+ ;; GNU Emacs is free software: you can redistribute it and/or modify
+ ;; it under the terms of the GNU General Public License as published by
+ ;; the Free Software Foundation, either version 3 of the License, or
+ ;; (at your option) any later version.
+ ;; GNU Emacs is distributed in the hope that it will be useful,
+ ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ ;; GNU General Public License for more details.
+ ;; You should have received a copy of the GNU General Public License
+ ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+ (defvar company-test-path
+   (file-name-directory (or load-file-name buffer-file-name)))
+ (require 'ert)
+ (dolist (test-file (directory-files company-test-path t "-tests.el$"))
+   (load test-file nil t))
index 0000000000000000000000000000000000000000,5d8be3e837372f07c42b038467680f9aad920607..5d8be3e837372f07c42b038467680f9aad920607
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,161 +1,161 @@@
+ ;;; async-tests.el --- company-mode tests  -*- lexical-binding: t -*-
+ ;; Copyright (C) 2015  Free Software Foundation, Inc.
+ ;; Author: Dmitry Gutov
+ ;; This file is part of GNU Emacs.
+ ;; GNU Emacs is free software: you can redistribute it and/or modify
+ ;; it under the terms of the GNU General Public License as published by
+ ;; the Free Software Foundation, either version 3 of the License, or
+ ;; (at your option) any later version.
+ ;; GNU Emacs is distributed in the hope that it will be useful,
+ ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ ;; GNU General Public License for more details.
+ ;; You should have received a copy of the GNU General Public License
+ ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+ (require 'company-tests)
+ (defun company-async-backend (command &optional _)
+   (pcase command
+     (`prefix "foo")
+     (`candidates
+      (cons :async
+            (lambda (cb)
+              (run-with-timer 0.05 nil
+                              #'funcall cb '("abc" "abd")))))))
+ (ert-deftest company-call-backend-forces-sync ()
+   (let ((company-backend 'company-async-backend)
+         (company-async-timeout 0.1))
+     (should (equal '("abc" "abd") (company-call-backend 'candidates)))))
+ (ert-deftest company-call-backend-errors-on-timeout ()
+   (with-temp-buffer
+     (let* ((company-backend (lambda (command &optional _arg)
+                               (pcase command
+                                 (`candidates (cons :async 'ignore)))))
+            (company-async-timeout 0.1)
+            (err (should-error (company-call-backend 'candidates "foo"))))
+       (should (string-match-p "async timeout" (cadr err))))))
+ (ert-deftest company-call-backend-raw-passes-return-value-verbatim ()
+   (let ((company-backend 'company-async-backend))
+     (should (equal "foo" (company-call-backend-raw 'prefix)))
+     (should (equal :async (car (company-call-backend-raw 'candidates "foo"))))
+     (should (equal 'closure (cadr (company-call-backend-raw 'candidates "foo"))))))
+ (ert-deftest company-manual-begin-forces-async-candidates-to-sync ()
+   (with-temp-buffer
+     (company-mode)
+     (let (company-frontends
+           company-transformers
+           (company-backends (list 'company-async-backend)))
+       (company-manual-begin)
+       (should (equal "foo" company-prefix))
+       (should (equal '("abc" "abd") company-candidates)))))
+ (ert-deftest company-idle-begin-allows-async-candidates ()
+   (with-temp-buffer
+     (company-mode)
+     (let (company-frontends
+           company-transformers
+           (company-backends (list 'company-async-backend)))
+       (company-idle-begin (current-buffer) (selected-window)
+                           (buffer-chars-modified-tick) (point))
+       (should (null company-candidates))
+       (sleep-for 0.1)
+       (should (equal "foo" company-prefix))
+       (should (equal '("abc" "abd") company-candidates)))))
+ (ert-deftest company-idle-begin-cancels-async-candidates-if-buffer-changed ()
+   (with-temp-buffer
+     (company-mode)
+     (let (company-frontends
+           (company-backends (list 'company-async-backend)))
+       (company-idle-begin (current-buffer) (selected-window)
+                           (buffer-chars-modified-tick) (point))
+       (should (null company-candidates))
+       (insert "a")
+       (sleep-for 0.1)
+       (should (null company-candidates)))))
+ (ert-deftest company-idle-begin-async-allows-immediate-callbacks ()
+   (with-temp-buffer
+     (company-mode)
+     (let (company-frontends
+           (company-backends
+            (list (lambda (command &optional arg)
+                    (pcase command
+                      (`prefix (buffer-substring (point-min) (point)))
+                      (`candidates
+                       (let ((c (all-completions arg '("abc" "def"))))
+                         (cons :async
+                               (lambda (cb) (funcall cb c)))))
+                      (`no-cache t)))))
+           (company-minimum-prefix-length 0))
+       (company-idle-begin (current-buffer) (selected-window)
+                           (buffer-chars-modified-tick) (point))
+       (should (equal '("abc" "def") company-candidates))
+       (let ((last-command-event ?a))
+         (company-call 'self-insert-command 1))
+       (should (equal '("abc") company-candidates)))))
+ (ert-deftest company-multi-backend-forces-prefix-to-sync ()
+   (with-temp-buffer
+     (let ((company-backend (list 'ignore
+                                  (lambda (command)
+                                    (should (eq command 'prefix))
+                                    (cons :async
+                                          (lambda (cb)
+                                            (run-with-timer
+                                             0.01 nil
+                                             (lambda () (funcall cb nil))))))
+                                  (lambda (command)
+                                    (should (eq command 'prefix))
+                                    "foo"))))
+       (should (equal "foo" (company-call-backend-raw 'prefix))))
+     (let ((company-backend (list (lambda (_command)
+                                    (cons :async
+                                          (lambda (cb)
+                                            (run-with-timer
+                                             0.01 nil
+                                             (lambda () (funcall cb "bar"))))))
+                                  (lambda (_command)
+                                    "foo"))))
+       (should (equal "bar" (company-call-backend-raw 'prefix))))))
+ (ert-deftest company-multi-backend-merges-deferred-candidates ()
+   (with-temp-buffer
+     (let* ((immediate (lambda (command &optional _)
+                         (pcase command
+                           (`prefix "foo")
+                           (`candidates
+                            (cons :async
+                                  (lambda (cb) (funcall cb '("f"))))))))
+            (company-backend (list 'ignore
+                                   (lambda (command &optional arg)
+                                     (pcase command
+                                       (`prefix "foo")
+                                       (`candidates
+                                        (should (equal arg "foo"))
+                                        (cons :async
+                                              (lambda (cb)
+                                                (run-with-timer
+                                                 0.01 nil
+                                                 (lambda () (funcall cb '("a" "b")))))))))
+                                   (lambda (command &optional _)
+                                     (pcase command
+                                       (`prefix "foo")
+                                       (`candidates '("c" "d" "e"))))
+                                   immediate)))
+       (should (equal :async (car (company-call-backend-raw 'candidates "foo"))))
+       (should (equal '("a" "b" "c" "d" "e" "f")
+                      (company-call-backend 'candidates "foo")))
+       (let ((company-backend (list immediate)))
+         (should (equal '("f") (company-call-backend 'candidates "foo")))))))
index 0000000000000000000000000000000000000000,c8c03b7802140c65c18e6a952dec841620dc45e5..c8c03b7802140c65c18e6a952dec841620dc45e5
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,25 +1,25 @@@
+ (require 'company-tests)
+ (require 'company-clang)
+ (ert-deftest company-clang-objc-templatify ()
+   (with-temp-buffer
+     (let ((text "createBookWithTitle:andAuthor:"))
+       (insert text)
+       (company-clang-objc-templatify text)
+       (should (equal "createBookWithTitle:arg0 andAuthor:arg1" (buffer-string)))
+       (should (looking-at "arg0"))
+       (should (null (overlay-get (company-template-field-at) 'display))))))
+ (ert-deftest company-clang-simple-annotation ()
+   (let ((str (propertize
+               "foo" 'meta
+               "wchar_t * wmemchr(wchar_t *__p, wchar_t __c, size_t __n)")))
+     (should (equal (company-clang 'annotation str)
+                    "(wchar_t *__p, wchar_t __c, size_t __n)"))))
+ (ert-deftest company-clang-generic-annotation ()
+   (let ((str (propertize
+               "foo" 'meta
+               "shared_ptr<_Tp> make_shared<typename _Tp>(_Args &&__args...)")))
+     (should (equal (company-clang 'annotation str)
+                    "<typename _Tp>(_Args &&__args...)"))))
index 0000000000000000000000000000000000000000,13e547e3d36b15ac566ad3dcc9119ea675a7c580..13e547e3d36b15ac566ad3dcc9119ea675a7c580
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,481 +1,481 @@@
+ ;;; core-tests.el --- company-mode tests  -*- lexical-binding: t -*-
+ ;; Copyright (C) 2015  Free Software Foundation, Inc.
+ ;; Author: Dmitry Gutov
+ ;; This file is part of GNU Emacs.
+ ;; GNU Emacs is free software: you can redistribute it and/or modify
+ ;; it under the terms of the GNU General Public License as published by
+ ;; the Free Software Foundation, either version 3 of the License, or
+ ;; (at your option) any later version.
+ ;; GNU Emacs is distributed in the hope that it will be useful,
+ ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ ;; GNU General Public License for more details.
+ ;; You should have received a copy of the GNU General Public License
+ ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+ (require 'company-tests)
+ (ert-deftest company-good-prefix ()
+   (let ((company-minimum-prefix-length 5)
+         company-abort-manual-when-too-short
+         company--manual-action            ;idle begin
+         (company-selection-changed t))    ;has no effect
+     (should (eq t (company--good-prefix-p "!@#$%")))
+     (should (eq nil (company--good-prefix-p "abcd")))
+     (should (eq nil (company--good-prefix-p 'stop)))
+     (should (eq t (company--good-prefix-p '("foo" . 5))))
+     (should (eq nil (company--good-prefix-p '("foo" . 4))))
+     (should (eq t (company--good-prefix-p '("foo" . t))))))
+ (ert-deftest company--manual-prefix-set-and-unset ()
+   (with-temp-buffer
+     (insert "ab")
+     (company-mode)
+     (let (company-frontends
+           (company-backends
+            (list (lambda (command &optional _)
+                    (cl-case command
+                      (prefix (buffer-substring (point-min) (point)))
+                      (candidates '("abc" "abd")))))))
+       (company-manual-begin)
+       (should (equal "ab" company--manual-prefix))
+       (company-abort)
+       (should (null company--manual-prefix)))))
+ (ert-deftest company-abort-manual-when-too-short ()
+   (let ((company-minimum-prefix-length 5)
+         (company-abort-manual-when-too-short t)
+         (company-selection-changed t))    ;has not effect
+     (let ((company--manual-action nil))   ;idle begin
+       (should (eq t (company--good-prefix-p "!@#$%")))
+       (should (eq t (company--good-prefix-p '("foo" . 5))))
+       (should (eq t (company--good-prefix-p '("foo" . t)))))
+     (let ((company--manual-action t)
+           (company--manual-prefix "abc")) ;manual begin from this prefix
+       (should (eq t (company--good-prefix-p "!@#$")))
+       (should (eq nil (company--good-prefix-p "ab")))
+       (should (eq nil (company--good-prefix-p 'stop)))
+       (should (eq t (company--good-prefix-p '("foo" . 4))))
+       (should (eq t (company--good-prefix-p "abcd")))
+       (should (eq t (company--good-prefix-p "abc")))
+       (should (eq t (company--good-prefix-p '("bar" . t)))))))
+ (ert-deftest company-common-with-non-prefix-completion ()
+   (let ((company-backend #'ignore)
+         (company-prefix "abc")
+         company-candidates
+         company-candidates-length
+         company-candidates-cache
+         company-common)
+     (company-update-candidates '("abc" "def-abc"))
+     (should (null company-common))
+     (company-update-candidates '("abc" "abe-c"))
+     (should (null company-common))
+     (company-update-candidates '("abcd" "abcde" "abcdf"))
+     (should (equal "abcd" company-common))))
+ (ert-deftest company-multi-backend-with-lambdas ()
+   (let ((company-backend
+          (list (lambda (command &optional _ &rest _r)
+                  (cl-case command
+                    (prefix "z")
+                    (candidates '("a" "b"))))
+                (lambda (command &optional _ &rest _r)
+                  (cl-case command
+                    (prefix "z")
+                    (candidates '("c" "d")))))))
+     (should (equal (company-call-backend 'candidates "z") '("a" "b" "c" "d")))))
+ (ert-deftest company-multi-backend-filters-backends-by-prefix ()
+   (let ((company-backend
+          (list (lambda (command &optional _ &rest _r)
+                  (cl-case command
+                    (prefix (cons "z" t))
+                    (candidates '("a" "b"))))
+                (lambda (command &optional _ &rest _r)
+                  (cl-case command
+                    (prefix "t")
+                    (candidates '("c" "d"))))
+                (lambda (command &optional _ &rest _r)
+                  (cl-case command
+                    (prefix "z")
+                    (candidates '("e" "f")))))))
+     (should (equal (company-call-backend 'candidates "z") '("a" "b" "e" "f")))))
+ (ert-deftest company-multi-backend-remembers-candidate-backend ()
+   (let ((company-backend
+          (list (lambda (command &optional _)
+                  (cl-case command
+                    (ignore-case nil)
+                    (annotation "1")
+                    (candidates '("a" "c"))
+                    (post-completion "13")))
+                (lambda (command &optional _)
+                  (cl-case command
+                    (ignore-case t)
+                    (annotation "2")
+                    (candidates '("b" "d"))
+                    (post-completion "42")))
+                (lambda (command &optional _)
+                  (cl-case command
+                    (annotation "3")
+                    (candidates '("e"))
+                    (post-completion "74"))))))
+     (let ((candidates (company-calculate-candidates nil)))
+       (should (equal candidates '("a" "b" "c" "d" "e")))
+       (should (equal t (company-call-backend 'ignore-case)))
+       (should (equal "1" (company-call-backend 'annotation (nth 0 candidates))))
+       (should (equal "2" (company-call-backend 'annotation (nth 1 candidates))))
+       (should (equal "13" (company-call-backend 'post-completion (nth 2 candidates))))
+       (should (equal "42" (company-call-backend 'post-completion (nth 3 candidates))))
+       (should (equal "3" (company-call-backend 'annotation (nth 4 candidates))))
+       (should (equal "74" (company-call-backend 'post-completion (nth 4 candidates)))))))
+ (ert-deftest company-multi-backend-handles-keyword-with ()
+   (let ((primo (lambda (command &optional _)
+                  (cl-case command
+                    (prefix "a")
+                    (candidates '("abb" "abc" "abd")))))
+         (secundo (lambda (command &optional _)
+                    (cl-case command
+                      (prefix "a")
+                      (candidates '("acc" "acd"))))))
+     (let ((company-backend (list 'ignore 'ignore :with secundo)))
+       (should (null (company-call-backend 'prefix))))
+     (let ((company-backend (list 'ignore primo :with secundo)))
+       (should (equal "a" (company-call-backend 'prefix)))
+       (should (equal '("abb" "abc" "abd" "acc" "acd")
+                      (company-call-backend 'candidates "a"))))))
+ (ert-deftest company-begin-backend-failure-doesnt-break-company-backends ()
+   (with-temp-buffer
+     (insert "a")
+     (company-mode)
+     (should-error
+      (company-begin-backend #'ignore))
+     (let (company-frontends
+           (company-backends
+            (list (lambda (command &optional _)
+                    (cl-case command
+                      (prefix "a")
+                      (candidates '("a" "ab" "ac")))))))
+       (let (this-command)
+         (company-call 'complete))
+       (should (eq 3 company-candidates-length)))))
+ (ert-deftest company-require-match-explicit ()
+   (with-temp-buffer
+     (insert "ab")
+     (company-mode)
+     (let (company-frontends
+           (company-require-match 'company-explicit-action-p)
+           (company-backends
+            (list (lambda (command &optional _)
+                    (cl-case command
+                      (prefix (buffer-substring (point-min) (point)))
+                      (candidates '("abc" "abd")))))))
+       (let (this-command)
+         (company-complete))
+       (let ((last-command-event ?e))
+         (company-call 'self-insert-command 1))
+       (should (eq 2 company-candidates-length))
+       (should (eq 3 (point))))))
+ (ert-deftest company-dont-require-match-when-idle ()
+   (with-temp-buffer
+     (insert "ab")
+     (company-mode)
+     (let (company-frontends
+           (company-minimum-prefix-length 2)
+           (company-require-match 'company-explicit-action-p)
+           (company-backends
+            (list (lambda (command &optional _)
+                    (cl-case command
+                      (prefix (buffer-substring (point-min) (point)))
+                      (candidates '("abc" "abd")))))))
+       (company-idle-begin (current-buffer) (selected-window)
+                           (buffer-chars-modified-tick) (point))
+       (should (eq 2 company-candidates-length))
+       (let ((last-command-event ?e))
+         (company-call 'self-insert-command 1))
+       (should (eq nil company-candidates-length))
+       (should (eq 4 (point))))))
+ (ert-deftest company-dont-require-match-if-was-a-match-and-old-prefix-ended ()
+   (with-temp-buffer
+     (insert "ab")
+     (company-mode)
+     (let (company-frontends
+           company-auto-complete
+           (company-require-match t)
+           (company-backends
+            (list (lambda (command &optional _)
+                    (cl-case command
+                      (prefix (company-grab-word))
+                      (candidates '("abc" "ab" "abd"))
+                      (sorted t))))))
+       (let (this-command)
+         (company-complete))
+       (let ((last-command-event ?e))
+         (company-call 'self-insert-command 1))
+       (should (eq 3 company-candidates-length))
+       (should (eq 3 (point)))
+       (let ((last-command-event ? ))
+         (company-call 'self-insert-command 1))
+       (should (null company-candidates-length))
+       (should (eq 4 (point))))))
+ (ert-deftest company-dont-require-match-if-was-a-match-and-new-prefix-is-stop ()
+   (with-temp-buffer
+     (company-mode)
+     (insert "c")
+     (let (company-frontends
+           (company-require-match t)
+           (company-backends
+            (list (lambda (command &optional _)
+                    (cl-case command
+                      (prefix (if (> (point) 2)
+                                  'stop
+                                (buffer-substring (point-min) (point))))
+                      (candidates '("a" "b" "c")))))))
+       (let (this-command)
+         (company-complete))
+       (should (eq 3 company-candidates-length))
+       (let ((last-command-event ?e))
+         (company-call 'self-insert-command 1))
+       (should (not company-candidates)))))
+ (ert-deftest company-should-complete-whitelist ()
+   (with-temp-buffer
+     (insert "ab")
+     (company-mode)
+     (let (company-frontends
+           company-begin-commands
+           (company-backends
+            (list (lambda (command &optional _)
+                    (cl-case command
+                      (prefix (buffer-substring (point-min) (point)))
+                      (candidates '("abc" "abd")))))))
+       (let ((company-continue-commands nil))
+         (let (this-command)
+           (company-complete))
+         (company-call 'backward-delete-char 1)
+         (should (null company-candidates-length)))
+       (let ((company-continue-commands '(backward-delete-char)))
+         (let (this-command)
+           (company-complete))
+         (company-call 'backward-delete-char 1)
+         (should (eq 2 company-candidates-length))))))
+ (ert-deftest company-should-complete-blacklist ()
+   (with-temp-buffer
+     (insert "ab")
+     (company-mode)
+     (let (company-frontends
+           company-begin-commands
+           (company-backends
+            (list (lambda (command &optional _)
+                    (cl-case command
+                      (prefix (buffer-substring (point-min) (point)))
+                      (candidates '("abc" "abd")))))))
+       (let ((company-continue-commands '(not backward-delete-char)))
+         (let (this-command)
+           (company-complete))
+         (company-call 'backward-delete-char 1)
+         (should (null company-candidates-length)))
+       (let ((company-continue-commands '(not backward-delete-char-untabify)))
+         (let (this-command)
+           (company-complete))
+         (company-call 'backward-delete-char 1)
+         (should (eq 2 company-candidates-length))))))
+ (ert-deftest company-auto-complete-explicit ()
+   (with-temp-buffer
+     (insert "ab")
+     (company-mode)
+     (let (company-frontends
+           (company-auto-complete 'company-explicit-action-p)
+           (company-auto-complete-chars '(? ))
+           (company-backends
+            (list (lambda (command &optional _)
+                    (cl-case command
+                      (prefix (buffer-substring (point-min) (point)))
+                      (candidates '("abcd" "abef")))))))
+       (let (this-command)
+         (company-complete))
+       (let ((last-command-event ? ))
+         (company-call 'self-insert-command 1))
+       (should (string= "abcd " (buffer-string))))))
+ (ert-deftest company-no-auto-complete-when-idle ()
+   (with-temp-buffer
+     (insert "ab")
+     (company-mode)
+     (let (company-frontends
+           (company-auto-complete 'company-explicit-action-p)
+           (company-auto-complete-chars '(? ))
+           (company-minimum-prefix-length 2)
+           (company-backends
+            (list (lambda (command &optional _)
+                    (cl-case command
+                      (prefix (buffer-substring (point-min) (point)))
+                      (candidates '("abcd" "abef")))))))
+       (company-idle-begin (current-buffer) (selected-window)
+                           (buffer-chars-modified-tick) (point))
+       (let ((last-command-event ? ))
+         (company-call 'self-insert-command 1))
+       (should (string= "ab " (buffer-string))))))
+ (ert-deftest company-clears-explicit-action-when-no-matches ()
+   (with-temp-buffer
+     (company-mode)
+     (let (company-frontends
+           company-backends)
+       (company-call 'manual-begin) ;; fails
+       (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 _)
+                    (cl-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 "A") ; 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 _)
+                    (cl-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-backends
+            (list (lambda (command &optional _)
+                    (cl-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))))))
+ (defvar ct-sorted nil)
+ (defun ct-equal-including-properties (list1 list2)
+   (or (and (not list1) (not list2))
+       (and (ert-equal-including-properties (car list1) (car list2))
+            (ct-equal-including-properties (cdr list1) (cdr list2)))))
+ (ert-deftest company-strips-duplicates-within-groups ()
+   (let* ((kvs '(("a" . "b")
+                 ("a" . nil)
+                 ("a" . "b")
+                 ("a" . "c")
+                 ("a" . "b")
+                 ("b" . "c")
+                 ("b" . nil)
+                 ("a" . "b")))
+          (fn (lambda (kvs)
+                (mapcar (lambda (kv) (propertize (car kv) 'ann (cdr kv)))
+                        kvs)))
+          (company-backend
+           (lambda (command &optional arg)
+             (pcase command
+               (`prefix "")
+               (`sorted ct-sorted)
+               (`duplicates t)
+               (`annotation (get-text-property 0 'ann arg)))))
+          (reference '(("a" . "b")
+                       ("a" . nil)
+                       ("a" . "c")
+                       ("b" . "c")
+                       ("b" . nil)
+                       ("a" . "b"))))
+     (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))))))
+ ;;; Row and column
+ (ert-deftest company-column-with-composition ()
+   :tags '(interactive)
+   (with-temp-buffer
+     (save-window-excursion
+       (set-window-buffer nil (current-buffer))
+       (insert "lambda ()")
+       (compose-region 1 (1+ (length "lambda")) "\\")
+       (should (= (company--column) 4)))))
+ (ert-deftest company-column-with-line-prefix ()
+   :tags '(interactive)
+   (with-temp-buffer
+     (save-window-excursion
+       (set-window-buffer nil (current-buffer))
+       (insert "foo")
+       (put-text-property (point-min) (point) 'line-prefix "  ")
+       (should (= (company--column) 5)))))
+ (ert-deftest company-column-with-line-prefix-on-empty-line ()
+   :tags '(interactive)
+   (with-temp-buffer
+     (save-window-excursion
+       (set-window-buffer nil (current-buffer))
+       (insert "\n")
+       (forward-char -1)
+       (put-text-property (point-min) (point-max) 'line-prefix "  ")
+       (should (= (company--column) 2)))))
+ (ert-deftest company-column-with-tabs ()
+   :tags '(interactive)
+   (with-temp-buffer
+     (save-window-excursion
+       (set-window-buffer nil (current-buffer))
+       (insert "|\t|\t|\t(")
+       (let ((tab-width 8))
+         (should (= (company--column) 25))))))
+ (ert-deftest company-row-with-header-line-format ()
+   :tags '(interactive)
+   (with-temp-buffer
+     (save-window-excursion
+       (set-window-buffer nil (current-buffer))
+       (should (= (company--row) 0))
+       (setq header-line-format "aaaaaaa")
+       (should (= (company--row) 0)))))
index 9b7cba33379bda942d69cf1bfc8ac158548881c2,7fd02dee48725b4bad6c5425267edc0aac0a3fe0..7fd02dee48725b4bad6c5425267edc0aac0a3fe0
@@@ -1,6 -1,6 +1,6 @@@
- ;;; company-elisp-tests.el --- company-elisp tests
+ ;;; elisp-tests.el --- company-elisp tests
  
- ;; Copyright (C) 2013-2014  Free Software Foundation, Inc.
+ ;; Copyright (C) 2013-2015  Free Software Foundation, Inc.
  
  ;; Author: Dmitry Gutov
  
  ;; You should have received a copy of the GNU General Public License
  ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
  
- ;;; Commentary:
- ;;
  ;;; Code:
  
+ (require 'company-tests)
  (require 'company-elisp)
  
  (defmacro company-elisp-with-buffer (contents &rest body)
index 0000000000000000000000000000000000000000,a10f91461f2c6ef2a4e65640ef97c8a08a8091d7..a10f91461f2c6ef2a4e65640ef97c8a08a8091d7
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,298 +1,298 @@@
+ ;;; frontends-tests.el --- company-mode tests  -*- lexical-binding: t -*-
+ ;; Copyright (C) 2015  Free Software Foundation, Inc.
+ ;; Author: Dmitry Gutov
+ ;; This file is part of GNU Emacs.
+ ;; GNU Emacs is free software: you can redistribute it and/or modify
+ ;; it under the terms of the GNU General Public License as published by
+ ;; the Free Software Foundation, either version 3 of the License, or
+ ;; (at your option) any later version.
+ ;; GNU Emacs is distributed in the hope that it will be useful,
+ ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ ;; GNU General Public License for more details.
+ ;; You should have received a copy of the GNU General Public License
+ ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+ (require 'company-tests)
+ (ert-deftest company-pseudo-tooltip-does-not-get-displaced ()
+   :tags '(interactive)
+   (with-temp-buffer
+     (save-window-excursion
+       (set-window-buffer nil (current-buffer))
+       (save-excursion (insert " ff"))
+       (company-mode)
+       (let ((company-frontends '(company-pseudo-tooltip-frontend))
+             (company-begin-commands '(self-insert-command))
+             (company-backends
+              (list (lambda (c &optional _)
+                      (cl-case c (prefix "") (candidates '("a" "b" "c")))))))
+         (let (this-command)
+           (company-call 'complete))
+         (company-call 'open-line 1)
+         (should (eq 1 (overlay-start company-pseudo-tooltip-overlay)))))))
+ (ert-deftest company-pseudo-tooltip-show ()
+   :tags '(interactive)
+   (with-temp-buffer
+     (save-window-excursion
+     (set-window-buffer nil (current-buffer))
+     (insert "aaaa\n  bb\nccccccc\nddd")
+     (search-backward "bb")
+     (let ((col (company--column))
+           (company-candidates-length 2)
+           (company-candidates '("123" "45"))
+           (company-backend 'ignore))
+       (company-pseudo-tooltip-show (company--row) col 0)
+       (let ((ov company-pseudo-tooltip-overlay))
+         ;; With margins.
+         (should (eq (overlay-get ov 'company-width) 5))
+         ;; FIXME: Make it 2?
+         (should (eq (overlay-get ov 'company-height) company-tooltip-limit))
+         (should (eq (overlay-get ov 'company-column) col))
+         (should (string= (overlay-get ov 'company-display)
+                          "\n  123 \nc 45  c\nddd\n")))))))
+ (ert-deftest company-pseudo-tooltip-edit-updates-width ()
+   :tags '(interactive)
+   (with-temp-buffer
+     (set-window-buffer nil (current-buffer))
+     (let ((company-candidates-length 5)
+           (company-candidates '("123" "45" "67" "89" "1011"))
+           (company-backend 'ignore)
+           (company-tooltip-limit 4)
+           (company-tooltip-offset-display 'scrollbar))
+       (company-pseudo-tooltip-show (company--row)
+                                    (company--column)
+                                    0)
+       (should (eq (overlay-get company-pseudo-tooltip-overlay 'company-width)
+                   6))
+       (company-pseudo-tooltip-edit 4)
+       (should (eq (overlay-get company-pseudo-tooltip-overlay 'company-width)
+                   7)))))
+ (ert-deftest company-preview-show-with-annotations ()
+   :tags '(interactive)
+   (with-temp-buffer
+     (save-window-excursion
+       (set-window-buffer nil (current-buffer))
+       (save-excursion (insert "\n"))
+       (let ((company-candidates-length 1)
+             (company-candidates '("123")))
+         (company-preview-show-at-point (point))
+         (let* ((ov company-preview-overlay)
+                (str (overlay-get ov 'after-string)))
+           (should (string= str "123"))
+           (should (eq (get-text-property 0 'cursor str) 1)))))))
+ (ert-deftest company-pseudo-tooltip-show-with-annotations ()
+   :tags '(interactive)
+   (with-temp-buffer
+     (save-window-excursion
+       (set-window-buffer nil (current-buffer))
+       (insert " ")
+       (save-excursion (insert "\n"))
+       (let ((company-candidates-length 2)
+             (company-backend (lambda (action &optional arg &rest _ignore)
+                                (when (eq action 'annotation)
+                                  (cdr (assoc arg '(("123" . "(4)")))))))
+             (company-candidates '("123" "45"))
+             company-tooltip-align-annotations)
+         (company-pseudo-tooltip-show-at-point (point) 0)
+         (let ((ov company-pseudo-tooltip-overlay))
+           ;; With margins.
+           (should (eq (overlay-get ov 'company-width) 8))
+           (should (string= (overlay-get ov 'company-display)
+                            "\n 123(4) \n 45     \n")))))))
+ (ert-deftest company-pseudo-tooltip-show-with-annotations-right-aligned ()
+   :tags '(interactive)
+   (with-temp-buffer
+     (save-window-excursion
+       (set-window-buffer nil (current-buffer))
+       (insert " ")
+       (save-excursion (insert "\n"))
+       (let ((company-candidates-length 3)
+             (company-backend (lambda (action &optional arg &rest _ignore)
+                                (when (eq action 'annotation)
+                                  (cdr (assoc arg '(("123" . "(4)")
+                                                    ("67" . "(891011)")))))))
+             (company-candidates '("123" "45" "67"))
+             (company-tooltip-align-annotations t))
+         (company-pseudo-tooltip-show-at-point (point) 0)
+         (let ((ov company-pseudo-tooltip-overlay))
+           ;; With margins.
+           (should (eq (overlay-get ov 'company-width) 13))
+           (should (string= (overlay-get ov 'company-display)
+                            "\n 123     (4) \n 45          \n 67 (891011) \n")))))))
+ (ert-deftest company-create-lines-shows-numbers ()
+   (let ((company-show-numbers t)
+         (company-candidates '("x" "y" "z"))
+         (company-candidates-length 3)
+         (company-backend 'ignore))
+     (should (equal '(" x 1 " " y 2 " " z 3 ")
+                    (company--create-lines 0 999)))))
+ (ert-deftest company-create-lines-truncates-annotations ()
+   (let* ((ww (company--window-width))
+          (data `(("1" . "(123)")
+                  ("2" . nil)
+                  ("3" . ,(concat "(" (make-string (- ww 2) ?4) ")"))
+                  (,(make-string ww ?4) . "<4>")))
+          (company-candidates (mapcar #'car data))
+          (company-candidates-length 4)
+          (company-tooltip-margin 1)
+          (company-backend (lambda (cmd &optional arg)
+                             (when (eq cmd 'annotation)
+                               (cdr (assoc arg data)))))
+          company-tooltip-align-annotations)
+     (should (equal (list (format " 1(123)%s " (company-space-string (- ww 8)))
+                          (format " 2%s " (company-space-string (- ww 3)))
+                          (format " 3(444%s " (make-string (- ww 7) ?4))
+                          (format " %s " (make-string (- ww 2) ?4)))
+                    (company--create-lines 0 999)))
+     (let ((company-tooltip-align-annotations t))
+       (should (equal (list (format " 1%s(123) " (company-space-string (- ww 8)))
+                            (format " 2%s " (company-space-string (- ww 3)))
+                            (format " 3 (444%s " (make-string (- ww 8) ?4))
+                            (format " %s " (make-string (- ww 2) ?4)))
+                      (company--create-lines 0 999))))))
+ (ert-deftest company-create-lines-truncates-common-part ()
+   (let* ((ww (company--window-width))
+          (company-candidates-length 2)
+          (company-tooltip-margin 1)
+          (company-backend #'ignore))
+     (let* ((company-common (make-string (- ww 3) ?1))
+            (company-candidates `(,(concat company-common "2")
+                                  ,(concat company-common "3"))))
+       (should (equal (list (format " %s2 " (make-string (- ww 3) ?1))
+                            (format " %s3 " (make-string (- ww 3) ?1)))
+                      (company--create-lines 0 999))))
+     (let* ((company-common (make-string (- ww 2) ?1))
+            (company-candidates `(,(concat company-common "2")
+                                  ,(concat company-common "3"))))
+       (should (equal (list (format " %s " company-common)
+                            (format " %s " company-common))
+                      (company--create-lines 0 999))))
+     (let* ((company-common (make-string ww ?1))
+            (company-candidates `(,(concat company-common "2")
+                                  ,(concat company-common "3")))
+            (res (company--create-lines 0 999)))
+       (should (equal (list (format " %s " (make-string (- ww 2) ?1))
+                            (format " %s " (make-string (- ww 2) ?1)))
+                      res))
+       (should (eq 'company-tooltip-common-selection
+                     (get-text-property (- ww 2) 'face
+                                        (car res))))
+       (should (eq 'company-tooltip-selection
+                   (get-text-property (1- ww) 'face
+                                      (car res))))
+       )))
+ (ert-deftest company-create-lines-clears-out-non-printables ()
+   :tags '(interactive)
+   (let (company-show-numbers
+         (company-candidates (list
+                              (decode-coding-string "avalis\351e" 'utf-8)
+                              "avatar"))
+         (company-candidates-length 2)
+         (company-backend 'ignore))
+     (should (equal '(" avalis‗e "
+                      " avatar   ")
+                    (company--create-lines 0 999)))))
+ (ert-deftest company-create-lines-handles-multiple-width ()
+   :tags '(interactive)
+   (let (company-show-numbers
+         (company-candidates '("蛙蛙蛙蛙" "蛙abc"))
+         (company-candidates-length 2)
+         (company-backend 'ignore))
+     (should (equal '(" 蛙蛙蛙蛙 "
+                      " 蛙abc    ")
+                    (company--create-lines 0 999)))))
+ (ert-deftest company-create-lines-handles-multiple-width-in-annotation ()
+   (let* (company-show-numbers
+          (alist '(("a" . " ︸") ("b" . " ︸︸")))
+          (company-candidates (mapcar #'car alist))
+          (company-candidates-length 2)
+          (company-backend (lambda (c &optional a)
+                             (when (eq c 'annotation)
+                               (assoc-default a alist)))))
+     (should (equal '(" a ︸   "
+                      " b ︸︸ ")
+                    (company--create-lines 0 999)))))
+ (ert-deftest company-column-with-composition ()
+   :tags '(interactive)
+   (with-temp-buffer
+     (save-window-excursion
+       (set-window-buffer nil (current-buffer))
+       (insert "lambda ()")
+       (compose-region 1 (1+ (length "lambda")) "\\")
+       (should (= (company--column) 4)))))
+ (ert-deftest company-plainify ()
+   (let ((tab-width 8))
+     (should (equal-including-properties
+              (company-plainify "\tabc\td\t")
+              (concat "        "
+                      "abc     "
+                      "d       "))))
+   (should (equal-including-properties
+            (company-plainify (propertize "foobar" 'line-prefix "-*-"))
+            "-*-foobar")))
+ (ert-deftest company-buffer-lines-with-lines-folded ()
+   :tags '(interactive)
+   (with-temp-buffer
+     (insert (propertize "aaa\nbbb\nccc\nddd\n" 'display "aaa+\n"))
+     (insert "eee\nfff\nggg")
+     (should (equal (company-buffer-lines (point-min) (point-max))
+                    '("aaa" "eee" "fff" "ggg")))))
+ (ert-deftest company-buffer-lines-with-multiline-display ()
+   :tags '(interactive)
+   (with-temp-buffer
+     (insert (propertize "a" 'display "bbb\nccc\ndddd\n"))
+     (insert "eee\nfff\nggg")
+     (should (equal (company-buffer-lines (point-min) (point-max))
+                    '("" "" "" "eee" "fff" "ggg")))))
+ (ert-deftest company-buffer-lines-with-multiline-after-string-at-eob ()
+   :tags '(interactive)
+   (with-temp-buffer
+     (insert "a\nb\nc\n")
+     (let ((ov (make-overlay (point-max) (point-max) nil t t)))
+       (overlay-put ov 'after-string "~\n~\n~"))
+     (should (equal (company-buffer-lines (point-min) (point-max))
+                    '("a" "b" "c")))))
+ (ert-deftest company-modify-line ()
+   (let ((str "-*-foobar"))
+     (should (equal-including-properties
+              (company-modify-line str "zz" 4)
+              "-*-fzzbar"))
+     (should (equal-including-properties
+              (company-modify-line str "xx" 0)
+              "xx-foobar"))
+     (should (equal-including-properties
+              (company-modify-line str "zz" 10)
+              "-*-foobar zz"))))
+ (ert-deftest company-scrollbar-bounds ()
+   (should (equal nil (company--scrollbar-bounds 0 3 3)))
+   (should (equal nil (company--scrollbar-bounds 0 4 3)))
+   (should (equal '(0 . 0) (company--scrollbar-bounds 0 1 2)))
+   (should (equal '(1 . 1) (company--scrollbar-bounds 2 2 4)))
+   (should (equal '(2 . 3) (company--scrollbar-bounds 7 4 12)))
+   (should (equal '(1 . 2) (company--scrollbar-bounds 3 4 12)))
+   (should (equal '(1 . 3) (company--scrollbar-bounds 4 5 11))))
index 0000000000000000000000000000000000000000,05843b26aa981e6de7c0c45190be2ed5be7b294a..05843b26aa981e6de7c0c45190be2ed5be7b294a
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,32 +1,32 @@@
+ ;;; keywords-tests.el --- company-keywords tests  -*- lexical-binding: t -*-
+ ;; Copyright (C) 2011, 2013-2015  Free Software Foundation, Inc.
+ ;; Author: Nikolaj Schumacher
+ ;; This file is part of GNU Emacs.
+ ;; GNU Emacs is free software: you can redistribute it and/or modify
+ ;; it under the terms of the GNU General Public License as published by
+ ;; the Free Software Foundation, either version 3 of the License, or
+ ;; (at your option) any later version.
+ ;; GNU Emacs is distributed in the hope that it will be useful,
+ ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ ;; GNU General Public License for more details.
+ ;; You should have received a copy of the GNU General Public License
+ ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+ (require 'company-keywords)
+ (ert-deftest company-sorted-keywords ()
+   "Test that keywords in `company-keywords-alist' are in alphabetical order."
+   (dolist (pair company-keywords-alist)
+     (when (consp (cdr pair))
+       (let ((prev (cadr pair)))
+         (dolist (next (cddr pair))
+           (should (not (equal prev next)))
+           (should (string< prev next))
+           (setq prev next))))))
index 0000000000000000000000000000000000000000,09548c4234e857c05098bfd81fc8584583ee5e35..09548c4234e857c05098bfd81fc8584583ee5e35
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,91 +1,91 @@@
+ ;;; template-tests.el --- company-mode tests  -*- lexical-binding: t -*-
+ ;; Copyright (C) 2015  Free Software Foundation, Inc.
+ ;; Author: Dmitry Gutov
+ ;; This file is part of GNU Emacs.
+ ;; GNU Emacs is free software: you can redistribute it and/or modify
+ ;; it under the terms of the GNU General Public License as published by
+ ;; the Free Software Foundation, either version 3 of the License, or
+ ;; (at your option) any later version.
+ ;; GNU Emacs is distributed in the hope that it will be useful,
+ ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ ;; GNU General Public License for more details.
+ ;; You should have received a copy of the GNU General Public License
+ ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+ (require 'company-tests)
+ (require 'company-template)
+ (ert-deftest company-template-removed-after-the-last-jump ()
+   (with-temp-buffer
+     (insert "{ }")
+     (goto-char 2)
+     (let ((tpl (company-template-declare-template (point) (1- (point-max)))))
+       (save-excursion
+         (dotimes (_ 2)
+           (insert " ")
+           (company-template-add-field tpl (point) "foo")))
+       (company-call 'template-forward-field)
+       (should (= 3 (point)))
+       (company-call 'template-forward-field)
+       (should (= 7 (point)))
+       (company-call 'template-forward-field)
+       (should (= 11 (point)))
+       (should (zerop (length (overlay-get tpl 'company-template-fields))))
+       (should (null (overlay-buffer tpl))))))
+ (ert-deftest company-template-removed-after-input-and-jump ()
+   (with-temp-buffer
+     (insert "{ }")
+     (goto-char 2)
+     (let ((tpl (company-template-declare-template (point) (1- (point-max)))))
+       (save-excursion
+         (insert " ")
+         (company-template-add-field tpl (point) "bar"))
+       (company-call 'template-move-to-first tpl)
+       (should (= 3 (point)))
+       (dolist (c (string-to-list "tee"))
+         (let ((last-command-event c))
+           (company-call 'self-insert-command 1)))
+       (should (string= "{ tee }" (buffer-string)))
+       (should (overlay-buffer tpl))
+       (company-call 'template-forward-field)
+       (should (= 7 (point)))
+       (should (null (overlay-buffer tpl))))))
+ (ert-deftest company-template-c-like-templatify ()
+   (with-temp-buffer
+     (let ((text "foo(int a, short b)"))
+       (insert text)
+       (company-template-c-like-templatify text)
+       (should (equal "foo(arg0, arg1)" (buffer-string)))
+       (should (looking-at "arg0"))
+       (should (equal "int a"
+                      (overlay-get (company-template-field-at) 'display))))))
+ (ert-deftest company-template-c-like-templatify-trims-after-closing-paren ()
+   (with-temp-buffer
+     (let ((text "foo(int a, short b)!@ #1334 a"))
+       (insert text)
+       (company-template-c-like-templatify text)
+       (should (equal "foo(arg0, arg1)" (buffer-string)))
+       (should (looking-at "arg0")))))
+ (ert-deftest company-template-c-like-templatify-generics ()
+   (with-temp-buffer
+     (let ((text "foo<TKey, TValue>(int i, Dict<TKey, TValue>, long l)"))
+       (insert text)
+       (company-template-c-like-templatify text)
+       (should (equal "foo<arg0, arg1>(arg2, arg3, arg4)" (buffer-string)))
+       (should (looking-at "arg0"))
+       (should (equal "TKey" (overlay-get (company-template-field-at) 'display)))
+       (search-forward "arg3")
+       (forward-char -1)
+       (should (equal "Dict<TKey, TValue>"
+                      (overlay-get (company-template-field-at) 'display))))))
index 0000000000000000000000000000000000000000,4d027e5d55360ee6abf9e377b8e6458dec8ff4ea..4d027e5d55360ee6abf9e377b8e6458dec8ff4ea
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,58 +1,58 @@@
+ ;;; transformers-tests.el --- company-mode tests  -*- lexical-binding: t -*-
+ ;; Copyright (C) 2015  Free Software Foundation, Inc.
+ ;; Author: Dmitry Gutov
+ ;; This file is part of GNU Emacs.
+ ;; GNU Emacs is free software: you can redistribute it and/or modify
+ ;; it under the terms of the GNU General Public License as published by
+ ;; the Free Software Foundation, either version 3 of the License, or
+ ;; (at your option) any later version.
+ ;; GNU Emacs is distributed in the hope that it will be useful,
+ ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ ;; GNU General Public License for more details.
+ ;; You should have received a copy of the GNU General Public License
+ ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+ (require 'company-tests)
+ (ert-deftest company-occurrence-prefer-closest-above ()
+   (with-temp-buffer
+     (save-window-excursion
+       (set-window-buffer nil (current-buffer))
+       (insert "foo0
+ foo1
+ ")
+       (save-excursion
+         (insert "
+ foo3
+ foo2"))
+       (let ((company-backend 'company-dabbrev)
+             (company-occurrence-weight-function
+              'company-occurrence-prefer-closest-above))
+         (should (equal '("foo1" "foo0" "foo3" "foo2" "foo4")
+                        (company-sort-by-occurrence
+                         '("foo0" "foo1" "foo2" "foo3" "foo4"))))))))
+ (ert-deftest company-occurrence-prefer-any-closest ()
+   (with-temp-buffer
+     (save-window-excursion
+       (set-window-buffer nil (current-buffer))
+       (insert "foo0
+ foo1
+ ")
+       (save-excursion
+         (insert "
+ foo3
+ foo2"))
+       (let ((company-backend 'company-dabbrev)
+             (company-occurrence-weight-function
+              'company-occurrence-prefer-any-closest))
+         (should (equal '("foo1" "foo3" "foo0" "foo2" "foo4")
+                        (company-sort-by-occurrence
+                         '("foo0" "foo1" "foo2" "foo3" "foo4"))))))))