]> rtime.felk.cvut.cz Git - sojka/company-mode.git/blob - company.el
Added documentation buffer.
[sojka/company-mode.git] / company.el
1 (eval-when-compile (require 'cl))
2
3 (add-to-list 'debug-ignored-errors
4              "^Pseudo tooltip frontend cannot be used twice$")
5 (add-to-list 'debug-ignored-errors "^Preview frontend cannot be used twice$")
6 (add-to-list 'debug-ignored-errors "^Echo area cannot be used twice$")
7 (add-to-list 'debug-ignored-errors "^No documentation available$")
8
9 (defgroup company nil
10   ""
11   :group 'abbrev
12   :group 'convenience
13   :group 'maching)
14
15 (defface company-tooltip
16   '((t :background "yellow"
17        :foreground "black"))
18   "*"
19   :group 'company)
20
21 (defface company-tooltip-selection
22   '((t :background "orange1"
23        :foreground "black"))
24   "*"
25   :group 'company)
26
27 (defface company-tooltip-common
28   '((t :inherit company-tooltip
29        :foreground "red"))
30   "*"
31   :group 'company)
32
33 (defface company-tooltip-common-selection
34   '((t :inherit company-tooltip-selection
35        :foreground "red"))
36   "*"
37   :group 'company)
38
39 (defcustom company-tooltip-limit 10
40   "*"
41   :group 'company
42   :type 'integer)
43
44 (defface company-preview
45   '((t :background "blue4"
46        :foreground "wheat"))
47   "*"
48   :group 'company)
49
50 (defface company-preview-common
51   '((t :inherit company-preview
52        :foreground "red"))
53   "*"
54   :group 'company)
55
56 (defface company-echo nil
57   "*"
58   :group 'company)
59
60 (defface company-echo-common
61   '((((background dark)) (:foreground "firebrick1"))
62     (((background light)) (:background "firebrick4")))
63   "*"
64   :group 'company)
65
66 (defun company-frontends-set (variable value)
67   ;; uniquify
68   (let ((remainder value))
69     (setcdr remainder (delq (car remainder) (cdr remainder))))
70   (and (memq 'company-pseudo-tooltip-unless-just-one-frontend value)
71        (memq 'company-pseudo-tooltip-frontend value)
72        (error "Pseudo tooltip frontend cannot be used twice"))
73   (and (memq 'company-preview-if-just-one-frontend value)
74        (memq 'company-preview-frontend value)
75        (error "Preview frontend cannot be used twice"))
76   (and (memq 'company-echo value)
77        (memq 'company-echo-metadata-frontend value)
78        (error "Echo area cannot be used twice"))
79   ;; preview must come last
80   (dolist (f '(company-preview-if-just-one-frontend company-preview-frontend))
81     (when (memq f value)
82       (setq value (append (delq f value) (list f)))))
83   (set variable value))
84
85 (defcustom company-frontends '(company-pseudo-tooltip-unless-just-one-frontend
86                                company-preview-if-just-one-frontend
87                                company-echo-metadata-frontend)
88   "*"
89   :set 'company-frontends-set
90   :group 'company
91   :type '(repeat (choice (const :tag "echo" company-echo-frontend)
92                          (const :tag "pseudo tooltip"
93                                 company-pseudo-tooltip-frontend)
94                          (const :tag "pseudo tooltip, multiple only"
95                                 company-pseudo-tooltip-unless-just-one-frontend)
96                          (const :tag "preview" company-preview-frontend)
97                          (const :tag "preview, unique only"
98                                 company-preview-if-just-one-frontend)
99                          (function :tag "custom function" nil))))
100
101 (defcustom company-backends '(company-elisp company-nxml company-css
102                               company-semantic company-oddmuse company-ispell)
103   "*"
104   :group 'company
105   :type '(repeat (function :tag "function" nil)))
106
107 (defcustom company-minimum-prefix-length 3
108   "*"
109   :group 'company
110   :type '(integer :tag "prefix length"))
111
112 (defvar company-timer nil)
113
114 (defun company-timer-set (variable value)
115   (set variable value)
116   (when company-timer (cancel-timer company-timer))
117   (when (numberp value)
118     (setq company-timer (run-with-idle-timer value t 'company-idle-begin))))
119
120 (defcustom company-idle-delay .7
121   "*"
122   :set 'company-timer-set
123   :group 'company
124   :type '(choice (const :tag "never (nil)" nil)
125                  (const :tag "immediate (t)" t)
126                  (number :tag "seconds")))
127
128 ;;; mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
129
130 (defvar company-mode-map
131   (let ((keymap (make-sparse-keymap)))
132     (define-key keymap (kbd "M-n") 'company-select-next)
133     (define-key keymap (kbd "M-p") 'company-select-previous)
134     (define-key keymap (kbd "M-<return>") 'company-complete-selection)
135     (define-key keymap "\t" 'company-complete)
136     (define-key keymap (kbd "<f1>") 'company-show-doc-buffer)
137     keymap))
138
139 ;;;###autoload
140 (define-minor-mode company-mode
141   ""
142   nil " comp" company-mode-map
143   (if company-mode
144       (progn
145         (add-hook 'pre-command-hook 'company-pre-command nil t)
146         (add-hook 'post-command-hook 'company-post-command nil t)
147         (company-timer-set 'company-idle-delay
148                            company-idle-delay))
149     (remove-hook 'pre-command-hook 'company-pre-command t)
150     (remove-hook 'post-command-hook 'company-post-command t)
151     (company-cancel)
152     (kill-local-variable 'company-point)))
153
154 ;;; backends ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
155
156 (defun company-grab (regexp &optional expression)
157   (when (looking-back regexp)
158     (or (match-string-no-properties (or expression 0)) "")))
159
160 (defun company-in-string-or-comment (&optional point)
161   (let ((pos (syntax-ppss)))
162     (or (nth 3 pos) (nth 4 pos) (nth 7 pos))))
163
164 ;;; completion mechanism ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
165
166 (defvar company-backend nil)
167 (make-variable-buffer-local 'company-backend)
168
169 (defvar company-prefix nil)
170 (make-variable-buffer-local 'company-prefix)
171
172 (defvar company-candidates nil)
173 (make-variable-buffer-local 'company-candidates)
174
175 (defvar company-candidates-cache nil)
176 (make-variable-buffer-local 'company-candidates-cache)
177
178 (defvar company-common nil)
179 (make-variable-buffer-local 'company-common)
180
181 (defvar company-selection 0)
182 (make-variable-buffer-local 'company-selection)
183
184 (defvar company-selection-changed nil)
185 (make-variable-buffer-local 'company-selection-changed)
186
187 (defvar company-point nil)
188 (make-variable-buffer-local 'company-point)
189
190 (defvar company-disabled-backends nil)
191
192 (defsubst company-strip-prefix (str)
193   (substring str (length company-prefix)))
194
195 (defsubst company-reformat (candidate)
196   ;; company-ispell needs this, because the results are always lower-case
197   ;; It's mory efficient to fix it only when they are displayed.
198   (concat company-prefix (substring candidate (length company-prefix))))
199
200 (defsubst company-should-complete (prefix)
201   (and (eq company-idle-delay t)
202        (>= (length prefix) company-minimum-prefix-length)))
203
204 (defsubst company-call-frontends (command)
205   (dolist (frontend company-frontends)
206     (funcall frontend command)))
207
208 (defsubst company-calculate-candidates (prefix)
209   (or (setq company-candidates (cdr (assoc prefix company-candidates-cache)))
210       (let ((len (length prefix))
211             (completion-ignore-case (funcall company-backend 'ignore-case))
212             prev)
213         (dotimes (i len)
214           (when (setq prev (cdr (assoc (substring prefix 0 (- len i))
215                                        company-candidates-cache)))
216             (setq company-candidates (all-completions prefix prev))
217             (return t))))
218       (progn
219         (setq company-candidates (funcall company-backend 'candidates prefix))
220         (unless (funcall company-backend 'sorted)
221           (setq company-candidates (sort company-candidates 'string<)))))
222   (unless (assoc prefix company-candidates-cache)
223     (push (cons prefix company-candidates) company-candidates-cache))
224   (setq company-selection 0
225         company-prefix prefix)
226   (let ((completion-ignore-case (funcall company-backend 'ignore-case)))
227     (setq company-common (try-completion company-prefix company-candidates)))
228   (when (eq company-common t)
229     (setq company-candidates nil))
230   company-candidates)
231
232 (defun company-idle-begin ()
233   (and company-mode
234        (not company-candidates)
235        (not (equal (point) company-point))
236        (let ((company-idle-delay t))
237          (company-begin)
238          (company-post-command))))
239
240 (defun company-manual-begin ()
241   (and company-mode
242        (not company-candidates)
243        (let ((company-idle-delay t)
244              (company-minimum-prefix-length 0))
245          (company-begin)))
246   ;; Return non-nil if active.
247   company-candidates)
248
249 (defun company-continue ()
250   (when company-candidates
251     (let ((new-prefix (funcall company-backend 'prefix)))
252       (unless (and (= (- (point) (length new-prefix))
253                       (- company-point (length company-prefix)))
254                    (or (equal company-prefix new-prefix)
255                        (company-calculate-candidates new-prefix)))
256         (setq company-candidates nil)))))
257
258 (defun company-begin ()
259   (company-continue)
260   (unless company-candidates
261     (let (prefix)
262       (dolist (backend company-backends)
263         (unless (fboundp backend)
264           (ignore-errors (require backend nil t)))
265         (if (fboundp backend)
266             (when (setq prefix (funcall backend 'prefix))
267               (when (company-should-complete prefix)
268                 (setq company-backend backend)
269                 (company-calculate-candidates prefix))
270               (return prefix))
271           (unless (memq backend company-disabled-backends)
272             (push backend company-disabled-backends)
273             (message "Company back-end '%s' could not be initialized"
274                      backend))))))
275   (if company-candidates
276       (progn
277         (setq company-point (point))
278         (company-call-frontends 'update))
279     (company-cancel)))
280
281 (defun company-cancel ()
282   (setq company-backend nil
283         company-prefix nil
284         company-candidates nil
285         company-candidates-cache nil
286         company-common nil
287         company-selection 0
288         company-selection-changed nil
289         company-point nil)
290   (company-call-frontends 'hide))
291
292 (defun company-abort ()
293   (company-cancel)
294   ;; Don't start again, unless started manually.
295   (setq company-point (point)))
296
297 (defun company-pre-command ()
298   (unless (eq this-command 'company-show-doc-buffer)
299     (when company-candidates
300       (company-call-frontends 'pre-command))))
301
302 (defun company-post-command ()
303   (unless (eq this-command 'company-show-doc-buffer)
304     (unless (equal (point) company-point)
305       (company-begin))
306     (when company-candidates
307       (company-call-frontends 'post-command))))
308
309 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
310
311 (defun company-select-next ()
312   (interactive)
313   (when (company-manual-begin)
314     (setq company-selection (min (1- (length company-candidates))
315                                  (1+ company-selection))
316           company-selection-changed t))
317   (company-call-frontends 'update))
318
319 (defun company-select-previous ()
320   (interactive)
321   (when (company-manual-begin)
322     (setq company-selection (max 0 (1- company-selection))
323           company-selection-changed t))
324   (company-call-frontends 'update))
325
326 (defun company-complete-selection ()
327   (interactive)
328   (when (company-manual-begin)
329     (insert (company-strip-prefix (nth company-selection company-candidates)))
330     (company-abort)))
331
332 (defun company-complete-common ()
333   (interactive)
334   (when (company-manual-begin)
335     (insert (company-strip-prefix company-common))))
336
337 (defun company-complete ()
338   (interactive)
339   (when (company-manual-begin)
340     (if (or company-selection-changed
341             (eq last-command 'company-complete-common))
342         (call-interactively 'company-complete-selection)
343       (call-interactively 'company-complete-common)
344       (setq this-command 'company-complete-common))))
345
346 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
347
348 (defconst company-space-strings-limit 100)
349
350 (defconst company-space-strings
351   (let (lst)
352     (dotimes (i company-space-strings-limit)
353       (push (make-string (- company-space-strings-limit 1 i) ?\  ) lst))
354     (apply 'vector lst)))
355
356 (defsubst company-space-string (len)
357   (if (< len company-space-strings-limit)
358       (aref company-space-strings len)
359     (make-string len ?\ )))
360
361 (defsubst company-safe-substring (str from &optional to)
362   (let ((len (length str)))
363     (if (> from len)
364         ""
365       (if (and to (> to len))
366           (concat (substring str from)
367                   (company-space-string (- to len)))
368         (substring str from to)))))
369
370 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
371
372 (defvar company-last-metadata nil)
373 (make-variable-buffer-local 'company-last-metadata)
374
375 (defun company-fetch-metadata ()
376   (let ((selected (nth company-selection company-candidates)))
377     (unless (equal selected (car company-last-metadata))
378       (setq company-last-metadata
379             (cons selected (funcall company-backend 'meta selected))))
380     (cdr company-last-metadata)))
381
382 (defun company-doc-buffer (&optional string)
383   (with-current-buffer (get-buffer-create "*Company meta-data*")
384     (erase-buffer)
385     (current-buffer)))
386
387 (defun company-show-doc-buffer ()
388   (interactive)
389   (when company-candidates
390     (save-window-excursion
391       (let* ((selected (nth company-selection company-candidates))
392              (buffer (funcall company-backend 'doc-buffer selected)))
393         (if (not buffer)
394             (error "No documentation available.")
395           (display-buffer buffer)
396           (read-event)
397           (when last-input-event
398             (clear-this-command-keys t)
399             (setq unread-command-events (list last-input-event))))))))
400
401 ;;; pseudo-tooltip ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
402
403 (defvar company-pseudo-tooltip-overlay nil)
404 (make-variable-buffer-local 'company-pseudo-tooltip-overlay)
405
406 (defvar company-tooltip-offset 0)
407 (make-variable-buffer-local 'company-tooltip-offset)
408
409 (defun company-pseudo-tooltip-update-offset (selection num-lines limit)
410
411   (decf limit 2)
412   (setq company-tooltip-offset
413         (max (min selection company-tooltip-offset)
414              (- selection -1 limit)))
415
416   (when (<= company-tooltip-offset 1)
417     (incf limit)
418     (setq company-tooltip-offset 0))
419
420   (when (>= company-tooltip-offset (- num-lines limit 1))
421     (incf limit)
422     (when (= selection (1- num-lines))
423       (setq company-tooltip-offset (max (1- company-tooltip-offset) 0))))
424
425   limit)
426
427 ;;; propertize
428
429 (defun company-fill-propertize (line width selected)
430   (setq line (company-safe-substring line 0 width))
431   (add-text-properties 0 width
432                        (list 'face (if selected
433                                        'company-tooltip-selection
434                                      'company-tooltip)) line)
435   (add-text-properties 0 (length company-common)
436                        (list 'face (if selected
437                                        'company-tooltip-common-selection
438                                      'company-tooltip-common)) line)
439   line)
440
441 ;;; replace
442
443 (defun company-buffer-lines (beg end)
444   (goto-char beg)
445   (let ((row (cdr (posn-col-row (posn-at-point))))
446         lines)
447     (while (< (point) end)
448       (move-to-window-line (incf row))
449       (push (buffer-substring beg (min end (1- (point)))) lines)
450       (setq beg (point)))
451     (nreverse lines)))
452
453 (defun company-modify-line (old new offset)
454   (concat (company-safe-substring old 0 offset)
455           new
456           (company-safe-substring old (+ offset (length new)))))
457
458 (defun company-replacement-string (old lines column nl)
459   (let (new)
460     ;; Inject into old lines.
461     (while old
462       (push (company-modify-line (pop old) (pop lines) column) new))
463     ;; Append whole new lines.
464     (while lines
465       (push (company-modify-line "" (pop lines) column) new))
466     (concat (when nl "\n")
467             (mapconcat 'identity (nreverse new) "\n")
468             "\n")))
469
470 (defun company-create-lines (column lines selection)
471
472   (let ((limit (max company-tooltip-limit 3))
473         (len (length lines))
474         width
475         lines-copy
476         previous
477         remainder
478         new)
479
480     ;; Scroll to offset.
481     (setq limit (company-pseudo-tooltip-update-offset selection len limit))
482
483     (when (> company-tooltip-offset 0)
484       (setq previous (format "...(%d)" company-tooltip-offset)))
485
486     (setq remainder (- len limit company-tooltip-offset)
487           remainder (when (> remainder 0)
488                       (setq remainder (format "...(%d)" remainder))))
489
490     (decf selection company-tooltip-offset)
491     (setq width (min (length previous) (length remainder))
492           lines (nthcdr company-tooltip-offset lines)
493           len (min limit (length lines))
494           lines-copy lines)
495
496     (dotimes (i len)
497       (setq width (max (length (pop lines-copy)) width)))
498     (setq width (min width (- (window-width) column)))
499
500     (when previous
501       (push (propertize (company-safe-substring previous 0 width)
502                         'face 'company-tooltip)
503             new))
504
505     (dotimes (i len)
506       (push (company-fill-propertize (company-reformat (pop lines))
507                                      width (equal i selection))
508             new))
509
510     (when remainder
511       (push (propertize (company-safe-substring remainder 0 width)
512                         'face 'company-tooltip)
513             new))
514
515     (setq lines (nreverse new))))
516
517 ;; show
518
519 (defun company-pseudo-tooltip-show (row column lines selection)
520   (company-pseudo-tooltip-hide)
521   (unless lines (error "No text provided"))
522   (save-excursion
523
524     (move-to-column 0)
525
526     (let* ((lines (company-create-lines column lines selection))
527            (nl (< (move-to-window-line row) row))
528            (beg (point))
529            (end (save-excursion
530                   (move-to-window-line (min (window-height)
531                                             (+ row company-tooltip-limit)))
532                   (point)))
533            (old-string (company-buffer-lines beg end))
534            str)
535
536       (setq company-pseudo-tooltip-overlay (make-overlay beg end))
537
538       (overlay-put company-pseudo-tooltip-overlay 'company-old old-string)
539       (overlay-put company-pseudo-tooltip-overlay 'company-column column)
540       (overlay-put company-pseudo-tooltip-overlay 'company-nl nl)
541       (overlay-put company-pseudo-tooltip-overlay 'company-before
542                    (company-replacement-string old-string lines column nl))
543
544       (overlay-put company-pseudo-tooltip-overlay 'window (selected-window)))))
545
546 (defun company-pseudo-tooltip-show-at-point (pos)
547   (let ((col-row (posn-col-row (posn-at-point pos))))
548     (company-pseudo-tooltip-show (1+ (cdr col-row)) (car col-row)
549                                  company-candidates company-selection)))
550
551 (defun company-pseudo-tooltip-edit (lines selection)
552   (let* ((old-string (overlay-get company-pseudo-tooltip-overlay 'company-old))
553          (column (overlay-get company-pseudo-tooltip-overlay 'company-column))
554          (nl (overlay-get company-pseudo-tooltip-overlay 'company-nl))
555          (lines (company-create-lines column lines selection)))
556     (overlay-put company-pseudo-tooltip-overlay 'company-before
557                  (company-replacement-string old-string lines column nl))))
558
559 (defun company-pseudo-tooltip-hide ()
560   (when company-pseudo-tooltip-overlay
561     (delete-overlay company-pseudo-tooltip-overlay)
562     (setq company-pseudo-tooltip-overlay nil)))
563
564 (defun company-pseudo-tooltip-hide-temporarily ()
565   (when (overlayp company-pseudo-tooltip-overlay)
566     (overlay-put company-pseudo-tooltip-overlay 'invisible nil)
567     (overlay-put company-pseudo-tooltip-overlay 'before-string nil)))
568
569 (defun company-pseudo-tooltip-unhide ()
570   (when company-pseudo-tooltip-overlay
571     (overlay-put company-pseudo-tooltip-overlay 'invisible t)
572     (overlay-put company-pseudo-tooltip-overlay 'before-string
573                  (overlay-get company-pseudo-tooltip-overlay 'company-before))))
574
575 (defun company-pseudo-tooltip-frontend (command)
576   (case command
577     ('pre-command (company-pseudo-tooltip-hide-temporarily))
578     ('post-command
579      (unless (overlayp company-pseudo-tooltip-overlay)
580        (company-pseudo-tooltip-show-at-point (- (point)
581                                                 (length company-prefix))))
582      (company-pseudo-tooltip-unhide))
583     ('hide (company-pseudo-tooltip-hide)
584            (setq company-tooltip-offset 0))
585     ('update (when (overlayp company-pseudo-tooltip-overlay)
586                (company-pseudo-tooltip-edit company-candidates
587                                             company-selection)))))
588
589 (defun company-pseudo-tooltip-unless-just-one-frontend (command)
590   (unless (and (eq command 'post-command)
591                (not (cdr company-candidates)))
592     (company-pseudo-tooltip-frontend command)))
593
594 ;;; overlay ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
595
596 (defvar company-preview-overlay nil)
597 (make-variable-buffer-local 'company-preview-overlay)
598
599 (defun company-preview-show-at-point (pos)
600   (company-preview-hide)
601
602   (setq company-preview-overlay (make-overlay pos pos))
603
604   (let ((completion (company-strip-prefix (nth company-selection
605                                                company-candidates))))
606     (and (equal pos (point))
607          (not (equal completion ""))
608          (add-text-properties 0 1 '(cursor t) completion))
609
610     (setq completion (propertize completion 'face 'company-preview))
611     (add-text-properties 0 (- (length company-common) (length company-prefix))
612                          '(face company-preview-common) completion)
613
614     (overlay-put company-preview-overlay 'after-string completion)
615     (overlay-put company-preview-overlay 'window (selected-window))))
616
617 (defun company-preview-hide ()
618   (when company-preview-overlay
619     (delete-overlay company-preview-overlay)
620     (setq company-preview-overlay nil)))
621
622 (defun company-preview-frontend (command)
623   (case command
624     ('pre-command (company-preview-hide))
625     ('post-command (company-preview-show-at-point (point)))
626     ('hide (company-preview-hide))))
627
628 (defun company-preview-if-just-one-frontend (command)
629   (unless (and (eq command 'post-command)
630                (cdr company-candidates))
631     (company-preview-frontend command)))
632
633 ;;; echo ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
634
635 (defvar company-echo-last-msg nil)
636 (make-variable-buffer-local 'company-echo-last-msg)
637
638 (defun company-echo-refresh ()
639   (let ((message-log-max nil))
640     (if company-echo-last-msg
641         (message "%s" company-echo-last-msg)
642       (message ""))))
643
644 (defun company-echo-show (candidates)
645
646   ;; Roll to selection.
647   (setq candidates (nthcdr company-selection candidates))
648
649   (let ((limit (window-width (minibuffer-window)))
650         (len -1)
651         comp msg)
652     (while candidates
653       (setq comp (company-reformat (pop candidates))
654             len (+ len 1 (length comp)))
655       (if (>= len limit)
656           (setq candidates nil)
657         (setq comp (propertize comp 'face 'company-echo))
658         (add-text-properties 0 (length company-common)
659                              '(face company-echo-common) comp)
660         (push comp msg)))
661
662     (setq company-echo-last-msg (mapconcat 'identity (nreverse msg) " "))
663     (company-echo-refresh)))
664
665 (defun company-echo-frontend (command)
666   (case command
667     ('pre-command (company-echo-refresh))
668     ('post-command (company-echo-show company-candidates))
669     ('hide (setq company-echo-last-msg nil))))
670
671 (defun company-echo-metadata-frontend (command)
672   (case command
673     ('pre-command (company-echo-refresh))
674     ('post-command (setq company-echo-last-msg (company-fetch-metadata))
675                    (company-echo-refresh))
676     ('hide (setq company-echo-last-msg nil))))
677
678
679 (provide 'company)
680 ;;; company.el ends here