1 ;;; company.el --- extensible inline text completion mechanism
3 ;; Copyright (C) 2009 Nikolaj Schumacher
5 ;; Author: Nikolaj Schumacher <bugs * nschum de>
7 ;; Keywords: abbrev, convenience, matchis
8 ;; URL: http://nschum.de/src/emacs/company/
9 ;; Compatibility: GNU Emacs 23.x
11 ;; This file is NOT part of GNU Emacs.
13 ;; This program is free software; you can redistribute it and/or
14 ;; modify it under the terms of the GNU General Public License
15 ;; as published by the Free Software Foundation; either version 2
16 ;; of the License, or (at your option) any later version.
18 ;; This program is distributed in the hope that it will be useful,
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ;; GNU General Public License for more details.
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
34 (eval-when-compile (require 'cl))
36 (add-to-list 'debug-ignored-errors
37 "^Pseudo tooltip frontend cannot be used twice$")
38 (add-to-list 'debug-ignored-errors "^Preview frontend cannot be used twice$")
39 (add-to-list 'debug-ignored-errors "^Echo area cannot be used twice$")
40 (add-to-list 'debug-ignored-errors "^No documentation available$")
48 (defface company-tooltip
49 '((t :background "yellow"
54 (defface company-tooltip-selection
55 '((t :background "orange1"
60 (defface company-tooltip-common
61 '((t :inherit company-tooltip
66 (defface company-tooltip-common-selection
67 '((t :inherit company-tooltip-selection
72 (defcustom company-tooltip-limit 10
77 (defface company-preview
78 '((t :background "blue4"
83 (defface company-preview-common
84 '((t :inherit company-preview
89 (defface company-echo nil
93 (defface company-echo-common
94 '((((background dark)) (:foreground "firebrick1"))
95 (((background light)) (:background "firebrick4")))
99 (defun company-frontends-set (variable value)
101 (let ((remainder value))
102 (setcdr remainder (delq (car remainder) (cdr remainder))))
103 (and (memq 'company-pseudo-tooltip-unless-just-one-frontend value)
104 (memq 'company-pseudo-tooltip-frontend value)
105 (error "Pseudo tooltip frontend cannot be used twice"))
106 (and (memq 'company-preview-if-just-one-frontend value)
107 (memq 'company-preview-frontend value)
108 (error "Preview frontend cannot be used twice"))
109 (and (memq 'company-echo value)
110 (memq 'company-echo-metadata-frontend value)
111 (error "Echo area cannot be used twice"))
112 ;; preview must come last
113 (dolist (f '(company-preview-if-just-one-frontend company-preview-frontend))
115 (setq value (append (delq f value) (list f)))))
116 (set variable value))
118 (defcustom company-frontends '(company-pseudo-tooltip-unless-just-one-frontend
119 company-preview-if-just-one-frontend
120 company-echo-metadata-frontend)
122 :set 'company-frontends-set
124 :type '(repeat (choice (const :tag "echo" company-echo-frontend)
125 (const :tag "pseudo tooltip"
126 company-pseudo-tooltip-frontend)
127 (const :tag "pseudo tooltip, multiple only"
128 company-pseudo-tooltip-unless-just-one-frontend)
129 (const :tag "preview" company-preview-frontend)
130 (const :tag "preview, unique only"
131 company-preview-if-just-one-frontend)
132 (function :tag "custom function" nil))))
134 (defcustom company-backends '(company-elisp company-nxml company-css
135 company-semantic company-oddmuse
136 company-files company-dabbrev)
139 :type '(repeat (function :tag "function" nil)))
141 (defcustom company-minimum-prefix-length 3
144 :type '(integer :tag "prefix length"))
146 (defvar company-timer nil)
148 (defun company-timer-set (variable value)
150 (when company-timer (cancel-timer company-timer))
151 (when (numberp value)
152 (setq company-timer (run-with-idle-timer value t 'company-idle-begin))))
154 (defcustom company-idle-delay .7
156 :set 'company-timer-set
158 :type '(choice (const :tag "never (nil)" nil)
159 (const :tag "immediate (t)" t)
160 (number :tag "seconds")))
162 ;;; mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
164 (defvar company-mode-map (make-sparse-keymap))
166 (defvar company-active-map
167 (let ((keymap (make-sparse-keymap)))
168 (define-key keymap (kbd "M-n") 'company-select-next)
169 (define-key keymap (kbd "M-p") 'company-select-previous)
170 (define-key keymap "\C-m" 'company-complete-selection)
171 (define-key keymap "\t" 'company-complete-common)
172 (define-key keymap (kbd "<f1>") 'company-show-doc-buffer)
173 (define-key keymap "\C-s" 'company-search-candidates)
177 (define-minor-mode company-mode
179 nil " comp" company-mode-map
182 (add-hook 'pre-command-hook 'company-pre-command nil t)
183 (add-hook 'post-command-hook 'company-post-command nil t)
184 (company-timer-set 'company-idle-delay
186 (remove-hook 'pre-command-hook 'company-pre-command t)
187 (remove-hook 'post-command-hook 'company-post-command t)
189 (kill-local-variable 'company-point)))
191 ;;; keymaps ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
193 (defvar company-overriding-keymap-bound nil)
194 (make-variable-buffer-local 'company-overriding-keymap-bound)
196 (defvar company-old-keymap nil)
197 (make-variable-buffer-local 'company-old-keymap)
199 (defvar company-my-keymap nil)
200 (make-variable-buffer-local 'company-my-keymap)
202 (defsubst company-enable-overriding-keymap (keymap)
203 (setq company-my-keymap keymap)
204 (when company-overriding-keymap-bound
205 (company-uninstall-map)))
207 (defun company-install-map ()
208 (unless (or company-overriding-keymap-bound
209 (null company-my-keymap))
210 (setq company-old-keymap overriding-terminal-local-map
211 overriding-terminal-local-map company-my-keymap
212 company-overriding-keymap-bound t)))
214 (defun company-uninstall-map ()
215 (when (and company-overriding-keymap-bound
216 (eq overriding-terminal-local-map company-my-keymap))
217 (setq overriding-terminal-local-map company-old-keymap
218 company-overriding-keymap-bound nil)))
221 ;; Emacs calculates the active keymaps before reading the event. That means we
222 ;; cannot change the keymap from a timer. So we send a bogus command.
223 (defun company-ignore ()
226 (global-set-key '[31415926] 'company-ignore)
228 (defun company-input-noop ()
229 (push 31415926 unread-command-events))
231 ;;; backends ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
233 (defun company-grab (regexp &optional expression)
234 (when (looking-back regexp)
235 (or (match-string-no-properties (or expression 0)) "")))
237 (defun company-in-string-or-comment (&optional point)
238 (let ((pos (syntax-ppss)))
239 (or (nth 3 pos) (nth 4 pos) (nth 7 pos))))
241 ;;; completion mechanism ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
243 (defvar company-backend nil)
244 (make-variable-buffer-local 'company-backend)
246 (defvar company-prefix nil)
247 (make-variable-buffer-local 'company-prefix)
249 (defvar company-candidates nil)
250 (make-variable-buffer-local 'company-candidates)
252 (defvar company-candidates-cache nil)
253 (make-variable-buffer-local 'company-candidates-cache)
255 (defvar company-common nil)
256 (make-variable-buffer-local 'company-common)
258 (defvar company-selection 0)
259 (make-variable-buffer-local 'company-selection)
261 (defvar company-selection-changed nil)
262 (make-variable-buffer-local 'company-selection-changed)
264 (defvar company-point nil)
265 (make-variable-buffer-local 'company-point)
267 (defvar company-disabled-backends nil)
269 (defsubst company-strip-prefix (str)
270 (substring str (length company-prefix)))
272 (defsubst company-reformat (candidate)
273 ;; company-ispell needs this, because the results are always lower-case
274 ;; It's mory efficient to fix it only when they are displayed.
275 (concat company-prefix (substring candidate (length company-prefix))))
277 (defsubst company-should-complete (prefix)
278 (and (eq company-idle-delay t)
279 (>= (length prefix) company-minimum-prefix-length)))
281 (defsubst company-call-frontends (command)
282 (dolist (frontend company-frontends)
283 (funcall frontend command)))
285 (defsubst company-set-selection (selection &optional force-update)
286 (setq selection (max 0 (min (1- (length company-candidates)) selection)))
287 (when (or force-update (not (equal selection company-selection)))
288 (setq company-selection selection
289 company-selection-changed t)
290 (company-call-frontends 'update)))
292 (defsubst company-calculate-candidates (prefix)
293 (or (setq company-candidates (cdr (assoc prefix company-candidates-cache)))
294 (let ((len (length prefix))
295 (completion-ignore-case (funcall company-backend 'ignore-case))
298 (when (setq prev (cdr (assoc (substring prefix 0 (- len i))
299 company-candidates-cache)))
300 (setq company-candidates (all-completions prefix prev))
303 (setq company-candidates (funcall company-backend 'candidates prefix))
304 (unless (funcall company-backend 'sorted)
305 (setq company-candidates (sort company-candidates 'string<)))))
306 (unless (assoc prefix company-candidates-cache)
307 (push (cons prefix company-candidates) company-candidates-cache))
308 (setq company-selection 0
309 company-prefix prefix)
310 (let ((completion-ignore-case (funcall company-backend 'ignore-case)))
311 (setq company-common (try-completion company-prefix company-candidates)))
312 (when (eq company-common t)
313 (setq company-candidates nil))
316 (defun company-idle-begin ()
318 (not company-candidates)
319 (not (equal (point) company-point))
320 (let ((company-idle-delay t))
322 (when company-candidates
324 (company-post-command)))))
326 (defun company-manual-begin ()
328 (not company-candidates)
329 (let ((company-idle-delay t)
330 (company-minimum-prefix-length 0))
332 ;; Return non-nil if active.
335 (defun company-continue ()
336 (when company-candidates
337 (when (funcall company-backend 'no-cache)
338 ;; Don't complete existing candidates, fetch new ones.
339 (setq company-candidates-cache nil))
340 (let ((new-prefix (funcall company-backend 'prefix)))
341 (unless (and (= (- (point) (length new-prefix))
342 (- company-point (length company-prefix)))
343 (or (equal company-prefix new-prefix)
344 (company-calculate-candidates new-prefix)))
345 (setq company-candidates nil)))))
347 (defun company-begin ()
348 (if (or buffer-read-only overriding-terminal-local-map overriding-local-map)
349 ;; Don't complete in these cases.
350 (setq company-candidates nil)
352 (unless company-candidates
354 (dolist (backend company-backends)
355 (unless (fboundp backend)
356 (ignore-errors (require backend nil t)))
357 (if (fboundp backend)
358 (when (setq prefix (funcall backend 'prefix))
359 (when (company-should-complete prefix)
360 (setq company-backend backend)
361 (company-calculate-candidates prefix))
363 (unless (memq backend company-disabled-backends)
364 (push backend company-disabled-backends)
365 (message "Company back-end '%s' could not be initialized"
367 (if company-candidates
369 (setq company-point (point))
370 (company-enable-overriding-keymap company-active-map)
371 (company-call-frontends 'update))
374 (defun company-cancel ()
375 (setq company-backend nil
377 company-candidates nil
378 company-candidates-cache nil
381 company-selection-changed nil
383 (company-search-mode 0)
384 (company-call-frontends 'hide)
385 (company-enable-overriding-keymap nil))
387 (defun company-abort ()
389 ;; Don't start again, unless started manually.
390 (setq company-point (point)))
392 (defun company-pre-command ()
393 (unless (eq this-command 'company-show-doc-buffer)
395 (when company-candidates
396 (company-call-frontends 'pre-command))
397 (error (message "Company: An error occurred in pre-command")
398 (message "%s" (error-message-string err))
400 (company-uninstall-map))
402 (defun company-post-command ()
403 (unless (eq this-command 'company-show-doc-buffer)
406 (unless (equal (point) company-point)
408 (when company-candidates
409 (company-call-frontends 'post-command)))
410 (error (message "Company: An error occurred in post-command")
411 (message "%s" (error-message-string err))
413 (company-install-map))
415 ;;; search ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
417 (defvar company-search-string nil)
418 (make-variable-buffer-local 'company-search-string)
420 (defvar company-search-lighter " Search: \"\"")
421 (make-variable-buffer-local 'company-search-lighter)
423 (defvar company-search-old-map nil)
424 (make-variable-buffer-local 'company-search-old-map)
426 (defvar company-search-old-selection 0)
427 (make-variable-buffer-local 'company-search-old-selection)
429 (defun company-search (text lines)
430 (let ((quoted (regexp-quote text))
433 (when (string-match quoted line (length company-prefix))
437 (defun company-search-printing-char ()
439 (setq company-search-string
440 (concat (or company-search-string "") (string last-command-event))
441 company-search-lighter (concat " Search: \"" company-search-string
443 (let ((pos (company-search company-search-string
444 (nthcdr company-selection company-candidates))))
447 (company-set-selection (+ company-selection pos) t))))
449 (defun company-search-repeat-forward ()
451 (let ((pos (company-search company-search-string
452 (cdr (nthcdr company-selection
453 company-candidates)))))
456 (company-set-selection (+ company-selection pos 1) t))))
458 (defun company-search-repeat-backward ()
460 (let ((pos (company-search company-search-string
461 (nthcdr (- (length company-candidates)
463 (reverse company-candidates)))))
466 (company-set-selection (- company-selection pos 1) t))))
468 (defun company-search-abort ()
470 (company-set-selection company-search-old-selection t)
471 (company-search-mode 0))
473 (defun company-search-other-char ()
475 (company-search-mode 0)
476 (when last-input-event
477 (clear-this-command-keys t)
478 (setq unread-command-events (list last-input-event))))
480 (defvar company-search-map
482 (keymap (make-keymap)))
483 (set-char-table-range (nth 1 keymap) (cons #x100 (max-char))
484 'company-search-printing-char)
485 (define-key keymap [t] 'company-search-other-char)
487 (define-key keymap (make-string 1 i) 'company-search-other-char)
490 (define-key keymap (vector i) 'company-search-printing-char)
492 (let ((meta-map (make-sparse-keymap)))
493 (define-key keymap (char-to-string meta-prefix-char) meta-map)
494 (define-key keymap [escape] meta-map))
495 (define-key keymap (vector meta-prefix-char t) 'company-search-other-char)
496 (define-key keymap "\e\e\e" 'company-search-other-char)
497 (define-key keymap [escape escape escape] 'company-search-other-char)
499 (define-key keymap "\C-g" 'company-search-abort)
500 (define-key keymap "\C-s" 'company-search-repeat-forward)
501 (define-key keymap "\C-r" 'company-search-repeat-backward)
504 (define-minor-mode company-search-mode
506 nil company-search-lighter nil
507 (if company-search-mode
508 (if (company-manual-begin)
510 (setq company-search-old-selection company-selection)
511 (company-enable-overriding-keymap company-search-map)
512 (company-call-frontends 'update))
513 (setq company-search-mode nil))
514 (kill-local-variable 'company-search-string)
515 (kill-local-variable 'company-search-lighter)
516 (kill-local-variable 'company-search-old-selection)
517 (company-enable-overriding-keymap company-active-map)))
519 (defun company-search-candidates ()
521 (company-search-mode 1))
523 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
525 (defun company-select-next ()
527 (when (company-manual-begin)
528 (company-set-selection (1+ company-selection))))
530 (defun company-select-previous ()
532 (when (company-manual-begin)
533 (company-set-selection (1- company-selection))))
535 (defun company-complete-selection ()
537 (when (company-manual-begin)
538 (insert (company-strip-prefix (nth company-selection company-candidates)))
541 (defun company-complete-common ()
543 (when (company-manual-begin)
544 (insert (company-strip-prefix company-common))))
546 (defun company-complete ()
548 (when (company-manual-begin)
549 (if (or company-selection-changed
550 (eq last-command 'company-complete-common))
551 (call-interactively 'company-complete-selection)
552 (call-interactively 'company-complete-common)
553 (setq this-command 'company-complete-common))))
555 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
557 (defconst company-space-strings-limit 100)
559 (defconst company-space-strings
561 (dotimes (i company-space-strings-limit)
562 (push (make-string (- company-space-strings-limit 1 i) ?\ ) lst))
563 (apply 'vector lst)))
565 (defsubst company-space-string (len)
566 (if (< len company-space-strings-limit)
567 (aref company-space-strings len)
568 (make-string len ?\ )))
570 (defsubst company-safe-substring (str from &optional to)
571 (let ((len (length str)))
574 (if (and to (> to len))
575 (concat (substring str from)
576 (company-space-string (- to len)))
577 (substring str from to)))))
579 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
581 (defvar company-last-metadata nil)
582 (make-variable-buffer-local 'company-last-metadata)
584 (defun company-fetch-metadata ()
585 (let ((selected (nth company-selection company-candidates)))
586 (unless (equal selected (car company-last-metadata))
587 (setq company-last-metadata
588 (cons selected (funcall company-backend 'meta selected))))
589 (cdr company-last-metadata)))
591 (defun company-doc-buffer (&optional string)
592 (with-current-buffer (get-buffer-create "*Company meta-data*")
596 (defun company-show-doc-buffer ()
598 (when company-candidates
599 (save-window-excursion
600 (let* ((height (window-height))
601 (row (cdr (posn-col-row (posn-at-point))))
602 (selected (nth company-selection company-candidates))
603 (buffer (funcall company-backend 'doc-buffer selected)))
605 (error "No documentation available.")
606 (display-buffer buffer)
607 (and (< (window-height) height)
608 (< (- (window-height) row 2) company-tooltip-limit)
609 (recenter (- (window-height) row 2)))
611 (when last-input-event
612 (clear-this-command-keys t)
613 (setq unread-command-events (list last-input-event))))))))
615 ;;; pseudo-tooltip ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
617 (defvar company-pseudo-tooltip-overlay nil)
618 (make-variable-buffer-local 'company-pseudo-tooltip-overlay)
620 (defvar company-tooltip-offset 0)
621 (make-variable-buffer-local 'company-tooltip-offset)
623 (defun company-pseudo-tooltip-update-offset (selection num-lines limit)
626 (setq company-tooltip-offset
627 (max (min selection company-tooltip-offset)
628 (- selection -1 limit)))
630 (when (<= company-tooltip-offset 1)
632 (setq company-tooltip-offset 0))
634 (when (>= company-tooltip-offset (- num-lines limit 1))
636 (when (= selection (1- num-lines))
637 (decf company-tooltip-offset)
638 (when (<= company-tooltip-offset 1)
639 (setq company-tooltip-offset 0)
646 (defun company-fill-propertize (line width selected)
647 (setq line (company-safe-substring line 0 width))
648 (add-text-properties 0 width (list 'face 'company-tooltip) line)
649 (add-text-properties 0 (length company-common)
650 (list 'face 'company-tooltip-common) line)
652 (if (and company-search-string
653 (string-match (regexp-quote company-search-string) line
654 (length company-prefix)))
656 (add-text-properties (match-beginning 0) (match-end 0)
657 '(face company-tooltip-selection) line)
658 (when (< (match-beginning 0) (length company-common))
659 (add-text-properties (match-beginning 0) (length company-common)
660 '(face company-tooltip-common-selection)
662 (add-text-properties 0 width '(face company-tooltip-selection) line)
663 (add-text-properties 0 (length company-common)
664 (list 'face 'company-tooltip-common-selection)
670 (defun company-buffer-lines (beg end)
672 (let ((row (cdr (posn-col-row (posn-at-point))))
674 (while (and (equal (move-to-window-line (incf row)) row)
676 (push (buffer-substring beg (min end (1- (point)))) lines)
679 (push (buffer-substring beg end) lines))
682 (defun company-modify-line (old new offset)
683 (concat (company-safe-substring old 0 offset)
685 (company-safe-substring old (+ offset (length new)))))
687 (defun company-replacement-string (old lines column nl)
689 ;; Inject into old lines.
691 (push (company-modify-line (pop old) (pop lines) column) new))
692 ;; Append whole new lines.
694 (push (company-modify-line "" (pop lines) column) new))
695 (concat (when nl "\n")
696 (mapconcat 'identity (nreverse new) "\n")
699 (defun company-create-lines (column lines selection limit)
701 (let ((len (length lines))
709 (setq limit (company-pseudo-tooltip-update-offset selection len limit))
711 (when (> company-tooltip-offset 0)
712 (setq previous (format "...(%d)" company-tooltip-offset)))
714 (setq remainder (- len limit company-tooltip-offset)
715 remainder (when (> remainder 0)
716 (setq remainder (format "...(%d)" remainder))))
718 (decf selection company-tooltip-offset)
719 (setq width (min (length previous) (length remainder))
720 lines (nthcdr company-tooltip-offset lines)
721 len (min limit (length lines))
725 (setq width (max (length (pop lines-copy)) width)))
726 (setq width (min width (- (window-width) column)))
729 (push (propertize (company-safe-substring previous 0 width)
730 'face 'company-tooltip)
734 (push (company-fill-propertize (company-reformat (pop lines))
735 width (equal i selection))
739 (push (propertize (company-safe-substring remainder 0 width)
740 'face 'company-tooltip)
743 (setq lines (nreverse new))))
747 (defsubst company-pseudo-tooltip-height ()
748 "Calculate the appropriate tooltip height."
749 (max 3 (min company-tooltip-limit
750 (- (window-height) (cdr (posn-col-row (posn-at-point))) 2))))
752 (defun company-pseudo-tooltip-show (row column lines selection)
753 (company-pseudo-tooltip-hide)
754 (unless lines (error "No text provided"))
759 (let* ((height (company-pseudo-tooltip-height))
760 (lines (company-create-lines column lines selection height))
761 (nl (< (move-to-window-line row) row))
764 (move-to-window-line (+ row height))
766 (old-string (company-buffer-lines beg end))
769 (setq company-pseudo-tooltip-overlay (make-overlay beg end))
771 (overlay-put company-pseudo-tooltip-overlay 'company-old old-string)
772 (overlay-put company-pseudo-tooltip-overlay 'company-column column)
773 (overlay-put company-pseudo-tooltip-overlay 'company-nl nl)
774 (overlay-put company-pseudo-tooltip-overlay 'company-before
775 (company-replacement-string old-string lines column nl))
776 (overlay-put company-pseudo-tooltip-overlay 'company-height height)
778 (overlay-put company-pseudo-tooltip-overlay 'window (selected-window)))))
780 (defun company-pseudo-tooltip-show-at-point (pos)
781 (let ((col-row (posn-col-row (posn-at-point pos))))
782 (company-pseudo-tooltip-show (1+ (cdr col-row)) (car col-row)
783 company-candidates company-selection)))
785 (defun company-pseudo-tooltip-edit (lines selection)
786 (let* ((old-string (overlay-get company-pseudo-tooltip-overlay 'company-old))
787 (column (overlay-get company-pseudo-tooltip-overlay 'company-column))
788 (nl (overlay-get company-pseudo-tooltip-overlay 'company-nl))
789 (height (overlay-get company-pseudo-tooltip-overlay 'company-height))
790 (lines (company-create-lines column lines selection height)))
791 (overlay-put company-pseudo-tooltip-overlay 'company-before
792 (company-replacement-string old-string lines column nl))))
794 (defun company-pseudo-tooltip-hide ()
795 (when company-pseudo-tooltip-overlay
796 (delete-overlay company-pseudo-tooltip-overlay)
797 (setq company-pseudo-tooltip-overlay nil)))
799 (defun company-pseudo-tooltip-hide-temporarily ()
800 (when (overlayp company-pseudo-tooltip-overlay)
801 (overlay-put company-pseudo-tooltip-overlay 'invisible nil)
802 (overlay-put company-pseudo-tooltip-overlay 'before-string nil)))
804 (defun company-pseudo-tooltip-unhide ()
805 (when company-pseudo-tooltip-overlay
806 (overlay-put company-pseudo-tooltip-overlay 'invisible t)
807 (overlay-put company-pseudo-tooltip-overlay 'before-string
808 (overlay-get company-pseudo-tooltip-overlay 'company-before))))
810 (defun company-pseudo-tooltip-frontend (command)
812 ('pre-command (company-pseudo-tooltip-hide-temporarily))
814 (unless (and (overlayp company-pseudo-tooltip-overlay)
815 (equal (overlay-get company-pseudo-tooltip-overlay
817 (company-pseudo-tooltip-height)))
819 (company-pseudo-tooltip-show-at-point (- (point)
820 (length company-prefix))))
821 (company-pseudo-tooltip-unhide))
822 ('hide (company-pseudo-tooltip-hide)
823 (setq company-tooltip-offset 0))
824 ('update (when (overlayp company-pseudo-tooltip-overlay)
825 (company-pseudo-tooltip-edit company-candidates
826 company-selection)))))
828 (defun company-pseudo-tooltip-unless-just-one-frontend (command)
829 (unless (and (eq command 'post-command)
830 (not (cdr company-candidates)))
831 (company-pseudo-tooltip-frontend command)))
833 ;;; overlay ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
835 (defvar company-preview-overlay nil)
836 (make-variable-buffer-local 'company-preview-overlay)
838 (defun company-preview-show-at-point (pos)
839 (company-preview-hide)
841 (setq company-preview-overlay (make-overlay pos pos))
843 (let ((completion (company-strip-prefix (nth company-selection
844 company-candidates))))
845 (and (equal pos (point))
846 (not (equal completion ""))
847 (add-text-properties 0 1 '(cursor t) completion))
849 (setq completion (propertize completion 'face 'company-preview))
850 (add-text-properties 0 (- (length company-common) (length company-prefix))
851 '(face company-preview-common) completion)
853 (overlay-put company-preview-overlay 'after-string completion)
854 (overlay-put company-preview-overlay 'window (selected-window))))
856 (defun company-preview-hide ()
857 (when company-preview-overlay
858 (delete-overlay company-preview-overlay)
859 (setq company-preview-overlay nil)))
861 (defun company-preview-frontend (command)
863 ('pre-command (company-preview-hide))
864 ('post-command (company-preview-show-at-point (point)))
865 ('hide (company-preview-hide))))
867 (defun company-preview-if-just-one-frontend (command)
868 (unless (and (eq command 'post-command)
869 (cdr company-candidates))
870 (company-preview-frontend command)))
872 ;;; echo ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
874 (defvar company-echo-last-msg nil)
875 (make-variable-buffer-local 'company-echo-last-msg)
877 (defun company-echo-refresh ()
878 (let ((message-log-max nil))
879 (if company-echo-last-msg
880 (message "%s" company-echo-last-msg)
883 (defun company-echo-show (candidates)
885 ;; Roll to selection.
886 (setq candidates (nthcdr company-selection candidates))
888 (let ((limit (window-width (minibuffer-window)))
892 (setq comp (company-reformat (pop candidates))
893 len (+ len 1 (length comp)))
895 (setq candidates nil)
896 (setq comp (propertize comp 'face 'company-echo))
897 (add-text-properties 0 (length company-common)
898 '(face company-echo-common) comp)
901 (setq company-echo-last-msg (mapconcat 'identity (nreverse msg) " "))
902 (company-echo-refresh)))
904 (defun company-echo-frontend (command)
906 ('pre-command (company-echo-refresh))
907 ('post-command (company-echo-show company-candidates))
908 ('hide (setq company-echo-last-msg nil))))
910 (defun company-echo-metadata-frontend (command)
912 ('pre-command (company-echo-refresh))
913 ('post-command (setq company-echo-last-msg (company-fetch-metadata))
914 (company-echo-refresh))
915 ('hide (setq company-echo-last-msg nil))))
919 ;;; company.el ends here