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