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