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