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