]> code.delx.au - gnu-emacs-elpa/commitdiff
Merge commit '51c140ca9ee32d27cacc7b2b07d4539bf98ae575' from company-master
authorDmitry Gutov <dgutov@yandex.ru>
Sat, 19 Apr 2014 10:11:04 +0000 (14:11 +0400)
committerDmitry Gutov <dgutov@yandex.ru>
Sat, 19 Apr 2014 10:11:04 +0000 (14:11 +0400)
Conflicts:
packages/company/company-pysmell.el

30 files changed:
1  2 
packages/company/.travis.yml
packages/company/Makefile
packages/company/NEWS.md
packages/company/company-abbrev.el
packages/company/company-bbdb.el
packages/company/company-capf.el
packages/company/company-clang.el
packages/company/company-cmake.el
packages/company/company-css.el
packages/company/company-dabbrev-code.el
packages/company/company-dabbrev.el
packages/company/company-eclim.el
packages/company/company-elisp-tests.el
packages/company/company-elisp.el
packages/company/company-etags.el
packages/company/company-files.el
packages/company/company-gtags.el
packages/company/company-ispell.el
packages/company/company-keywords.el
packages/company/company-nxml.el
packages/company/company-oddmuse.el
packages/company/company-pysmell.el
packages/company/company-ropemacs.el
packages/company/company-semantic.el
packages/company/company-template.el
packages/company/company-tempo.el
packages/company/company-tests.el
packages/company/company-xcode.el
packages/company/company-yasnippet.el
packages/company/company.el

index cdf55d1ec01fceb8f10e3bed7c0c3cbe8bdb7a89,11d7fd48291546a4008079bf1797ab5b00589cd8..11d7fd48291546a4008079bf1797ab5b00589cd8
@@@ -4,25 -4,19 +4,19 @@@ language: emacs-lis
  
  env:
    matrix:
-     - EMACS=emacs23
      - EMACS=emacs24
      - EMACS=emacs-snapshot
  
  install:
-   - if [ "$EMACS" = "emacs23" ]; then
-         sudo apt-get update -qq &&
-         sudo apt-get install -qq emacs23-gtk emacs23-el;
-     fi
    - if [ "$EMACS" = "emacs24" ]; then
          sudo add-apt-repository -y ppa:cassou/emacs &&
          sudo apt-get update -qq &&
          sudo apt-get install -qq emacs24 emacs24-el;
      fi
    - if [ "$EMACS" = "emacs-snapshot" ]; then
-         sudo add-apt-repository -y ppa:cassou/emacs &&
+         sudo add-apt-repository -y ppa:ubuntu-elisp/ppa &&
          sudo apt-get update -qq &&
-         sudo apt-get install -qq emacs-snapshot &&
-         sudo apt-get install -qq emacs-snapshot-el emacs-snapshot-gtk;
+         sudo apt-get install -qq emacs-snapshot;
      fi
  
  before_script:
index 2602191aa7e4f709960fc0a49a860a9c15f45c0e,4d7a9ad1c3cbaac6d37483a9915e0d0671c5201e..4d7a9ad1c3cbaac6d37483a9915e0d0671c5201e
@@@ -22,11 -22,11 +22,11 @@@ clean
        @rm -rf company-*/ company-*.tar company-*.tar.bz2 *.elc ert.el
  
  test:
-       ${EMACS} -Q -nw -L . -l company-tests.el \
+       ${EMACS} -Q -nw -L . -l company-tests.el -l company-elisp-tests.el \
        --eval "(let (pop-up-windows) (ert t))"
  
  test-batch:
-       ${EMACS} -Q --batch -L . -l company-tests.el \
+       ${EMACS} -Q --batch -L . -l company-tests.el -l company-elisp-tests.el \
        --eval "(ert-run-tests-batch-and-exit '(not (tag interactive)))"
  
  downloads:
diff --combined packages/company/NEWS.md
index b72f53455fff656b3caf36004754487f3fd3af17,97dc2849d558b0c962c407523293201f987a355a..97dc2849d558b0c962c407523293201f987a355a
@@@ -1,5 -1,19 +1,19 @@@
  # History of user-visible changes
  
+ ## 2014-04-19 (0.8.0)
+ * `company-capf` is included in `company-backends` in any supported Emacs
+   version (>= 24.1). `company-elisp` goes before it if Emacs version is < 24.4.
+ * New user option `company-clang-insert-arguments`, by default t.
+ * Default value of `company-idle-delay` lowered to `0.5`.
+ * New user option `company-tooltip-minimum-width`, by default 0.
+ * New function `company-grab-symbol-cons`.
+ * `company-clang` fetches completion candidates asynchronously.
+ * Added support for asynchronous back-ends (experimental).
+ * Support for back-end command `crop` dropped (it was never documented).
+ * Support for Emacs 23 dropped.
+ * New user option `company-abort-manual-when-too-short`.
  ## 2014-03-25 (0.7.3)
  
  * New user option `company-etags-ignore-case`.
index 0c4e327bc46baef1983269ae4267a33d616fbdac,a454aaa90d277c2d3950b7a5177969152fa2090f..a454aaa90d277c2d3950b7a5177969152fa2090f
@@@ -26,7 -26,7 +26,7 @@@
  ;;; Code:
  
  (require 'company)
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  (require 'abbrev)
  
  (defun company-abbrev-insert (match)
@@@ -37,7 -37,7 +37,7 @@@
  (defun company-abbrev (command &optional arg &rest ignored)
    "`company-mode' completion back-end for abbrev."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-abbrev
                                          'company-abbrev-insert))
      (prefix (company-grab-symbol))
index 8e4705f73910437c958d04e50d5a659c42def25b,acdd30ac14922aeb683bb1e14984cd3202736c06..acdd30ac14922aeb683bb1e14984cd3202736c06
@@@ -20,7 -20,7 +20,7 @@@
  ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
  
  (require 'company)
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  
  (declare-function bbdb-record-get-field "bbdb")
  (declare-function bbdb-records "bbdb")
  (defun company-bbdb (command &optional arg &rest ignore)
    "`company-mode' completion back-end for `bbdb'."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-bbdb))
      (prefix (and (eq major-mode 'message-mode)
                   (featurep 'bbdb-com)
                   (looking-back "^\\(To\\|Cc\\|Bcc\\):.*"
                                 (line-beginning-position))
                   (company-grab-symbol)))
-     (candidates (mapcan (lambda (record)
-                           (mapcar (lambda (mail) (bbdb-dwim-mail record mail))
-                                   (bbdb-record-get-field record 'mail)))
-                         (bbdb-search (bbdb-records) arg nil arg)))
+     (candidates (cl-mapcan (lambda (record)
+                              (mapcar (lambda (mail) (bbdb-dwim-mail record mail))
+                                      (bbdb-record-get-field record 'mail)))
+                            (bbdb-search (bbdb-records) arg nil arg)))
      (sorted t)
      (no-cache t)))
  
index 17be772126736ab282b2524fd509c8cc190a9c7f,3aaeb137a8000550d61b5be4388651cb6a775235..3aaeb137a8000550d61b5be4388651cb6a775235
@@@ -25,7 -25,7 +25,7 @@@
  
  ;;; Code:
  
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  
  (defvar company--capf-data nil)
  (make-variable-buffer-local 'company--capf-data)
  (defun company--capf-data ()
    ;; Ignore tags-completion-at-point-function because it subverts company-etags
    ;; in the default value of company-backends, where the latter comes later.
-   (letf* (((default-value 'completion-at-point-functions) nil)
-           (data (run-hook-wrapped 'completion-at-point-functions
-                                   ;; Ignore misbehaving functions.
-                                   #'completion--capf-wrapper 'optimist)))
+   (cl-letf* (((default-value 'completion-at-point-functions) nil)
+              (data (run-hook-wrapped 'completion-at-point-functions
+                                      ;; Ignore misbehaving functions.
+                                      #'completion--capf-wrapper 'optimist)))
      (when (and (consp (cdr data)) (numberp (nth 1 data))) data)))
  
  (defun company-capf (command &optional arg &rest _args)
-   "`company-mode' back-end using `completion-at-point-functions'.
- Requires Emacs 24.1 or newer."
+   "`company-mode' back-end using `completion-at-point-functions'."
    (interactive (list 'interactive))
    (pcase command
      (`interactive (company-begin-backend 'company-capf))
index 787ecef6eaa6e87d88115a099e72e3002cb06dcb,4f0f3189eb45e4db3c6e9d86f50817b79bb1dee8..4f0f3189eb45e4db3c6e9d86f50817b79bb1dee8
@@@ -1,6 -1,6 +1,6 @@@
- ;;; company-clang.el --- company-mode completion back-end for Clang
+ ;;; company-clang.el --- company-mode completion back-end for Clang  -*- lexical-binding: t -*-
  
- ;; Copyright (C) 2009, 2011, 2013  Free Software Foundation, Inc.
+ ;; Copyright (C) 2009, 2011, 2013-2014  Free Software Foundation, Inc.
  
  ;; Author: Nikolaj Schumacher
  
@@@ -27,7 -27,7 +27,7 @@@
  
  (require 'company)
  (require 'company-template)
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  
  (defgroup company-clang nil
    "Completion back-end for Clang."
@@@ -60,6 -60,9 +60,9 @@@ or automatically through a custom `comp
  (defvar company-clang-modes '(c-mode c++-mode objc-mode)
    "Major modes which clang may complete.")
  
+ (defcustom company-clang-insert-arguments t
+   "When non-nil, insert function arguments as a template after completion.")
  ;; prefix ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
  (defvar company-clang--prefix nil)
  (defconst company-clang--completion-pattern
    "^COMPLETION: \\_<\\(%s[a-zA-Z0-9_:]*\\)\\(?: : \\(.*\\)$\\)?$")
  
- (defconst company-clang--error-buffer-name "*clang error*")
+ (defconst company-clang--error-buffer-name "*clang-error*")
  
  (defun company-clang--lang-option ()
       (if (eq major-mode 'objc-mode)
               "objective-c" "objective-c++")
         (substring (symbol-name major-mode) 0 -5)))
  
- (defun company-clang--parse-output (prefix objc)
+ (defun company-clang--parse-output (prefix _objc)
    (goto-char (point-min))
    (let ((pattern (format company-clang--completion-pattern
                           (regexp-quote prefix)))
          (setq buffer-read-only t)
          (goto-char (point-min))))))
  
- (defun company-clang--call-process (prefix &rest args)
+ (defun company-clang--start-process (prefix callback &rest args)
    (let ((objc (derived-mode-p 'objc-mode))
-         (buf (get-buffer-create "*clang-output*"))
-         res)
+         (buf (get-buffer-create "*clang-output*")))
      (with-current-buffer buf (erase-buffer))
-     (setq res (if (company-clang--auto-save-p)
-                   (apply 'call-process company-clang-executable nil buf nil args)
-                 (apply 'call-process-region (point-min) (point-max)
-                        company-clang-executable nil buf nil args)))
-     (with-current-buffer buf
-       (unless (eq 0 res)
-         (company-clang--handle-error res args))
-       ;; Still try to get any useful input.
-       (company-clang--parse-output prefix objc))))
+     (if (get-buffer-process buf)
+         (funcall callback nil)
+       (let ((process (apply #'start-process "company-clang" buf
+                             company-clang-executable args)))
+         (set-process-sentinel
+          process
+          (lambda (proc status)
+            (unless (string-match-p "hangup" status)
+              (funcall
+               callback
+               (let ((res (process-exit-status proc)))
+                 (with-current-buffer buf
+                   (unless (eq 0 res)
+                     (company-clang--handle-error res args))
+                   ;; Still try to get any useful input.
+                   (company-clang--parse-output prefix objc)))))))
+         (unless (company-clang--auto-save-p)
+           (send-region process (point-min) (point-max))
+           (send-string process "\n")
+           (process-send-eof process))))))
  
  (defsubst company-clang--build-location (pos)
    (save-excursion
            (list (company-clang--build-location pos))
            (list (if (company-clang--auto-save-p) buffer-file-name "-"))))
  
- (defun company-clang--candidates (prefix)
+ (defun company-clang--candidates (prefix callback)
    (and (company-clang--auto-save-p)
         (buffer-modified-p)
         (basic-save-buffer))
    (when (null company-clang--prefix)
      (company-clang-set-prefix (or (funcall company-clang-prefix-guesser)
                                    'none)))
-   (apply 'company-clang--call-process
+   (apply 'company-clang--start-process
           prefix
+          callback
           (company-clang--build-complete-args (- (point) (length prefix)))))
  
  (defun company-clang--prefix ()
-   (let ((symbol (company-grab-symbol)))
-     (if symbol
-         (if (and company-clang-begin-after-member-access
-                  (save-excursion
-                    (forward-char (- (length symbol)))
-                    (looking-back "\\.\\|->\\|::" (- (point) 2))))
-             (cons symbol t)
-           symbol)
-       'stop)))
+   (if company-clang-begin-after-member-access
+       (company-grab-symbol-cons "\\.\\|->\\|::" 2)
+     (company-grab-symbol)))
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
            (if (< (point) end)
                (insert " ")
              (throw 'stop t))
-           (incf cnt))))
+           (cl-incf cnt))))
      (company-template-move-to-first templ)))
  
  (defun company-clang (command &optional arg &rest ignored)
@@@ -288,7 -296,7 +296,7 @@@ With Clang versions before 2.9, we hav
  performing completion.  With Clang 2.9 and later, buffer contents are
  passed via standard input."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-clang))
      (init (when (memq major-mode company-clang-modes)
              (unless company-clang-executable
                   buffer-file-name
                   company-clang-executable
                   (not (company-in-string-or-comment))
-                  (company-clang--prefix)))
-     (candidates (company-clang--candidates arg))
+                  (or (company-clang--prefix) 'stop)))
+     (candidates (cons :async
+                       (lambda (cb) (company-clang--candidates arg cb))))
      (meta       (company-clang--meta arg))
      (annotation (company-clang--annotation arg))
      (post-completion (let ((anno (company-clang--annotation arg)))
-                        (when anno
+                        (when (and company-clang-insert-arguments anno)
                           (insert anno)
                           (if (string-match ":" anno)
                               (company-clang-objc-templatify anno)
index 34359dc7ab011a1e0a9b298cfcd66e8fa29c9136,a466f60b7a75b5abdad3ec06a4fd3e367ca9a46f..a466f60b7a75b5abdad3ec06a4fd3e367ca9a46f
@@@ -25,8 -25,8 +25,8 @@@
  
  ;;; Code:
  
- (eval-when-compile (require 'cl))
  (require 'company)
+ (require 'cl-lib)
  
  (defgroup company-cmake nil
    "Completion back-end for CMake."
@@@ -112,7 -112,7 +112,7 @@@ They affect which types of symbols we g
    "`company-mode' completion back-end for CMake.
  CMake is a cross-platform, open-source make system."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-cmake))
      (init (when (memq major-mode company-cmake-modes)
              (unless company-cmake-executable
index 11e195adabdf2c03584be1d63826a8a8a1224d98,c4154c2ec4efa85847d4d289c0e354cc22c0b8d5..c4154c2ec4efa85847d4d289c0e354cc22c0b8d5
@@@ -24,7 -24,7 +24,7 @@@
  ;;; Code:
  
  (require 'company)
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  
  (defconst company-css-property-alist
    ;; see http://www.w3.org/TR/CSS21/propidx.html
@@@ -280,7 -280,7 +280,7 @@@ Returns \"\" if no property found, but 
  (defun company-css (command &optional arg &rest ignored)
    "`company-mode' completion back-end for `css-mode'."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-css))
      (prefix (and (derived-mode-p 'css-mode)
                   (or (company-grab company-css-tag-regexp 1)
index 6f827cd50d7e71bb8ee250f7651829774203f809,1039e4a66d192e511bc5e989f3067b564d4a0c6f..1039e4a66d192e511bc5e989f3067b564d4a0c6f
@@@ -27,7 -27,7 +27,7 @@@
  
  (require 'company)
  (require 'company-dabbrev)
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  
  (defgroup company-dabbrev-code nil
    "dabbrev-like completion back-end for code."
@@@ -80,7 -80,7 +80,7 @@@ See also `company-dabbrev-code-time-lim
  The back-end looks for all symbols in the current buffer that aren't in
  comments or strings."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-dabbrev-code))
      (prefix (and (or (eq t company-dabbrev-code-modes)
                       (apply 'derived-mode-p company-dabbrev-code-modes))
index c0cd0e0ab6818ee0150a4a4b9d75492a38fb34cf,401fcc9181f5391ebcdae07f20b37aedfdc78b0d..401fcc9181f5391ebcdae07f20b37aedfdc78b0d
@@@ -26,7 -26,7 +26,7 @@@
  ;;; Code:
  
  (require 'company)
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  
  (defgroup company-dabbrev nil
    "dabbrev-like completion back-end."
@@@ -73,7 -73,7 +73,7 @@@ If you set this value to nil, you may a
         (while ,test
           ,@body
           (and ,limit
-               (eq (incf company-time-limit-while-counter) 25)
+               (eq (cl-incf company-time-limit-while-counter) 25)
                (setq company-time-limit-while-counter 0)
                (> (float-time (time-since ,start)) ,limit)
                (throw 'done 'company-time-out))))))
           (symbols (company-dabbrev--search-buffer regexp (point) nil start limit
                                                    ignore-comments)))
      (when other-buffers
-       (dolist (buffer (delq (current-buffer) (buffer-list)))
+       (cl-dolist (buffer (delq (current-buffer) (buffer-list)))
          (and (or (eq other-buffers 'all)
                   (eq (buffer-local-value 'major-mode buffer) major-mode))
               (with-current-buffer buffer
                                                       limit ignore-comments))))
          (and limit
               (> (float-time (time-since start)) limit)
-              (return))))
+              (cl-return))))
      symbols))
  
  ;;;###autoload
  (defun company-dabbrev (command &optional arg &rest ignored)
    "dabbrev-like `company-mode' completion back-end."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-dabbrev))
      (prefix (company-grab-word))
      (candidates
index d6f699a9d4de055effc43717ea4ff828c823c804,0eaf38228675de1d41467a7a2e32c986f2197037..0eaf38228675de1d41467a7a2e32c986f2197037
@@@ -32,7 -32,7 +32,7 @@@
  
  (require 'company)
  (require 'company-template)
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  
  (defgroup company-eclim nil
    "Completion back-end for Eclim."
  
  (defun company-eclim-executable-find ()
    (let (file)
-     (dolist (eclipse-root '("/Applications/eclipse" "/usr/lib/eclipse"
+     (cl-dolist (eclipse-root '("/Applications/eclipse" "/usr/lib/eclipse"
                              "/usr/local/lib/eclipse"))
        (and (file-exists-p (setq file (expand-file-name "plugins" eclipse-root)))
             (setq file (car (last (directory-files file t "^org.eclim_"))))
             (file-exists-p (setq file (expand-file-name "bin/eclim" file)))
-            (return file)))))
+            (cl-return file)))))
  
  (defcustom company-eclim-executable
    (or (executable-find "eclim") (company-eclim-executable-find))
@@@ -92,7 -92,7 +92,7 @@@ eclim can only complete correctly when 
        (setq company-eclim--project-dir
              (directory-file-name
               (expand-file-name
-               (company-locate-dominating-file buffer-file-name ".project"))))
+               (locate-dominating-file buffer-file-name ".project"))))
      company-eclim--project-dir))
  
  (defun company-eclim--project-name ()
        (let ((dir (company-eclim--project-dir)))
          (when dir
            (setq company-eclim--project-name
-                 (loop for project in (company-eclim--project-list)
-                       when (equal (cdr (assoc 'path project)) dir)
-                       return (cdr (assoc 'name project))))))))
+                 (cl-loop for project in (company-eclim--project-list)
+                          when (equal (cdr (assoc 'path project)) dir)
+                          return (cdr (assoc 'name project))))))))
  
  (defun company-eclim--candidates (prefix)
    (interactive "d")
        (all-completions prefix completions))))
  
  (defun company-eclim--search-point (prefix)
-   (if (or (plusp (length prefix)) (eq (char-before) ?.))
+   (if (or (cl-plusp (length prefix)) (eq (char-before) ?.))
        (1- (point))
      (point)))
  
@@@ -163,7 -163,7 +163,7 @@@ Eclim version 1.7.13 or newer (?) is re
  Completions only work correctly when the buffer has been saved.
  `company-eclim-auto-save' determines whether to do this automatically."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-eclim))
      (prefix (and (derived-mode-p 'java-mode 'jde-mode)
                   buffer-file-name
index 0000000000000000000000000000000000000000,9b7cba33379bda942d69cf1bfc8ac158548881c2..9b7cba33379bda942d69cf1bfc8ac158548881c2
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,193 +1,193 @@@
+ ;;; company-elisp-tests.el --- company-elisp tests
+ ;; Copyright (C) 2013-2014  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/>.
+ ;;; Commentary:
+ ;;
+ ;;; Code:
+ (require 'company-elisp)
+ (defmacro company-elisp-with-buffer (contents &rest body)
+   (declare (indent 0))
+   `(with-temp-buffer
+      (insert ,contents)
+      (setq major-mode 'emacs-lisp-mode)
+      (re-search-backward "|")
+      (replace-match "")
+      (let ((company-elisp-detect-function-context t))
+        ,@body)))
+ (ert-deftest company-elisp-candidates-predicate ()
+   (company-elisp-with-buffer
+     "(foo ba|)"
+     (should (eq (company-elisp--candidates-predicate "ba")
+                 'boundp))
+     (should (eq (let (company-elisp-detect-function-context)
+                   (company-elisp--candidates-predicate "ba"))
+                 'company-elisp--predicate)))
+   (company-elisp-with-buffer
+     "(foo| )"
+     (should (eq (company-elisp--candidates-predicate "foo")
+                 'fboundp))
+     (should (eq (let (company-elisp-detect-function-context)
+                   (company-elisp--candidates-predicate "foo"))
+                 'company-elisp--predicate)))
+   (company-elisp-with-buffer
+     "(foo 'b|)"
+     (should (eq (company-elisp--candidates-predicate "b")
+                 'company-elisp--predicate))))
+ (ert-deftest company-elisp-candidates-predicate-in-docstring ()
+   (company-elisp-with-buffer
+    "(def foo () \"Doo be doo `ide|"
+    (should (eq 'company-elisp--predicate
+                (company-elisp--candidates-predicate "ide")))))
+ ;; This one's also an integration test.
+ (ert-deftest company-elisp-candidates-recognizes-binding-form ()
+   (let ((company-elisp-detect-function-context t)
+         (obarray [when what whelp])
+         (what 1)
+         (whelp 2)
+         (wisp 3))
+     (company-elisp-with-buffer
+       "(let ((foo 7) (wh| )))"
+       (should (equal '("what" "whelp")
+                      (company-elisp-candidates "wh"))))
+     (company-elisp-with-buffer
+       "(cond ((null nil) (wh| )))"
+       (should (equal '("when")
+                      (company-elisp-candidates "wh"))))))
+ (ert-deftest company-elisp-candidates-predicate-binding-without-value ()
+   (cl-loop for (text prefix predicate) in '(("(let (foo|" "foo" boundp)
+                                             ("(let (foo (bar|" "bar" boundp)
+                                             ("(let (foo) (bar|" "bar" fboundp))
+            do
+            (eval `(company-elisp-with-buffer
+                    ,text
+                    (should (eq ',predicate
+                                (company-elisp--candidates-predicate ,prefix)))))))
+ (ert-deftest company-elisp-finds-vars ()
+   (let ((obarray [boo bar baz backquote])
+         (boo t)
+         (bar t)
+         (baz t))
+     (should (equal '("bar" "baz")
+                    (company-elisp--globals "ba" 'boundp)))))
+ (ert-deftest company-elisp-finds-functions ()
+   (let ((obarray [when what whelp])
+         (what t)
+         (whelp t))
+     (should (equal '("when")
+                    (company-elisp--globals "wh" 'fboundp)))))
+ (ert-deftest company-elisp-finds-things ()
+   (let ((obarray [when what whelp])
+         (what t)
+         (whelp t))
+     (should (equal '("what" "whelp" "when")
+                    (sort (company-elisp--globals "wh" 'company-elisp--predicate)
+                          'string<)))))
+ (ert-deftest company-elisp-locals-vars ()
+   (company-elisp-with-buffer
+     "(let ((foo 5) (bar 6))
+        (cl-labels ((borg ()))
+          (lambda (boo baz)
+            b|)))"
+     (should (equal '("bar" "baz" "boo")
+                    (company-elisp--locals "b" nil)))))
+ (ert-deftest company-elisp-locals-single-var ()
+   (company-elisp-with-buffer
+     "(dotimes (itk 100)
+        (dolist (item items)
+          it|))"
+     (should (equal '("itk" "item")
+                    (company-elisp--locals "it" nil)))))
+ (ert-deftest company-elisp-locals-funs ()
+   (company-elisp-with-buffer
+     "(cl-labels ((foo ())
+                  (fee ()))
+        (let ((fun 4))
+          (f| )))"
+     (should (equal '("fee" "foo")
+                    (sort (company-elisp--locals "f" t) 'string<)))))
+ (ert-deftest company-elisp-locals-skips-current-varlist ()
+   (company-elisp-with-buffer
+     "(let ((foo 1)
+            (f| )))"
+     (should (null (company-elisp--locals "f" nil)))))
+ (ert-deftest company-elisp-show-locals-first ()
+   (company-elisp-with-buffer
+     "(let ((floo 1)
+            (flop 2)
+            (flee 3))
+        fl|)"
+     (let ((obarray [float-pi]))
+       (let (company-elisp-show-locals-first)
+         (should (eq nil (company-elisp 'sorted))))
+       (let ((company-elisp-show-locals-first t))
+         (should (eq t (company-elisp 'sorted)))
+         (should (equal '("flee" "floo" "flop" "float-pi")
+                        (company-elisp-candidates "fl")))))))
+ (ert-deftest company-elisp-candidates-no-duplicates ()
+   (company-elisp-with-buffer
+     "(let ((float-pi 4))
+        f|)"
+     (let ((obarray [float-pi])
+           (company-elisp-show-locals-first t))
+       (should (equal '("float-pi") (company-elisp-candidates "f"))))))
+ (ert-deftest company-elisp-shouldnt-complete-defun-name ()
+   (company-elisp-with-buffer
+     "(defun foob|)"
+     (should (null (company-elisp 'prefix)))))
+ (ert-deftest company-elisp-should-complete-def-call ()
+   (company-elisp-with-buffer
+     "(defu|"
+     (should (equal "defu" (company-elisp 'prefix)))))
+ (ert-deftest company-elisp-should-complete-in-defvar ()
+   ;; It will also complete the var name, at least for now.
+   (company-elisp-with-buffer
+     "(defvar abc de|"
+     (should (equal "de" (company-elisp 'prefix)))))
+ (ert-deftest company-elisp-shouldnt-complete-in-defun-arglist ()
+   (company-elisp-with-buffer
+     "(defsubst foobar (ba|"
+     (should (null (company-elisp 'prefix)))))
+ (ert-deftest company-elisp-prefix-in-defun-body ()
+   (company-elisp-with-buffer
+     "(defun foob ()|)"
+     (should (equal "" (company-elisp 'prefix)))))
index 0ea4c69403f67739b9071e971b5a235541b70695,5efd8d051e2104e803bfdb4bbd5ad161011b3c32..5efd8d051e2104e803bfdb4bbd5ad161011b3c32
@@@ -26,7 -26,7 +26,7 @@@
  ;;; Code:
  
  (require 'company)
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  (require 'help-mode)
  (require 'find-func)
  
@@@ -131,14 -131,14 +131,14 @@@ first in the candidates list.
                              (when (looking-at "[ \t\n]*(")
                                (down-list 1))
                              (when (looking-at regexp)
-                               (pushnew (match-string-no-properties 1) res)))
+                               (cl-pushnew (match-string-no-properties 1) res)))
                            (forward-sexp))
                        (scan-error nil)))
                     ((unless functions-p
                        (looking-at company-elisp-var-binding-regexp-1))
                      (down-list 1)
                      (when (looking-at regexp)
-                       (pushnew (match-string-no-properties 1) res)))))))))
+                       (cl-pushnew (match-string-no-properties 1) res)))))))))
        (scan-error nil))
      res))
  
    (let* ((predicate (company-elisp--candidates-predicate prefix))
           (locals (company-elisp--locals prefix (eq predicate 'fboundp)))
           (globals (company-elisp--globals prefix predicate))
-          (locals (loop for local in locals
-                        when (not (member local globals))
-                        collect local)))
+          (locals (cl-loop for local in locals
+                           when (not (member local globals))
+                           collect local)))
      (if company-elisp-show-locals-first
          (append (sort locals 'string<)
                  (sort globals 'string<))
  (defun company-elisp (command &optional arg &rest ignored)
    "`company-mode' completion back-end for Emacs Lisp."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-elisp))
      (prefix (and (derived-mode-p 'emacs-lisp-mode 'inferior-emacs-lisp-mode)
                   (company-elisp--prefix)))
index 0c84458a1b8f278e035a05678a3c8339d9b4d86e,8634103fe9f346df1c15819dd3294f93bec90e36..8634103fe9f346df1c15819dd3294f93bec90e36
@@@ -25,8 -25,8 +25,8 @@@
  
  ;;; Code:
  
- (eval-when-compile (require 'cl))
  (require 'company)
+ (require 'cl-lib)
  (require 'etags)
  
  (defgroup company-etags nil
@@@ -51,9 -51,9 +51,9 @@@ buffer automatically.
  (make-variable-buffer-local 'company-etags-buffer-table)
  
  (defun company-etags-find-table ()
-   (let ((file (company-locate-dominating-file (or buffer-file-name
-                                                   default-directory)
-                                               "TAGS")))
+   (let ((file (locate-dominating-file (or buffer-file-name
+                                           default-directory)
+                                       "TAGS")))
      (when file
        (list (expand-file-name file)))))
  
@@@ -76,7 -76,7 +76,7 @@@
  (defun company-etags (command &optional arg &rest ignored)
    "`company-mode' completion back-end for etags."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-etags))
      (prefix (and (apply 'derived-mode-p company-etags-modes)
                   (not (company-in-string-or-comment))
index b897e3d3751404b358652bfa00f6b3ed247a0816,a839f799ee5cafe6ab3a167f50baeb628d9de174..a839f799ee5cafe6ab3a167f50baeb628d9de174
@@@ -26,7 -26,7 +26,7 @@@
  ;;; Code:
  
  (require 'company)
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  
  (defun company-files-directory-files (dir prefix)
    (ignore-errors
@@@ -45,9 -45,9 +45,9 @@@
  (defun company-files-grab-existing-name ()
    ;; Grab file names with spaces, only when they include quotes.
    (let (file dir)
-     (and (dolist (regexp company-files-regexps)
+     (and (cl-dolist (regexp company-files-regexps)
             (when (setq file (company-grab-line regexp 1))
-              (return file)))
+              (cl-return file)))
           (setq dir (file-name-directory file))
           (not (string-match "//" dir))
           (file-exists-p dir)
@@@ -78,7 -78,7 +78,7 @@@
  (defun company-files (command &optional arg &rest ignored)
    "`company-mode' completion back-end existing file names."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-files))
      (prefix (company-files-grab-existing-name))
      (candidates (company-files-complete arg))
index 6b4e399420618407c57d2f0eb05ec1981f75fe14,0ae98d7d62e0d66a33327c27a816398b980056de..0ae98d7d62e0d66a33327c27a816398b980056de
@@@ -26,7 -26,7 +26,7 @@@
  ;;; Code:
  
  (require 'company)
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  
  (defgroup company-gtags nil
    "Completion back-end for GNU Global."
@@@ -49,7 -49,7 +49,7 @@@
  (defun company-gtags--tags-available-p ()
    (if (eq company-gtags--tags-available-p 'unknown)
        (setq company-gtags--tags-available-p
-             (company-locate-dominating-file buffer-file-name "GTAGS"))
+             (locate-dominating-file buffer-file-name "GTAGS"))
      company-gtags--tags-available-p))
  
  (defun company-gtags-fetch-tags (prefix)
@@@ -75,7 -75,7 +75,7 @@@
  (defun company-gtags (command &optional arg &rest ignored)
    "`company-mode' completion back-end for GNU Global."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-gtags))
      (prefix (and company-gtags-executable
                   (memq major-mode company-gtags-modes)
index 3e599f03e51fee11468c71f2c5b9724134617ba5,1561beef1a1b62e633c79ae4451c5a53d8fa1be8..1561beef1a1b62e633c79ae4451c5a53d8fa1be8
@@@ -26,8 -26,8 +26,8 @@@
  ;;; Code:
  
  (require 'company)
+ (require 'cl-lib)
  (require 'ispell)
- (eval-when-compile (require 'cl))
  
  (defgroup company-ispell nil
    "Completion back-end using Ispell."
@@@ -56,7 -56,7 +56,7 @@@ If nil, use `ispell-complete-word-dict'
  (defun company-ispell (command &optional arg &rest ignored)
    "`company-mode' completion back-end using Ispell."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-ispell))
      (prefix (when (company-ispell-available)
                (company-grab-word)))
index 461fdf6b04ec4b506073c945a7e7c952224bd737,c700af769bee7b235ae94f2dfa160092d6e5cdb7..c700af769bee7b235ae94f2dfa160092d6e5cdb7
@@@ -26,7 -26,7 +26,7 @@@
  ;;; Code:
  
  (require 'company)
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  
  (defun company-keywords-upper-lower (&rest lst)
    ;; Upcase order is different for _.
  (defun company-keywords (command &optional arg &rest ignored)
    "`company-mode' back-end for programming language keywords."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-keywords))
      (prefix (and (assq major-mode company-keywords-alist)
                   (not (company-in-string-or-comment))
index 62e6e31543af65d2a6df2fdff4b2b6987821c677,70e1c096bf31b561d403a5ade0d22187c5e10b3f..70e1c096bf31b561d403a5ade0d22187c5e10b3f
@@@ -26,7 -26,7 +26,7 @@@
  ;;; Code:
  
  (require 'company)
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  
  (defvar rng-open-elements)
  (defvar rng-validate-mode)
@@@ -76,7 -76,7 +76,7 @@@
         ,@body)))
  
  (defun company-nxml-tag (command &optional arg &rest ignored)
-   (case command
+   (cl-case command
      (prefix (and (derived-mode-p 'nxml-mode)
                   rng-validate-mode
                   (company-grab company-nxml-in-tag-name-regexp 1)))
@@@ -86,7 -86,7 +86,7 @@@
      (sorted t)))
  
  (defun company-nxml-attribute (command &optional arg &rest ignored)
-   (case command
+   (cl-case command
      (prefix (and (derived-mode-p 'nxml-mode)
                   rng-validate-mode
                   (memq (char-after) '(?\  ?\t ?\n)) ;; outside word
@@@ -99,7 -99,7 +99,7 @@@
      (sorted t)))
  
  (defun company-nxml-attribute-value (command &optional arg &rest ignored)
-   (case command
+   (cl-case command
      (prefix (and (derived-mode-p 'nxml-mode)
                   rng-validate-mode
                   (and (memq (char-after) '(?' ?\" ?\  ?\t ?\n)) ;; outside word
  (defun company-nxml (command &optional arg &rest ignored)
    "`company-mode' completion back-end for `nxml-mode'."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-nxml))
      (prefix (or (company-nxml-tag 'prefix)
                  (company-nxml-attribute 'prefix)
index 358d5ea9258333584c8b82488904d635ac2d4dc7,aa30f2a296794456d2c717b934f5710d138d5f00..aa30f2a296794456d2c717b934f5710d138d5f00
@@@ -26,7 -26,7 +26,7 @@@
  ;;; Code:
  
  (require 'company)
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  (eval-when-compile (require 'yaooddmuse nil t))
  (eval-when-compile (require 'oddmuse nil t))
  
@@@ -34,7 -34,7 +34,7 @@@
    "\\(\\<[A-Z][[:alnum:]]*\\>\\)\\|\\[\\[\\([[:alnum:]]+\\>\\|\\)")
  
  (defun company-oddmuse-get-page-table ()
-   (case major-mode
+   (cl-case major-mode
      (yaoddmuse-mode (with-no-warnings
                        (yaoddmuse-get-pagename-table yaoddmuse-wikiname)))
      (oddmuse-mode (with-no-warnings
@@@ -44,7 -44,7 +44,7 @@@
  (defun company-oddmuse (command &optional arg &rest ignored)
    "`company-mode' completion back-end for `oddmuse-mode'."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-oddmuse))
      (prefix (let ((case-fold-search nil))
                (and (memq major-mode '(oddmuse-mode yaoddmuse-mode))
index 5c44f06aafa799a522dcfac1546f8e6776d31f50,d9cf86b0fb9b5bb0b829c6d633342fea0e83b4a3..2f22bf0f53d5d1501d27220b4260f7eb65220952
@@@ -1,6 -1,6 +1,6 @@@
  ;;; company-pysmell.el --- company-mode completion back-end for pysmell.el
  
- ;; Copyright (C) 2009-2011, 2013  Free Software Foundation, Inc.
 -;; Copyright (C) 2009-2011  Free Software Foundation, Inc.
++;; Copyright (C) 2009-2011, 2013-2014  Free Software Foundation, Inc.
  
  ;; Author: Nikolaj Schumacher
  
@@@ -27,8 -27,8 +27,8 @@@
  
  ;;; Code:
  
- (eval-when-compile (require 'cl))
 -(require 'pysmell)
 +(if t (require 'pysmell))               ;Don't load during compilation.
+ (require 'cl-lib)
  
  (defvar company-pysmell--available-p 'unknown)
  (make-variable-buffer-local 'company-pysmell--available-p)
@@@ -36,7 -36,7 +36,7 @@@
  (defun company-pysmell--available-p ()
    (if (eq company-pysmell--available-p 'unknown)
        (setq company-pysmell--available-p
-             (company-locate-dominating-file buffer-file-name "PYSMELLTAGS"))
+             (locate-dominating-file buffer-file-name "PYSMELLTAGS"))
      company-pysmell--available-p))
  
  (defun company-pysmell--grab-symbol ()
@@@ -56,7 -56,7 +56,7 @@@
    "`company-mode' completion back-end for pysmell.
  This requires pysmell.el and pymacs.el."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-pysmell))
      (prefix (and (derived-mode-p 'python-mode)
                   buffer-file-name
index 0ba26e68b2a8f8ee6b0ca3801c3c7fc564bc59db,677c4536bc59aff209b3d44b7e867fcf521e123b..677c4536bc59aff209b3d44b7e867fcf521e123b
@@@ -25,7 -25,7 +25,7 @@@
  
  ;;; Code:
  
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  
  (defun company-ropemacs--grab-symbol ()
    (let ((symbol (company-grab-symbol)))
@@@ -58,7 -58,7 +58,7 @@@
  Depends on third-party code: Pymacs (both Python and Emacs packages),
  rope, ropemacs and ropemode."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (init (when (and (derived-mode-p 'python-mode)
                       (not (fboundp 'rope-completions)))
              (require 'pymacs)
index 372a6f6c9e60ba93f007043568a3489b4d87a433,110d4fd8946adf0bb26994609bc0fca324067700..110d4fd8946adf0bb26994609bc0fca324067700
@@@ -26,7 -26,7 +26,7 @@@
  ;;; Code:
  
  (require 'company)
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  
  (defvar semantic-idle-summary-function)
  (declare-function semantic-documentation-for-tag "semantic/doc" )
@@@ -121,7 -121,7 +121,7 @@@ Symbols are chained by \".\" or \"->\".
  (defun company-semantic (command &optional arg &rest ignored)
    "`company-mode' completion back-end using CEDET Semantic."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-semantic))
      (prefix (and (featurep 'semantic)
                   (semantic-active-p)
index ab180166ca00ef7d66c02088b483adf34e4d88fb,d689183b97099b202174fcf5551bc669c578213b..d689183b97099b202174fcf5551bc669c578213b
@@@ -21,7 -21,7 +21,7 @@@
  
  ;;; Code:
  
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  
  (defface company-template-field
    '((((background dark)) (:background "yellow" :foreground "black"))
@@@ -59,8 -59,8 +59,8 @@@
    (let* ((start (point))
           (templates (company-template-templates-at (point)))
           (minimum (apply 'max (mapcar 'overlay-end templates)))
-          (fields (loop for templ in templates
-                        append (overlay-get templ 'company-template-fields))))
+          (fields (cl-loop for templ in templates
+                           append (overlay-get templ 'company-template-fields))))
      (dolist (pos (mapcar 'overlay-start fields))
        (and pos
             (> pos (point))
@@@ -71,9 -71,9 +71,9 @@@
      (company-template-remove-field (company-template-field-at start))))
  
  (defun company-template-field-at (&optional point)
-   (loop for ovl in (overlays-at (or point (point)))
-         when (overlay-get ovl 'company-template-parent)
-         return ovl))
+   (cl-loop for ovl in (overlays-at (or point (point)))
+            when (overlay-get ovl 'company-template-parent)
+            return ovl))
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
@@@ -98,7 -98,7 +98,7 @@@
    "Add new field to template TEMPL at POS, inserting TEXT.
  When DISPLAY is non-nil, set the respective property on the overlay.
  Leave point at the end of the field."
-   (assert templ)
+   (cl-assert templ)
    (goto-char pos)
    (insert text)
    (when (> (point) (overlay-end templ))
                (save-excursion
                  (company-template-add-field templ (match-beginning 1)
                                              (format "arg%d" cnt) sig))
-               (incf cnt)))
+               (cl-incf cnt)))
            (company-template-move-to-first templ))))))
  
  (provide 'company-template)
index feea6982a47badd018b3699074308b5b7bb8eb28,ac91988623d3d1a8ea4b926e8474d81212933b96..ac91988623d3d1a8ea4b926e8474d81212933b96
@@@ -26,7 -26,7 +26,7 @@@
  ;;; Code:
  
  (require 'company)
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  (require 'tempo)
  
  (defsubst company-tempo-lookup (match)
@@@ -50,7 -50,7 +50,7 @@@
  (defun company-tempo (command &optional arg &rest ignored)
    "`company-mode' completion back-end for tempo."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-tempo
                                          'company-tempo-insert))
      (prefix (or (car (tempo-find-match-string tempo-match-finder)) ""))
index 5a2608632ffb0009a2b3f7f8d3deef3cd3156460,abd970423e110c6ca898e554d22edd7f1fa942fe..abd970423e110c6ca898e554d22edd7f1fa942fe
@@@ -1,4 -1,4 +1,4 @@@
- ;;; company-tests.el --- company-mode tests
+ ;;; company-tests.el --- company-mode tests  -*- lexical-binding: t -*-
  
  ;; Copyright (C) 2011, 2013-2014  Free Software Foundation, Inc.
  
  
  ;;; Code:
  
- (eval-when-compile (require 'cl))
  (require 'ert)
  (require 'company)
  (require 'company-keywords)
- (require 'company-elisp)
  (require 'company-clang)
  
  ;;; Core
  
  (ert-deftest company-good-prefix ()
    (let ((company-minimum-prefix-length 5)
-         company--explicit-action)
+         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 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)
-                  (case command
+                  (cl-case command
                     (prefix "z")
                     (candidates '("a" "b"))))
                 (lambda (command &optional arg &rest ignore)
-                  (case command
+                  (cl-case command
                     (prefix "z")
                     (candidates '("c" "d")))))))
      (should (equal (company-call-backend 'candidates "z") '("a" "b" "c" "d")))))
  
  (ert-deftest company-multi-backend-remembers-candidate-backend ()
    (let ((company-backend
-          (list (lambda (command &optional arg &rest ignore)
-                  (case command
+          (list (lambda (command &optional arg)
+                  (cl-case command
                     (ignore-case nil)
                     (annotation "1")
                     (candidates '("a" "c"))
                     (post-completion "13")))
-                (lambda (command &optional arg &rest ignore)
-                  (case command
+                (lambda (command &optional arg)
+                  (cl-case command
                     (ignore-case t)
                     (annotation "2")
                     (candidates '("b" "d"))
-                    (post-completion "42"))))))
+                    (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")))
+       (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 "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)
-                  (case command
+                  (cl-case command
                     (prefix "a")
                     (candidates '("abb" "abc" "abd")))))
          (secundo (lambda (command &optional arg)
-                    (case command
+                    (cl-case command
                       (prefix "a")
                       (candidates '("acc" "acd"))))))
      (let ((company-backend (list 'ignore 'ignore :with secundo)))
      (let (company-frontends
            (company-backends
             (list (lambda (command &optional arg)
-                    (case command
+                    (cl-case command
                       (prefix "a")
                       (candidates '("a" "ab" "ac")))))))
        (let (this-command)
            (company-require-match 'company-explicit-action-p)
            (company-backends
             (list (lambda (command &optional arg)
-                    (case command
+                    (cl-case command
                       (prefix (buffer-substring (point-min) (point)))
                       (candidates '("abc" "abd")))))))
        (let (this-command)
            (company-require-match 'company-explicit-action-p)
            (company-backends
             (list (lambda (command &optional arg)
-                    (case command
+                    (cl-case command
                       (prefix (buffer-substring (point-min) (point)))
                       (candidates '("abc" "abd")))))))
        (company-idle-begin (current-buffer) (selected-window)
            company-begin-commands
            (company-backends
             (list (lambda (command &optional arg)
-                    (case command
+                    (cl-case command
                       (prefix (buffer-substring (point-min) (point)))
                       (candidates '("abc" "abd")))))))
        (let ((company-continue-commands nil))
            company-begin-commands
            (company-backends
             (list (lambda (command &optional arg)
-                    (case command
+                    (cl-case command
                       (prefix (buffer-substring (point-min) (point)))
                       (candidates '("abc" "abd")))))))
        (let ((company-continue-commands '(not backward-delete-char)))
            (company-auto-complete-chars '(? ))
            (company-backends
             (list (lambda (command &optional arg)
-                    (case command
+                    (cl-case command
                       (prefix (buffer-substring (point-min) (point)))
                       (candidates '("abcd" "abef")))))))
        (let (this-command)
            (company-auto-complete-chars '(? ))
            (company-backends
             (list (lambda (command &optional arg)
-                    (case command
+                    (cl-case command
                       (prefix (buffer-substring (point-min) (point)))
                       (candidates '("abcd" "abef")))))))
        (company-idle-begin (current-buffer) (selected-window)
            company-end-of-buffer-workaround
            (company-backends
             (list (lambda (command &optional arg)
-                    (case command
+                    (cl-case command
                       (prefix (buffer-substring (point-min) (point)))
                       (candidates '("abcd" "abef"))
                       (ignore-case t))))))
      (let (company-frontends
            (company-backends
             (list (lambda (command &optional arg)
-                    (case command
+                    (cl-case command
                       (prefix (buffer-substring (point-min) (point)))
                       (candidates '("abcd" "abef"))
                       (ignore-case 'keep-prefix))))))
            company-end-of-buffer-workaround
            (company-backends
             (list (lambda (command &optional arg)
-                    (case command
+                    (cl-case command
                       (prefix (buffer-substring (point-min) (point)))
                       (candidates '("tea-cup" "teal-color")))))))
        (let (this-command)
              (company-begin-commands '(self-insert-command))
              (company-backends
               (list (lambda (c &optional arg)
-                      (case c (prefix "") (candidates '("a" "b" "c")))))))
+                      (cl-case c (prefix "") (candidates '("a" "b" "c")))))))
          (let (this-command)
            (company-call 'complete))
          (company-call 'open-line 1)
    (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-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-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-prefix))
+       (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")))))))
  ;;; Template
  
  (ert-deftest company-template-removed-after-the-last-jump ()
        (should (equal "foo(arg0, arg1)" (buffer-string)))
        (should (looking-at "arg0")))))
  
- ;;; Elisp
- (defmacro company-elisp-with-buffer (contents &rest body)
-   (declare (indent 0))
-   `(with-temp-buffer
-      (insert ,contents)
-      (setq major-mode 'emacs-lisp-mode)
-      (re-search-backward "|")
-      (replace-match "")
-      (let ((company-elisp-detect-function-context t))
-        ,@body)))
- (ert-deftest company-elisp-candidates-predicate ()
-   (company-elisp-with-buffer
-     "(foo ba|)"
-     (should (eq (company-elisp--candidates-predicate "ba")
-                 'boundp))
-     (should (eq (let (company-elisp-detect-function-context)
-                   (company-elisp--candidates-predicate "ba"))
-                 'company-elisp--predicate)))
-   (company-elisp-with-buffer
-     "(foo| )"
-     (should (eq (company-elisp--candidates-predicate "foo")
-                 'fboundp))
-     (should (eq (let (company-elisp-detect-function-context)
-                   (company-elisp--candidates-predicate "foo"))
-                 'company-elisp--predicate)))
-   (company-elisp-with-buffer
-     "(foo 'b|)"
-     (should (eq (company-elisp--candidates-predicate "b")
-                 'company-elisp--predicate))))
- (ert-deftest company-elisp-candidates-predicate-in-docstring ()
-   (company-elisp-with-buffer
-    "(def foo () \"Doo be doo `ide|"
-    (should (eq 'company-elisp--predicate
-                (company-elisp--candidates-predicate "ide")))))
- ;; This one's also an integration test.
- (ert-deftest company-elisp-candidates-recognizes-binding-form ()
-   (let ((company-elisp-detect-function-context t)
-         (obarray [when what whelp])
-         (what 1)
-         (whelp 2)
-         (wisp 3))
-     (company-elisp-with-buffer
-       "(let ((foo 7) (wh| )))"
-       (should (equal '("what" "whelp")
-                      (company-elisp-candidates "wh"))))
-     (company-elisp-with-buffer
-       "(cond ((null nil) (wh| )))"
-       (should (equal '("when")
-                      (company-elisp-candidates "wh"))))))
- (ert-deftest company-elisp-candidates-predicate-binding-without-value ()
-   (loop for (text prefix predicate) in '(("(let (foo|" "foo" boundp)
-                                          ("(let (foo (bar|" "bar" boundp)
-                                          ("(let (foo) (bar|" "bar" fboundp))
-         do
-         (eval `(company-elisp-with-buffer
-                  ,text
-                  (should (eq ',predicate
-                              (company-elisp--candidates-predicate ,prefix)))))))
- (ert-deftest company-elisp-finds-vars ()
-   (let ((obarray [boo bar baz backquote])
-         (boo t)
-         (bar t)
-         (baz t))
-     (should (equal '("bar" "baz")
-                    (company-elisp--globals "ba" 'boundp)))))
- (ert-deftest company-elisp-finds-functions ()
-   (let ((obarray [when what whelp])
-         (what t)
-         (whelp t))
-     (should (equal '("when")
-                    (company-elisp--globals "wh" 'fboundp)))))
- (ert-deftest company-elisp-finds-things ()
-   (let ((obarray [when what whelp])
-         (what t)
-         (whelp t))
-     (should (equal '("what" "whelp" "when")
-                    (sort (company-elisp--globals "wh" 'company-elisp--predicate)
-                          'string<)))))
- (ert-deftest company-elisp-locals-vars ()
-   (company-elisp-with-buffer
-     "(let ((foo 5) (bar 6))
-        (cl-labels ((borg ()))
-          (lambda (boo baz)
-            b|)))"
-     (should (equal '("bar" "baz" "boo")
-                    (company-elisp--locals "b" nil)))))
- (ert-deftest company-elisp-locals-single-var ()
-   (company-elisp-with-buffer
-     "(dotimes (itk 100)
-        (dolist (item items)
-          it|))"
-     (should (equal '("itk" "item")
-                    (company-elisp--locals "it" nil)))))
- (ert-deftest company-elisp-locals-funs ()
-   (company-elisp-with-buffer
-     "(cl-labels ((foo ())
-                  (fee ()))
-        (let ((fun 4))
-          (f| )))"
-     (should (equal '("fee" "foo")
-                    (sort (company-elisp--locals "f" t) 'string<)))))
- (ert-deftest company-elisp-locals-skips-current-varlist ()
-   (company-elisp-with-buffer
-     "(let ((foo 1)
-            (f| )))"
-     (should (null (company-elisp--locals "f" nil)))))
- (ert-deftest company-elisp-show-locals-first ()
-   (company-elisp-with-buffer
-     "(let ((floo 1)
-            (flop 2)
-            (flee 3))
-        fl|)"
-     (let ((obarray [float-pi]))
-       (let (company-elisp-show-locals-first)
-         (should (eq nil (company-elisp 'sorted))))
-       (let ((company-elisp-show-locals-first t))
-         (should (eq t (company-elisp 'sorted)))
-         (should (equal '("flee" "floo" "flop" "float-pi")
-                        (company-elisp-candidates "fl")))))))
- (ert-deftest company-elisp-candidates-no-duplicates ()
-   (company-elisp-with-buffer
-     "(let ((float-pi 4))
-        f|)"
-     (let ((obarray [float-pi])
-           (company-elisp-show-locals-first t))
-       (should (equal '("float-pi") (company-elisp-candidates "f"))))))
- (ert-deftest company-elisp-shouldnt-complete-defun-name ()
-   (company-elisp-with-buffer
-     "(defun foob|)"
-     (should (null (company-elisp 'prefix)))))
- (ert-deftest company-elisp-should-complete-def-call ()
-   (company-elisp-with-buffer
-     "(defu|"
-     (should (equal "defu" (company-elisp 'prefix)))))
- (ert-deftest company-elisp-should-complete-in-defvar ()
-   ;; It will also complete the var name, at least for now.
-   (company-elisp-with-buffer
-     "(defvar abc de|"
-     (should (equal "de" (company-elisp 'prefix)))))
- (ert-deftest company-elisp-shouldnt-complete-in-defun-arglist ()
-   (company-elisp-with-buffer
-     "(defsubst foobar (ba|"
-     (should (null (company-elisp 'prefix)))))
- (ert-deftest company-elisp-prefix-in-defun-body ()
-   (company-elisp-with-buffer
-     "(defun foob ()|)"
-     (should (equal "" (company-elisp 'prefix)))))
  ;;; Clang
  
  (ert-deftest company-clang-objc-templatify ()
index ac8d133454e8626ae49ac3cecaf560df2a583fb1,7a985aaedc2e183bb419a1dc41b7391378738e61..7a985aaedc2e183bb419a1dc41b7391378738e61
@@@ -26,7 -26,7 +26,7 @@@
  ;;; Code:
  
  (require 'company)
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  
  (defgroup company-xcode nil
    "Completion back-end for Xcode projects."
@@@ -109,7 -109,7 +109,7 @@@ valid in most contexts.
  (defun company-xcode (command &optional arg &rest ignored)
    "`company-mode' completion back-end for Xcode projects."
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-xcode))
      (prefix (and company-xcode-xcodeindex-executable
                   (company-xcode-tags)
index ae370c78feca440e0eb64cc024604e3fd88fb111,4730b211b7989e09d2639155a511b1154d79ccf6..4730b211b7989e09d2639155a511b1154d79ccf6
@@@ -25,6 -25,7 +25,7 @@@
  
  ;;; Code:
  
+ (require 'cl-lib)
  (require 'yasnippet)
  
  (defun company-yasnippet--candidates (prefix)
@@@ -74,7 -75,7 +75,7 @@@ shadow back-ends that come after it.  R
    (global-set-key (kbd \"C-c y\") 'company-yasnippet)
  "
    (interactive (list 'interactive))
-   (case command
+   (cl-case command
      (interactive (company-begin-backend 'company-yasnippet))
      (prefix
       ;; Should probably use `yas--current-key', but that's bound to be slower.
index a633af3aee97cc0d6b24b394f6892b9786c5ed04,632b7dc64de6b179e7de1628e9f789f2e789dec1..632b7dc64de6b179e7de1628e9f789f2e789dec1
@@@ -1,13 -1,13 +1,13 @@@
- ;;; company.el --- Modular in-buffer completion framework  -*- lexical-binding: t -*-
+ ;;; company.el --- Modular text completion framework  -*- lexical-binding: t -*-
  
  ;; Copyright (C) 2009-2014  Free Software Foundation, Inc.
  
  ;; Author: Nikolaj Schumacher
  ;; Maintainer: Dmitry Gutov <dgutov@yandex.ru>
- ;; Version: 0.7.3
- ;; Keywords: abbrev, convenience, matching
  ;; URL: http://company-mode.github.io/
- ;; Compatibility: GNU Emacs 23.x, GNU Emacs 24.x
+ ;; Version: 0.8.0
+ ;; Keywords: abbrev, convenience, matching
+ ;; Package-Requires: ((emacs "24.1") (cl-lib "0.5"))
  
  ;; This file is part of GNU Emacs.
  
  ;; Here is a simple example completing "foo":
  ;;
  ;; (defun company-my-backend (command &optional arg &rest ignored)
- ;;   (case command
- ;;     (prefix (when (looking-back "foo\\>")
+ ;;   (pcase command
+ ;;     (`prefix (when (looking-back "foo\\>")
  ;;               (match-string 0)))
- ;;     (candidates (list "foobar" "foobaz" "foobarbaz"))
- ;;     (meta (format "This value is named %s" arg))))
+ ;;     (`candidates (list "foobar" "foobaz" "foobarbaz"))
+ ;;     (`meta (format "This value is named %s" arg))))
  ;;
  ;; Sometimes it is a good idea to mix several back-ends together, for example to
  ;; enrich gtags with dabbrev-code results (to emulate local variables).
@@@ -69,7 -69,7 +69,7 @@@
  
  ;;; Code:
  
- (eval-when-compile (require 'cl))
+ (require 'cl-lib)
  (require 'newcomment)
  
  ;; FIXME: Use `user-error'.
@@@ -244,6 -244,11 +244,11 @@@ The visualized data is stored in `compa
  If this many lines are not available, prefer to display the tooltip above."
    :type 'integer)
  
+ (defcustom company-tooltip-minimum-width 0
+   "The minimum width of the tooltip's inner area.
+ This doesn't include the margins and the scroll bar."
+   :type 'integer)
  (defcustom company-tooltip-margin 1
    "Width of margin columns to show around the toolip."
    :type 'integer)
  
  (defun company-safe-backends-p (backends)
    (and (consp backends)
-        (not (dolist (backend backends)
+        (not (cl-dolist (backend backends)
                (unless (if (consp backend)
                            (company-safe-backends-p backend)
                          (assq backend company-safe-backends))
-                 (return t))))))
- (defvar company--include-capf (version< "24.3.50" emacs-version))
+                 (cl-return t))))))
  
- (defcustom company-backends `(,@(unless company--include-capf
+ (defcustom company-backends `(,@(unless (version< "24.3.50" emacs-version)
                                    (list 'company-elisp))
                                company-bbdb
                                company-nxml company-css
                                company-eclim company-semantic company-clang
                                company-xcode company-ropemacs company-cmake
-                               ,@(when company--include-capf
-                                   (list 'company-capf))
+                               company-capf
                                (company-dabbrev-code company-gtags company-etags
                                 company-keywords)
                                company-oddmuse company-files company-dabbrev)
@@@ -395,7 -397,18 +397,18 @@@ The latter is the case for the `prefix
  the keyword `:with', the back-ends after it are ignored for this command.
  
  The completions from back-ends in a group are merged (but only from those
- that return the same `prefix')."
+ that return the same `prefix').
+ Asynchronous back-ends:
+ The return value of each command can also be a cons (:async . FETCHER)
+ where FETCHER is a function of one argument, CALLBACK.  When the data
+ arrives, FETCHER must call CALLBACK and pass it the appropriate return
+ value, as described above.
+ True asynchronous operation is only supported for command `candidates', and
+ only during idle completion.  Other commands will block the user interface,
+ even if the back-end uses the asynchronous calling convention."
    :type `(repeat
            (choice
             :tag "Back-end"
@@@ -445,6 -458,12 +458,12 @@@ back-end, consider using the `post-comp
    "The minimum prefix length for idle completion."
    :type '(integer :tag "prefix length"))
  
+ (defcustom company-abort-manual-when-too-short nil
+   "If enabled, cancel a manually started completion when the prefix gets
+ shorter than both `company-minimum-prefix-length' and the length of the
+ prefix it was started from."
+   :type 'boolean)
  (defcustom company-require-match 'company-explicit-action-p
    "If enabled, disallow non-matching input.
  This can be a function do determine if a match is required.
@@@ -496,7 -515,7 +515,7 @@@ A character that is part of a valid can
                        (const :tag "Generic comment fence." ?!))
                   (function :tag "Predicate function")))
  
- (defcustom company-idle-delay .7
+ (defcustom company-idle-delay .5
    "The idle delay in seconds until completion starts automatically.
  A value of nil means no idle completion, t means show candidates
  immediately when a prefix of `company-minimum-prefix-length' is reached."
@@@ -544,6 -563,13 +563,13 @@@ commands in the `company-' namespace, a
    "Work around a visualization bug when completing at the end of the buffer.
  The work-around consists of adding a newline.")
  
+ (defvar company-async-wait 0.03
+   "Pause between checks to see if the value's been set when turning an
+ asynchronous call into synchronous.")
+ (defvar company-async-timeout 2
+   "Maximum wait time for a value to be set during asynchronous call.")
  ;;; mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
  (defvar company-mode-map (make-sparse-keymap)
         (unless (memq backend company--disabled-backends)
           (message "Company back-end '%s' could not be initialized:\n%s"
                    backend (error-message-string err)))
-        (pushnew backend company--disabled-backends)
+        (cl-pushnew backend company--disabled-backends)
         nil)))
     ;; No initialization for lambdas.
     ((functionp backend) t)
     (t ;; Must be a list.
-     (dolist (b backend)
+     (cl-dolist (b backend)
        (unless (keywordp b)
          (company-init-backend b))))))
  
@@@ -760,67 -786,126 +786,126 @@@ means that `company-mode' is always tur
      (unless (and (char-after) (eq (char-syntax (char-after)) ?w))
        "")))
  
+ (defun company-grab-symbol-cons (idle-begin-after-re &optional max-len)
+   (let ((symbol (company-grab-symbol)))
+     (when symbol
+       (save-excursion
+         (forward-char (- (length symbol)))
+         (if (looking-back idle-begin-after-re (if max-len
+                                                   (- (point) max-len)
+                                                 (line-beginning-position)))
+             (cons symbol t)
+           symbol)))))
  (defun company-in-string-or-comment ()
    (let ((ppss (syntax-ppss)))
      (or (car (setq ppss (nthcdr 3 ppss)))
          (car (setq ppss (cdr ppss)))
          (nth 3 ppss))))
  
- (if (fboundp 'locate-dominating-file)
-     (defalias 'company-locate-dominating-file 'locate-dominating-file)
-   (defun company-locate-dominating-file (file name)
-     (catch 'root
-       (let ((dir (file-name-directory file))
-             (prev-dir nil))
-         (while (not (equal dir prev-dir))
-           (when (file-exists-p (expand-file-name name dir))
-             (throw 'root dir))
-           (setq prev-dir dir
-                 dir (file-name-directory (directory-file-name dir))))))))
  (defun company-call-backend (&rest args)
+   (company--force-sync #'company-call-backend-raw args company-backend))
+ (defun company--force-sync (fun args backend)
+   (let ((value (apply fun args)))
+     (if (not (eq (car-safe value) :async))
+         value
+       (let ((res 'trash)
+             (start (time-to-seconds)))
+         (funcall (cdr value)
+                  (lambda (result) (setq res result)))
+         (while (eq res 'trash)
+           (if (> (- (time-to-seconds) start) company-async-timeout)
+               (error "Company: Back-end %s async timeout with args %s"
+                      backend args)
+             (sleep-for company-async-wait)))
+         res))))
+ (defun company-call-backend-raw (&rest args)
    (condition-case err
        (if (functionp company-backend)
            (apply company-backend args)
-         (apply 'company--multi-backend-adapter company-backend args))
+         (apply #'company--multi-backend-adapter company-backend args))
      (error (error "Company: Back-end %s error \"%s\" with args %s"
-                     company-backend (error-message-string err) args))))
+                   company-backend (error-message-string err) args))))
  
  (defun company--multi-backend-adapter (backends command &rest args)
-   (let ((backends (loop for b in backends
-                         when (not (and (symbolp b)
-                                        (eq 'failed (get b 'company-init))))
-                         collect b)))
+   (let ((backends (cl-loop for b in backends
+                            when (not (and (symbolp b)
+                                           (eq 'failed (get b 'company-init))))
+                            collect b)))
      (setq backends
            (if (eq command 'prefix)
                (butlast backends (length (member :with backends)))
              (delq :with backends)))
-     (case command
-       (candidates
-        ;; Small perf optimization: don't tag the candidates received
-        ;; from the first backend in the group.
-        (append (apply (car backends) 'candidates args)
-                (loop for backend in (cdr backends)
-                      when (equal (funcall backend 'prefix)
-                                  (car args))
-                      append (mapcar
-                              (lambda (str)
-                                (propertize str 'company-backend backend))
-                              (apply backend 'candidates args)))))
-       (sorted nil)
-       (duplicates t)
-       ((prefix ignore-case no-cache require-match)
+     (pcase command
+       (`candidates
+        (company--multi-backend-adapter-candidates backends (car args)))
+       (`sorted nil)
+       (`duplicates t)
+       ((or `prefix `ignore-case `no-cache `require-match)
         (let (value)
-          (dolist (backend backends)
-            (when (setq value (apply backend command args))
-              (return value)))))
-       (otherwise
+          (cl-dolist (backend backends)
+            (when (setq value (company--force-sync
+                               backend (cons command args) backend))
+              (cl-return value)))))
+       (_
         (let ((arg (car args)))
           (when (> (length arg) 0)
             (let ((backend (or (get-text-property 0 'company-backend arg)
                                (car backends))))
               (apply backend command args))))))))
  
+ (defun company--multi-backend-adapter-candidates (backends prefix)
+   (let ((pairs (cl-loop for backend in (cdr backends)
+                         when (equal (funcall backend 'prefix)
+                                     prefix)
+                         collect (cons (funcall backend 'candidates prefix)
+                                       (let ((b backend))
+                                         (lambda (candidates)
+                                           (mapcar
+                                            (lambda (str)
+                                              (propertize str 'company-backend b))
+                                            candidates)))))))
+     (when (equal (funcall (car backends) 'prefix) prefix)
+       ;; Small perf optimization: don't tag the candidates received
+       ;; from the first backend in the group.
+       (push (cons (funcall (car backends) 'candidates prefix)
+                   'identity)
+             pairs))
+     (company--merge-async pairs (lambda (values) (apply #'append values)))))
+ (defun company--merge-async (pairs merger)
+   (let ((async (cl-loop for pair in pairs
+                         thereis
+                         (eq :async (car-safe (car pair))))))
+     (if (not async)
+         (funcall merger (cl-loop for (val . mapper) in pairs
+                                  collect (funcall mapper val)))
+       (cons
+        :async
+        (lambda (callback)
+          (let* (lst pending
+                 (finisher (lambda ()
+                             (unless pending
+                               (funcall callback
+                                        (funcall merger
+                                                 (nreverse lst)))))))
+            (dolist (pair pairs)
+              (let ((val (car pair))
+                    (mapper (cdr pair)))
+                (if (not (eq :async (car-safe val)))
+                    (push (funcall mapper val) lst)
+                  (push nil lst)
+                  (let ((cell lst)
+                        (fetcher (cdr val)))
+                    (push fetcher pending)
+                    (funcall fetcher
+                             (lambda (res)
+                               (setq pending (delq fetcher pending))
+                               (setcar cell (funcall mapper res))
+                               (funcall finisher)))))))))))))
  ;;; completion mechanism ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
  (defvar company-prefix nil)
  (defvar company-selection-changed nil)
  (make-variable-buffer-local 'company-selection-changed)
  
- (defvar company--explicit-action nil
-   "Non-nil, if explicit completion took place.")
- (make-variable-buffer-local 'company--explicit-action)
+ (defvar company--manual-action nil
+   "Non-nil, if manual completion took place.")
+ (make-variable-buffer-local 'company--manual-action)
+ (defvar company--manual-prefix nil)
+ (make-variable-buffer-local 'company--manual-prefix)
  
  (defvar company--auto-completion nil
    "Non-nil when current candidate is being inserted automatically.
@@@ -892,7 -980,7 +980,7 @@@ can retrieve meta-data for them.
  
  (defun company-explicit-action-p ()
    "Return whether explicit completion action was taken by the user."
-   (or company--explicit-action
+   (or company--manual-action
        company-selection-changed))
  
  (defun company-reformat (candidate)
                company-candidates candidates)
          (when selected
            (while (and candidates (string< (pop candidates) selected))
-             (incf company-selection))
+             (cl-incf company-selection))
            (unless candidates
              ;; Make sure selection isn't out of bounds.
              (setq company-selection (min (1- company-candidates-length)
      ;; `company-complete-common'.
      (setq company-common
            (if (cdr company-candidates)
-               (company--safe-candidate
-                (let ((common (try-completion company-prefix company-candidates)))
-                  (if (eq common t)
-                      ;; Mulple equal strings, probably with different
-                      ;; annotations.
-                      company-prefix
-                    common)))
+               (let ((common (try-completion company-prefix company-candidates)))
+                 (if (eq common t)
+                     ;; Mulple equal strings, probably with different
+                     ;; annotations.
+                     company-prefix
+                   common))
              (car company-candidates)))))
  
- (defun company--safe-candidate (str)
-   ;; XXX: This feature is deprecated.
-   (or (company-call-backend 'crop str)
-       str))
  (defun company-calculate-candidates (prefix)
    (let ((candidates (cdr (assoc prefix company-candidates-cache)))
          (ignore-case (company-call-backend 'ignore-case)))
            (let ((len (length prefix))
                  (completion-ignore-case ignore-case)
                  prev)
-             (dotimes (i (1+ len))
+             (cl-dotimes (i (1+ len))
                (when (setq prev (cdr (assoc (substring prefix 0 (- len i))
                                             company-candidates-cache)))
                  (setq candidates (all-completions prefix prev))
-                 (return t)))))
+                 (cl-return t)))))
          ;; no cache match, call back-end
-         (progn
-           (setq candidates (company-call-backend 'candidates prefix))
-           (when company-candidates-predicate
-             (setq candidates
-                   (company-apply-predicate candidates
-                                            company-candidates-predicate)))
-           (unless (company-call-backend 'sorted)
-             (setq candidates (sort candidates 'string<)))
-           (when (company-call-backend 'duplicates)
-             (company--strip-duplicates candidates))))
+         (setq candidates
+               (company--process-candidates
+                (company--fetch-candidates prefix))))
      (setq candidates (company--transform-candidates candidates))
      (when candidates
        (if (or (cdr candidates)
          ;; Already completed and unique; don't start.
          t))))
  
+ (defun company--fetch-candidates (prefix)
+   (let ((c (if company--manual-action
+                (company-call-backend 'candidates prefix)
+              (company-call-backend-raw 'candidates prefix)))
+         res)
+     (if (not (eq (car c) :async))
+         c
+       (let ((buf (current-buffer))
+             (win (selected-window))
+             (tick (buffer-chars-modified-tick))
+             (pt (point))
+             (backend company-backend))
+         (funcall
+          (cdr c)
+          (lambda (candidates)
+            (if (not (and candidates (eq res 'done)))
+                ;; Fetcher called us right back.
+                (setq res candidates)
+              (setq company-backend backend
+                    company-candidates-cache
+                    (list (cons prefix
+                                (company--process-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.
+       ;; A throw-catch would be one possible improvement.
+       (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)))
+   (unless (company-call-backend 'sorted)
+     (setq candidates (sort candidates 'string<)))
+   (when (company-call-backend 'duplicates)
+     (company--strip-duplicates candidates))
+   candidates)
  (defun company--strip-duplicates (candidates)
    (let ((c2 candidates))
      (while c2
@@@ -1054,7 -1170,7 +1170,7 @@@ point. The rest of the list is appende
  Keywords and function definition names are ignored."
    (let* (occurs
           (noccurs
-           (delete-if
+           (cl-delete-if
             (lambda (candidate)
               (when (or
                      (save-excursion
         (eq win (selected-window))
         (eq tick (buffer-chars-modified-tick))
         (eq pos (point))
-        (not (equal (point) company-point))
         (when (company-auto-begin)
           (when (version< emacs-version "24.3.50")
             (company-input-noop))
         (not company-candidates)
         (let ((company-idle-delay t)
               (company-begin-commands t))
-          (condition-case-no-debug err
+          (condition-case-unless-debug err
               (company-begin)
             (error (message "Company: An error occurred in auto-begin")
                    (message "%s" (error-message-string err))
  (defun company-manual-begin ()
    (interactive)
    (company-assert-enabled)
-   (setq company--explicit-action t)
+   (setq company--manual-action t)
    (unwind-protect
        (let ((company-minimum-prefix-length 0))
          (company-auto-begin))
      (unless company-candidates
-       (setq company--explicit-action nil))))
+       (setq company--manual-action nil))))
  
  (defun company-other-backend (&optional backward)
    (interactive (list current-prefix-arg))
    (company-assert-enabled)
-   (if company-backend
-       (let* ((after (cdr (member company-backend company-backends)))
-              (before (cdr (member company-backend (reverse company-backends))))
-              (next (if backward
-                        (append before (reverse after))
-                      (append after (reverse before)))))
-         (company-cancel)
-         (dolist (backend next)
-           (when (ignore-errors (company-begin-backend backend))
-             (return t))))
-     (company-manual-begin))
+   (let* ((after (if company-backend
+                     (cdr (member company-backend company-backends))
+                   company-backends))
+          (before (cdr (member company-backend (reverse company-backends))))
+          (next (if backward
+                    (append before (reverse after))
+                  (append after (reverse before)))))
+     (company-cancel)
+     (cl-dolist (backend next)
+       (when (ignore-errors (company-begin-backend backend))
+         (cl-return t))))
    (unless company-candidates
      (error "No other back-end")))
  
       (t (company-cancel)))))
  
  (defun company--good-prefix-p (prefix)
-   (and (or (company-explicit-action-p)
-            (unless (eq prefix 'stop)
-              (or (eq (cdr-safe prefix) t)
-                  (>= (or (cdr-safe prefix) (length prefix))
-                      company-minimum-prefix-length))))
-        (stringp (or (car-safe prefix) prefix))))
+   (and (stringp (or (car-safe prefix) prefix)) ;excludes 'stop
+        (or (eq (cdr-safe prefix) t)
+            (let ((len (or (cdr-safe prefix) (length prefix))))
+              (if company--manual-prefix
+                  (or (not company-abort-manual-when-too-short)
+                      ;; Must not be less than minimum or initial length.
+                      (>= len (min company-minimum-prefix-length
+                                   (length company--manual-prefix))))
+                (>= len company-minimum-prefix-length))))))
  
  (defun company--continue ()
    (when (company-call-backend 'no-cache company-prefix)
  
  (defun company--begin-new ()
    (let (prefix c)
-     (dolist (backend (if company-backend
-                          ;; prefer manual override
-                          (list company-backend)
-                        company-backends))
+     (cl-dolist (backend (if company-backend
+                             ;; prefer manual override
+                             (list company-backend)
+                           company-backends))
        (setq prefix
              (if (or (symbolp backend)
                      (functionp backend))
                  c (company-calculate-candidates prefix))
            ;; t means complete/unique.  We don't start, so no hooks.
            (if (not (consp c))
-               (when company--explicit-action
+               (when company--manual-action
                  (message "No completion found"))
              (setq company-prefix prefix)
+             (when company--manual-action
+               (setq company--manual-prefix prefix))
              (when (symbolp backend)
                (setq company-lighter (concat " " (symbol-name backend))))
              (company-update-candidates c)
              (run-hook-with-args 'company-completion-started-hook
                                  (company-explicit-action-p))
              (company-call-frontends 'show)))
-         (return c)))))
+         (cl-return c)))))
  
  (defun company-begin ()
    (or (and company-candidates (company--continue))
          company-common nil
          company-selection 0
          company-selection-changed nil
-         company--explicit-action nil
+         company--manual-action nil
+         company--manual-prefix nil
          company-lighter company-default-lighter
          company--point-max nil
          company-point nil)
              (and (numberp company-idle-delay)
                   (or (eq t company-begin-commands)
                       (memq this-command company-begin-commands))
+                  (not (equal (point) company-point))
                   (setq company-timer
                         (run-with-timer company-idle-delay nil
                                         'company-idle-begin
  (defun company-search (text lines)
    (let ((quoted (regexp-quote text))
          (i 0))
-     (dolist (line lines)
+     (cl-dolist (line lines)
        (when (string-match quoted line (length company-prefix))
-         (return i))
-       (incf i))))
+         (cl-return i))
+       (cl-incf i))))
  
  (defun company-search-printing-char ()
    (interactive)
      (define-key keymap [t] 'company-search-other-char)
      (while (< i ?\s)
        (define-key keymap (make-string 1 i) 'company-search-other-char)
-       (incf i))
+       (cl-incf i))
      (while (< i 256)
        (define-key keymap (vector i) 'company-search-printing-char)
-       (incf i))
+       (cl-incf i))
      (let ((meta-map (make-sparse-keymap)))
        (define-key keymap (char-to-string meta-prefix-char) meta-map)
        (define-key keymap [escape] meta-map))
@@@ -1595,10 -1717,10 +1717,10 @@@ and invoke the normal binding.
    (let* ((col-row (posn-actual-col-row (event-start event)))
           (col (car col-row))
           (row (cdr col-row)))
-     (incf col (window-hscroll))
+     (cl-incf col (window-hscroll))
      (and header-line-format
           (version< "24" emacs-version)
-          (decf row))
+          (cl-decf row))
      (cons col row)))
  
  (defun company-select-mouse (event)
    (interactive)
    (when (company-manual-begin)
      (let ((result (nth company-selection company-candidates)))
-       (when company--auto-completion
-         (setq result (company--safe-candidate result)))
        (company-finish result))))
  
  (defun company-complete-common ()
@@@ -1672,7 -1792,7 +1792,7 @@@ To show the number next to the candidat
    (when (company-manual-begin)
      (and (< n 1) (> n company-candidates-length)
           (error "No candidate number %d" n))
-     (decf n)
+     (cl-decf n)
      (company-finish (nth n company-candidates))))
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  (defvar company-callback nil)
  (make-variable-buffer-local 'company-callback)
  
- (defvar company-begin-with-marker nil)
- (make-variable-buffer-local 'company-begin-with-marker)
  (defun company-remove-callback (&optional ignored)
    (remove-hook 'company-completion-finished-hook company-callback t)
    (remove-hook 'company-completion-cancelled-hook 'company-remove-callback t)
-   (remove-hook 'company-completion-finished-hook 'company-remove-callback t)
-   (when company-begin-with-marker
-     (set-marker company-begin-with-marker nil)))
+   (remove-hook 'company-completion-finished-hook 'company-remove-callback t))
  
  (defun company-begin-backend (backend &optional callback)
    "Start a completion at point using BACKEND."
@@@ -1824,20 -1939,18 +1939,18 @@@ CALLBACK is a function called with the 
  successfully completes the input.
  
  Example: \(company-begin-with '\(\"foo\" \"foobar\" \"foobarbaz\"\)\)"
-   ;; FIXME: When Emacs 23 is no longer a concern, replace
-   ;; `company-begin-with-marker' with a lexical variable; use a lexical closure.
-   (setq company-begin-with-marker (copy-marker (point) t))
-   (company-begin-backend
-    `(lambda (command &optional arg &rest ignored)
-       (cond
-        ((eq command 'prefix)
-         (when (equal (point) (marker-position company-begin-with-marker))
-           (buffer-substring ,(- (point) (or prefix-length 0)) (point))))
-        ((eq command 'candidates)
-         (all-completions arg ',candidates))
-        ((eq command 'require-match)
-         ,require-match)))
-    callback))
+   (let ((begin-marker (copy-marker (point) t)))
+     (company-begin-backend
+      (lambda (command &optional arg &rest ignored)
+        (pcase command
+         (`prefix
+          (when (equal (point) (marker-position begin-marker))
+            (buffer-substring (- (point) (or prefix-length 0)) (point))))
+         (`candidates
+          (all-completions arg candidates))
+         (`require-match
+          require-match)))
+      callback)))
  
  (defun company-version (&optional show-version)
    "Get the Company version as string.
@@@ -1860,26 -1973,26 +1973,26 @@@ If SHOW-VERSION is non-nil, show the ve
  (make-variable-buffer-local 'company-tooltip-offset)
  
  (defun company-tooltip--lines-update-offset (selection num-lines limit)
-   (decf limit 2)
+   (cl-decf limit 2)
    (setq company-tooltip-offset
          (max (min selection company-tooltip-offset)
               (- selection -1 limit)))
  
    (when (<= company-tooltip-offset 1)
-     (incf limit)
+     (cl-incf limit)
      (setq company-tooltip-offset 0))
  
    (when (>= company-tooltip-offset (- num-lines limit 1))
-     (incf limit)
+     (cl-incf limit)
      (when (= selection (1- num-lines))
-       (decf company-tooltip-offset)
+       (cl-decf company-tooltip-offset)
        (when (<= company-tooltip-offset 1)
          (setq company-tooltip-offset 0)
-         (incf limit))))
+         (cl-incf limit))))
  
    limit)
  
- (defun company-tooltip--simple-update-offset (selection num-lines limit)
+ (defun company-tooltip--simple-update-offset (selection _num-lines limit)
    (setq company-tooltip-offset
          (if (< selection company-tooltip-offset)
              selection
      (length lst)))
  
  (defun company--replacement-string (lines old column nl &optional align-top)
-   (decf column company-tooltip-margin)
+   (cl-decf column company-tooltip-margin)
  
    (let ((width (length (car lines)))
          (remaining-cols (- (+ (company--window-width) (window-hscroll))
                             column)))
      (when (> width remaining-cols)
-       (decf column (- width remaining-cols))))
+       (cl-decf column (- width remaining-cols))))
  
    (let ((offset (and (< column 0) (- column)))
          new)
              remainder (when (> remainder 0)
                          (setq remainder (format "...(%d)" remainder))))))
  
-     (decf selection company-tooltip-offset)
+     (cl-decf selection company-tooltip-offset)
      (setq width (max (length previous) (length remainder))
            lines (nthcdr company-tooltip-offset company-candidates)
            len (min limit len)
            lines-copy lines)
  
-     (decf window-width (* 2 company-tooltip-margin))
-     (when scrollbar-bounds (decf window-width))
+     (cl-decf window-width (* 2 company-tooltip-margin))
+     (when scrollbar-bounds (cl-decf window-width))
  
      (dotimes (_ len)
        (let* ((value (pop lines-copy))
                           width))))
  
      (setq width (min window-width
-                      (if (and company-show-numbers
-                               (< company-tooltip-offset 10))
-                          (+ 2 width)
-                        width)))
+                      (max company-tooltip-minimum-width
+                           (if (and company-show-numbers
+                                    (< company-tooltip-offset 10))
+                               (+ 2 width)
+                             width))))
  
      ;; number can make tooltip too long
      (when company-show-numbers
                 (right (company-space-string company-tooltip-margin))
                 (width width))
            (when (< numbered 10)
-             (decf width 2)
-             (incf numbered)
+             (cl-decf width 2)
+             (cl-incf numbered)
              (setq right (concat (format " %d" (mod numbered 10)) right)))
            (push (concat
                   (company-fill-propertize str annotation
@@@ -2249,7 -2363,7 +2363,7 @@@ Returns a negative number if the toolti
  
  (defun company-pseudo-tooltip-frontend (command)
    "`company-mode' front-end similar to a tooltip but based on overlays."
-   (case command
+   (cl-case command
      (pre-command (company-pseudo-tooltip-hide-temporarily))
      (post-command
       (let ((old-height (if (overlayp company-pseudo-tooltip-overlay)
  
  (defun company-preview-frontend (command)
    "`company-mode' front-end showing the selection as if it had been inserted."
-   (case command
-     (pre-command (company-preview-hide))
-     (post-command (company-preview-show-at-point (point)))
-     (hide (company-preview-hide))))
+   (pcase command
+     (`pre-command (company-preview-hide))
+     (`post-command (company-preview-show-at-point (point)))
+     (`hide (company-preview-hide))))
  
  (defun company-preview-if-just-one-frontend (command)
    "`company-preview-frontend', but only shown for single candidates."
            (progn
              (setq comp (propertize (format "%d: %s" i comp)
                                     'face 'company-echo))
-             (incf len 3)
-             (incf i)
+             (cl-incf len 3)
+             (cl-incf i)
              (add-text-properties 3 (+ 3 (length company-common))
                                   '(face company-echo-common) comp))
          (setq comp (propertize comp 'face 'company-echo))
        (when (< i 10)
          ;; Add number.
          (setq comp (format "%s (%d)" comp i))
-         (incf len 4)
-         (incf i))
+         (cl-incf len 4)
+         (cl-incf i))
        (if (>= len limit)
            (setq candidates nil)
          (push (propertize comp 'face 'company-echo) msg)))
  
  (defun company-echo-frontend (command)
    "`company-mode' front-end showing the candidates in the echo area."
-   (case command
-     (post-command (company-echo-show-soon 'company-echo-format))
-     (hide (company-echo-hide))))
+   (pcase command
+     (`post-command (company-echo-show-soon 'company-echo-format))
+     (`hide (company-echo-hide))))
  
  (defun company-echo-strip-common-frontend (command)
    "`company-mode' front-end showing the candidates in the echo area."
-   (case command
-     (post-command (company-echo-show-soon 'company-echo-strip-common-format))
-     (hide (company-echo-hide))))
+   (pcase command
+     (`post-command (company-echo-show-soon 'company-echo-strip-common-format))
+     (`hide (company-echo-hide))))
  
  (defun company-echo-metadata-frontend (command)
    "`company-mode' front-end showing the documentation in the echo area."
-   (case command
-     (post-command (company-echo-show-when-idle 'company-fetch-metadata))
-     (hide (company-echo-hide))))
+   (pcase command
+     (`post-command (company-echo-show-when-idle 'company-fetch-metadata))
+     (`hide (company-echo-hide))))
  
  (provide 'company)
  ;;; company.el ends here