]> code.delx.au - gnu-emacs-elpa/blob - company.el
Allow calculating candidates without setting them.
[gnu-emacs-elpa] / company.el
1 ;;; company.el --- extensible inline text completion mechanism
2 ;;
3 ;; Copyright (C) 2009 Nikolaj Schumacher
4 ;;
5 ;; Author: Nikolaj Schumacher <bugs * nschum de>
6 ;; Version: 0.2.1
7 ;; Keywords: abbrev, convenience, matchis
8 ;; URL: http://nschum.de/src/emacs/company/
9 ;; Compatibility: GNU Emacs 22.x, GNU Emacs 23.x
10 ;;
11 ;; This file is NOT part of GNU Emacs.
12 ;;
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.
17 ;;
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.
22 ;;
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/>.
25 ;;
26 ;;; Commentary:
27 ;;
28 ;; Company is a modular completion mechanism. Modules for retrieving completion
29 ;; candidates are called back-ends, modules for displaying them are front-ends.
30 ;;
31 ;; Company comes with many back-ends, e.g. `company-elisp'. These are
32 ;; distributed in individual files and can be used individually.
33 ;;
34 ;; Place company.el and the back-ends you want to use in a directory and add the
35 ;; following to your .emacs:
36 ;; (add-to-list 'load-path "/path/to/company")
37 ;; (autoload 'company-mode "company" nil t)
38 ;;
39 ;; Enable company-mode with M-x company-mode. For further information look at
40 ;; the documentation for `company-mode' (C-h f company-mode RET)
41 ;;
42 ;; To write your own back-end, look at the documentation for `company-backends'.
43 ;; Here is a simple example completing "foo":
44 ;;
45 ;; (defun company-my-backend (command &optional arg &rest ignored)
46 ;; (case command
47 ;; ('prefix (when (looking-back "foo\\>")
48 ;; (match-string 0)))
49 ;; ('candidates (list "foobar" "foobaz" "foobarbaz"))
50 ;; ('meta (format "This value is named %s" arg))))
51 ;;
52 ;; Sometimes it is a good idea to mix two back-ends together, for example to
53 ;; enrich gtags with dabbrev text (to emulate local variables):
54 ;;
55 ;; (defun gtags-gtags-dabbrev-backend (command &optional arg &rest ignored)
56 ;; (case command
57 ;; (prefix (company-gtags 'prefix))
58 ;; (candidates (append (company-gtags 'candidates arg)
59 ;; (company-dabbrev 'candidates arg)))))
60 ;;
61 ;; Known Issues:
62 ;; When point is at the very end of the buffer, the pseudo-tooltip appears very
63 ;; wrong, unless company is allowed to temporarily insert a fake newline.
64 ;; This behavior is enabled by `company-end-of-buffer-workaround'.
65 ;;
66 ;;; Change Log:
67 ;;
68 ;; 2009-04-05 (0.2.1)
69 ;; Improved Emacs Lisp back-end behavior for local variables.
70 ;; Added `company-elisp-detect-function-context' option.
71 ;; The mouse can now be used for selection.
72 ;;
73 ;; 2009-03-22 (0.2)
74 ;; Added `company-show-location'.
75 ;; Added etags back-end.
76 ;; Added work-around for end-of-buffer bug.
77 ;; Added `company-filter-candidates'.
78 ;; More local Lisp variables are now included in the candidates.
79 ;;
80 ;; 2009-03-21 (0.1.5)
81 ;; Fixed elisp documentation buffer always showing the same doc.
82 ;; Added `company-echo-strip-common-frontend'.
83 ;; Added `company-show-numbers' option and M-0 ... M-9 default bindings.
84 ;; Don't hide the echo message if it isn't shown.
85 ;;
86 ;; 2009-03-20 (0.1)
87 ;; Initial release.
88 ;;
89 ;;; Code:
90
91 (eval-when-compile (require 'cl))
92
93 (add-to-list 'debug-ignored-errors
94 "^Pseudo tooltip frontend cannot be used twice$")
95 (add-to-list 'debug-ignored-errors "^Preview frontend cannot be used twice$")
96 (add-to-list 'debug-ignored-errors "^Echo area cannot be used twice$")
97 (add-to-list 'debug-ignored-errors "^No documentation available$")
98 (add-to-list 'debug-ignored-errors "^No location available$")
99 (add-to-list 'debug-ignored-errors "^Company not enabled$")
100 (add-to-list 'debug-ignored-errors "^Company not in search mode$")
101 (add-to-list 'debug-ignored-errors "^No candidate number ")
102
103 (defgroup company nil
104 "Extensible inline text completion mechanism"
105 :group 'abbrev
106 :group 'convenience
107 :group 'maching)
108
109 (defface company-tooltip
110 '((t :background "yellow"
111 :foreground "black"))
112 "*Face used for the tool tip."
113 :group 'company)
114
115 (defface company-tooltip-selection
116 '((default :inherit company-tooltip)
117 (((class color) (min-colors 88)) (:background "orange1"))
118 (t (:background "green")))
119 "*Face used for the selection in the tool tip."
120 :group 'company)
121
122 (defface company-tooltip-mouse
123 '((default :inherit highlight))
124 "*Face used for the tool tip item under the mouse."
125 :group 'company)
126
127 (defface company-tooltip-common
128 '((t :inherit company-tooltip
129 :foreground "red"))
130 "*Face used for the common completion in the tool tip."
131 :group 'company)
132
133 (defface company-tooltip-common-selection
134 '((t :inherit company-tooltip-selection
135 :foreground "red"))
136 "*Face used for the selected common completion in the tool tip."
137 :group 'company)
138
139 (defcustom company-tooltip-limit 10
140 "*The maximum number of candidates in the tool tip"
141 :group 'company
142 :type 'integer)
143
144 (defface company-preview
145 '((t :background "blue4"
146 :foreground "wheat"))
147 "*Face used for the completion preview."
148 :group 'company)
149
150 (defface company-preview-common
151 '((t :inherit company-preview
152 :foreground "red"))
153 "*Face used for the common part of the completion preview."
154 :group 'company)
155
156 (defface company-preview-search
157 '((t :inherit company-preview
158 :background "blue1"))
159 "*Face used for the search string in the completion preview."
160 :group 'company)
161
162 (defface company-echo nil
163 "*Face used for completions in the echo area."
164 :group 'company)
165
166 (defface company-echo-common
167 '((((background dark)) (:foreground "firebrick1"))
168 (((background light)) (:background "firebrick4")))
169 "*Face used for the common part of completions in the echo area."
170 :group 'company)
171
172 (defun company-frontends-set (variable value)
173 ;; uniquify
174 (let ((remainder value))
175 (setcdr remainder (delq (car remainder) (cdr remainder))))
176 (and (memq 'company-pseudo-tooltip-unless-just-one-frontend value)
177 (memq 'company-pseudo-tooltip-frontend value)
178 (error "Pseudo tooltip frontend cannot be used twice"))
179 (and (memq 'company-preview-if-just-one-frontend value)
180 (memq 'company-preview-frontend value)
181 (error "Preview frontend cannot be used twice"))
182 (and (memq 'company-echo value)
183 (memq 'company-echo-metadata-frontend value)
184 (error "Echo area cannot be used twice"))
185 ;; preview must come last
186 (dolist (f '(company-preview-if-just-one-frontend company-preview-frontend))
187 (when (memq f value)
188 (setq value (append (delq f value) (list f)))))
189 (set variable value))
190
191 (defcustom company-frontends '(company-pseudo-tooltip-unless-just-one-frontend
192 company-preview-frontend
193 company-echo-metadata-frontend)
194 "*The list of active front-ends (visualizations).
195 Each front-end is a function that takes one argument. It is called with
196 one of the following arguments:
197
198 'show: When the visualization should start.
199
200 'hide: When the visualization should end.
201
202 'update: When the data has been updated.
203
204 'pre-command: Before every command that is executed while the
205 visualization is active.
206
207 'post-command: After every command that is executed while the
208 visualization is active.
209
210 The visualized data is stored in `company-prefix', `company-candidates',
211 `company-common', `company-selection', `company-point' and
212 `company-search-string'."
213 :set 'company-frontends-set
214 :group 'company
215 :type '(repeat (choice (const :tag "echo" company-echo-frontend)
216 (const :tag "echo, strip common"
217 company-echo-strip-common-frontend)
218 (const :tag "show echo meta-data in echo"
219 company-echo-metadata-frontend)
220 (const :tag "pseudo tooltip"
221 company-pseudo-tooltip-frontend)
222 (const :tag "pseudo tooltip, multiple only"
223 company-pseudo-tooltip-unless-just-one-frontend)
224 (const :tag "preview" company-preview-frontend)
225 (const :tag "preview, unique only"
226 company-preview-if-just-one-frontend)
227 (function :tag "custom function" nil))))
228
229 (defcustom company-backends '(company-elisp company-nxml company-css
230 company-semantic company-gtags company-etags
231 company-oddmuse company-files company-dabbrev)
232 "*The list of active back-ends (completion engines).
233 Each back-end is a function that takes a variable number of arguments.
234 The first argument is the command requested from the back-end. It is one
235 of the following:
236
237 'prefix: The back-end should return the text to be completed. It must be
238 text immediately before `point'. Returning nil passes control to the next
239 back-end.
240
241 'candidates: The second argument is the prefix to be completed. The
242 return value should be a list of candidates that start with the prefix.
243
244 Optional commands:
245
246 'sorted: The back-end may return t here to indicate that the candidates
247 are sorted and will not need to be sorted again.
248
249 'no-cache: Usually company doesn't ask for candidates again as completion
250 progresses, unless the back-end returns t for this command. The second
251 argument is the latest prefix.
252
253 'meta: The second argument is a completion candidate. The back-end should
254 return a (short) documentation string for it.
255
256 'doc-buffer: The second argument is a completion candidate. The back-end should
257 create a buffer (preferably with `company-doc-buffer'), fill it with
258 documentation and return it.
259
260 'location: The second argument is a completion candidate. The back-end can
261 return the cons of buffer and buffer location, or of file and line
262 number where the completion candidate was defined.
263
264 The back-end should return nil for all commands it does not support or
265 does not know about."
266 :group 'company
267 :type '(repeat (function :tag "function" nil)))
268
269 (defcustom company-minimum-prefix-length 3
270 "*The minimum prefix length for automatic completion."
271 :group 'company
272 :type '(integer :tag "prefix length"))
273
274 (defcustom company-idle-delay .7
275 "*The idle delay in seconds until automatic completions starts.
276 A value of nil means never complete automatically, t means complete
277 immediately when a prefix of `company-minimum-prefix-length' is reached."
278 :group 'company
279 :type '(choice (const :tag "never (nil)" nil)
280 (const :tag "immediate (t)" t)
281 (number :tag "seconds")))
282
283 (defcustom company-show-numbers nil
284 "*If enabled, show quick-access numbers for the first ten candidates."
285 :group 'company
286 :type '(choice (const :tag "off" nil)
287 (const :tag "on" t)))
288
289 (defvar company-end-of-buffer-workaround t
290 "*Work around a visualization bug when completing at the end of the buffer.
291 The work-around consists of adding a newline.")
292
293 ;;; mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
294
295 (defvar company-mode-map (make-sparse-keymap)
296 "Keymap used by `company-mode'.")
297
298 (defvar company-active-map
299 (let ((keymap (make-sparse-keymap)))
300 (define-key keymap (kbd "M-n") 'company-select-next)
301 (define-key keymap (kbd "M-p") 'company-select-previous)
302 (define-key keymap (kbd "<down>") 'company-select-next)
303 (define-key keymap (kbd "<up>") 'company-select-previous)
304 (define-key keymap [down-mouse-1] 'ignore)
305 (define-key keymap [down-mouse-3] 'ignore)
306 (define-key keymap [mouse-1] 'company-complete-mouse)
307 (define-key keymap [mouse-3] 'company-select-mouse)
308 (define-key keymap [up-mouse-1] 'ignore)
309 (define-key keymap [up-mouse-3] 'ignore)
310 (define-key keymap "\C-m" 'company-complete-selection)
311 (define-key keymap "\t" 'company-complete-common)
312 (define-key keymap (kbd "<f1>") 'company-show-doc-buffer)
313 (define-key keymap "\C-w" 'company-show-location)
314 (define-key keymap "\C-s" 'company-search-candidates)
315 (define-key keymap "\C-\M-s" 'company-filter-candidates)
316 (dotimes (i 10)
317 (define-key keymap (vector (+ (aref (kbd "M-0") 0) i))
318 `(lambda () (interactive) (company-complete-number ,i))))
319
320 keymap)
321 "Keymap that is enabled during an active completion.")
322
323 ;;;###autoload
324 (define-minor-mode company-mode
325 "\"complete anything\"; in in-buffer completion framework.
326 Completion starts automatically, depending on the values
327 `company-idle-delay' and `company-minimum-prefix-length'.
328
329 Completion can be controlled with the commands:
330 `company-complete-common', `company-complete-selection', `company-complete',
331 `company-select-next', `company-select-previous'. If these commands are
332 called before `company-idle-delay', completion will also start.
333
334 Completions can be searched with `company-search-candidates' or
335 `company-filter-candidates'. These can be used while completion is
336 inactive, as well.
337
338 The completion data is retrieved using `company-backends' and displayed using
339 `company-frontends'.
340
341 regular keymap (`company-mode-map'):
342
343 \\{company-mode-map}
344 keymap during active completions (`company-active-map'):
345
346 \\{company-active-map}"
347 nil " comp" company-mode-map
348 (if company-mode
349 (progn
350 (add-hook 'pre-command-hook 'company-pre-command nil t)
351 (add-hook 'post-command-hook 'company-post-command nil t)
352 (dolist (backend company-backends)
353 (unless (fboundp backend)
354 (ignore-errors (require backend nil t)))
355 (unless (fboundp backend)
356 (message "Company back-end '%s' could not be initialized"
357 backend))))
358 (remove-hook 'pre-command-hook 'company-pre-command t)
359 (remove-hook 'post-command-hook 'company-post-command t)
360 (company-cancel)
361 (kill-local-variable 'company-point)))
362
363 ;;; keymaps ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
364
365 (defvar company-overriding-keymap-bound nil)
366 (make-variable-buffer-local 'company-overriding-keymap-bound)
367
368 (defvar company-old-keymap nil)
369 (make-variable-buffer-local 'company-old-keymap)
370
371 (defvar company-my-keymap nil)
372 (make-variable-buffer-local 'company-my-keymap)
373
374 (defsubst company-enable-overriding-keymap (keymap)
375 (setq company-my-keymap keymap)
376 (when company-overriding-keymap-bound
377 (company-uninstall-map)))
378
379 (defun company-install-map ()
380 (unless (or company-overriding-keymap-bound
381 (null company-my-keymap))
382 (setq company-old-keymap overriding-terminal-local-map
383 overriding-terminal-local-map company-my-keymap
384 company-overriding-keymap-bound t)))
385
386 (defun company-uninstall-map ()
387 (when (and company-overriding-keymap-bound
388 (eq overriding-terminal-local-map company-my-keymap))
389 (setq overriding-terminal-local-map company-old-keymap
390 company-overriding-keymap-bound nil)))
391
392 ;; Hack:
393 ;; Emacs calculates the active keymaps before reading the event. That means we
394 ;; cannot change the keymap from a timer. So we send a bogus command.
395 (defun company-ignore ()
396 (interactive))
397
398 (global-set-key '[31415926] 'company-ignore)
399
400 (defun company-input-noop ()
401 (push 31415926 unread-command-events))
402
403 ;;; backends ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
404
405 (defun company-grab (regexp &optional expression)
406 (when (looking-back regexp)
407 (or (match-string-no-properties (or expression 0)) "")))
408
409 (defun company-in-string-or-comment (&optional point)
410 (let ((pos (syntax-ppss)))
411 (or (nth 3 pos) (nth 4 pos) (nth 7 pos))))
412
413 ;;; completion mechanism ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
414
415 (defvar company-backend nil)
416 (make-variable-buffer-local 'company-backend)
417
418 (defvar company-prefix nil)
419 (make-variable-buffer-local 'company-prefix)
420
421 (defvar company-candidates nil)
422 (make-variable-buffer-local 'company-candidates)
423
424 (defvar company-candidates-length nil)
425 (make-variable-buffer-local 'company-candidates-length)
426
427 (defvar company-candidates-cache nil)
428 (make-variable-buffer-local 'company-candidates-cache)
429
430 (defvar company-candidates-predicate nil)
431 (make-variable-buffer-local 'company-candidates-predicate)
432
433 (defvar company-common nil)
434 (make-variable-buffer-local 'company-common)
435
436 (defvar company-selection 0)
437 (make-variable-buffer-local 'company-selection)
438
439 (defvar company-selection-changed nil)
440 (make-variable-buffer-local 'company-selection-changed)
441
442 (defvar company-point nil)
443 (make-variable-buffer-local 'company-point)
444
445 (defvar company-timer nil)
446
447 (defvar company-added-newline nil)
448 (make-variable-buffer-local 'company-added-newline)
449
450 (defsubst company-strip-prefix (str)
451 (substring str (length company-prefix)))
452
453 (defsubst company-reformat (candidate)
454 ;; company-ispell needs this, because the results are always lower-case
455 ;; It's mory efficient to fix it only when they are displayed.
456 (concat company-prefix (substring candidate (length company-prefix))))
457
458 (defsubst company-should-complete (prefix)
459 (and (eq company-idle-delay t)
460 (>= (length prefix) company-minimum-prefix-length)))
461
462 (defsubst company-call-frontends (command)
463 (dolist (frontend company-frontends)
464 (condition-case err
465 (funcall frontend command)
466 (error (error "Company: Front-end %s error \"%s\" on command %s"
467 frontend (error-message-string err) command)))))
468
469 (defsubst company-set-selection (selection &optional force-update)
470 (setq selection (max 0 (min (1- company-candidates-length) selection)))
471 (when (or force-update (not (equal selection company-selection)))
472 (setq company-selection selection
473 company-selection-changed t)
474 (company-call-frontends 'update)))
475
476 (defun company-apply-predicate (candidates predicate)
477 (let (new)
478 (dolist (c candidates)
479 (when (funcall predicate c)
480 (push c new)))
481 (nreverse new)))
482
483 (defun company-update-candidates (candidates)
484 (setq company-candidates-length (length candidates))
485 (if (> company-selection 0)
486 ;; Try to restore the selection
487 (let ((selected (nth company-selection company-candidates)))
488 (setq company-selection 0
489 company-candidates candidates)
490 (when selected
491 (while (and candidates (string< (pop candidates) selected))
492 (incf company-selection))
493 (unless candidates
494 ;; Make sure selection isn't out of bounds.
495 (setq company-selection (min (1- company-candidates-length)
496 company-selection)))))
497 (setq company-selection 0
498 company-candidates candidates))
499 ;; Save in cache:
500 (push (cons company-prefix company-candidates) company-candidates-cache)
501 ;; Calculate common.
502 (let ((completion-ignore-case (funcall company-backend 'ignore-case)))
503 (setq company-common (try-completion company-prefix company-candidates)))
504 (when (eq company-common t)
505 (setq company-candidates nil)))
506
507 (defun company-calculate-candidates (prefix)
508 (or (cdr (assoc prefix company-candidates-cache))
509 (when company-candidates-cache
510 (let ((len (length prefix))
511 (completion-ignore-case (funcall company-backend 'ignore-case))
512 prev)
513 (dotimes (i len)
514 (when (setq prev (cdr (assoc (substring prefix 0 (- len i))
515 company-candidates-cache)))
516 (return (all-completions prefix prev))))))
517 (let ((candidates (funcall company-backend 'candidates prefix)))
518 (when company-candidates-predicate
519 (setq candidates
520 (company-apply-predicate candidates
521 company-candidates-predicate)))
522 (unless (funcall company-backend 'sorted)
523 (setq candidates (sort candidates 'string<)))
524 candidates)))
525
526 (defun company-idle-begin (buf win tick pos)
527 (and company-mode
528 (eq buf (current-buffer))
529 (eq win (selected-window))
530 (eq tick (buffer-chars-modified-tick))
531 (eq pos (point))
532 (not company-candidates)
533 (not (equal (point) company-point))
534 (let ((company-idle-delay t))
535 (company-begin)
536 (when company-candidates
537 (company-input-noop)
538 (company-post-command)))))
539
540 (defun company-manual-begin ()
541 (interactive)
542 (unless company-mode (error "Company not enabled"))
543 (and company-mode
544 (not company-candidates)
545 (let ((company-idle-delay t)
546 (company-minimum-prefix-length 0))
547 (company-begin)))
548 ;; Return non-nil if active.
549 company-candidates)
550
551 (defun company-continue ()
552 (when company-candidates
553 (when (funcall company-backend 'no-cache company-prefix)
554 ;; Don't complete existing candidates, fetch new ones.
555 (setq company-candidates-cache nil))
556 (let ((new-prefix (funcall company-backend 'prefix)))
557 (unless (and (= (- (point) (length new-prefix))
558 (- company-point (length company-prefix)))
559 (or (equal company-prefix new-prefix)
560 (let ((c (company-calculate-candidates new-prefix)))
561 (when c
562 (setq company-prefix new-prefix)
563 (company-update-candidates c)
564 t))))
565 (setq company-candidates nil)))))
566
567 (defun company-begin ()
568 (if (or buffer-read-only overriding-terminal-local-map overriding-local-map)
569 ;; Don't complete in these cases.
570 (setq company-candidates nil)
571 (company-continue)
572 (unless company-candidates
573 (let (prefix)
574 (dolist (backend company-backends)
575 (when (and (fboundp backend)
576 (setq prefix (funcall backend 'prefix)))
577 (setq company-backend backend)
578 (when (company-should-complete prefix)
579 (setq company-prefix prefix)
580 (company-update-candidates (company-calculate-candidates prefix))
581 (company-call-frontends 'show))
582 (return prefix))))))
583 (if company-candidates
584 (progn
585 (when (and company-end-of-buffer-workaround (eobp))
586 (save-excursion (insert "\n"))
587 (setq company-added-newline (buffer-chars-modified-tick)))
588 (setq company-point (point))
589 (company-enable-overriding-keymap company-active-map)
590 (company-call-frontends 'update))
591 (company-cancel)))
592
593 (defun company-cancel ()
594 (and company-added-newline
595 (> (point-max) (point-min))
596 (let ((tick (buffer-chars-modified-tick)))
597 (delete-region (1- (point-max)) (point-max))
598 (equal tick company-added-newline))
599 ;; Only set unmodified when tick remained the same since insert.
600 (set-buffer-modified-p nil))
601 (setq company-added-newline nil
602 company-backend nil
603 company-prefix nil
604 company-candidates nil
605 company-candidates-length nil
606 company-candidates-cache nil
607 company-candidates-predicate nil
608 company-common nil
609 company-selection 0
610 company-selection-changed nil
611 company-point nil)
612 (when company-timer
613 (cancel-timer company-timer))
614 (company-search-mode 0)
615 (company-call-frontends 'hide)
616 (company-enable-overriding-keymap nil))
617
618 (defun company-abort ()
619 (company-cancel)
620 ;; Don't start again, unless started manually.
621 (setq company-point (point)))
622
623 (defsubst company-keep (command)
624 (and (symbolp command) (get command 'company-keep)))
625
626 (defun company-pre-command ()
627 (unless (company-keep this-command)
628 (condition-case err
629 (when company-candidates
630 (company-call-frontends 'pre-command))
631 (error (message "Company: An error occurred in pre-command")
632 (message "%s" (error-message-string err))
633 (company-cancel))))
634 (when company-timer
635 (cancel-timer company-timer))
636 (company-uninstall-map))
637
638 (defun company-post-command ()
639 (unless (company-keep this-command)
640 (condition-case err
641 (progn
642 (unless (equal (point) company-point)
643 (company-begin))
644 (when company-candidates
645 (company-call-frontends 'post-command))
646 (when (numberp company-idle-delay)
647 (setq company-timer
648 (run-with-timer company-idle-delay nil 'company-idle-begin
649 (current-buffer) (selected-window)
650 (buffer-chars-modified-tick) (point)))))
651 (error (message "Company: An error occurred in post-command")
652 (message "%s" (error-message-string err))
653 (company-cancel))))
654 (company-install-map))
655
656 ;;; search ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
657
658 (defvar company-search-string nil)
659 (make-variable-buffer-local 'company-search-string)
660
661 (defvar company-search-lighter " Search: \"\"")
662 (make-variable-buffer-local 'company-search-lighter)
663
664 (defvar company-search-old-map nil)
665 (make-variable-buffer-local 'company-search-old-map)
666
667 (defvar company-search-old-selection 0)
668 (make-variable-buffer-local 'company-search-old-selection)
669
670 (defun company-search (text lines)
671 (let ((quoted (regexp-quote text))
672 (i 0))
673 (dolist (line lines)
674 (when (string-match quoted line (length company-prefix))
675 (return i))
676 (incf i))))
677
678 (defun company-search-printing-char ()
679 (interactive)
680 (unless company-mode (error "Company not enabled"))
681 (unless company-search-mode (error "Company not in search mode"))
682 (setq company-search-string
683 (concat (or company-search-string "") (string last-command-event))
684 company-search-lighter (concat " Search: \"" company-search-string
685 "\""))
686 (let ((pos (company-search company-search-string
687 (nthcdr company-selection company-candidates))))
688 (if (null pos)
689 (ding)
690 (company-set-selection (+ company-selection pos) t))))
691
692 (defun company-search-repeat-forward ()
693 "Repeat the incremental search in completion candidates forward."
694 (interactive)
695 (unless company-mode (error "Company not enabled"))
696 (unless company-search-mode (error "Company not in search mode"))
697 (let ((pos (company-search company-search-string
698 (cdr (nthcdr company-selection
699 company-candidates)))))
700 (if (null pos)
701 (ding)
702 (company-set-selection (+ company-selection pos 1) t))))
703
704 (defun company-search-repeat-backward ()
705 "Repeat the incremental search in completion candidates backwards."
706 (interactive)
707 (unless company-mode (error "Company not enabled"))
708 (unless company-search-mode (error "Company not in search mode"))
709 (let ((pos (company-search company-search-string
710 (nthcdr (- company-candidates-length
711 company-selection)
712 (reverse company-candidates)))))
713 (if (null pos)
714 (ding)
715 (company-set-selection (- company-selection pos 1) t))))
716
717 (defun company-create-match-predicate ()
718 (setq company-candidates-predicate
719 `(lambda (candidate)
720 ,(if company-candidates-predicate
721 `(and (string-match ,company-search-string candidate)
722 (funcall ,company-candidates-predicate
723 candidate))
724 `(string-match ,company-search-string candidate))))
725 (company-update-candidates
726 (company-apply-predicate company-candidates company-candidates-predicate))
727 ;; Invalidate cache.
728 (setq company-candidates-cache (cons company-prefix company-candidates)))
729
730 (defun company-filter-printing-char ()
731 (interactive)
732 (unless company-mode (error "Company not enabled"))
733 (unless company-search-mode (error "Company not in search mode"))
734 (company-search-printing-char)
735 (company-create-match-predicate)
736 (company-call-frontends 'update))
737
738 (defun company-search-kill-others ()
739 "Limit the completion candidates to the ones matching the search string."
740 (interactive)
741 (unless company-mode (error "Company not enabled"))
742 (unless company-search-mode (error "Company not in search mode"))
743 (company-create-match-predicate)
744 (company-search-mode 0)
745 (company-call-frontends 'update))
746
747 (defun company-search-abort ()
748 "Abort searching the completion candidates."
749 (interactive)
750 (unless company-mode (error "Company not enabled"))
751 (unless company-search-mode (error "Company not in search mode"))
752 (company-set-selection company-search-old-selection t)
753 (company-search-mode 0))
754
755 (defun company-search-other-char ()
756 (interactive)
757 (unless company-mode (error "Company not enabled"))
758 (unless company-search-mode (error "Company not in search mode"))
759 (company-search-mode 0)
760 (when last-input-event
761 (clear-this-command-keys t)
762 (setq unread-command-events (list last-input-event))))
763
764 (defvar company-search-map
765 (let ((i 0)
766 (keymap (make-keymap)))
767 (if (fboundp 'max-char)
768 (set-char-table-range (nth 1 keymap) (cons #x100 (max-char))
769 'company-search-printing-char)
770 (with-no-warnings
771 ;; obselete in Emacs 23
772 (let ((l (generic-character-list))
773 (table (nth 1 keymap)))
774 (while l
775 (set-char-table-default table (car l) 'company-search-printing-char)
776 (setq l (cdr l))))))
777 (define-key keymap [t] 'company-search-other-char)
778 (while (< i ?\s)
779 (define-key keymap (make-string 1 i) 'company-search-other-char)
780 (incf i))
781 (while (< i 256)
782 (define-key keymap (vector i) 'company-search-printing-char)
783 (incf i))
784 (let ((meta-map (make-sparse-keymap)))
785 (define-key keymap (char-to-string meta-prefix-char) meta-map)
786 (define-key keymap [escape] meta-map))
787 (define-key keymap (vector meta-prefix-char t) 'company-search-other-char)
788 (define-key keymap "\e\e\e" 'company-search-other-char)
789 (define-key keymap [escape escape escape] 'company-search-other-char)
790
791 (define-key keymap "\C-g" 'company-search-abort)
792 (define-key keymap "\C-s" 'company-search-repeat-forward)
793 (define-key keymap "\C-r" 'company-search-repeat-backward)
794 (define-key keymap "\C-o" 'company-search-kill-others)
795 keymap)
796 "Keymap used for incrementally searching the completion candidates.")
797
798 (define-minor-mode company-search-mode
799 "Search mode for completion candidates.
800 Don't start this directly, use `company-search-candidates' or
801 `company-filter-candidates'."
802 nil company-search-lighter nil
803 (if company-search-mode
804 (if (company-manual-begin)
805 (progn
806 (setq company-search-old-selection company-selection)
807 (company-call-frontends 'update))
808 (setq company-search-mode nil))
809 (kill-local-variable 'company-search-string)
810 (kill-local-variable 'company-search-lighter)
811 (kill-local-variable 'company-search-old-selection)
812 (company-enable-overriding-keymap company-active-map)))
813
814 (defun company-search-candidates ()
815 "Start searching the completion candidates incrementally.
816
817 \\<company-search-map>Search can be controlled with the commands:
818 - `company-search-repeat-forward' (\\[company-search-repeat-forward])
819 - `company-search-repeat-backward' (\\[company-search-repeat-backward])
820 - `company-search-abort' (\\[company-search-abort])
821
822 Regular characters are appended to the search string.
823
824 The command `company-search-kill-others' (\\[company-search-kill-others]) uses
825 the search string to limit the completion candidates."
826 (interactive)
827 (company-search-mode 1)
828 (company-enable-overriding-keymap company-search-map))
829
830 (defvar company-filter-map
831 (let ((keymap (make-keymap)))
832 (define-key keymap [remap company-search-printing-char]
833 'company-filter-printing-char)
834 (set-keymap-parent keymap company-search-map)
835 keymap)
836 "Keymap used for incrementally searching the completion candidates.")
837
838 (defun company-filter-candidates ()
839 "Start filtering the completion candidates incrementally.
840 This works the same way as `company-search-candidates' immediately
841 followed by `company-search-kill-others' after each input."
842 (interactive)
843 (company-search-mode 1)
844 (company-enable-overriding-keymap company-filter-map))
845
846 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
847
848 (defun company-select-next ()
849 "Select the next candidate in the list."
850 (interactive)
851 (when (company-manual-begin)
852 (company-set-selection (1+ company-selection))))
853
854 (defun company-select-previous ()
855 "Select the previous candidate in the list."
856 (interactive)
857 (when (company-manual-begin)
858 (company-set-selection (1- company-selection))))
859
860 (defun company-select-mouse (event)
861 "Select the candidate picked by the mouse."
862 (interactive "e")
863 (when (nth 4 (event-start event))
864 (company-set-selection (- (cdr (posn-col-row (event-start event)))
865 (cdr (posn-col-row (posn-at-point)))
866 1))
867 t))
868
869 (defun company-complete-mouse (event)
870 "Complete the candidate picked by the mouse."
871 (interactive "e")
872 (when (company-select-mouse event)
873 (company-complete-selection)))
874
875 (defun company-complete-selection ()
876 "Complete the selected candidate."
877 (interactive)
878 (when (company-manual-begin)
879 (insert (company-strip-prefix (nth company-selection company-candidates)))
880 (company-abort)))
881
882 (defun company-complete-common ()
883 "Complete the common part of all candidates."
884 (interactive)
885 (when (company-manual-begin)
886 (insert (company-strip-prefix company-common))))
887
888 (defun company-complete ()
889 "Complete the common part of all candidates or the current selection.
890 The first time this is called, the common part is completed, the second time, or
891 when the selection has been changed, the selected candidate is completed."
892 (interactive)
893 (when (company-manual-begin)
894 (if (or company-selection-changed
895 (eq last-command 'company-complete-common))
896 (call-interactively 'company-complete-selection)
897 (call-interactively 'company-complete-common)
898 (setq this-command 'company-complete-common))))
899
900 (defun company-complete-number (n)
901 "Complete the Nth candidate."
902 (when (company-manual-begin)
903 (and (< n 1) (> n company-candidates-length)
904 (error "No candidate number %d" n))
905 (decf n)
906 (insert (company-strip-prefix (nth n company-candidates)))
907 (company-abort)))
908
909 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
910
911 (defconst company-space-strings-limit 100)
912
913 (defconst company-space-strings
914 (let (lst)
915 (dotimes (i company-space-strings-limit)
916 (push (make-string (- company-space-strings-limit 1 i) ?\ ) lst))
917 (apply 'vector lst)))
918
919 (defsubst company-space-string (len)
920 (if (< len company-space-strings-limit)
921 (aref company-space-strings len)
922 (make-string len ?\ )))
923
924 (defsubst company-safe-substring (str from &optional to)
925 (let ((len (length str)))
926 (if (> from len)
927 ""
928 (if (and to (> to len))
929 (concat (substring str from)
930 (company-space-string (- to len)))
931 (substring str from to)))))
932
933 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
934
935 (defvar company-last-metadata nil)
936 (make-variable-buffer-local 'company-last-metadata)
937
938 (defun company-fetch-metadata ()
939 (let ((selected (nth company-selection company-candidates)))
940 (unless (equal selected (car company-last-metadata))
941 (setq company-last-metadata
942 (cons selected (funcall company-backend 'meta selected))))
943 (cdr company-last-metadata)))
944
945 (defun company-doc-buffer (&optional string)
946 (with-current-buffer (get-buffer-create "*Company meta-data*")
947 (erase-buffer)
948 (current-buffer)))
949
950 (defmacro company-electric (&rest body)
951 (declare (indent 0) (debug t))
952 `(if company-mode
953 (when (company-manual-begin)
954 (save-window-excursion
955 (let ((height (window-height))
956 (row (cdr (posn-col-row (posn-at-point)))))
957 ,@body
958 (and (< (window-height) height)
959 (< (- (window-height) row 2) company-tooltip-limit)
960 (recenter (- (window-height) row 2)))
961 (while (eq 'scroll-other-window
962 (key-binding (vector (list (read-event)))))
963 (call-interactively 'scroll-other-window))
964 (when last-input-event
965 (clear-this-command-keys t)
966 (setq unread-command-events (list last-input-event))))))
967 (error "Company not enabled")))
968
969 (defun company-show-doc-buffer ()
970 "Temporarily show a buffer with the complete documentation for the selection."
971 (interactive)
972 (company-electric
973 (let ((selected (nth company-selection company-candidates)))
974 (display-buffer (or (funcall company-backend 'doc-buffer selected)
975 (error "No documentation available")) t))))
976 (put 'company-show-doc-buffer 'company-keep t)
977
978 (defun company-show-location ()
979 "Temporarily display a buffer showing the selected candidate in context."
980 (interactive)
981 (company-electric
982 (let* ((selected (nth company-selection company-candidates))
983 (location (funcall company-backend 'location selected))
984 (pos (or (cdr location) (error "No location available")))
985 (buffer (or (and (bufferp (car location)) (car location))
986 (find-file-noselect (car location) t))))
987 (with-selected-window (display-buffer buffer t)
988 (if (bufferp (car location))
989 (goto-char pos)
990 (goto-line pos))
991 (set-window-start nil (point))))))
992 (put 'company-show-location 'company-keep t)
993
994 ;;; pseudo-tooltip ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
995
996 (defvar company-pseudo-tooltip-overlay nil)
997 (make-variable-buffer-local 'company-pseudo-tooltip-overlay)
998
999 (defvar company-tooltip-offset 0)
1000 (make-variable-buffer-local 'company-tooltip-offset)
1001
1002 (defun company-pseudo-tooltip-update-offset (selection num-lines limit)
1003
1004 (decf limit 2)
1005 (setq company-tooltip-offset
1006 (max (min selection company-tooltip-offset)
1007 (- selection -1 limit)))
1008
1009 (when (<= company-tooltip-offset 1)
1010 (incf limit)
1011 (setq company-tooltip-offset 0))
1012
1013 (when (>= company-tooltip-offset (- num-lines limit 1))
1014 (incf limit)
1015 (when (= selection (1- num-lines))
1016 (decf company-tooltip-offset)
1017 (when (<= company-tooltip-offset 1)
1018 (setq company-tooltip-offset 0)
1019 (incf limit))))
1020
1021 limit)
1022
1023 ;;; propertize
1024
1025 (defsubst company-round-tab (arg)
1026 (* (/ (+ arg tab-width) tab-width) tab-width))
1027
1028 (defun company-untabify (str)
1029 (let* ((pieces (split-string str "\t"))
1030 (copy pieces))
1031 (while (cdr copy)
1032 (setcar copy (company-safe-substring
1033 (car copy) 0 (company-round-tab (string-width (car copy)))))
1034 (pop copy))
1035 (apply 'concat pieces)))
1036
1037 (defun company-fill-propertize (line width selected)
1038 (setq line (company-safe-substring line 0 width))
1039 (add-text-properties 0 width '(face company-tooltip
1040 mouse-face company-tooltip-mouse)
1041 line)
1042 (add-text-properties 0 (length company-common)
1043 '(face company-tooltip-common
1044 mouse-face company-tooltip-mouse)
1045 line)
1046 (when selected
1047 (if (and company-search-string
1048 (string-match (regexp-quote company-search-string) line
1049 (length company-prefix)))
1050 (progn
1051 (add-text-properties (match-beginning 0) (match-end 0)
1052 '(face company-tooltip-selection)
1053 line)
1054 (when (< (match-beginning 0) (length company-common))
1055 (add-text-properties (match-beginning 0) (length company-common)
1056 '(face company-tooltip-common-selection)
1057 line)))
1058 (add-text-properties 0 width '(face company-tooltip-selection
1059 mouse-face company-tooltip-selection)
1060 line)
1061 (add-text-properties 0 (length company-common)
1062 '(face company-tooltip-common-selection
1063 mouse-face company-tooltip-selection)
1064 line)))
1065 line)
1066
1067 ;;; replace
1068
1069 (defun company-buffer-lines (beg end)
1070 (goto-char beg)
1071 (let ((row (cdr (posn-col-row (posn-at-point))))
1072 lines)
1073 (while (and (equal (move-to-window-line (incf row)) row)
1074 (<= (point) end))
1075 (push (buffer-substring beg (min end (1- (point)))) lines)
1076 (setq beg (point)))
1077 (unless (eq beg end)
1078 (push (buffer-substring beg end) lines))
1079 (nreverse lines)))
1080
1081 (defsubst company-modify-line (old new offset)
1082 (concat (company-safe-substring old 0 offset)
1083 new
1084 (company-safe-substring old (+ offset (length new)))))
1085
1086 (defun company-replacement-string (old lines column nl)
1087 (let (new)
1088 ;; Inject into old lines.
1089 (while old
1090 (push (company-modify-line (pop old) (pop lines) column) new))
1091 ;; Append whole new lines.
1092 (while lines
1093 (push (concat (company-space-string column) (pop lines)) new))
1094 (concat (when nl "\n")
1095 (mapconcat 'identity (nreverse new) "\n")
1096 "\n")))
1097
1098 (defun company-create-lines (column selection limit)
1099
1100 (let ((len company-candidates-length)
1101 (numbered 99999)
1102 lines
1103 width
1104 lines-copy
1105 previous
1106 remainder
1107 new)
1108
1109 ;; Scroll to offset.
1110 (setq limit (company-pseudo-tooltip-update-offset selection len limit))
1111
1112 (when (> company-tooltip-offset 0)
1113 (setq previous (format "...(%d)" company-tooltip-offset)))
1114
1115 (setq remainder (- len limit company-tooltip-offset)
1116 remainder (when (> remainder 0)
1117 (setq remainder (format "...(%d)" remainder))))
1118
1119 (decf selection company-tooltip-offset)
1120 (setq width (min (length previous) (length remainder))
1121 lines (nthcdr company-tooltip-offset company-candidates)
1122 len (min limit len)
1123 lines-copy lines)
1124
1125 (dotimes (i len)
1126 (setq width (max (length (pop lines-copy)) width)))
1127 (setq width (min width (- (window-width) column)))
1128
1129 (setq lines-copy lines)
1130
1131 ;; number can make tooltip too long
1132 (and company-show-numbers
1133 (< (setq numbered company-tooltip-offset) 10)
1134 (incf width 2))
1135
1136 (when previous
1137 (push (propertize (company-safe-substring previous 0 width)
1138 'face 'company-tooltip)
1139 new))
1140
1141 (dotimes (i len)
1142 (push (company-fill-propertize
1143 (if (>= numbered 10)
1144 (company-reformat (pop lines))
1145 (incf numbered)
1146 (format "%s %d"
1147 (company-safe-substring (company-reformat (pop lines))
1148 0 (- width 2))
1149 (mod numbered 10)))
1150 width (equal i selection))
1151 new))
1152
1153 (when remainder
1154 (push (propertize (company-safe-substring remainder 0 width)
1155 'face 'company-tooltip)
1156 new))
1157
1158 (setq lines (nreverse new))))
1159
1160 ;; show
1161
1162 (defsubst company-pseudo-tooltip-height ()
1163 "Calculate the appropriate tooltip height."
1164 (max 3 (min company-tooltip-limit
1165 (- (window-height) 2
1166 (count-lines (window-start) (point-at-bol))))))
1167
1168 (defun company-pseudo-tooltip-show (row column selection)
1169 (company-pseudo-tooltip-hide)
1170 (save-excursion
1171
1172 (move-to-column 0)
1173
1174 (let* ((height (company-pseudo-tooltip-height))
1175 (lines (company-create-lines column selection height))
1176 (nl (< (move-to-window-line row) row))
1177 (beg (point))
1178 (end (save-excursion
1179 (move-to-window-line (+ row height))
1180 (point)))
1181 (old-string
1182 (mapcar 'company-untabify (company-buffer-lines beg end)))
1183 str)
1184
1185 (setq company-pseudo-tooltip-overlay (make-overlay beg end))
1186
1187 (overlay-put company-pseudo-tooltip-overlay 'company-old old-string)
1188 (overlay-put company-pseudo-tooltip-overlay 'company-column column)
1189 (overlay-put company-pseudo-tooltip-overlay 'company-nl nl)
1190 (overlay-put company-pseudo-tooltip-overlay 'company-before
1191 (company-replacement-string old-string lines column nl))
1192 (overlay-put company-pseudo-tooltip-overlay 'company-height height)
1193
1194 (overlay-put company-pseudo-tooltip-overlay 'window (selected-window)))))
1195
1196 (defun company-pseudo-tooltip-show-at-point (pos)
1197 (let ((col-row (posn-col-row (posn-at-point pos))))
1198 (company-pseudo-tooltip-show (1+ (cdr col-row)) (car col-row) company-selection)))
1199
1200 (defun company-pseudo-tooltip-edit (lines selection)
1201 (let* ((old-string (overlay-get company-pseudo-tooltip-overlay 'company-old))
1202 (column (overlay-get company-pseudo-tooltip-overlay 'company-column))
1203 (nl (overlay-get company-pseudo-tooltip-overlay 'company-nl))
1204 (height (overlay-get company-pseudo-tooltip-overlay 'company-height))
1205 (lines (company-create-lines column selection height)))
1206 (overlay-put company-pseudo-tooltip-overlay 'company-before
1207 (company-replacement-string old-string lines column nl))))
1208
1209 (defun company-pseudo-tooltip-hide ()
1210 (when company-pseudo-tooltip-overlay
1211 (delete-overlay company-pseudo-tooltip-overlay)
1212 (setq company-pseudo-tooltip-overlay nil)))
1213
1214 (defun company-pseudo-tooltip-hide-temporarily ()
1215 (when (overlayp company-pseudo-tooltip-overlay)
1216 (overlay-put company-pseudo-tooltip-overlay 'invisible nil)
1217 (overlay-put company-pseudo-tooltip-overlay 'before-string nil)))
1218
1219 (defun company-pseudo-tooltip-unhide ()
1220 (when company-pseudo-tooltip-overlay
1221 (overlay-put company-pseudo-tooltip-overlay 'invisible t)
1222 (overlay-put company-pseudo-tooltip-overlay 'before-string
1223 (overlay-get company-pseudo-tooltip-overlay 'company-before))
1224 (overlay-put company-pseudo-tooltip-overlay 'window (selected-window))))
1225
1226 (defun company-pseudo-tooltip-frontend (command)
1227 "A `company-mode' front-end similar to a tool-tip but based on overlays."
1228 (case command
1229 ('pre-command (company-pseudo-tooltip-hide-temporarily))
1230 ('post-command
1231 (unless (and (overlayp company-pseudo-tooltip-overlay)
1232 (equal (overlay-get company-pseudo-tooltip-overlay
1233 'company-height)
1234 (company-pseudo-tooltip-height)))
1235 ;; Redraw needed.
1236 (company-pseudo-tooltip-show-at-point (- (point)
1237 (length company-prefix))))
1238 (company-pseudo-tooltip-unhide))
1239 ('hide (company-pseudo-tooltip-hide)
1240 (setq company-tooltip-offset 0))
1241 ('update (when (overlayp company-pseudo-tooltip-overlay)
1242 (company-pseudo-tooltip-edit company-candidates
1243 company-selection)))))
1244
1245 (defun company-pseudo-tooltip-unless-just-one-frontend (command)
1246 "`company-pseudo-tooltip-frontend', but not shown for single candidates."
1247 (unless (and (eq command 'post-command)
1248 (not (cdr company-candidates)))
1249 (company-pseudo-tooltip-frontend command)))
1250
1251 ;;; overlay ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1252
1253 (defvar company-preview-overlay nil)
1254 (make-variable-buffer-local 'company-preview-overlay)
1255
1256 (defun company-preview-show-at-point (pos)
1257 (company-preview-hide)
1258
1259 (setq company-preview-overlay (make-overlay pos pos))
1260
1261 (let ((completion(nth company-selection company-candidates)))
1262 (setq completion (propertize completion 'face 'company-preview))
1263 (add-text-properties 0 (length company-common)
1264 '(face company-preview-common) completion)
1265
1266 ;; Add search string
1267 (and company-search-string
1268 (string-match (regexp-quote company-search-string) completion)
1269 (add-text-properties (match-beginning 0)
1270 (match-end 0)
1271 '(face company-preview-search)
1272 completion))
1273
1274 (setq completion (company-strip-prefix completion))
1275
1276 (and (equal pos (point))
1277 (not (equal completion ""))
1278 (add-text-properties 0 1 '(cursor t) completion))
1279
1280 (overlay-put company-preview-overlay 'after-string completion)
1281 (overlay-put company-preview-overlay 'window (selected-window))))
1282
1283 (defun company-preview-hide ()
1284 (when company-preview-overlay
1285 (delete-overlay company-preview-overlay)
1286 (setq company-preview-overlay nil)))
1287
1288 (defun company-preview-frontend (command)
1289 "A `company-mode' front-end showing the selection as if it had been inserted."
1290 (case command
1291 ('pre-command (company-preview-hide))
1292 ('post-command (company-preview-show-at-point (point)))
1293 ('hide (company-preview-hide))))
1294
1295 (defun company-preview-if-just-one-frontend (command)
1296 "`company-preview-frontend', but only shown for single candidates."
1297 (unless (and (eq command 'post-command)
1298 (cdr company-candidates))
1299 (company-preview-frontend command)))
1300
1301 ;;; echo ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1302
1303 (defvar company-echo-last-msg nil)
1304 (make-variable-buffer-local 'company-echo-last-msg)
1305
1306 (defvar company-echo-timer nil)
1307
1308 (defvar company-echo-delay .1)
1309
1310 (defun company-echo-show (&optional getter)
1311 (when getter
1312 (setq company-echo-last-msg (funcall getter)))
1313 (let ((message-log-max nil))
1314 (if company-echo-last-msg
1315 (message "%s" company-echo-last-msg)
1316 (message ""))))
1317
1318 (defsubst company-echo-show-soon (&optional getter)
1319 (when company-echo-timer
1320 (cancel-timer company-echo-timer))
1321 (setq company-echo-timer (run-with-timer company-echo-delay nil
1322 'company-echo-show getter)))
1323
1324 (defun company-echo-format ()
1325
1326 (let ((limit (window-width (minibuffer-window)))
1327 (len -1)
1328 ;; Roll to selection.
1329 (candidates (nthcdr company-selection company-candidates))
1330 (i (if company-show-numbers company-selection 99999))
1331 comp msg)
1332
1333 (while candidates
1334 (setq comp (company-reformat (pop candidates))
1335 len (+ len 1 (length comp)))
1336 (if (< i 10)
1337 ;; Add number.
1338 (progn
1339 (setq comp (propertize (format "%d: %s" i comp)
1340 'face 'company-echo))
1341 (incf len 3)
1342 (incf i)
1343 (add-text-properties 3 (+ 3 (length company-common))
1344 '(face company-echo-common) comp))
1345 (setq comp (propertize comp 'face 'company-echo))
1346 (add-text-properties 0 (length company-common)
1347 '(face company-echo-common) comp))
1348 (if (>= len limit)
1349 (setq candidates nil)
1350 (push comp msg)))
1351
1352 (mapconcat 'identity (nreverse msg) " ")))
1353
1354 (defun company-echo-strip-common-format ()
1355
1356 (let ((limit (window-width (minibuffer-window)))
1357 (len (+ (length company-prefix) 2))
1358 ;; Roll to selection.
1359 (candidates (nthcdr company-selection company-candidates))
1360 (i (if company-show-numbers company-selection 99999))
1361 msg comp)
1362
1363 (while candidates
1364 (setq comp (company-strip-prefix (pop candidates))
1365 len (+ len 2 (length comp)))
1366 (when (< i 10)
1367 ;; Add number.
1368 (setq comp (format "%s (%d)" comp i))
1369 (incf len 4)
1370 (incf i))
1371 (if (>= len limit)
1372 (setq candidates nil)
1373 (push (propertize comp 'face 'company-echo) msg)))
1374
1375 (concat (propertize company-prefix 'face 'company-echo-common) "{"
1376 (mapconcat 'identity (nreverse msg) ", ")
1377 "}")))
1378
1379 (defun company-echo-hide ()
1380 (when company-echo-timer
1381 (cancel-timer company-echo-timer))
1382 (unless (equal company-echo-last-msg "")
1383 (setq company-echo-last-msg "")
1384 (company-echo-show)))
1385
1386 (defun company-echo-frontend (command)
1387 "A `company-mode' front-end showing the candidates in the echo area."
1388 (case command
1389 ('pre-command (company-echo-show-soon))
1390 ('post-command (company-echo-show-soon 'company-echo-format))
1391 ('hide (company-echo-hide))))
1392
1393 (defun company-echo-strip-common-frontend (command)
1394 "A `company-mode' front-end showing the candidates in the echo area."
1395 (case command
1396 ('pre-command (company-echo-show-soon))
1397 ('post-command (company-echo-show-soon 'company-echo-strip-common-format))
1398 ('hide (company-echo-hide))))
1399
1400 (defun company-echo-metadata-frontend (command)
1401 "A `company-mode' front-end showing the documentation in the echo area."
1402 (case command
1403 ('pre-command (company-echo-show-soon))
1404 ('post-command (company-echo-show-soon 'company-fetch-metadata))
1405 ('hide (company-echo-hide))))
1406
1407 (provide 'company)
1408 ;;; company.el ends here