Writing backends

Alexander-Miller edited this page Nov 30, 2015 · 18 revisions

This page is about writing backends

Simple example

This backend will suggest foobar foobaz foobarbaz whenever you type foo.

(require 'cl-lib)

(defun company-simple-backend (command &optional arg &rest ignored)
  (interactive (list 'interactive))
  (cl-case command
    (interactive (company-begin-backend 'company-simple-backend))
    (prefix (when (looking-back "foo\\>")
              (match-string 0)))
    (candidates (when (equal arg "foo")
                  (list "foobar" "foobaz" "foobarbaz")))
    (meta (format "This value is named %s" arg))))

Advanced example

This backend will complete after . or ->, using company-advanced-keywords to generate meta & annotate strings. To understand what annotation or meta does, read the docstring of the variable company-backends.

Tips:

  • Company offers various functions (like company-grab-symbol/word) to fetch the prefix for which to complete. The exact symbol/word that is returned will vary for different major modes as the decision which characters constitute a symbol/word depends on the current major mode's syntax table.
  • Using company-grab-symbol-cons simplifies writing the prefix part.
  • Using propertize or put-text-property, you can differentiate between various overloads that should still complete to the same text, like company-advanced--annotation does.
(require 'cl-lib)

(defvar company-advanced-keywords
  '(("foo" "overload 1") ("foo" "overload 2") ("bar" "method 1")))

(defun company-advanced--make-candidate (candidate)
  (let ((text (car candidate))
        (meta (cadr candidate)))
    (propertize text 'meta meta)))

(defun company-advanced--candidates (prefix)
  (let (res)
    (dolist (item company-advanced-keywords)
      (when (string-prefix-p prefix (car item))
        (push (company-advanced--make-candidate item) res)))
    res))

(defun company-advanced--meta (candidate)
  (format "This will use %s of %s"
          (get-text-property 0 'meta candidate)
          (substring-no-properties candidate)))

(defun company-advanced--annotation (candidate)
  (format " (%s)" (get-text-property 0 'meta candidate)))

(defun company-advanced (command &optional arg &rest ignored)
  (interactive (list 'interactive))
  (cl-case command
    (interactive (company-begin-backend 'company-advanced))
    (prefix (company-grab-symbol-cons "\\.\\|->" 2))
    (candidates (company-advanced--candidates arg))
    (annotation (company-advanced--annotation arg))
    (meta (company-advanced--meta arg))))

Example with explanations

Here's an article on writing a simple company-mode backend. This covers some of the same material as above, but it includes a bit more description.