]> code.delx.au - gnu-emacs-elpa/blobdiff - company.el
Remove the As
[gnu-emacs-elpa] / company.el
index 20f490eefb314fe4159ff803e7ead2bd43a605ab..86aff7462d80c985bbe1f71942e8ae33696972e3 100644 (file)
@@ -1,35 +1,36 @@
-;;; company.el --- extensible inline text completion mechanism
-;;
-;; Copyright (C) 2009 Nikolaj Schumacher
-;;
-;; Author: Nikolaj Schumacher <bugs * nschum de>
-;; Version: 0.4
-;; Keywords: abbrev, convenience, matchis
-;; URL: http://nschum.de/src/emacs/company/
-;; Compatibility: GNU Emacs 22.x, GNU Emacs 23.x
-;;
-;; This file is NOT part of GNU Emacs.
-;;
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License
-;; as published by the Free Software Foundation; either version 2
-;; of the License, or (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
+;;; company.el --- Modular in-buffer completion framework  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2009-2013  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+;; Maintainer: Dmitry Gutov <dgutov@yandex.ru>
+;; Version: 0.6.7
+;; Keywords: abbrev, convenience, matching
+;; URL: http://company-mode.github.com/
+;; Compatibility: GNU Emacs 22.x, GNU Emacs 23.x, GNU Emacs 24.x
+
+;; 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 this program.  If not, see <http://www.gnu.org/licenses/>.
-;;
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+
 ;;; Commentary:
 ;;
 ;; Company is a modular completion mechanism.  Modules for retrieving completion
 ;; candidates are called back-ends, modules for displaying them are front-ends.
 ;;
 ;; Company comes with many back-ends, e.g. `company-elisp'.  These are
-;; distributed in individual files and can be used individually.
+;; distributed in separate files and can be used individually.
 ;;
 ;; Place company.el and the back-ends you want to use in a directory and add the
 ;; following to your .emacs:
 ;;
 ;; (defun company-my-backend (command &optional arg &rest ignored)
 ;;   (case command
-;;     ('prefix (when (looking-back "foo\\>")
-;;                (match-string 0)))
-;;     ('candidates (list "foobar" "foobaz" "foobarbaz"))
-;;     ('meta (format "This value is named %s" arg))))
-;;
-;; Sometimes it is a good idea to mix two back-ends together, for example to
-;; enrich gtags with dabbrev text (to emulate local variables):
+;;     (prefix (when (looking-back "foo\\>")
+;;               (match-string 0)))
+;;     (candidates (list "foobar" "foobaz" "foobarbaz"))
+;;     (meta (format "This value is named %s" arg))))
 ;;
-;; (defun gtags-gtags-dabbrev-backend (command &optional arg &rest ignored)
-;;   (case command
-;;     (prefix (company-gtags 'prefix))
-;;     (candidates (append (company-gtags 'candidates arg)
-;;                         (company-dabbrev 'candidates 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).
+;; To do this, add a list with both back-ends as an element in company-backends.
 ;;
 ;; Known Issues:
 ;; When point is at the very end of the buffer, the pseudo-tooltip appears very
 ;;
 ;;; Change Log:
 ;;
-;;    Added `global-company-mode'.
-;;    Performance enhancements.
-;;    Added `company-eclim' back-end.
-;;    Added safer workaround for Emacs `posn-col-row' bug.
-;;
-;; 2009-04-18 (0.4)
-;;    Automatic completion is now aborted if the prefix gets too short.
-;;    Added option `company-dabbrev-time-limit'.
-;;    `company-backends' now supports merging back-ends.
-;;    Added back-end `company-dabbrev-code' for generic code.
-;;    Fixed `company-begin-with'.
-;;
-;; 2009-04-15 (0.3.1)
-;;    Added 'stop prefix to prevent dabbrev from completing inside of symbols.
-;;    Fixed issues with tabbar-mode and line-spacing.
-;;    Performance enhancements.
-;;
-;; 2009-04-12 (0.3)
-;;    Added `company-begin-commands' option.
-;;    Added abbrev, tempo and Xcode back-ends.
-;;    Back-ends are now interactive.  You can start them with M-x backend-name.
-;;    Added `company-begin-with' for starting company from elisp-code.
-;;    Added hooks.
-;;    Added `company-require-match' and `company-auto-complete' options.
-;;
-;; 2009-04-05 (0.2.1)
-;;    Improved Emacs Lisp back-end behavior for local variables.
-;;    Added `company-elisp-detect-function-context' option.
-;;    The mouse can now be used for selection.
-;;
-;; 2009-03-22 (0.2)
-;;    Added `company-show-location'.
-;;    Added etags back-end.
-;;    Added work-around for end-of-buffer bug.
-;;    Added `company-filter-candidates'.
-;;    More local Lisp variables are now included in the candidates.
-;;
-;; 2009-03-21 (0.1.5)
-;;    Fixed elisp documentation buffer always showing the same doc.
-;;    Added `company-echo-strip-common-frontend'.
-;;    Added `company-show-numbers' option and M-0 ... M-9 default bindings.
-;;    Don't hide the echo message if it isn't shown.
-;;
-;; 2009-03-20 (0.1)
-;;    Initial release.
-;;
+;; See NEWS.md in the repository.
+
 ;;; Code:
 
 (eval-when-compile (require 'cl))
 (add-to-list 'debug-ignored-errors "^Company not ")
 (add-to-list 'debug-ignored-errors "^No candidate number ")
 (add-to-list 'debug-ignored-errors "^Cannot complete at point$")
+(add-to-list 'debug-ignored-errors "^No other back-end$")
 
 (defgroup company nil
   "Extensible inline text completion mechanism"
   :group 'abbrev
   :group 'convenience
-  :group 'maching)
+  :group 'matching)
 
 (defface company-tooltip
-  '((t :background "yellow"
-       :foreground "black"))
-  "*Face used for the tool tip."
+  '((default :foreground "black")
+    (((class color) (min-colors 88) (background light))
+     (:background "cornsilk"))
+    (((class color) (min-colors 88) (background dark))
+     (:background "yellow")))
+  "Face used for the tool tip."
   :group 'company)
 
 (defface company-tooltip-selection
   '((default :inherit company-tooltip)
-    (((class color) (min-colors 88)) (:background "orange1"))
+    (((class color) (min-colors 88) (background light))
+     (:background "light blue"))
+    (((class color) (min-colors 88) (background dark))
+     (:background "orange1"))
     (t (:background "green")))
-  "*Face used for the selection in the tool tip."
+  "Face used for the selection in the tool tip."
   :group 'company)
 
 (defface company-tooltip-mouse
   '((default :inherit highlight))
-  "*Face used for the tool tip item under the mouse."
+  "Face used for the tool tip item under the mouse."
   :group 'company)
 
 (defface company-tooltip-common
-  '((t :inherit company-tooltip
-       :foreground "red"))
-  "*Face used for the common completion in the tool tip."
+  '((default :inherit company-tooltip)
+    (((background light))
+     :foreground "darkred")
+    (((background dark))
+     :foreground "red"))
+  "Face used for the common completion in the tool tip."
   :group 'company)
 
 (defface company-tooltip-common-selection
-  '((t :inherit company-tooltip-selection
-       :foreground "red"))
-  "*Face used for the selected common completion in the tool tip."
+  '((default :inherit company-tooltip-selection)
+    (((background light))
+     :foreground "darkred")
+    (((background dark))
+     :foreground "red"))
+  "Face used for the selected common completion in the tool tip."
   :group 'company)
 
-(defcustom company-tooltip-limit 10
-  "*The maximum number of candidates in the tool tip"
-  :group 'company
-  :type 'integer)
-
 (defface company-preview
   '((t :background "blue4"
        :foreground "wheat"))
-  "*Face used for the completion preview."
+  "Face used for the completion preview."
   :group 'company)
 
 (defface company-preview-common
   '((t :inherit company-preview
        :foreground "red"))
-  "*Face used for the common part of the completion preview."
+  "Face used for the common part of the completion preview."
   :group 'company)
 
 (defface company-preview-search
   '((t :inherit company-preview
        :background "blue1"))
-  "*Face used for the search string in the completion preview."
+  "Face used for the search string in the completion preview."
   :group 'company)
 
 (defface company-echo nil
-  "*Face used for completions in the echo area."
+  "Face used for completions in the echo area."
   :group 'company)
 
 (defface company-echo-common
   '((((background dark)) (:foreground "firebrick1"))
     (((background light)) (:background "firebrick4")))
-  "*Face used for the common part of completions in the echo area."
+  "Face used for the common part of completions in the echo area."
   :group 'company)
 
 (defun company-frontends-set (variable value)
   (set variable value))
 
 (defcustom company-frontends '(company-pseudo-tooltip-unless-just-one-frontend
-                               company-preview-frontend
+                               company-preview-if-just-one-frontend
                                company-echo-metadata-frontend)
-  "*The list of active front-ends (visualizations).
+  "The list of active front-ends (visualizations).
 Each front-end is a function that takes one argument.  It is called with
 one of the following arguments:
 
@@ -252,8 +212,20 @@ The visualized data is stored in `company-prefix', `company-candidates',
                                 company-preview-if-just-one-frontend)
                          (function :tag "custom function" nil))))
 
+(defcustom company-tooltip-limit 10
+  "The maximum number of candidates in the tool tip"
+  :group 'company
+  :type 'integer)
+
+(defcustom company-tooltip-minimum 6
+  "The minimum height of the tool tip.
+If this many lines are not available, prefer to display the tooltip above."
+  :group 'company
+  :type 'integer)
+
 (defvar company-safe-backends
   '((company-abbrev . "Abbrev")
+    (company-clang . "clang")
     (company-css . "CSS")
     (company-dabbrev . "dabbrev for plain text")
     (company-dabbrev-code . "dabbrev for code")
@@ -266,6 +238,8 @@ The visualized data is stored in `company-prefix', `company-candidates',
     (company-keywords . "Programming language keywords")
     (company-nxml . "nxml")
     (company-oddmuse . "Oddmuse")
+    (company-pysmell . "PySmell")
+    (company-ropemacs . "ropemacs")
     (company-semantic . "CEDET Semantic")
     (company-tempo . "Tempo templates")
     (company-xcode . "Xcode")))
@@ -279,56 +253,93 @@ The visualized data is stored in `company-prefix', `company-candidates',
                         (assq backend company-safe-backends))
                 (return t))))))
 
+(defun company-capf (command &optional arg &rest args)
+  "`company-mode' back-end using `completion-at-point-functions'.
+Requires Emacs 24.1 or newer."
+  (interactive (list 'interactive))
+  (case command
+    (interactive (company-begin-backend 'company-capf))
+    (prefix
+     (let ((res (run-hook-wrapped 'completion-at-point-functions
+                                  ;; Ignore misbehaving functions.
+                                  #'completion--capf-wrapper 'optimist)))
+       (when (consp res)
+         (if (> (nth 2 res) (point))
+             'stop
+           (buffer-substring-no-properties (nth 1 res) (point))))))
+    (candidates
+     (let ((res (run-hook-wrapped 'completion-at-point-functions
+                                  ;; Ignore misbehaving functions.
+                                  #'completion--capf-wrapper 'optimist)))
+       (when (consp res)
+         (all-completions arg (nth 3 res)
+                          (plist-get (nthcdr 4 res) :predicate)))))))
+
 (defcustom company-backends '(company-elisp company-nxml company-css
-                              company-eclim company-semantic company-xcode
+                              company-clang company-semantic company-eclim
+                              company-xcode company-ropemacs
                               (company-gtags company-etags company-dabbrev-code
                                company-keywords)
                               company-oddmuse company-files company-dabbrev)
-  "*The list of active back-ends (completion engines).
+  "The list of active back-ends (completion engines).
 Each list elements can itself be a list of back-ends.  In that case their
 completions are merged.  Otherwise only the first matching back-end returns
 results.
 
+`company-begin-backend' can be used to start a specific back-end,
+`company-other-backend' will skip to the next matching back-end in the list.
+
 Each back-end is a function that takes a variable number of arguments.
 The first argument is the command requested from the back-end.  It is one
 of the following:
 
-'prefix: The back-end should return the text to be completed.  It must be
+`prefix': The back-end should return the text to be completed.  It must be
 text immediately before `point'.  Returning nil passes control to the next
 back-end.  The function should return 'stop if it should complete but cannot
-\(e.g. if it is in the middle of a string\).
+\(e.g. if it is in the middle of a string\).  If the returned value is only
+part of the prefix (e.g. the part after \"->\" in C), the back-end may return a
+cons of prefix and prefix length, which is then used in the
+`company-minimum-prefix-length' test.
 
-'candidates: The second argument is the prefix to be completed.  The
+`candidates': The second argument is the prefix to be completed.  The
 return value should be a list of candidates that start with the prefix.
 
 Optional commands:
 
-'sorted: The back-end may return t here to indicate that the candidates
+`sorted': The back-end may return t here to indicate that the candidates
 are sorted and will not need to be sorted again.
 
-'duplicates: If non-nil, company will take care of removing duplicates
+`duplicates': If non-nil, company will take care of removing duplicates
 from the list.
 
-'no-cache: Usually company doesn't ask for candidates again as completion
+`no-cache': Usually company doesn't ask for candidates again as completion
 progresses, unless the back-end returns t for this command.  The second
 argument is the latest prefix.
 
-'meta: The second argument is a completion candidate.  The back-end should
+`meta': The second argument is a completion candidate.  The back-end should
 return a (short) documentation string for it.
 
-'doc-buffer: The second argument is a completion candidate.  The back-end should
-create a buffer (preferably with `company-doc-buffer'), fill it with
-documentation and return it.
+`doc-buffer': The second argument is a completion candidate.
+The back-end should create a buffer (preferably with `company-doc-buffer'),
+fill it with documentation and return it.
 
-'location: The second argument is a completion candidate.  The back-end can
+`location': The second argument is a completion candidate.  The back-end can
 return the cons of buffer and buffer location, or of file and line
 number where the completion candidate was defined.
 
-'require-match: If this value is t, the user is not allowed to enter anything
-not offering as a candidate.  Use with care!  The default value nil gives the
+`require-match': If this value is t, the user is not allowed to enter anything
+not offered as a candidate.  Use with care!  The default value nil gives the
 user that choice with `company-require-match'.  Return value 'never overrides
 that option the other way around.
 
+`init': Called once for each buffer, the back-end can check for external
+programs and files and load any required libraries.  Raising an error here will
+show up in message log once, and the backend will not be used for completion.
+
+`post-completion': Called after a completion candidate has been inserted into
+the buffer.  The second argument is the candidate.  Can be used to modify it,
+e.g. to expand a snippet.
+
 The back-end should return nil for all commands it does not support or
 does not know about.  It should also be callable interactively and use
 `company-begin-backend' to start itself in that case."
@@ -346,35 +357,38 @@ does not know about.  It should also be callable interactively and use
                                      company-safe-backends)
                            (symbol :tag "User defined"))))))
 
-(put 'company-backends 'safe-local-variable 'company-safe-backend-p)
+(put 'company-backends 'safe-local-variable 'company-safe-backends-p)
 
 (defcustom company-completion-started-hook nil
-  "*Hook run when company starts completing.
+  "Hook run when company starts completing.
 The hook is called with one argument that is non-nil if the completion was
 started manually."
   :group 'company
   :type 'hook)
 
 (defcustom company-completion-cancelled-hook nil
-  "*Hook run when company cancels completing.
+  "Hook run when company cancels completing.
 The hook is called with one argument that is non-nil if the completion was
 aborted manually."
   :group 'company
   :type 'hook)
 
 (defcustom company-completion-finished-hook nil
-  "*Hook run when company successfully completes.
-The hook is called with the selected candidate as an argument."
+  "Hook run when company successfully completes.
+The hook is called with the selected candidate as an argument.
+
+If you indend to use it to post-process candidates from a specific back-end,
+consider using the `post-completion' command instead."
   :group 'company
   :type 'hook)
 
 (defcustom company-minimum-prefix-length 3
-  "*The minimum prefix length for automatic completion."
+  "The minimum prefix length for automatic completion."
   :group 'company
   :type '(integer :tag "prefix length"))
 
 (defcustom company-require-match 'company-explicit-action-p
-  "*If enabled, disallow non-matching input.
+  "If enabled, disallow non-matching input.
 This can be a function do determine if a match is required.
 
 This can be overridden by the back-end, if it returns t or 'never to
@@ -406,7 +420,7 @@ completion.  If it is a list of syntax description characters (see
 This can also be a function, which is called with the new input and should
 return non-nil if company should auto-complete.
 
-A character that is part of a valid candidate never starts auto-completion."
+A character that is part of a valid candidate never triggers auto-completion."
   :group 'company
   :type '(choice (string :tag "Characters")
                  (set :tag "Syntax"
@@ -427,7 +441,7 @@ A character that is part of a valid candidate never starts auto-completion."
                  (function :tag "Predicate function")))
 
 (defcustom company-idle-delay .7
-  "*The idle delay in seconds until automatic completions starts.
+  "The idle delay in seconds until automatic completions starts.
 A value of nil means never complete automatically, t means complete
 immediately when a prefix of `company-minimum-prefix-length' is reached."
   :group 'company
@@ -436,7 +450,7 @@ immediately when a prefix of `company-minimum-prefix-length' is reached."
                  (number :tag "seconds")))
 
 (defcustom company-begin-commands t
-  "*A list of commands following which company will start completing.
+  "A list of commands following which company will start completing.
 If this is t, it will complete after any command.  See `company-idle-delay'.
 
 Alternatively any command with a non-nil 'company-begin property is treated as
@@ -447,13 +461,13 @@ if it was on this list."
                  (repeat :tag "Commands" function)))
 
 (defcustom company-show-numbers nil
-  "*If enabled, show quick-access numbers for the first ten candidates."
+  "If enabled, show quick-access numbers for the first ten candidates."
   :group 'company
   :type '(choice (const :tag "off" nil)
                  (const :tag "on" t)))
 
 (defvar company-end-of-buffer-workaround t
-  "*Work around a visualization bug when completing at the end of the buffer.
+  "Work around a visualization bug when completing at the end of the buffer.
 The work-around consists of adding a newline.")
 
 ;;; mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -467,16 +481,18 @@ The work-around consists of adding a newline.")
     (define-key keymap "\C-g" 'company-abort)
     (define-key keymap (kbd "M-n") 'company-select-next)
     (define-key keymap (kbd "M-p") 'company-select-previous)
-    (define-key keymap (kbd "<down>") 'company-select-next)
-    (define-key keymap (kbd "<up>") 'company-select-previous)
+    (define-key keymap (kbd "<down>") 'company-select-next-or-abort)
+    (define-key keymap (kbd "<up>") 'company-select-previous-or-abort)
     (define-key keymap [down-mouse-1] 'ignore)
     (define-key keymap [down-mouse-3] 'ignore)
     (define-key keymap [mouse-1] 'company-complete-mouse)
     (define-key keymap [mouse-3] 'company-select-mouse)
     (define-key keymap [up-mouse-1] 'ignore)
     (define-key keymap [up-mouse-3] 'ignore)
-    (define-key keymap "\C-m" 'company-complete-selection)
-    (define-key keymap "\t" 'company-complete-common)
+    (define-key keymap [return] 'company-complete-selection)
+    (define-key keymap (kbd "RET") 'company-complete-selection)
+    (define-key keymap [tab] 'company-complete-common)
+    (define-key keymap (kbd "TAB") 'company-complete-common)
     (define-key keymap (kbd "<f1>") 'company-show-doc-buffer)
     (define-key keymap "\C-w" 'company-show-location)
     (define-key keymap "\C-s" 'company-search-candidates)
@@ -488,6 +504,8 @@ The work-around consists of adding a newline.")
     keymap)
   "Keymap that is enabled during an active completion.")
 
+(defvar company--disabled-backends nil)
+
 (defun company-init-backend (backend)
   (and (symbolp backend)
        (not (fboundp backend))
@@ -495,17 +513,27 @@ The work-around consists of adding a newline.")
 
   (if (or (symbolp backend)
           (functionp backend))
-      (if (ignore-errors (funcall backend 'init) t)
-          (put backend 'company-init t)
-        (put backend 'company-init 'failed)
-        (message "Company back-end '%s' could not be initialized"
-                 backend)
-        nil)
+      (condition-case err
+          (progn
+            (funcall backend 'init)
+            (put backend 'company-init t))
+        (error
+         (put backend 'company-init 'failed)
+         (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)
+         nil))
     (mapc 'company-init-backend backend)))
 
+(defvar company-default-lighter " company")
+
+(defvar company-lighter company-default-lighter)
+(make-variable-buffer-local 'company-lighter)
+
 ;;;###autoload
 (define-minor-mode company-mode
-  "\"complete anything\"; in in-buffer completion framework.
+  "\"complete anything\"; is an in-buffer completion framework.
 Completion starts automatically, depending on the values
 `company-idle-delay' and `company-minimum-prefix-length'.
 
@@ -528,7 +556,7 @@ regular keymap (`company-mode-map'):
 keymap during active completions (`company-active-map'):
 
 \\{company-active-map}"
-  nil " comp" company-mode-map
+  nil company-lighter company-mode-map
   (if company-mode
       (progn
         (add-hook 'pre-command-hook 'company-pre-command nil t)
@@ -539,8 +567,12 @@ keymap during active completions (`company-active-map'):
     (company-cancel)
     (kill-local-variable 'company-point)))
 
-(define-globalized-minor-mode global-company-mode company-mode
-  (lambda () (company-mode 1)))
+;;;###autoload
+(define-globalized-minor-mode global-company-mode company-mode company-mode-on)
+
+(defun company-mode-on ()
+  (unless (or noninteractive (eq (aref (buffer-name) 0) ?\s))
+    (company-mode 1)))
 
 (defsubst company-assert-enabled ()
   (unless company-mode
@@ -549,31 +581,28 @@ keymap during active completions (`company-active-map'):
 
 ;;; keymaps ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(defvar company-overriding-keymap-bound nil)
-(make-variable-buffer-local 'company-overriding-keymap-bound)
-
-(defvar company-old-keymap nil)
-(make-variable-buffer-local 'company-old-keymap)
-
 (defvar company-my-keymap nil)
 (make-variable-buffer-local 'company-my-keymap)
 
+(defvar company-emulation-alist '((t . nil)))
+
 (defsubst company-enable-overriding-keymap (keymap)
-  (setq company-my-keymap keymap)
-  (when company-overriding-keymap-bound
-    (company-uninstall-map)))
+  (company-uninstall-map)
+  (setq company-my-keymap keymap))
+
+(defun company-ensure-emulation-alist ()
+  (unless (eq 'company-emulation-alist (car emulation-mode-map-alists))
+    (setq emulation-mode-map-alists
+          (cons 'company-emulation-alist
+                (delq 'company-emulation-alist emulation-mode-map-alists)))))
 
 (defun company-install-map ()
-  (unless (or company-overriding-keymap-bound
+  (unless (or (cdar company-emulation-alist)
               (null company-my-keymap))
-    (setq company-old-keymap overriding-terminal-local-map
-          overriding-terminal-local-map company-my-keymap
-          company-overriding-keymap-bound t)))
+    (setf (cdar company-emulation-alist) company-my-keymap)))
 
 (defun company-uninstall-map ()
-  (when (eq overriding-terminal-local-map company-my-keymap)
-    (setq overriding-terminal-local-map company-old-keymap
-          company-overriding-keymap-bound nil)))
+  (setf (cdar company-emulation-alist) nil))
 
 ;; Hack:
 ;; Emacs calculates the active keymaps before reading the event.  That means we
@@ -628,23 +657,41 @@ keymap during active completions (`company-active-map'):
         (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)
   (if (functionp company-backend)
       (apply company-backend args)
     (apply 'company--multi-backend-adapter company-backend args)))
 
 (defun company--multi-backend-adapter (backends command &rest args)
-  (case command
-    ('candidates
-     (apply 'append (mapcar (lambda (backend) (apply backend command args))
-                            backends)))
-    ('sorted nil)
-    ('duplicates t)
-    (otherwise
-     (let (value)
-       (dolist (backend backends)
-         (when (setq value (apply backend command args))
-           (return value)))))))
+  (let ((backends (loop for b in backends
+                        when (not (and (symbolp b)
+                                       (eq 'failed (get b 'company-init))))
+                        collect b)))
+    (case command
+      (candidates
+       (loop for backend in backends
+             when (equal (funcall backend 'prefix)
+                         (car args))
+             append (apply backend 'candidates args)))
+      (sorted nil)
+      (duplicates t)
+      (otherwise
+       (let (value)
+         (dolist (backend backends)
+           (when (setq value (apply backend command args))
+             (return value))))))))
 
 ;;; completion mechanism ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
@@ -679,6 +726,10 @@ keymap during active completions (`company-active-map'):
   "Non-nil, if explicit completion took place.")
 (make-variable-buffer-local 'company--explicit-action)
 
+(defvar company--auto-completion nil
+  "Non-nil when current candidate is being completed automatically.
+Controlled by `company-auto-complete'.")
+
 (defvar company--point-max nil)
 (make-variable-buffer-local 'company--point-max)
 
@@ -693,6 +744,19 @@ keymap during active completions (`company-active-map'):
 (defsubst company-strip-prefix (str)
   (substring str (length company-prefix)))
 
+(defmacro company-with-candidate-inserted (candidate &rest body)
+  "Evaluate BODY with CANDIDATE temporarily inserted.
+This is a tool for back-ends that need candidates inserted before they
+can retrieve meta-data for them."
+  (declare (indent 1))
+  `(let ((inhibit-modification-hooks t)
+         (inhibit-point-motion-hooks t)
+         (modified-p (buffer-modified-p)))
+     (insert (company-strip-prefix ,candidate))
+     (unwind-protect
+         (progn ,@body)
+       (delete-region company-point (point)))))
+
 (defun company-explicit-action-p ()
   "Return whether explicit completion action was taken by the user."
   (or company--explicit-action
@@ -705,7 +769,11 @@ keymap during active completions (`company-active-map'):
 
 (defun company--should-complete ()
   (and (not (or buffer-read-only overriding-terminal-local-map
-                overriding-local-map))
+                overriding-local-map
+                (minibufferp)))
+       ;; Check if in the middle of entering a key combination.
+       (or (equal (this-command-keys-vector) [])
+           (not (keymapp (key-binding (this-command-keys-vector)))))
        (eq company-idle-delay t)
        (or (eq t company-begin-commands)
            (memq this-command company-begin-commands)
@@ -753,16 +821,22 @@ keymap during active completions (`company-active-map'):
   (push (cons company-prefix company-candidates) company-candidates-cache)
   ;; Calculate common.
   (let ((completion-ignore-case (company-call-backend 'ignore-case)))
-    (setq company-common (try-completion company-prefix company-candidates)))
+    (setq company-common (company--safe-candidate
+                          (try-completion company-prefix company-candidates))))
   (when (eq company-common t)
     (setq company-candidates nil)))
 
+(defun company--safe-candidate (str)
+  (or (company-call-backend 'crop str)
+      str))
+
 (defun company-calculate-candidates (prefix)
-  (let ((candidates (cdr (assoc prefix company-candidates-cache))))
+  (let ((candidates (cdr (assoc prefix company-candidates-cache)))
+        (ignore-case (company-call-backend 'ignore-case)))
     (or candidates
         (when company-candidates-cache
           (let ((len (length prefix))
-                (completion-ignore-case (company-call-backend 'ignore-case))
+                (completion-ignore-case ignore-case)
                 prev)
             (dotimes (i (1+ len))
               (when (setq prev (cdr (assoc (substring prefix 0 (- len i))
@@ -784,12 +858,13 @@ keymap during active completions (`company-active-map'):
               (while c2
                 (setcdr c2 (progn (while (equal (pop c2) (car c2)))
                                   c2)))))))
-    (if (or (cdr candidates)
-            (not (equal (car candidates) prefix)))
-        ;; Don't start when already completed and unique.
-        candidates
-      ;; Not the right place? maybe when setting?
-      (and company-candidates t))))
+    (when candidates
+      (if (or (cdr candidates)
+              (not (eq t (compare-strings (car candidates) nil nil
+                                          prefix nil nil ignore-case))))
+          candidates
+        ;; Already completed and unique; don't start.
+        t))))
 
 (defun company-idle-begin (buf win tick pos)
   (and company-mode
@@ -820,7 +895,27 @@ keymap during active completions (`company-active-map'):
 (defun company-manual-begin ()
   (interactive)
   (setq company--explicit-action t)
-  (company-auto-begin))
+  (unwind-protect
+      (company-auto-begin)
+    (unless company-candidates
+      (setq company--explicit-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))
+  (unless company-candidates
+    (error "No other back-end")))
 
 (defun company-require-match-p ()
   (let ((backend-value (company-call-backend 'require-match)))
@@ -866,7 +961,8 @@ keymap during active completions (`company-active-map'):
         ;; auto-complete
         (save-excursion
           (goto-char company-point)
-          (company-complete-selection)
+          (let ((company--auto-completion t))
+            (company-complete-selection))
           nil))
        ((and (company--string-incremental-p company-prefix new-prefix)
              (company-require-match-p))
@@ -880,17 +976,23 @@ keymap during active completions (`company-active-map'):
         (company-cancel company-prefix)
         nil)))))
 
+(defun company--good-prefix-p (prefix)
+  (and (or (company-explicit-action-p)
+           (unless (eq prefix 'stop)
+             (>= (or (cdr-safe prefix) (length prefix))
+                 company-minimum-prefix-length)))
+       (stringp (or (car-safe prefix) prefix))))
+
 (defun company--continue ()
   (when (company-call-backend 'no-cache company-prefix)
     ;; Don't complete existing candidates, fetch new ones.
     (setq company-candidates-cache nil))
   (let* ((new-prefix (company-call-backend 'prefix))
-         (c (when (and (stringp new-prefix)
-                       (or (company-explicit-action-p)
-                           (>= (length new-prefix)
-                               company-minimum-prefix-length))
+         (c (when (and (company--good-prefix-p new-prefix)
+                       (setq new-prefix (or (car-safe new-prefix) new-prefix))
                        (= (- (point) (length new-prefix))
                           (- company-point (length company-prefix))))
+              (setq new-prefix (or (car-safe new-prefix) new-prefix))
               (company-calculate-candidates new-prefix))))
     (or (cond
          ((eq c t)
@@ -921,13 +1023,17 @@ keymap during active completions (`company-active-map'):
                   (funcall backend 'prefix))
               (company--multi-backend-adapter backend 'prefix)))
       (when prefix
-        (when (and (stringp prefix)
-                   (>= (length prefix) company-minimum-prefix-length))
-          (setq company-backend backend
+        (when (company--good-prefix-p prefix)
+          (setq prefix (or (car-safe prefix) prefix)
+                company-backend backend
                 c (company-calculate-candidates prefix))
           ;; t means complete/unique.  We don't start, so no hooks.
-          (when (consp c)
+          (if (not (consp c))
+              (when company--explicit-action
+                (message "No completion found"))
             (setq company-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))
@@ -935,15 +1041,15 @@ keymap during active completions (`company-active-map'):
         (return c)))))
 
 (defun company-begin ()
-  (setq company-candidates
-        (or (and company-candidates (company--continue))
-            (and (company--should-complete) (company--begin-new))))
+  (or (and company-candidates (company--continue))
+      (and (company--should-complete) (company--begin-new)))
   (when company-candidates
     (when (and company-end-of-buffer-workaround (eobp))
       (save-excursion (insert "\n"))
       (setq company-added-newline (buffer-chars-modified-tick)))
     (setq company-point (point)
           company--point-max (point-max))
+    (company-ensure-emulation-alist)
     (company-enable-overriding-keymap company-active-map)
     (company-call-frontends 'update)))
 
@@ -957,7 +1063,10 @@ keymap during active completions (`company-active-map'):
        (set-buffer-modified-p nil))
   (when company-prefix
     (if (stringp result)
-        (run-hook-with-args 'company-completion-finished-hook result)
+        (progn
+          (company-call-backend 'pre-completion result)
+          (run-hook-with-args 'company-completion-finished-hook result)
+          (company-call-backend 'post-completion result))
       (run-hook-with-args 'company-completion-cancelled-hook result)))
   (setq company-added-newline nil
         company-backend nil
@@ -970,6 +1079,7 @@ keymap during active completions (`company-active-map'):
         company-selection 0
         company-selection-changed nil
         company--explicit-action nil
+        company-lighter company-default-lighter
         company--point-max nil
         company-point nil)
   (when company-timer
@@ -1124,9 +1234,7 @@ keymap during active completions (`company-active-map'):
   (interactive)
   (company-search-assert-enabled)
   (company-search-mode 0)
-  (when last-input-event
-    (clear-this-command-keys t)
-    (setq unread-command-events (list last-input-event))))
+  (company--unread-last-input))
 
 (defvar company-search-map
   (let ((i 0)
@@ -1135,7 +1243,7 @@ keymap during active completions (`company-active-map'):
         (set-char-table-range (nth 1 keymap) (cons #x100 (max-char))
                               'company-search-printing-char)
       (with-no-warnings
-        ;; obselete in Emacs 23
+        ;; obsolete in Emacs 23
         (let ((l (generic-character-list))
               (table (nth 1 keymap)))
           (while l
@@ -1230,6 +1338,24 @@ followed by `company-search-kill-others' after each input."
   (when (company-manual-begin)
     (company-set-selection (1- company-selection))))
 
+(defun company-select-next-or-abort ()
+  "Select the next candidate if more than one, else abort
+and invoke the normal binding."
+  (interactive)
+  (if (> company-candidates-length 1)
+      (company-select-next)
+    (company-abort)
+    (company--unread-last-input)))
+
+(defun company-select-previous-or-abort ()
+  "Select the previous candidate if more than one, else abort
+and invoke the normal binding."
+  (interactive)
+  (if (> company-candidates-length 1)
+      (company-select-previous)
+    (company-abort)
+    (company--unread-last-input)))
+
 (defun company-select-mouse (event)
   "Select the candidate picked by the mouse."
   (interactive "e")
@@ -1249,7 +1375,10 @@ followed by `company-search-kill-others' after each input."
   "Complete the selected candidate."
   (interactive)
   (when (company-manual-begin)
-    (company-finish (nth company-selection company-candidates))))
+    (let ((result (nth company-selection company-candidates)))
+      (when company--auto-completion
+        (setq result (company--safe-candidate result)))
+      (company-finish result))))
 
 (defun company-complete-common ()
   "Complete the common part of all candidates."
@@ -1298,13 +1427,20 @@ To show the number next to the candidates in some back-ends, enable
     (make-string len ?\ )))
 
 (defsubst company-safe-substring (str from &optional to)
-  (let ((len (length str)))
-    (if (> from len)
-        ""
-      (if (and to (> to len))
-          (concat (substring str from)
-                  (company-space-string (- to len)))
-        (substring str from to)))))
+  (if (> from (string-width str))
+      ""
+    (with-temp-buffer
+      (insert str)
+      (move-to-column from)
+      (let ((beg (point)))
+        (if to
+            (progn
+              (move-to-column to)
+              (concat (buffer-substring beg (point))
+                      (let ((padding (- to (current-column))))
+                        (when (> padding 0)
+                          (company-space-string padding)))))
+          (buffer-substring beg (point-max)))))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
@@ -1323,45 +1459,59 @@ To show the number next to the candidates in some back-ends, enable
     (erase-buffer)
     (current-buffer)))
 
-(defmacro company-electric (&rest body)
+(defvar company--electric-commands
+  '(scroll-other-window scroll-other-window-down)
+  "List of Commands that won't break out of electric commands.")
+
+(defmacro company--electric-do (&rest body)
   (declare (indent 0) (debug t))
   `(when (company-manual-begin)
      (save-window-excursion
        (let ((height (window-height))
-             (row (company--row)))
+             (row (company--row))
+             cmd)
          ,@body
          (and (< (window-height) height)
               (< (- (window-height) row 2) company-tooltip-limit)
               (recenter (- (window-height) row 2)))
-         (while (eq 'scroll-other-window
-                    (key-binding (vector (list (read-event)))))
-           (call-interactively 'scroll-other-window))
-         (when last-input-event
-           (clear-this-command-keys t)
-           (setq unread-command-events (list last-input-event)))))))
+         (while (memq (setq cmd (key-binding (vector (list (read-event)))))
+                      company--electric-commands)
+           (call-interactively cmd))
+         (company--unread-last-input)))))
+
+(defun company--unread-last-input ()
+  (when last-input-event
+    (clear-this-command-keys t)
+    (setq unread-command-events (list last-input-event))))
 
 (defun company-show-doc-buffer ()
   "Temporarily show a buffer with the complete documentation for the selection."
   (interactive)
-  (company-electric
-    (let ((selected (nth company-selection company-candidates)))
-      (display-buffer (or (company-call-backend 'doc-buffer selected)
-                          (error "No documentation available")) t))))
+  (company--electric-do
+    (let* ((selected (nth company-selection company-candidates))
+           (doc-buffer (or (company-call-backend 'doc-buffer selected)
+                           (error "No documentation available"))))
+      (with-current-buffer doc-buffer
+        (goto-char (point-min)))
+      (display-buffer doc-buffer t))))
 (put 'company-show-doc-buffer 'company-keep t)
 
 (defun company-show-location ()
   "Temporarily display a buffer showing the selected candidate in context."
   (interactive)
-  (company-electric
+  (company--electric-do
     (let* ((selected (nth company-selection company-candidates))
            (location (company-call-backend 'location selected))
            (pos (or (cdr location) (error "No location available")))
            (buffer (or (and (bufferp (car location)) (car location))
                        (find-file-noselect (car location) t))))
       (with-selected-window (display-buffer buffer t)
-        (if (bufferp (car location))
-            (goto-char pos)
-          (goto-line pos))
+        (save-restriction
+          (widen)
+          (if (bufferp (car location))
+              (goto-char pos)
+            (goto-char (point-min))
+            (forward-line (1- pos))))
         (set-window-start nil (point))))))
 (put 'company-show-location 'company-keep t)
 
@@ -1377,7 +1527,8 @@ To show the number next to the candidates in some back-ends, enable
   (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)
-  (set-marker company-begin-with-marker nil))
+  (when company-begin-with-marker
+    (set-marker company-begin-with-marker nil)))
 
 (defun company-begin-backend (backend &optional callback)
   "Start a completion at point using BACKEND."
@@ -1393,7 +1544,9 @@ To show the number next to the candidates in some back-ends, enable
   (setq company-backend backend)
   ;; Return non-nil if active.
   (or (company-manual-begin)
-      (error "Cannot complete at point")))
+      (progn
+        (setq company-backend nil)
+        (error "Cannot complete at point"))))
 
 (defun company-begin-with (candidates
                            &optional prefix-length require-match callback)
@@ -1496,9 +1649,8 @@ Example:
 
 (defun company-buffer-lines (beg end)
   (goto-char beg)
-  (let ((row (company--row))
-        lines)
-    (while (and (equal (move-to-window-line (incf row)) row)
+  (let (lines)
+    (while (and (= 1 (vertical-motion 1))
                 (<= (point) end))
       (push (buffer-substring beg (min end (1- (point)))) lines)
       (setq beg (point)))
@@ -1511,19 +1663,36 @@ Example:
           new
           (company-safe-substring old (+ offset (length new)))))
 
-(defun company-replacement-string (old lines column nl)
+(defsubst company--length-limit (lst limit)
+  (if (nthcdr limit lst)
+      limit
+    (length lst)))
+
+(defun company--replacement-string (lines old column nl &optional align-top)
+
+  (let ((width (length (car lines))))
+    (when (> width (- (window-width) column))
+      (setq column (max 0 (- (window-width) width)))))
+
   (let (new)
-    ;; Inject into old lines.
+    (when align-top
+      ;; untouched lines first
+      (dotimes (i (- (length old) (length lines)))
+        (push (pop old) new)))
+    ;; length into old lines.
     (while old
       (push (company-modify-line (pop old) (pop lines) column) new))
     ;; Append whole new lines.
     (while lines
       (push (concat (company-space-string column) (pop lines)) new))
-    (concat (when nl "\n")
-            (mapconcat 'identity (nreverse new) "\n")
-            "\n")))
 
-(defun company-create-lines (column selection limit)
+    (let ((str (concat (when nl "\n")
+                       (mapconcat 'identity (nreverse new) "\n")
+                       "\n")))
+      (font-lock-append-text-property 0 (length str) 'face 'default str)
+      str)))
+
+(defun company--create-lines (selection limit)
 
   (let ((len company-candidates-length)
         (numbered 99999)
@@ -1552,7 +1721,7 @@ Example:
 
     (dotimes (i len)
       (setq width (max (length (pop lines-copy)) width)))
-    (setq width (min width (- (window-width) column)))
+    (setq width (min width (window-width)))
 
     (setq lines-copy lines)
 
@@ -1586,11 +1755,19 @@ Example:
 
 ;; show
 
-(defsubst company-pseudo-tooltip-height ()
-  "Calculate the appropriate tooltip height."
-  (max 3 (min company-tooltip-limit
-              (- (window-height) 2
-                 (count-lines (window-start) (point-at-bol))))))
+(defsubst company--window-inner-height ()
+  (let ((edges (window-inside-edges (selected-window))))
+    (- (nth 3 edges) (nth 1 edges))))
+
+(defsubst company--pseudo-tooltip-height ()
+  "Calculate the appropriate tooltip height.
+Returns a negative number if the tooltip should be displayed above point."
+  (let* ((lines (company--row))
+         (below (- (company--window-inner-height) 1 lines)))
+    (if (and (< below (min company-tooltip-minimum company-candidates-length))
+             (> lines below))
+        (- (max 3 (min company-tooltip-limit lines)))
+      (max 3 (min company-tooltip-limit below)))))
 
 (defun company-pseudo-tooltip-show (row column selection)
   (company-pseudo-tooltip-hide)
@@ -1598,27 +1775,32 @@ Example:
 
     (move-to-column 0)
 
-    (let* ((height (company-pseudo-tooltip-height))
-           (lines (company-create-lines column selection height))
-           (nl (< (move-to-window-line row) row))
-           (beg (point))
-           (end (save-excursion
-                  (move-to-window-line (+ row height))
-                  (point)))
-           (old-string
-            (mapcar 'company-untabify (company-buffer-lines beg end)))
-           str)
-
-      (setq company-pseudo-tooltip-overlay (make-overlay beg end))
-
-      (overlay-put company-pseudo-tooltip-overlay 'company-old old-string)
-      (overlay-put company-pseudo-tooltip-overlay 'company-column column)
-      (overlay-put company-pseudo-tooltip-overlay 'company-nl nl)
-      (overlay-put company-pseudo-tooltip-overlay 'company-before
-                   (company-replacement-string old-string lines column nl))
-      (overlay-put company-pseudo-tooltip-overlay 'company-height height)
-
-      (overlay-put company-pseudo-tooltip-overlay 'window (selected-window)))))
+    (let* ((height (company--pseudo-tooltip-height))
+           above)
+
+      (when (< height 0)
+        (setq row (+ row height -1)
+              above t))
+
+      (let* ((nl (< (move-to-window-line row) row))
+             (beg (point))
+             (end (save-excursion
+                    (move-to-window-line (+ row (abs height)))
+                    (point)))
+             (ov (make-overlay beg end))
+             (args (list (mapcar 'company-untabify
+                                 (company-buffer-lines beg end))
+                         column nl above)))
+
+        (setq company-pseudo-tooltip-overlay ov)
+        (overlay-put ov 'company-replacement-args args)
+        (overlay-put ov 'company-before
+                     (apply 'company--replacement-string
+                            (company--create-lines selection (abs height))
+                            args))
+
+        (overlay-put ov 'company-column column)
+        (overlay-put ov 'company-height height)))))
 
 (defun company-pseudo-tooltip-show-at-point (pos)
   (let ((col-row (company--col-row pos)))
@@ -1627,13 +1809,13 @@ Example:
                                    company-selection))))
 
 (defun company-pseudo-tooltip-edit (lines selection)
-  (let* ((old-string (overlay-get company-pseudo-tooltip-overlay 'company-old))
-         (column (overlay-get company-pseudo-tooltip-overlay 'company-column))
-         (nl (overlay-get company-pseudo-tooltip-overlay 'company-nl))
-         (height (overlay-get company-pseudo-tooltip-overlay 'company-height))
-         (lines (company-create-lines column selection height)))
+  (let ((column (overlay-get company-pseudo-tooltip-overlay 'company-column))
+        (height (overlay-get company-pseudo-tooltip-overlay 'company-height)))
     (overlay-put company-pseudo-tooltip-overlay 'company-before
-                 (company-replacement-string old-string lines column nl))))
+                 (apply 'company--replacement-string
+                        (company--create-lines selection (abs height))
+                        (overlay-get company-pseudo-tooltip-overlay
+                                     'company-replacement-args)))))
 
 (defun company-pseudo-tooltip-hide ()
   (when company-pseudo-tooltip-overlay
@@ -1652,24 +1834,36 @@ Example:
                  (overlay-get company-pseudo-tooltip-overlay 'company-before))
     (overlay-put company-pseudo-tooltip-overlay 'window (selected-window))))
 
+(defun company-pseudo-tooltip-guard ()
+  (buffer-substring-no-properties
+   (point) (overlay-start company-pseudo-tooltip-overlay)))
+
 (defun company-pseudo-tooltip-frontend (command)
-  "`company-mode' front-end similar to a tool-tip but based on overlays."
+  "`company-mode' front-end similar to a tool-tip but based on overlays."
   (case command
-    ('pre-command (company-pseudo-tooltip-hide-temporarily))
-    ('post-command
-     (unless (and (overlayp company-pseudo-tooltip-overlay)
-                  (equal (overlay-get company-pseudo-tooltip-overlay
-                                      'company-height)
-                         (company-pseudo-tooltip-height)))
-       ;; Redraw needed.
-       (company-pseudo-tooltip-show-at-point (- (point)
-                                                (length company-prefix))))
+    (pre-command (company-pseudo-tooltip-hide-temporarily))
+    (post-command
+     (let ((old-height (if (overlayp company-pseudo-tooltip-overlay)
+                           (overlay-get company-pseudo-tooltip-overlay
+                                        'company-height)
+                         0))
+           (new-height (company--pseudo-tooltip-height)))
+       (unless (and (>= (* old-height new-height) 0)
+                    (>= (abs old-height) (abs new-height))
+                    (equal (company-pseudo-tooltip-guard)
+                           (overlay-get company-pseudo-tooltip-overlay
+                                        'company-guard)))
+         ;; Redraw needed.
+         (company-pseudo-tooltip-show-at-point (- (point)
+                                                  (length company-prefix)))
+         (overlay-put company-pseudo-tooltip-overlay
+                      'company-guard (company-pseudo-tooltip-guard))))
      (company-pseudo-tooltip-unhide))
-    ('hide (company-pseudo-tooltip-hide)
-           (setq company-tooltip-offset 0))
-    ('update (when (overlayp company-pseudo-tooltip-overlay)
-               (company-pseudo-tooltip-edit company-candidates
-                                            company-selection)))))
+    (hide (company-pseudo-tooltip-hide)
+          (setq company-tooltip-offset 0))
+    (update (when (overlayp company-pseudo-tooltip-overlay)
+              (company-pseudo-tooltip-edit company-candidates
+                                           company-selection)))))
 
 (defun company-pseudo-tooltip-unless-just-one-frontend (command)
   "`company-pseudo-tooltip-frontend', but not shown for single candidates."
@@ -1715,11 +1909,11 @@ Example:
     (setq company-preview-overlay nil)))
 
 (defun company-preview-frontend (command)
-  "`company-mode' front-end showing the selection as if it had been inserted."
+  "`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))))
+    (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."
@@ -1734,7 +1928,7 @@ Example:
 
 (defvar company-echo-timer nil)
 
-(defvar company-echo-delay .1)
+(defvar company-echo-delay .01)
 
 (defun company-echo-show (&optional getter)
   (when getter
@@ -1747,8 +1941,16 @@ Example:
 (defsubst company-echo-show-soon (&optional getter)
   (when company-echo-timer
     (cancel-timer company-echo-timer))
-  (setq company-echo-timer (run-with-timer company-echo-delay nil
-                                           'company-echo-show getter)))
+  (setq company-echo-timer (run-with-timer 0 nil 'company-echo-show getter)))
+
+(defsubst company-echo-show-when-idle (&optional getter)
+  (when (sit-for .01)
+    (company-echo-show getter)))
+
+(defsubst company-echo-show-when-not-busy (&optional getter)
+  "Run `company-echo-show' with arg GETTER once Emacs isn't busy."
+  (when (sit-for company-echo-delay)
+    (company-echo-show getter)))
 
 (defun company-echo-format ()
 
@@ -1806,32 +2008,27 @@ Example:
             "}")))
 
 (defun company-echo-hide ()
-  (when company-echo-timer
-    (cancel-timer company-echo-timer))
   (unless (equal company-echo-last-msg "")
     (setq company-echo-last-msg "")
     (company-echo-show)))
 
 (defun company-echo-frontend (command)
-  "`company-mode' front-end showing the candidates in the echo area."
+  "`company-mode' front-end showing the candidates in the echo area."
   (case command
-    ('pre-command (company-echo-show-soon))
-    ('post-command (company-echo-show-soon 'company-echo-format))
-    ('hide (company-echo-hide))))
+    (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."
+  "`company-mode' front-end showing the candidates in the echo area."
   (case command
-    ('pre-command (company-echo-show-soon))
-    ('post-command (company-echo-show-soon 'company-echo-strip-common-format))
-    ('hide (company-echo-hide))))
+    (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."
+  "`company-mode' front-end showing the documentation in the echo area."
   (case command
-    ('pre-command (company-echo-show-soon))
-    ('post-command (company-echo-show-soon 'company-fetch-metadata))
-    ('hide (company-echo-hide))))
+    (post-command (company-echo-show-when-idle 'company-fetch-metadata))
+    (hide (company-echo-hide))))
 
 (provide 'company)
 ;;; company.el ends here