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