]> code.delx.au - gnu-emacs-elpa/blobdiff - company.el
New transformer: company-sort-prefer-same-case-prefix
[gnu-emacs-elpa] / company.el
index d61245eed51362e5cf6c0c77abd5a774018e9edd..28ed56be3286e6ce640b75efdbc50323dd7d6a88 100644 (file)
@@ -1,6 +1,6 @@
 ;;; company.el --- Modular text completion framework  -*- lexical-binding: t -*-
 
 ;;; company.el --- Modular text completion framework  -*- lexical-binding: t -*-
 
-;; Copyright (C) 2009-2015  Free Software Foundation, Inc.
+;; Copyright (C) 2009-2016  Free Software Foundation, Inc.
 
 ;; Author: Nikolaj Schumacher
 ;; Maintainer: Dmitry Gutov <dgutov@yandex.ru>
 
 ;; Author: Nikolaj Schumacher
 ;; Maintainer: Dmitry Gutov <dgutov@yandex.ru>
 
 ;;; Commentary:
 ;;
 
 ;;; Commentary:
 ;;
-;; Company is a modular completion mechanism.  Modules for retrieving completion
-;; candidates are called back-ends, modules for displaying them are front-ends.
+;; Company is a modular completion framework.  Modules for retrieving completion
+;; candidates are called backends, modules for displaying them are frontends.
 ;;
 ;;
-;; Company comes with many back-ends, e.g. `company-elisp'.  These are
+;; Company comes with many backends, e.g. `company-etags'.  These are
 ;; distributed in separate 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:
-;; (add-to-list 'load-path "/path/to/company")
-;; (autoload 'company-mode "company" nil t)
+;; Enable `company-mode' in all buffers with M-x global-company-mode.  For
+;; further information look at the documentation for `company-mode' (C-h f
+;; company-mode RET).
 ;;
 ;;
-;; Enable company-mode with M-x company-mode.  For further information look at
-;; the documentation for `company-mode' (C-h f company-mode RET)
-;;
-;; If you want to start a specific back-end, call it interactively or use
+;; If you want to start a specific backend, call it interactively or use
 ;; `company-begin-backend'.  For example:
 ;; M-x company-abbrev will prompt for and insert an abbrev.
 ;;
 ;; `company-begin-backend'.  For example:
 ;; M-x company-abbrev will prompt for and insert an abbrev.
 ;;
-;; To write your own back-end, look at the documentation for `company-backends'.
+;; To write your own backend, look at the documentation for `company-backends'.
 ;; Here is a simple example completing "foo":
 ;;
 ;; (defun company-my-backend (command &optional arg &rest ignored)
 ;;   (pcase command
 ;; Here is a simple example completing "foo":
 ;;
 ;; (defun company-my-backend (command &optional arg &rest ignored)
 ;;   (pcase command
-;;     (`prefix (when (looking-back "foo\\>")
-;;               (match-string 0)))
+;;     (`prefix (company-grab-symbol))
 ;;     (`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).
-;; To do this, add a list with both back-ends as an element in company-backends.
+;; Sometimes it is a good idea to mix several backends together, for example to
+;; enrich gtags with dabbrev-code results (to emulate local variables).  To do
+;; this, add a list with both backends as an element in `company-backends'.
 ;;
 ;;; Change Log:
 ;;
 ;;
 ;;; Change Log:
 ;;
@@ -66,6 +61,7 @@
 
 (require 'cl-lib)
 (require 'newcomment)
 
 (require 'cl-lib)
 (require 'newcomment)
+(require 'pcase)
 
 ;; FIXME: Use `user-error'.
 (add-to-list 'debug-ignored-errors "^.* frontend cannot be used twice$")
 
 ;; FIXME: Use `user-error'.
 (add-to-list 'debug-ignored-errors "^.* frontend cannot be used twice$")
@@ -74,7 +70,7 @@
 (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 "^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$")
+(add-to-list 'debug-ignored-errors "^No other backend$")
 
 ;;; Compatibility
 (eval-and-compile
 
 ;;; Compatibility
 (eval-and-compile
@@ -104,8 +100,7 @@ buffer-local wherever it is set."
   "Face used for the tooltip.")
 
 (defface company-tooltip-selection
   "Face used for the tooltip.")
 
 (defface company-tooltip-selection
-  '((default :inherit company-tooltip)
-    (((class color) (min-colors 88) (background light))
+  '((((class color) (min-colors 88) (background light))
      (:background "light blue"))
     (((class color) (min-colors 88) (background dark))
      (:background "orange1"))
      (:background "light blue"))
     (((class color) (min-colors 88) (background dark))
      (:background "orange1"))
@@ -121,28 +116,26 @@ buffer-local wherever it is set."
   "Face used for the tooltip item under the mouse.")
 
 (defface company-tooltip-common
   "Face used for the tooltip item under the mouse.")
 
 (defface company-tooltip-common
-  '((default :inherit company-tooltip)
-    (((background light))
+  '((((background light))
      :foreground "darkred")
     (((background dark))
      :foreground "red"))
   "Face used for the common completion in the tooltip.")
 
 (defface company-tooltip-common-selection
      :foreground "darkred")
     (((background dark))
      :foreground "red"))
   "Face used for the common completion in the tooltip.")
 
 (defface company-tooltip-common-selection
-  '((default :inherit company-tooltip-selection)
-    (((background light))
-     :foreground "darkred")
-    (((background dark))
-     :foreground "red"))
+  '((default :inherit company-tooltip-common))
   "Face used for the selected common completion in the tooltip.")
 
 (defface company-tooltip-annotation
   "Face used for the selected common completion in the tooltip.")
 
 (defface company-tooltip-annotation
-  '((default :inherit company-tooltip)
-    (((background light))
+  '((((background light))
      :foreground "firebrick4")
     (((background dark))
      :foreground "red4"))
      :foreground "firebrick4")
     (((background dark))
      :foreground "red4"))
-  "Face used for the annotation in the tooltip.")
+  "Face used for the completion annotation in the tooltip.")
+
+(defface company-tooltip-annotation-selection
+  '((default :inherit company-tooltip-annotation))
+  "Face used for the selected completion annotation in the tooltip.")
 
 (defface company-scrollbar-fg
   '((((background light))
 
 (defface company-scrollbar-fg
   '((((background light))
@@ -152,8 +145,7 @@ buffer-local wherever it is set."
   "Face used for the tooltip scrollbar thumb.")
 
 (defface company-scrollbar-bg
   "Face used for the tooltip scrollbar thumb.")
 
 (defface company-scrollbar-bg
-  '((default :inherit company-tooltip)
-    (((background light))
+  '((((background light))
      :background "wheat")
     (((background dark))
      :background "gold"))
      :background "wheat")
     (((background dark))
      :background "gold"))
@@ -161,7 +153,7 @@ buffer-local wherever it is set."
 
 (defface company-preview
   '((((background light))
 
 (defface company-preview
   '((((background light))
-     :inherit company-tooltip-selection)
+     :inherit (company-tooltip-selection company-tooltip))
     (((background dark))
      :background "blue4"
      :foreground "wheat"))
     (((background dark))
      :background "blue4"
      :foreground "wheat"))
@@ -169,7 +161,7 @@ buffer-local wherever it is set."
 
 (defface company-preview-common
   '((((background light))
 
 (defface company-preview-common
   '((((background light))
-     :inherit company-tooltip-selection)
+     :inherit company-tooltip-common-selection)
     (((background dark))
      :inherit company-preview
      :foreground "red"))
     (((background dark))
      :inherit company-preview
      :foreground "red"))
@@ -212,8 +204,8 @@ buffer-local wherever it is set."
 (defcustom company-frontends '(company-pseudo-tooltip-unless-just-one-frontend
                                company-preview-if-just-one-frontend
                                company-echo-metadata-frontend)
 (defcustom company-frontends '(company-pseudo-tooltip-unless-just-one-frontend
                                company-preview-if-just-one-frontend
                                company-echo-metadata-frontend)
-  "The list of active front-ends (visualizations).
-Each front-end is a function that takes one argument.  It is called with
+  "The list of active frontends (visualizations).
+Each frontend is a function that takes one argument.  It is called with
 one of the following arguments:
 
 `show': When the visualization should start.
 one of the following arguments:
 
 `show': When the visualization should start.
@@ -320,30 +312,32 @@ This doesn't include the margins and the scroll bar."
                               company-eclim company-semantic company-clang
                               company-xcode company-cmake
                               company-capf
                               company-eclim company-semantic company-clang
                               company-xcode company-cmake
                               company-capf
+                              company-files
                               (company-dabbrev-code company-gtags company-etags
                                company-keywords)
                               (company-dabbrev-code company-gtags company-etags
                                company-keywords)
-                              company-oddmuse company-files company-dabbrev)
-  "The list of active back-ends (completion engines).
+                              company-oddmuse company-dabbrev)
+  "The list of active backends (completion engines).
 
 
-Only one back-end is used at a time.  The choice depends on the order of
+Only one backend is used at a time.  The choice depends on the order of
 the items in this list, and on the values they return in response to the
 the items in this list, and on the values they return in response to the
-`prefix' command (see below).  But a back-end can also be a \"grouped\"
+`prefix' command (see below).  But a backend can also be a \"grouped\"
 one (see below).
 
 one (see below).
 
-`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.
+`company-begin-backend' can be used to start a specific backend,
+`company-other-backend' will skip to the next matching backend 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
+Each backend is a function that takes a variable number of arguments.
+The first argument is the command requested from the backend.  It is one
 of the following:
 
 of the following:
 
-`prefix': The back-end should return the text to be completed.  It must be
+`prefix': The backend should return the text to be completed.  It must be
 text immediately before point.  Returning nil from this command passes
 text immediately before point.  Returning nil from this command passes
-control to the next back-end.  The function should return `stop' if it
+control to the next backend.  The function should return `stop' if it
 should complete but cannot (e.g. if it is in the middle of a string).
 should complete but cannot (e.g. if it is in the middle of a string).
-Instead of a string, the back-end may return a cons where car is the prefix
-and cdr is used in `company-minimum-prefix-length' test.  It must be either
-number or t, and in the latter case the test automatically succeeds.
+Instead of a string, the backend may return a cons (PREFIX . LENGTH)
+where LENGTH is a number used in place of PREFIX's length when
+comparing against `company-minimum-prefix-length'.  LENGTH can also
+be just t, and in the latter case the test automatically succeeds.
 
 `candidates': The second argument is the prefix to be completed.  The
 return value should be a list of candidates that match the prefix.
 
 `candidates': The second argument is the prefix to be completed.  The
 return value should be a list of candidates that match the prefix.
@@ -353,7 +347,8 @@ prefix, but match it in some backend-defined way).  Backends that use this
 feature must disable cache (return t to `no-cache') and might also want to
 respond to `match'.
 
 feature must disable cache (return t to `no-cache') and might also want to
 respond to `match'.
 
-Optional commands:
+Optional commands
+=================
 
 `sorted': Return t here to indicate that the candidates are sorted and will
 not need to be sorted again.
 
 `sorted': Return t here to indicate that the candidates are sorted and will
 not need to be sorted again.
@@ -362,16 +357,23 @@ not need to be sorted again.
 from the list.
 
 `no-cache': Usually company doesn't ask for candidates again as completion
 from the list.
 
 `no-cache': Usually company doesn't ask for candidates again as completion
-progresses, unless the back-end returns t for this command.  The second
+progresses, unless the backend returns t for this command.  The second
 argument is the latest prefix.
 
 argument is the latest prefix.
 
+`ignore-case': Return t here if the backend returns case-insensitive
+matches.  This value is used to determine the longest common prefix (as
+used in `company-complete-common'), and to filter completions when fetching
+them from cache.
+
 `meta': The second argument is a completion candidate.  Return a (short)
 documentation string for it.
 
 `doc-buffer': The second argument is a completion candidate.  Return a
 `meta': The second argument is a completion candidate.  Return a (short)
 documentation string for it.
 
 `doc-buffer': The second argument is a completion candidate.  Return a
-buffer with documentation for it.  Preferably use `company-doc-buffer',
+buffer with documentation for it.  Preferably use `company-doc-buffer'.  If
+not all buffer contents pertain to this candidate, return a cons of buffer
+and window start position.
 
 
-`location': The second argument is a completion candidate.  Return the cons
+`location': The second argument is a completion candidate.  Return a cons
 of buffer and buffer location, or of file and line number where the
 completion candidate was defined.
 
 of buffer and buffer location, or of file and line number where the
 completion candidate was defined.
 
@@ -388,56 +390,62 @@ will be used when rendering the popup.  This command only makes sense for
 backends that provide non-prefix completion.
 
 `require-match': If this returns t, the user is not allowed to enter
 backends that provide non-prefix completion.
 
 `require-match': If this returns t, the user is not allowed to enter
-anything not offered as a candidate.  Use with care!  The default value nil
-gives the user that choice with `company-require-match'.  Return value
-`never' overrides that option the other way around.
+anything not offered as a candidate.  Please don't use that value in normal
+backends.  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
+`init': Called once for each buffer. The backend can check for external
 programs and files and load any required libraries.  Raising an error here
 programs and files and load any required libraries.  Raising an error here
-will show up in message log once, and the back-end will not be used for
+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.
 
 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
+The backend 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.
 
 does not know about.  It should also be callable interactively and use
 `company-begin-backend' to start itself in that case.
 
-Grouped back-ends:
+Grouped backends
+================
 
 
-An element of `company-backends' can also itself be a list of back-ends,
-then it's considered to be a \"grouped\" back-end.
+An element of `company-backends' can also be a list of backends.  The
+completions from backends in such groups are merged, but only from those
+backends which return the same `prefix'.
 
 
-When possible, commands taking a candidate as an argument are dispatched to
-the back-end it came from.  In other cases, the first non-nil value among
-all the back-ends is returned.
+If a backend command takes a candidate as an argument (e.g. `meta'), the
+call is dispatched to the backend the candidate came from.  In other
+cases (except for `duplicates' and `sorted'), the first non-nil value among
+all the backends is returned.
 
 
-The latter is the case for the `prefix' command.  But if the group contains
-the keyword `:with', the back-ends after it are ignored for this command.
+The group can also contain keywords.  Currently, `:with' and `:sorted'
+keywords are defined.  If the group contains keyword `:with', the backends
+listed after this keyword are ignored for the purpose of the `prefix'
+command.  If the group contains keyword `:sorted', the final list of
+candidates is not sorted after concatenation.
 
 
-The completions from back-ends in a group are merged (but only from those
-that return the same `prefix').
-
-Asynchronous back-ends:
+Asynchronous backends
+=====================
 
 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
 
 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.
+value, as described above.  That call must happen in the same buffer as
+where completion was initiated.
 
 True asynchronous operation is only supported for command `candidates', and
 only during idle completion.  Other commands will block the user interface,
 
 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."
+even if the backend uses the asynchronous calling convention."
   :type `(repeat
           (choice
   :type `(repeat
           (choice
-           :tag "Back-end"
+           :tag "backend"
            ,@(mapcar (lambda (b) `(const :tag ,(cdr b) ,(car b)))
                      company-safe-backends)
            (symbol :tag "User defined")
            ,@(mapcar (lambda (b) `(const :tag ,(cdr b) ,(car b)))
                      company-safe-backends)
            (symbol :tag "User defined")
-           (repeat :tag "Merged Back-ends"
-                   (choice :tag "Back-end"
+           (repeat :tag "Merged backends"
+                   (choice :tag "backend"
                            ,@(mapcar (lambda (b)
                                        `(const :tag ,(cdr b) ,(car b)))
                                      company-safe-backends)
                            ,@(mapcar (lambda (b)
                                        `(const :tag ,(cdr b) ,(car b)))
                                      company-safe-backends)
@@ -455,8 +463,10 @@ without duplicates."
   :type '(choice
           (const :tag "None" nil)
           (const :tag "Sort by occurrence" (company-sort-by-occurrence))
   :type '(choice
           (const :tag "None" nil)
           (const :tag "Sort by occurrence" (company-sort-by-occurrence))
-          (const :tag "Sort by back-end importance"
+          (const :tag "Sort by backend importance"
                  (company-sort-by-backend-importance))
                  (company-sort-by-backend-importance))
+          (const :tag "Prefer case sensitive prefix"
+                 (company-sort-prefer-same-case-prefix))
           (repeat :tag "User defined" (function))))
 
 (defcustom company-completion-started-hook nil
           (repeat :tag "User defined" (function))))
 
 (defcustom company-completion-started-hook nil
@@ -476,7 +486,7 @@ aborted manually."
 The hook is called with the selected candidate as an argument.
 
 If you indend to use it to post-process candidates from a specific
 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."
+backend, consider using the `post-completion' command instead."
   :type 'hook)
 
 (defcustom company-minimum-prefix-length 3
   :type 'hook)
 
 (defcustom company-minimum-prefix-length 3
@@ -494,7 +504,7 @@ prefix it was started from."
   "If enabled, disallow non-matching input.
 This can be a function do determine if a match is required.
 
   "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
+This can be overridden by the backend, if it returns t or `never' to
 `require-match'.  `company-auto-complete' also takes precedence over this."
   :type '(choice (const :tag "Off" nil)
                  (function :tag "Predicate function")
 `require-match'.  `company-auto-complete' also takes precedence over this."
   :type '(choice (const :tag "Off" nil)
                  (function :tag "Predicate function")
@@ -649,7 +659,7 @@ asynchronous call into synchronous.")
       (error
        (put backend 'company-init 'failed)
        (unless (memq backend company--disabled-backends)
       (error
        (put backend 'company-init 'failed)
        (unless (memq backend company--disabled-backends)
-         (message "Company back-end '%s' could not be initialized:\n%s"
+         (message "Company backend '%s' could not be initialized:\n%s"
                   backend (error-message-string err)))
        (cl-pushnew backend company--disabled-backends)
        nil)))
                   backend (error-message-string err)))
        (cl-pushnew backend company--disabled-backends)
        nil)))
@@ -697,9 +707,12 @@ Completions can be searched with `company-search-candidates' or
 inactive, as well.
 
 The completion data is retrieved using `company-backends' and displayed
 inactive, as well.
 
 The completion data is retrieved using `company-backends' and displayed
-using `company-frontends'.  If you want to start a specific back-end, call
+using `company-frontends'.  If you want to start a specific backend, call
 it interactively or use `company-begin-backend'.
 
 it interactively or use `company-begin-backend'.
 
+By default, the completions list is sorted alphabetically, unless the
+backend chooses otherwise, or `company-transformers' changes it later.
+
 regular keymap (`company-mode-map'):
 
 \\{company-mode-map}
 regular keymap (`company-mode-map'):
 
 \\{company-mode-map}
@@ -795,7 +808,9 @@ means that `company-mode' is always turned on except in `message-mode' buffers."
   (let ((col (car (posn-col-row posn)))
         ;; `posn-col-row' doesn't work well with lines of different height.
         ;; `posn-actual-col-row' doesn't handle multiple-width characters.
   (let ((col (car (posn-col-row posn)))
         ;; `posn-col-row' doesn't work well with lines of different height.
         ;; `posn-actual-col-row' doesn't handle multiple-width characters.
-        (row (cdr (posn-actual-col-row posn))))
+        (row (cdr (or (posn-actual-col-row posn)
+                      ;; When position is non-visible for some reason.
+                      (posn-col-row posn)))))
     (when (and header-line-format (version< emacs-version "24.3.93.3"))
       ;; http://debbugs.gnu.org/18384
       (cl-decf row))
     (when (and header-line-format (version< emacs-version "24.3.93.3"))
       ;; http://debbugs.gnu.org/18384
       (cl-decf row))
@@ -816,9 +831,16 @@ means that `company-mode' is always turned on except in `message-mode' buffers."
     (or (match-string-no-properties (or expression 0)) "")))
 
 (defun company-grab-line (regexp &optional expression)
     (or (match-string-no-properties (or expression 0)) "")))
 
 (defun company-grab-line (regexp &optional expression)
-  (company-grab regexp expression (point-at-bol)))
+  "Return a match string for REGEXP if it matches text before point.
+If EXPRESSION is non-nil, return the match string for the respective
+parenthesized expression in REGEXP.
+Matching is limited to the current line."
+  (let ((inhibit-field-text-motion t))
+    (company-grab regexp expression (point-at-bol))))
 
 (defun company-grab-symbol ()
 
 (defun company-grab-symbol ()
+  "If point is at the end of a symbol, return it.
+Otherwise, if point is not inside a symbol, return an empty string."
   (if (looking-at "\\_>")
       (buffer-substring (point) (save-excursion (skip-syntax-backward "w_")
                                                 (point)))
   (if (looking-at "\\_>")
       (buffer-substring (point) (save-excursion (skip-syntax-backward "w_")
                                                 (point)))
@@ -826,6 +848,8 @@ means that `company-mode' is always turned on except in `message-mode' buffers."
       "")))
 
 (defun company-grab-word ()
       "")))
 
 (defun company-grab-word ()
+  "If point is at the end of a word, return it.
+Otherwise, if point is not inside a symbol, return an empty string."
   (if (looking-at "\\>")
       (buffer-substring (point) (save-excursion (skip-syntax-backward "w")
                                                 (point)))
   (if (looking-at "\\>")
       (buffer-substring (point) (save-excursion (skip-syntax-backward "w")
                                                 (point)))
@@ -833,6 +857,9 @@ means that `company-mode' is always turned on except in `message-mode' buffers."
       "")))
 
 (defun company-grab-symbol-cons (idle-begin-after-re &optional max-len)
       "")))
 
 (defun company-grab-symbol-cons (idle-begin-after-re &optional max-len)
+  "Return a string SYMBOL or a cons (SYMBOL . t).
+SYMBOL is as returned by `company-grab-symbol'.  If the text before point
+matches IDLE-BEGIN-AFTER-RE, return it wrapped in a cons."
   (let ((symbol (company-grab-symbol)))
     (when symbol
       (save-excursion
   (let ((symbol (company-grab-symbol)))
     (when symbol
       (save-excursion
@@ -844,6 +871,7 @@ means that `company-mode' is always turned on except in `message-mode' buffers."
           symbol)))))
 
 (defun company-in-string-or-comment ()
           symbol)))))
 
 (defun company-in-string-or-comment ()
+  "Return non-nil if point is within a string or comment."
   (let ((ppss (syntax-ppss)))
     (or (car (setq ppss (nthcdr 3 ppss)))
         (car (setq ppss (cdr ppss)))
   (let ((ppss (syntax-ppss)))
     (or (car (setq ppss (nthcdr 3 ppss)))
         (car (setq ppss (cdr ppss)))
@@ -862,7 +890,7 @@ means that `company-mode' is always turned on except in `message-mode' buffers."
                  (lambda (result) (setq res result)))
         (while (eq res 'trash)
           (if (> (- (time-to-seconds) start) company-async-timeout)
                  (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"
+              (error "Company: backend %s async timeout with args %s"
                      backend args)
             (sleep-for company-async-wait)))
         res))))
                      backend args)
             (sleep-for company-async-wait)))
         res))))
@@ -872,7 +900,7 @@ means that `company-mode' is always turned on except in `message-mode' buffers."
       (if (functionp company-backend)
           (apply company-backend args)
         (apply #'company--multi-backend-adapter company-backend args))
       (if (functionp company-backend)
           (apply company-backend args)
         (apply #'company--multi-backend-adapter company-backend args))
-    (error (error "Company: Back-end %s error \"%s\" with args %s"
+    (error (error "Company: backend %s error \"%s\" with args %s"
                   company-backend (error-message-string err) args))))
 
 (defun company--multi-backend-adapter (backends command &rest args)
                   company-backend (error-message-string err) args))))
 
 (defun company--multi-backend-adapter (backends command &rest args)
@@ -880,14 +908,17 @@ means that `company-mode' is always turned on except in `message-mode' buffers."
                            when (not (and (symbolp b)
                                           (eq 'failed (get b 'company-init))))
                            collect b)))
                            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)))
+
+    (when (eq command 'prefix)
+      (setq backends (butlast backends (length (member :with backends)))))
+
+    (unless (memq command '(sorted))
+      (setq backends (cl-delete-if #'keywordp backends)))
+
     (pcase command
       (`candidates
        (company--multi-backend-adapter-candidates backends (car args)))
     (pcase command
       (`candidates
        (company--multi-backend-adapter-candidates backends (car args)))
-      (`sorted nil)
+      (`sorted (memq :sorted backends))
       (`duplicates t)
       ((or `prefix `ignore-case `no-cache `require-match)
        (let (value)
       (`duplicates t)
       ((or `prefix `ignore-case `no-cache `require-match)
        (let (value)
@@ -993,17 +1024,18 @@ Controlled by `company-auto-complete'.")
   (substring str (length company-prefix)))
 
 (defun company--insert-candidate (candidate)
   (substring str (length company-prefix)))
 
 (defun company--insert-candidate (candidate)
-  (setq candidate (substring-no-properties candidate))
-  ;; XXX: Return value we check here is subject to change.
-  (if (eq (company-call-backend 'ignore-case) 'keep-prefix)
-      (insert (company-strip-prefix candidate))
-    (unless (equal company-prefix candidate)
-      (delete-region (- (point) (length company-prefix)) (point))
-      (insert candidate))))
+  (when (> (length candidate) 0)
+    (setq candidate (substring-no-properties candidate))
+    ;; XXX: Return value we check here is subject to change.
+    (if (eq (company-call-backend 'ignore-case) 'keep-prefix)
+        (insert (company-strip-prefix candidate))
+      (unless (equal company-prefix candidate)
+        (delete-region (- (point) (length company-prefix)) (point))
+        (insert candidate)))))
 
 (defmacro company-with-candidate-inserted (candidate &rest body)
   "Evaluate BODY with CANDIDATE temporarily inserted.
 
 (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
+This is a tool for backends that need candidates inserted before they
 can retrieve meta-data for them."
   (declare (indent 1))
   `(let ((inhibit-modification-hooks t)
 can retrieve meta-data for them."
   (declare (indent 1))
   `(let ((inhibit-modification-hooks t)
@@ -1051,7 +1083,7 @@ can retrieve meta-data for them."
   (dolist (frontend company-frontends)
     (condition-case-unless-debug err
         (funcall frontend command)
   (dolist (frontend company-frontends)
     (condition-case-unless-debug err
         (funcall frontend command)
-      (error (error "Company: Front-end %s error \"%s\" on command %s"
+      (error (error "Company: frontend %s error \"%s\" on command %s"
                     frontend (error-message-string err) command)))))
 
 (defun company-set-selection (selection &optional force-update)
                     frontend (error-message-string err) command)))))
 
 (defun company-set-selection (selection &optional force-update)
@@ -1066,7 +1098,8 @@ can retrieve meta-data for them."
 
 (defun company--group-lighter (candidate base)
   (let ((backend (or (get-text-property 0 'company-backend candidate)
 
 (defun company--group-lighter (candidate base)
   (let ((backend (or (get-text-property 0 'company-backend candidate)
-                     (car company-backend))))
+                     (cl-some (lambda (x) (and (not (keywordp x)) x))
+                              company-backend))))
     (when (and backend (symbolp backend))
       (let ((name (replace-regexp-in-string "company-\\|-company" ""
                                             (symbol-name backend))))
     (when (and backend (symbolp backend))
       (let ((name (replace-regexp-in-string "company-\\|-company" ""
                                             (symbol-name backend))))
@@ -1136,10 +1169,11 @@ can retrieve meta-data for them."
         t))))
 
 (defun company--fetch-candidates (prefix)
         t))))
 
 (defun company--fetch-candidates (prefix)
-  (let ((c (if company--manual-action
-               (company-call-backend 'candidates prefix)
-             (company-call-backend-raw 'candidates prefix)))
-        res)
+  (let* ((non-essential (not (company-explicit-action-p)))
+         (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))
     (if (not (eq (car c) :async))
         c
       (let ((buf (current-buffer))
@@ -1158,7 +1192,11 @@ can retrieve meta-data for them."
                    company-candidates-cache
                    (list (cons prefix
                                (company--preprocess-candidates candidates))))
                    company-candidates-cache
                    (list (cons prefix
                                (company--preprocess-candidates candidates))))
-             (company-idle-begin buf win tick pt)))))
+             (unwind-protect
+                 (company-idle-begin buf win tick pt)
+               (unless company-candidates
+                 (setq company-backend nil
+                       company-candidates-cache nil)))))))
       ;; FIXME: Relying on the fact that the callers
       ;; will interpret nil as "do nothing" is shaky.
       ;; A throw-catch would be one possible improvement.
       ;; FIXME: Relying on the fact that the callers
       ;; will interpret nil as "do nothing" is shaky.
       ;; A throw-catch would be one possible improvement.
@@ -1166,6 +1204,7 @@ can retrieve meta-data for them."
           (progn (setq res 'done) nil)))))
 
 (defun company--preprocess-candidates (candidates)
           (progn (setq res 'done) nil)))))
 
 (defun company--preprocess-candidates (candidates)
+  (cl-assert (cl-every #'stringp candidates))
   (unless (company-call-backend 'sorted)
     (setq candidates (sort candidates 'string<)))
   (when (company-call-backend 'duplicates)
   (unless (company-call-backend 'sorted)
     (setq candidates (sort candidates 'string<)))
   (when (company-call-backend 'duplicates)
@@ -1279,8 +1318,8 @@ Keywords and function definition names are ignored."
 (defun company-sort-by-backend-importance (candidates)
   "Sort CANDIDATES as two priority groups.
 If `company-backend' is a function, do nothing.  If it's a list, move
 (defun company-sort-by-backend-importance (candidates)
   "Sort CANDIDATES as two priority groups.
 If `company-backend' is a function, do nothing.  If it's a list, move
-candidates from back-ends before keyword `:with' to the front.  Candidates
-from the rest of the back-ends in the group, if any, will be left at the end."
+candidates from backends before keyword `:with' to the front.  Candidates
+from the rest of the backends in the group, if any, will be left at the end."
   (if (functionp company-backend)
       candidates
     (let ((low-priority (cdr (memq :with company-backend))))
   (if (functionp company-backend)
       candidates
     (let ((low-priority (cdr (memq :with company-backend))))
@@ -1294,6 +1333,16 @@ from the rest of the back-ends in the group, if any, will be left at the end."
                  (let ((b1 (get-text-property 0 'company-backend c1)))
                    (or (not b1) (not (memq b1 low-priority)))))))))))
 
                  (let ((b1 (get-text-property 0 'company-backend c1)))
                    (or (not b1) (not (memq b1 low-priority)))))))))))
 
+(defun company-sort-prefer-same-case-prefix (candidates)
+  "Prefer CANDIDATES with the same case sensitive prefix.
+If a backend returns case insensitive matches, candidates with the an exact
+prefix match will be prioritized even if this changes the lexical order."
+  (cl-loop for candidate in candidates
+           if (string-prefix-p company-prefix candidate)
+           collect candidate into same-case
+           else collect candidate into other-case
+           finally return (append same-case other-case)))
+
 (defun company-idle-begin (buf win tick pos)
   (and (eq buf (current-buffer))
        (eq win (selected-window))
 (defun company-idle-begin (buf win tick pos)
   (and (eq buf (current-buffer))
        (eq win (selected-window))
@@ -1318,6 +1367,7 @@ from the rest of the back-ends in the group, if any, will be left at the end."
                   (company-cancel))
            (quit (company-cancel))))))
 
                   (company-cancel))
            (quit (company-cancel))))))
 
+;;;###autoload
 (defun company-manual-begin ()
   (interactive)
   (company-assert-enabled)
 (defun company-manual-begin ()
   (interactive)
   (company-assert-enabled)
@@ -1344,7 +1394,7 @@ from the rest of the back-ends in the group, if any, will be left at the end."
       (when (ignore-errors (company-begin-backend backend))
         (cl-return t))))
   (unless company-candidates
       (when (ignore-errors (company-begin-backend backend))
         (cl-return t))))
   (unless company-candidates
-    (error "No other back-end")))
+    (error "No other backend")))
 
 (defun company-require-match-p ()
   (let ((backend-value (company-call-backend 'require-match)))
 
 (defun company-require-match-p ()
   (let ((backend-value (company-call-backend 'require-match)))
@@ -1459,10 +1509,14 @@ from the rest of the back-ends in the group, if any, will be left at the end."
           (setq company-prefix (company--prefix-str prefix)
                 company-backend backend
                 c (company-calculate-candidates company-prefix))
           (setq company-prefix (company--prefix-str prefix)
                 company-backend backend
                 c (company-calculate-candidates company-prefix))
-          ;; t means complete/unique.  We don't start, so no hooks.
           (if (not (consp c))
           (if (not (consp c))
-              (when company--manual-action
-                (message "No completion found"))
+              (progn
+                (when company--manual-action
+                  (message "No completion found"))
+                (when (eq c t)
+                  ;; t means complete/unique.
+                  ;; Run the hooks anyway, to e.g. clear the cache.
+                  (company-cancel 'unique)))
             (when company--manual-action
               (setq company--manual-prefix prefix))
             (company-update-candidates c)
             (when company--manual-action
               (setq company--manual-prefix prefix))
             (company-update-candidates c)
@@ -1483,14 +1537,8 @@ from the rest of the back-ends in the group, if any, will be left at the end."
     (company-call-frontends 'update)))
 
 (defun company-cancel (&optional result)
     (company-call-frontends 'update)))
 
 (defun company-cancel (&optional result)
-  (unwind-protect
-      (when company-prefix
-        (if (stringp 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)))
+  (let ((prefix company-prefix)
+        (backend company-backend))
     (setq company-backend nil
           company-prefix nil
           company-candidates nil
     (setq company-backend nil
           company-prefix nil
           company-candidates nil
@@ -1506,9 +1554,19 @@ from the rest of the back-ends in the group, if any, will be left at the end."
           company-point nil)
     (when company-timer
       (cancel-timer company-timer))
           company-point nil)
     (when company-timer
       (cancel-timer company-timer))
+    (company-echo-cancel t)
     (company-search-mode 0)
     (company-call-frontends 'hide)
     (company-search-mode 0)
     (company-call-frontends 'hide)
-    (company-enable-overriding-keymap nil))
+    (company-enable-overriding-keymap nil)
+    (when prefix
+      ;; FIXME: RESULT can also be e.g. `unique'.  We should call
+      ;; `company-completion-finished-hook' in that case, with right argument.
+      (if (stringp result)
+          (let ((company-backend backend))
+            (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))))
   ;; Make return value explicit.
   nil)
 
   ;; Make return value explicit.
   nil)
 
@@ -1524,6 +1582,7 @@ from the rest of the back-ends in the group, if any, will be left at the end."
   (and (symbolp command) (get command 'company-keep)))
 
 (defun company-pre-command ()
   (and (symbolp command) (get command 'company-keep)))
 
 (defun company-pre-command ()
+  (company--electric-restore-window-configuration)
   (unless (company-keep this-command)
     (condition-case-unless-debug err
         (when company-candidates
   (unless (company-keep this-command)
     (condition-case-unless-debug err
         (when company-candidates
@@ -1536,10 +1595,12 @@ from the rest of the back-ends in the group, if any, will be left at the end."
   (when company-timer
     (cancel-timer company-timer)
     (setq company-timer nil))
   (when company-timer
     (cancel-timer company-timer)
     (setq company-timer nil))
+  (company-echo-cancel t)
   (company-uninstall-map))
 
 (defun company-post-command ()
   (company-uninstall-map))
 
 (defun company-post-command ()
-  (when (null this-command)
+  (when (and company-candidates
+             (null this-command))
     ;; Happens when the user presses `C-g' while inside
     ;; `flyspell-post-command-hook', for example.
     ;; Or any other `post-command-hook' function that can call `sit-for',
     ;; Happens when the user presses `C-g' while inside
     ;; `flyspell-post-command-hook', for example.
     ;; Or any other `post-command-hook' function that can call `sit-for',
@@ -1555,6 +1616,7 @@ from the rest of the back-ends in the group, if any, will be left at the end."
           (if company-candidates
               (company-call-frontends 'post-command)
             (and (numberp company-idle-delay)
           (if company-candidates
               (company-call-frontends 'post-command)
             (and (numberp company-idle-delay)
+                 (not defining-kbd-macro)
                  (company--should-begin)
                  (setq company-timer
                        (run-with-timer company-idle-delay nil
                  (company--should-begin)
                  (setq company-timer
                        (run-with-timer company-idle-delay nil
@@ -1584,6 +1646,19 @@ from the rest of the back-ends in the group, if any, will be left at the end."
 
 ;;; search ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
 ;;; search ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+(defcustom company-search-regexp-function #'regexp-quote
+  "Function to construct the search regexp from input.
+It's called with one argument, the current search input.  It must return
+either a regexp without groups, or one where groups don't intersect and
+each one wraps a part of the input string."
+  :type '(choice
+          (const :tag "Exact match" regexp-quote)
+          (const :tag "Words separated with spaces" company-search-words-regexp)
+          (const :tag "Words separated with spaces, in any order"
+                 company-search-words-in-any-order-regexp)
+          (const :tag "All characters in given order, with anything in between"
+                 company-search-flex-regexp)))
+
 (defvar-local company-search-string "")
 
 (defvar company-search-lighter '(" "
 (defvar-local company-search-string "")
 
 (defvar company-search-lighter '(" "
@@ -1599,11 +1674,42 @@ from the rest of the back-ends in the group, if any, will be left at the end."
 
 (defvar-local company--search-old-changed nil)
 
 
 (defvar-local company--search-old-changed nil)
 
+(defun company-search-words-regexp (input)
+  (mapconcat (lambda (word) (format "\\(%s\\)" (regexp-quote word)))
+             (split-string input " +" t) ".*"))
+
+(defun company-search-words-in-any-order-regexp (input)
+  (let* ((words (mapcar (lambda (word) (format "\\(%s\\)" (regexp-quote word)))
+                        (split-string input " +" t)))
+         (permutations (company--permutations words)))
+    (mapconcat (lambda (words)
+                 (mapconcat #'identity words ".*"))
+               permutations
+               "\\|")))
+
+(defun company-search-flex-regexp (input)
+  (if (zerop (length input))
+      ""
+    (concat (regexp-quote (string (aref input 0)))
+            (mapconcat (lambda (c)
+                         (concat "[^" (string c) "]*"
+                                 (regexp-quote (string c))))
+                       (substring input 1) ""))))
+
+(defun company--permutations (lst)
+  (if (not lst)
+      '(nil)
+    (cl-mapcan
+     (lambda (e)
+       (mapcar (lambda (perm) (cons e perm))
+               (company--permutations (cl-remove e lst :count 1))))
+     lst)))
+
 (defun company--search (text lines)
 (defun company--search (text lines)
-  (let ((quoted (regexp-quote text))
+  (let ((re (funcall company-search-regexp-function text))
         (i 0))
     (cl-dolist (line lines)
         (i 0))
     (cl-dolist (line lines)
-      (when (string-match quoted line (length company-prefix))
+      (when (string-match-p re line (length company-prefix))
         (cl-return i))
       (cl-incf i))))
 
         (cl-return i))
       (cl-incf i))))
 
@@ -1621,11 +1727,12 @@ from the rest of the back-ends in the group, if any, will be left at the end."
       (company--search-update-predicate ss))
     (company--search-update-string ss)))
 
       (company--search-update-predicate ss))
     (company--search-update-string ss)))
 
-(defun company--search-update-predicate (&optional ss)
-  (let* ((company-candidates-predicate
-          (and (not (string= ss ""))
+(defun company--search-update-predicate (ss)
+  (let* ((re (funcall company-search-regexp-function ss))
+         (company-candidates-predicate
+          (and (not (string= re ""))
                company-search-filtering
                company-search-filtering
-               (lambda (candidate) (string-match ss candidate))))
+               (lambda (candidate) (string-match re candidate))))
          (cc (company-calculate-candidates company-prefix)))
     (unless cc (error "No match"))
     (company-update-candidates cc)))
          (cc (company-calculate-candidates company-prefix)))
     (unless cc (error "No match"))
     (company-update-candidates cc)))
@@ -1780,6 +1887,9 @@ Don't start this directly, use `company-search-candidates' or
 
 Regular characters are appended to the search string.
 
 
 Regular characters are appended to the search string.
 
+Customize `company-search-regexp-function' to change how the input
+is interpreted when searching.
+
 The command `company-search-toggle-filtering' (\\[company-search-toggle-filtering])
 uses the search string to filter the completion candidates."
   (interactive)
 The command `company-search-toggle-filtering' (\\[company-search-toggle-filtering])
 uses the search string to filter the completion candidates."
   (interactive)
@@ -1921,8 +2031,7 @@ With ARG, move by that many elements."
     (if (and (not (cdr company-candidates))
              (equal company-common (car company-candidates)))
         (company-complete-selection)
     (if (and (not (cdr company-candidates))
              (equal company-common (car company-candidates)))
         (company-complete-selection)
-      (when company-common
-        (company--insert-candidate company-common)))))
+      (company--insert-candidate company-common))))
 
 (defun company-complete-common-or-cycle (&optional arg)
   "Insert the common part of all candidates, or select the next one.
 
 (defun company-complete-common-or-cycle (&optional arg)
   "Insert the common part of all candidates, or select the next one.
@@ -1937,6 +2046,21 @@ With ARG, move by that many elements."
               (current-prefix-arg arg))
           (call-interactively 'company-select-next))))))
 
               (current-prefix-arg arg))
           (call-interactively 'company-select-next))))))
 
+(defun company-indent-or-complete-common ()
+  "Indent the current line or region, or complete the common part."
+  (interactive)
+  (cond
+   ((use-region-p)
+    (indent-region (region-beginning) (region-end)))
+   ((let ((old-point (point))
+          (old-tick (buffer-chars-modified-tick))
+          (tab-always-indent t))
+      (call-interactively #'indent-for-tab-command)
+      (when (and (eq old-point (point))
+                 (eq old-tick (buffer-chars-modified-tick)))
+        (company-complete-common))))))
+
+;;;###autoload
 (defun company-complete ()
   "Insert the common part of all candidates or the current selection.
 The first time this is called, the common part is inserted, the second
 (defun company-complete ()
   "Insert the common part of all candidates or the current selection.
 The first time this is called, the common part is inserted, the second
@@ -1952,7 +2076,7 @@ inserted."
 
 (defun company-complete-number (n)
   "Insert the Nth candidate visible in the tooltip.
 
 (defun company-complete-number (n)
   "Insert the Nth candidate visible in the tooltip.
-To show the number next to the candidates in some back-ends, enable
+To show the number next to the candidates in some backends, enable
 `company-show-numbers'.  When called interactively, uses the last typed
 character, stripping the modifiers.  That character must be a digit."
   (interactive
 `company-show-numbers'.  When called interactively, uses the last typed
 character, stripping the modifiers.  That character must be a digit."
   (interactive
@@ -2022,28 +2146,30 @@ character, stripping the modifiers.  That character must be a digit."
         (insert string)))
     (current-buffer)))
 
         (insert string)))
     (current-buffer)))
 
+(defvar company--electric-saved-window-configuration nil)
+
 (defvar company--electric-commands
   '(scroll-other-window scroll-other-window-down mwheel-scroll)
   "List of Commands that won't break out of electric commands.")
 
 (defvar company--electric-commands
   '(scroll-other-window scroll-other-window-down mwheel-scroll)
   "List of Commands that won't break out of electric commands.")
 
+(defun company--electric-restore-window-configuration ()
+  "Restore window configuration (after electric commands)."
+  (when (and company--electric-saved-window-configuration
+             (not (memq this-command company--electric-commands)))
+    (set-window-configuration company--electric-saved-window-configuration)
+    (setq company--electric-saved-window-configuration nil)))
+
 (defmacro company--electric-do (&rest body)
   (declare (indent 0) (debug t))
   `(when (company-manual-begin)
 (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))
-             cmd)
-         ,@body
-         (and (< (window-height) height)
-              (< (- (window-height) row 2) company-tooltip-limit)
-              (recenter (- (window-height) row 2)))
-         (while (memq (setq cmd (key-binding (read-key-sequence-vector nil)))
-                      company--electric-commands)
-           (condition-case err
-               (call-interactively cmd)
-             ((beginning-of-buffer end-of-buffer)
-              (message (error-message-string err)))))
-         (company--unread-last-input)))))
+     (cl-assert (null company--electric-saved-window-configuration))
+     (setq company--electric-saved-window-configuration (current-window-configuration))
+     (let ((height (window-height))
+           (row (company--row)))
+       ,@body
+       (and (< (window-height) height)
+            (< (- (window-height) row 2) company-tooltip-limit)
+            (recenter (- (window-height) row 2))))))
 
 (defun company--unread-last-input ()
   (when last-input-event
 
 (defun company--unread-last-input ()
   (when last-input-event
@@ -2057,11 +2183,14 @@ character, stripping the modifiers.  That character must be a digit."
     (company--electric-do
       (let* ((selected (nth company-selection company-candidates))
              (doc-buffer (or (company-call-backend 'doc-buffer selected)
     (company--electric-do
       (let* ((selected (nth company-selection company-candidates))
              (doc-buffer (or (company-call-backend 'doc-buffer selected)
-                             (error "No documentation available"))))
+                             (error "No documentation available")))
+             start)
+        (when (consp doc-buffer)
+          (setq start (cdr doc-buffer)
+                doc-buffer (car doc-buffer)))
         (setq other-window-scroll-buffer (get-buffer doc-buffer))
         (setq other-window-scroll-buffer (get-buffer doc-buffer))
-        (with-current-buffer doc-buffer
-          (goto-char (point-min)))
-        (display-buffer doc-buffer t)))))
+        (let ((win (display-buffer doc-buffer t)))
+          (set-window-start win (if start start (point-min))))))))
 (put 'company-show-doc-buffer 'company-keep t)
 
 (defun company-show-location ()
 (put 'company-show-doc-buffer 'company-keep t)
 
 (defun company-show-location ()
@@ -2096,7 +2225,7 @@ character, stripping the modifiers.  That character must be a digit."
 
 (defun company-begin-backend (backend &optional callback)
   "Start a completion at point using BACKEND."
 
 (defun company-begin-backend (backend &optional callback)
   "Start a completion at point using BACKEND."
-  (interactive (let ((val (completing-read "Company back-end: "
+  (interactive (let ((val (completing-read "Company backend: "
                                            obarray
                                            'functionp nil "company-")))
                  (when val
                                            obarray
                                            'functionp nil "company-")))
                  (when val
@@ -2134,12 +2263,16 @@ Example: \(company-begin-with '\(\"foo\" \"foobar\" \"foobarbaz\"\)\)"
           require-match)))
      callback)))
 
           require-match)))
      callback)))
 
+(declare-function find-library-name "find-func")
+(declare-function lm-version "lisp-mnt")
+
 (defun company-version (&optional show-version)
   "Get the Company version as string.
 
 If SHOW-VERSION is non-nil, show the version in the echo area."
   (interactive (list t))
   (with-temp-buffer
 (defun company-version (&optional show-version)
   "Get the Company version as string.
 
 If SHOW-VERSION is non-nil, show the version in the echo area."
   (interactive (list t))
   (with-temp-buffer
+    (require 'find-func)
     (insert-file-contents (find-library-name "company"))
     (require 'lisp-mnt)
     (if show-version
     (insert-file-contents (find-library-name "company"))
     (require 'lisp-mnt)
     (if show-version
@@ -2147,8 +2280,8 @@ If SHOW-VERSION is non-nil, show the version in the echo area."
       (lm-version))))
 
 (defun company-diag ()
       (lm-version))))
 
 (defun company-diag ()
-  (interactive)
   "Pop a buffer with information about completions at point."
   "Pop a buffer with information about completions at point."
+  (interactive)
   (let* ((bb company-backends)
          backend
          (prefix (cl-loop for b in bb
   (let* ((bb company-backends)
          backend
          (prefix (cl-loop for b in bb
@@ -2243,6 +2376,8 @@ If SHOW-VERSION is non-nil, show the version in the echo area."
                      (if company-common
                          (string-width company-common)
                        0)))
                      (if company-common
                          (string-width company-common)
                        0)))
+         (_ (setq value (company--pre-render value)
+                  annotation (and annotation (company--pre-render annotation t))))
          (ann-ralign company-tooltip-align-annotations)
          (ann-truncate (< width
                           (+ (length value) (length annotation)
          (ann-ralign company-tooltip-align-annotations)
          (ann-truncate (< width
                           (+ (length value) (length annotation)
@@ -2269,38 +2404,62 @@ If SHOW-VERSION is non-nil, show the version in the echo area."
     (setq common (+ (min common width) margin))
     (setq width (+ width margin (length right)))
 
     (setq common (+ (min common width) margin))
     (setq width (+ width margin (length right)))
 
-    (add-text-properties 0 width '(face company-tooltip
-                                   mouse-face company-tooltip-mouse)
-                         line)
-    (add-text-properties margin common
-                         '(face company-tooltip-common
-                           mouse-face company-tooltip-mouse)
-                         line)
+    (font-lock-append-text-property 0 width 'mouse-face
+                                    'company-tooltip-mouse
+                                    line)
     (when (< ann-start ann-end)
     (when (< ann-start ann-end)
-      (add-text-properties ann-start ann-end
-                           '(face company-tooltip-annotation
-                             mouse-face company-tooltip-mouse)
-                           line))
+      (font-lock-append-text-property ann-start ann-end 'face
+                                      (if selected
+                                          'company-tooltip-annotation-selection
+                                        'company-tooltip-annotation)
+                                      line))
+    (font-lock-prepend-text-property margin common 'face
+                                     (if selected
+                                         'company-tooltip-common-selection
+                                       'company-tooltip-common)
+                                     line)
     (when selected
     (when selected
-      (if (and (not (string= company-search-string ""))
-               (string-match (regexp-quote company-search-string) value
-                             (length company-prefix)))
-          (let ((beg (+ margin (match-beginning 0)))
-                (end (+ margin (match-end 0)))
-                (width (- width (length right))))
-            (when (< beg width)
-              (add-text-properties beg (min end width)
-                                   '(face company-tooltip-search)
-                                   line)))
-        (add-text-properties 0 width '(face company-tooltip-selection
-                                       mouse-face company-tooltip-selection)
-                             line)
-        (add-text-properties margin common
-                             '(face company-tooltip-common-selection
-                               mouse-face company-tooltip-selection)
-                             line)))
+      (if (let ((re (funcall company-search-regexp-function
+                             company-search-string)))
+            (and (not (string= re ""))
+                 (string-match re value (length company-prefix))))
+          (pcase-dolist (`(,mbeg . ,mend) (company--search-chunks))
+            (let ((beg (+ margin mbeg))
+                  (end (+ margin mend))
+                  (width (- width (length right))))
+              (when (< beg width)
+                (font-lock-prepend-text-property beg (min end width)
+                                                 'face 'company-tooltip-search
+                                                 line))))
+        (font-lock-append-text-property 0 width 'face
+                                        'company-tooltip-selection
+                                        line)))
+    (font-lock-append-text-property 0 width 'face
+                                    'company-tooltip
+                                    line)
     line))
 
     line))
 
+(defun company--search-chunks ()
+  (let ((md (match-data t))
+        res)
+    (if (<= (length md) 2)
+        (push (cons (nth 0 md) (nth 1 md)) res)
+      (while (setq md (nthcdr 2 md))
+        (when (car md)
+          (push (cons (car md) (cadr md)) res))))
+    res))
+
+(defun company--pre-render (str &optional annotation-p)
+  (or (company-call-backend 'pre-render str annotation-p)
+      (progn
+        (when (or (text-property-not-all 0 (length str) 'face nil str)
+                  (text-property-not-all 0 (length str) 'mouse-face nil str))
+          (setq str (copy-sequence str))
+          (remove-text-properties 0 (length str)
+                                  '(face nil font-lock-face nil mouse-face nil)
+                                  str))
+        str)))
+
 (defun company--clean-string (str)
   (replace-regexp-in-string
    "\\([^[:graph:] ]\\)\\|\\(\ufeff\\)\\|[[:multibyte:]]"
 (defun company--clean-string (str)
   (replace-regexp-in-string
    "\\([^[:graph:] ]\\)\\|\\(\ufeff\\)\\|[[:multibyte:]]"
@@ -2328,7 +2487,7 @@ If SHOW-VERSION is non-nil, show the version in the echo area."
     (while (and (not (eobp)) ; http://debbugs.gnu.org/19553
                 (> (setq lines-moved (vertical-motion 1)) 0)
                 (<= (point) end))
     (while (and (not (eobp)) ; http://debbugs.gnu.org/19553
                 (> (setq lines-moved (vertical-motion 1)) 0)
                 (<= (point) end))
-      (let ((bound (min end (1- (point)))))
+      (let ((bound (min end (point))))
         ;; A visual line can contain several physical lines (e.g. with outline's
         ;; folding overlay).  Take only the first one.
         (push (buffer-substring beg
         ;; A visual line can contain several physical lines (e.g. with outline's
         ;; folding overlay).  Take only the first one.
         (push (buffer-substring beg
@@ -2376,8 +2535,12 @@ If SHOW-VERSION is non-nil, show the version in the echo area."
                     (or (cdr margins) 0)))))
     (when (and word-wrap
                (version< emacs-version "24.4.51.5"))
                     (or (cdr margins) 0)))))
     (when (and word-wrap
                (version< emacs-version "24.4.51.5"))
-      ;; http://debbugs.gnu.org/18384
+      ;; http://debbugs.gnu.org/19300
       (cl-decf ww))
       (cl-decf ww))
+    ;; whitespace-mode with newline-mark
+    (when (and buffer-display-table
+               (aref buffer-display-table ?\n))
+      (cl-decf ww (1- (length (aref buffer-display-table ?\n)))))
     ww))
 
 (defun company--replacement-string (lines old column nl &optional align-top)
     ww))
 
 (defun company--replacement-string (lines old column nl &optional align-top)
@@ -2412,8 +2575,7 @@ If SHOW-VERSION is non-nil, show the version in the echo area."
                     (company--offset-line (pop lines) offset))
             new))
 
                     (company--offset-line (pop lines) offset))
             new))
 
-    (let ((str (concat (when nl " ")
-                       "\n"
+    (let ((str (concat (when nl " \n")
                        (mapconcat 'identity (nreverse new) "\n")
                        "\n")))
       (font-lock-append-text-property 0 (length str) 'face 'default str)
                        (mapconcat 'identity (nreverse new) "\n")
                        "\n")))
       (font-lock-append-text-property 0 (length str) 'face 'default str)
@@ -2565,7 +2727,7 @@ Returns a negative number if the tooltip should be displayed above point."
              (end (save-excursion
                     (move-to-window-line (+ row (abs height)))
                     (point)))
              (end (save-excursion
                     (move-to-window-line (+ row (abs height)))
                     (point)))
-             (ov (make-overlay (if nl beg (1- beg)) end nil t))
+             (ov (make-overlay beg end nil t))
              (args (list (mapcar 'company-plainify
                                  (company-buffer-lines beg end))
                          column nl above)))
              (args (list (mapcar 'company-plainify
                                  (company-buffer-lines beg end))
                          column nl above)))
@@ -2606,7 +2768,9 @@ Returns a negative number if the tooltip should be displayed above point."
 (defun company-pseudo-tooltip-hide-temporarily ()
   (when (overlayp company-pseudo-tooltip-overlay)
     (overlay-put company-pseudo-tooltip-overlay 'invisible nil)
 (defun company-pseudo-tooltip-hide-temporarily ()
   (when (overlayp company-pseudo-tooltip-overlay)
     (overlay-put company-pseudo-tooltip-overlay 'invisible nil)
-    (overlay-put company-pseudo-tooltip-overlay 'after-string nil)))
+    (overlay-put company-pseudo-tooltip-overlay 'line-prefix nil)
+    (overlay-put company-pseudo-tooltip-overlay 'after-string nil)
+    (overlay-put company-pseudo-tooltip-overlay 'display nil)))
 
 (defun company-pseudo-tooltip-unhide ()
   (when company-pseudo-tooltip-overlay
 
 (defun company-pseudo-tooltip-unhide ()
   (when company-pseudo-tooltip-overlay
@@ -2614,12 +2778,15 @@ Returns a negative number if the tooltip should be displayed above point."
            (disp (overlay-get ov 'company-display)))
       ;; Beat outline's folding overlays, at least.
       (overlay-put ov 'priority 1)
            (disp (overlay-get ov 'company-display)))
       ;; Beat outline's folding overlays, at least.
       (overlay-put ov 'priority 1)
-      ;; `display' could be better (http://debbugs.gnu.org/18285), but it
-      ;; doesn't work when the overlay is empty, which is what happens at eob.
-      ;; It also seems to interact badly with `cursor'.
-      ;; We deal with priorities by having the overlay start before the newline.
-      (overlay-put ov 'after-string disp)
-      (overlay-put ov 'invisible t)
+      ;; No (extra) prefix for the first line.
+      (overlay-put ov 'line-prefix "")
+      ;; `display' is better
+      ;; (http://debbugs.gnu.org/18285, http://debbugs.gnu.org/20847),
+      ;; but it doesn't work on 0-length overlays.
+      (if (< (overlay-start ov) (overlay-end ov))
+          (overlay-put ov 'display disp)
+        (overlay-put ov 'after-string disp)
+        (overlay-put ov 'invisible t))
       (overlay-put ov 'window (selected-window)))))
 
 (defun company-pseudo-tooltip-guard ()
       (overlay-put ov 'window (selected-window)))))
 
 (defun company-pseudo-tooltip-guard ()
@@ -2634,7 +2801,7 @@ Returns a negative number if the tooltip should be displayed above point."
         (when (>= overhang 0) overhang))))))
 
 (defun company-pseudo-tooltip-frontend (command)
         (when (>= overhang 0) overhang))))))
 
 (defun company-pseudo-tooltip-frontend (command)
-  "`company-mode' front-end similar to a tooltip but based on overlays."
+  "`company-mode' frontend similar to a tooltip but based on overlays."
   (cl-case command
     (pre-command (company-pseudo-tooltip-hide-temporarily))
     (post-command
   (cl-case command
     (pre-command (company-pseudo-tooltip-hide-temporarily))
     (post-command
@@ -2671,17 +2838,22 @@ Returns a negative number if the tooltip should be displayed above point."
   (company-preview-hide)
 
   (let ((completion (nth company-selection company-candidates)))
   (company-preview-hide)
 
   (let ((completion (nth company-selection company-candidates)))
-    (setq completion (propertize completion 'face 'company-preview))
-    (add-text-properties 0 (length company-common)
-                         '(face company-preview-common) completion)
+    (setq completion (copy-sequence (company--pre-render completion)))
+    (font-lock-append-text-property 0 (length completion)
+                                    'face 'company-preview
+                                    completion)
+    (font-lock-prepend-text-property 0 (length company-common)
+                                     'face 'company-preview-common
+                                     completion)
 
     ;; Add search string
 
     ;; Add search string
-    (and company-search-string
-         (string-match (regexp-quote company-search-string) completion)
-         (add-text-properties (match-beginning 0)
-                              (match-end 0)
-                              '(face company-preview-search)
-                              completion))
+    (and (string-match (funcall company-search-regexp-function
+                                company-search-string)
+                       completion)
+         (pcase-dolist (`(,mbeg . ,mend) (company--search-chunks))
+           (font-lock-prepend-text-property mbeg mend
+                                            'face 'company-preview-search
+                                            completion)))
 
     (setq completion (company-strip-prefix completion))
 
 
     (setq completion (company-strip-prefix completion))
 
@@ -2714,7 +2886,7 @@ Returns a negative number if the tooltip should be displayed above point."
     (setq company-preview-overlay nil)))
 
 (defun company-preview-frontend (command)
     (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' frontend showing the selection as if it had been inserted."
   (pcase command
     (`pre-command (company-preview-hide))
     (`post-command (company-preview-show-at-point (point)))
   (pcase command
     (`pre-command (company-preview-hide))
     (`post-command (company-preview-show-at-point (point)))
@@ -2749,13 +2921,19 @@ Returns a negative number if the tooltip should be displayed above point."
       (message ""))))
 
 (defun company-echo-show-soon (&optional getter)
       (message ""))))
 
 (defun company-echo-show-soon (&optional getter)
+  (company-echo-cancel)
+  (setq company-echo-timer (run-with-timer 0 nil 'company-echo-show getter)))
+
+(defun company-echo-cancel (&optional unset)
   (when company-echo-timer
     (cancel-timer company-echo-timer))
   (when company-echo-timer
     (cancel-timer company-echo-timer))
-  (setq company-echo-timer (run-with-timer 0 nil 'company-echo-show getter)))
+  (when unset
+    (setq company-echo-timer nil)))
 
 
-(defsubst company-echo-show-when-idle (&optional getter)
-  (when (sit-for company-echo-delay)
-    (company-echo-show getter)))
+(defun company-echo-show-when-idle (&optional getter)
+  (company-echo-cancel)
+  (setq company-echo-timer
+        (run-with-idle-timer company-echo-delay nil 'company-echo-show getter)))
 
 (defun company-echo-format ()
 
 
 (defun company-echo-format ()
 
@@ -2818,19 +2996,19 @@ Returns a negative number if the tooltip should be displayed above point."
     (company-echo-show)))
 
 (defun company-echo-frontend (command)
     (company-echo-show)))
 
 (defun company-echo-frontend (command)
-  "`company-mode' front-end showing the candidates in the echo area."
+  "`company-mode' frontend showing the candidates in the echo area."
   (pcase command
     (`post-command (company-echo-show-soon 'company-echo-format))
     (`hide (company-echo-hide))))
 
 (defun company-echo-strip-common-frontend (command)
   (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."
+  "`company-mode' frontend showing the candidates in the echo area."
   (pcase command
     (`post-command (company-echo-show-soon 'company-echo-strip-common-format))
     (`hide (company-echo-hide))))
 
 (defun company-echo-metadata-frontend (command)
   (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."
+  "`company-mode' frontend showing the documentation in the echo area."
   (pcase 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))))