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