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