branch: externals/company
commit 50a4c55a989666383b9aff1e78201024ed55d66c
Merge: ec3345050b 32488c25fb
Author: Dmitry Gutov <[email protected]>
Commit: Dmitry Gutov <[email protected]>

    Merge branch 'master' into better-doc-and-location-bindings
---
 NEWS.md               |   9 +++
 company-capf.el       |   3 +-
 company-childframe.el |  23 ++++++--
 company.el            | 151 ++++++++++++++++++++++++++++++++++++++++++++------
 4 files changed, 162 insertions(+), 24 deletions(-)

diff --git a/NEWS.md b/NEWS.md
index a19a1dbbb8..9adecdb63e 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -17,6 +17,15 @@
   (define-key company-active-map (kbd "M-g") nil))
 ```
 
+* `company-search-regexp-function` defaults to
+  `company-search-words-in-any-order-regexp`. Another alternative value for it
+  was also added: `company-search-flex-words-in-any-order-regexp`, working
+  somewhat similar to the popular completion style Orderless.
+* The `search` faces in the popup inherit from `isearch`.
+* New option `company-global-minibuffer` for completion during 
`eval-expression`
+  (`M-:`). The "pseudo-tooltip" frontend is not supported by this feature,
+  `company-childframe` is recommended instead.
+* `C-M-i` is bound to `company-complete-common` when completion is active.
 * Search mode input is displayed at the bottom of the popup
   ([#1535](https://github.com/company-mode/company-mode/pull/1535)).
 * New built-in frontend using "real graphical" widget for the popup
diff --git a/company-capf.el b/company-capf.el
index 8d159608c9..5c7b8486b3 100644
--- a/company-capf.el
+++ b/company-capf.el
@@ -36,7 +36,8 @@
   :group 'company)
 
 (defcustom company-capf-disabled-functions '(tags-completion-at-point-function
-                                             ispell-completion-at-point)
+                                             ispell-completion-at-point
+                                             
company--fake-capf-complete-common)
   "List of completion functions which should be ignored in this backend.
 
 By default it contains the functions that duplicate the built-in backends
diff --git a/company-childframe.el b/company-childframe.el
index 6a45c125e7..103948c52d 100644
--- a/company-childframe.el
+++ b/company-childframe.el
@@ -88,17 +88,28 @@ Users of HiDPI screens might like to set it to 2."
 (defun company-childframe-show-at-prefix (info)
   "Poshandler showing `company-childframe' at `company-prefix'."
   (let* ((parent-window (plist-get info :parent-window))
-         (point (with-current-buffer (window-buffer parent-window)
-                  (- (plist-get info :position)
-                     (plist-get info :company-prefix-length))))
+         (point (- (plist-get info :position)
+                   (plist-get info :company-prefix-length)))
+         (after-string-width
+          (with-current-buffer (window-buffer parent-window)
+            (thread-last
+              (and (= point (point-max))
+                   (overlays-in point point))
+              (mapcar (lambda (o) (company--string-pixel-width
+                              (overlay-get o 'after-string))))
+              (cl-reduce #'+))))
          (posn (posn-at-point point parent-window))
          ;; TODO: Strictly speaking, if company-childframe-font is not nil, 
that
          ;; should be used to find the default width...
          (expected-margin-width (* (plist-get info :company-margin) 
(default-font-width)))
          (xy (posn-x-y posn)))
-    (setcar xy (- (car xy) expected-margin-width (if (display-graphic-p)
-                                                     
company-childframe-border-width
-                                                   0)))
+    (setcar xy (- (car xy) expected-margin-width
+                  (if (display-graphic-p)
+                      company-childframe-border-width
+                    0)
+                  ;; Might bite us if the posn-at-point behavior changes
+                  ;; someday, but the odds seem low.
+                  after-string-width))
     (posframe-poshandler-point-bottom-left-corner (plist-put info :position 
posn))))
 
 (defun company-childframe-show ()
diff --git a/company.el b/company.el
index 32b977c27c..83e116896f 100644
--- a/company.el
+++ b/company.el
@@ -98,11 +98,11 @@
   "Face used for the deprecated items.")
 
 (defface company-tooltip-search
-  '((default :inherit highlight))
+  '((default :inherit isearch))
   "Face used for the search string in the tooltip.")
 
 (defface company-tooltip-search-selection
-  '((default :inherit highlight))
+  '((default :inherit isearch))
   "Face used for the search string inside the selection in the tooltip.")
 
 (defface company-tooltip-mouse
@@ -174,7 +174,7 @@
   "Face used for the common part of the completion preview.")
 
 (defface company-preview-search
-  '((default :inherit company-tooltip-common-selection))
+  '((default :inherit isearch))
   "Face used for the search string in the completion preview.")
 
 (defface company-echo nil
@@ -886,7 +886,11 @@ asynchronous call into synchronous.")
 
 ;;; mode 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(defvar company-mode-map (make-sparse-keymap)
+(defvar company-mode-map
+  (let ((keymap (make-sparse-keymap)))
+    (define-key keymap [remap indent-for-tab-command] 
'company-indent-for-tab-command)
+    (define-key keymap [remap c-indent-line-or-region] 
'company-indent-for-tab-command)
+    keymap)
   "Keymap used by `company-mode'.")
 
 (defvar company-active-map
@@ -910,6 +914,7 @@ asynchronous call into synchronous.")
     (define-key keymap [tab] 'company-complete-common-or-cycle)
     (define-key keymap (kbd "TAB") 'company-complete-common-or-cycle)
     (define-key keymap [backtab] 'company-cycle-backward)
+    (define-key keymap (kbd "C-M-i") 'company-complete-common)
     (define-key keymap (kbd "<f1>") 'company--show-doc-buffer-and-warn)
     (define-key keymap (kbd "C-h") 'company--show-doc-buffer-and-warn)
     (define-key keymap (kbd "M-h") 'company-show-doc-buffer)
@@ -1043,8 +1048,20 @@ means that `company-mode' is always turned on except in 
`message-mode' buffers."
                       (const :tag "Except" not)
                       (repeat :inline t (symbol :tag "mode")))))
 
+(defcustom company-global-minibuffer t
+  "Non-nil to enable `company-mode' in the minibuffer.
+The value can be t (meaning only enable if the minibuffer has a local
+`completion-at-point-functions' value) or a custom predicate function.
+
+The overlay based popup is not supported, completion won't start in
+minibuffer if it's in configured frontends: use `company-childframe'."
+  :type 'boolean)
+
 ;;;###autoload
-(define-globalized-minor-mode global-company-mode company-mode company-mode-on)
+(define-globalized-minor-mode global-company-mode company-mode company-mode-on
+  (if global-company-mode
+      (add-hook 'minibuffer-setup-hook #'company--minibuffer-on 100)
+    (remove-hook 'minibuffer-setup-hook #'company--minibuffer-on)))
 
 (defun company-mode-on ()
   (when (and (not (or noninteractive (eq (aref (buffer-name) 0) ?\s)))
@@ -1055,6 +1072,14 @@ means that `company-mode' is always turned on except in 
`message-mode' buffers."
                    (t (memq major-mode company-global-modes))))
     (company-mode 1)))
 
+(defun company--minibuffer-on ()
+  (when (and company-global-minibuffer
+             (not (try-completion "company-pseudo-tooltip" company-frontends))
+             (if (eq company-global-minibuffer t)
+                 (local-variable-p 'completion-at-point-functions)
+               (funcall company-global-minibuffer)))
+    (company-mode 1)))
+
 (defsubst company-assert-enabled ()
   (unless company-mode
     (company-uninstall-map)
@@ -2237,7 +2262,7 @@ Searches for each in the currently visible part of the 
current buffer and
 prioritizes the matches according to `company-occurrence-weight-function'.
 The rest of the list is appended unchanged.
 Keywords and function definition names are ignored."
-  (let* ((w-start (window-start))
+  (let* ((w-start (max (window-start) (field-beginning)))
          (w-end (window-end))
          (start-point (point))
          occurs
@@ -2734,7 +2759,7 @@ For more details see `company-insertion-on-trigger' and
 
 ;;; search 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(defcustom company-search-regexp-function #'regexp-quote
+(defcustom company-search-regexp-function 
#'company-search-words-in-any-order-regexp
   "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
@@ -2745,7 +2770,9 @@ each one wraps a part of the input string."
           (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)))
+                 company-search-flex-regexp)
+          (const :tag "Space separated words in any order, all chars inside a 
word with anything in between"
+                 company-search-flex-words-in-any-order-regexp)))
 
 (defvar-local company-search-string "")
 
@@ -2779,12 +2806,23 @@ each one wraps a part of the input string."
 (defun company-search-flex-regexp (input)
   (if (zerop (length input))
       ""
-    (concat (regexp-quote (string (aref input 0)))
+    (concat (format "\\(%s\\)" (regexp-quote (string (aref input 0))))
             (mapconcat (lambda (c)
                          (concat "[^" (string c) "]*"
-                                 (regexp-quote (string c))))
+                                 (format "\\(%s\\)"
+                                         (regexp-quote (string c)))))
                        (substring input 1) ""))))
 
+(defun company-search-flex-words-in-any-order-regexp (input)
+  (let* ((words (mapcar (lambda (word) (format "\\(?:%s\\)"
+                                          (company-search-flex-regexp word)))
+                        (split-string input " +" t)))
+         (permutations (company--permutations words)))
+    (mapconcat (lambda (words)
+                 (mapconcat #'identity words ".*"))
+               permutations
+               "\\|")))
+
 (defun company--permutations (lst)
   (if (not lst)
       '(nil)
@@ -2835,9 +2873,16 @@ each one wraps a part of the input string."
   (let* ((selection (or company-selection 0))
          (pos (company--search new (nthcdr selection company-candidates))))
     (if (null pos)
+        (let ((pos (company--search new (nthcdr (- company-candidates-length
+                                                   selection)
+                                                (reverse 
company-candidates)))))
+          (if (null pos)
+              (ding)
+            (setq company-search-string new)
+            (company-set-selection (- selection pos 1) t)))
         (ding)
-      (setq company-search-string new)
-      (company-set-selection (+ selection pos) t))))
+        (setq company-search-string new)
+        (company-set-selection (+ selection pos) t))))
 
 (defun company--search-assert-input ()
   (company--search-assert-enabled)
@@ -2850,7 +2895,7 @@ each one wraps a part of the input string."
   (company--search-assert-input)
   (let* ((selection (or company-selection 0))
          (pos (company--search company-search-string
-                              (cdr (nthcdr selection company-candidates)))))
+                               (cdr (nthcdr selection company-candidates)))))
     (if (null pos)
         (ding)
       (company-set-selection (+ selection pos 1) t))))
@@ -3535,6 +3580,25 @@ from the candidates list.")
         (let ((win (display-buffer doc-buffer t)))
           (set-window-start win (if start start (point-min)))))))
 
+(defun company--fake-capf-complete-common (&rest _)
+  (company-complete-common)
+  (list (point) (point) nil))
+
+(defun company-indent-for-tab-command (&optional arg)
+  "Like `indent-for-tab-command' which see but calls `company-complete-common'
+instead of `completion-at-point' as the fallback.  That only happens when
+`tab-always-indent' is `complete', and only when reindentation was a no-op."
+  (interactive)
+  (unwind-protect
+      (progn
+        (add-hook 'completion-at-point-functions
+                  #'company--fake-capf-complete-common
+                  nil t)
+        (funcall-interactively #'indent-for-tab-command arg))
+    (remove-hook 'completion-at-point-functions
+                 #'company--fake-capf-complete-common
+                 t)))
+
 (defun company-show-doc-buffer (&optional toggle-auto-update)
   "Show the documentation buffer for the selection.
 With a prefix argument TOGGLE-AUTO-UPDATE, toggle the value of
@@ -4253,7 +4317,11 @@ Value of SELECTED determines the added face."
                                  (if company-search-filtering
                                      'filter
                                    'search))))
-         (left (funcall company-format-margin-function "" nil))
+         (left (if company-format-margin-function
+                   (funcall company-format-margin-function "" nil)
+                 (concat
+                  (company-space-string company-tooltip-margin)
+                  (format "%s: " (company-call-backend 'kind)))))
          (line (concat
                 company-search-string))
          (width (+ (company--string-width left) width (length right-margin))))
@@ -4516,6 +4584,9 @@ Delay is determined by `company-tooltip-idle-delay'."
 (defvar-local company-preview-overlay nil)
 
 (defun company-preview-show-at-point (pos completion &optional boundaries)
+  (when (minibufferp)
+    (company-echo-hide))
+
   (company-preview-hide)
 
   (let* ((boundaries (or boundaries (company--boundaries completion)))
@@ -4576,6 +4647,8 @@ Delay is determined by `company-tooltip-idle-delay'."
       (let ((ov company-preview-overlay))
         (overlay-put ov (if (> end beg) 'display 'after-string)
                      completion)
+        ;; Show before minibuffer-message-overlay if there.
+        (overlay-put ov 'priority 1101)
         (overlay-put ov 'window (selected-window))))))
 
 (defun company-preview-hide ()
@@ -4655,9 +4728,31 @@ Delay is determined by `company-tooltip-idle-delay'."
 (defun company-echo-show (&optional getter)
   (let ((last-msg company-echo-last-msg)
         (message-log-max nil)
+        (preview-o company-preview-overlay)
         (message-truncate-lines company-echo-truncate-lines))
     (when getter
       (setq company-echo-last-msg (funcall getter)))
+    (when-let* ((mini-window (and company-echo-truncate-lines
+                                  (active-minibuffer-window)))
+                (posn (posn-at-point
+                       (with-current-buffer (window-buffer mini-window)
+                         (max (point-min)
+                              (1- (point-max))))
+                       mini-window))
+                (max-len (max 0
+                              (- (window-width mini-window)
+                                 (car
+                                  (posn-col-row posn))
+                                 (if preview-o
+                                     (company--string-width
+                                      (or
+                                       (overlay-get preview-o 'display)
+                                       (overlay-get preview-o 'after-string)
+                                       ""))
+                                   0)
+                                 5))))
+      (when (> (length company-echo-last-msg) max-len)
+        (setq company-echo-last-msg (substring company-echo-last-msg 0 
max-len))))
     ;; Avoid modifying the echo area if we don't have anything to say, and we
     ;; didn't put the previous message there (thus there's nothing to clear),
     ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=62816#20
@@ -4743,8 +4838,7 @@ Delay is determined by `company-tooltip-idle-delay'."
 
 (defun company-echo-hide ()
   (unless (string-empty-p company-echo-last-msg)
-    (setq company-echo-last-msg "")
-    (company-echo-show)))
+    (company-echo-show #'ignore)))
 
 (defun company-echo-frontend (command)
   "`company-mode' frontend showing the candidates in the echo area."
@@ -4762,11 +4856,34 @@ Delay is determined by `company-tooltip-idle-delay'."
   "`company-mode' frontend showing the documentation in the echo area."
   (pcase command
     (`pre-command
-     (when (> company-echo-delay 0)
+     (when (and (> company-echo-delay 0)
+                (or (not (minibufferp))
+                    (memq this-command
+                          '(self-insert-command
+                            delete-backward-char
+                            company-select-next
+                            company-select-previous
+                            company-select-next-or-abort
+                            company-select-previous-or-abort
+                            company-next-page
+                            company-previous-page
+                            company-search-repeat-forward
+                            company-search-repeat-backward
+                            company-complete-common-or-cycle))))
        (company-echo-show)))
     (`post-command (company-echo-show-soon 'company-fetch-metadata))
     (`unhide (company-echo-show))
     (`hide (company-echo-hide))))
 
+(eldoc-add-command-completions "company-")
+
+(defun company--eldoc-no-inteference-p ()
+  (or (not company-candidates)
+      (member company-echo-last-msg '(nil ""))))
+
+(advice-add #'eldoc-display-message-no-interference-p
+            :after-while
+            #'company--eldoc-no-inteference-p)
+
 (provide 'company)
 ;;; company.el ends here

Reply via email to