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