Home

Awesome

MELPA Build Status

company-lsp

Company completion backend for lsp-mode.

Completion with snippet expansion.

It provides features that are not available by using company-capf + lsp-mode:

Usage

Company-lsp is available on MELPA. To install it, first setup MELPA, then M-x package-install <RET> company-lsp.

After installing company-lsp, simply add company-lsp to company-backends:

(require 'company-lsp)
(push 'company-lsp company-backends)

Customization

Defining completion snippet for a certain language

If the language server for that language doesn't support returning snippets, you can customize the variable company-lsp--snippet-functions do define snippets for candidates. company-lsp--snippet-functions is an alist of (LANGUAGE-ID . SNIPPET-FUNCTION).

LANGUAGE-ID is the language ID defined by the lsp client. Currently there is no good way knowing it other than guessing or reading the code of the lsp client for the language. For example if you use lsp-rust, it's defined as following in lsp-rust.el:

(lsp-define-stdio-client lsp-rust "rust" #'lsp-rust--get-root nil
			 :command-fn #'lsp-rust--rls-command
			 :initialize #'lsp-rust--initialize-client)

The language ID is the second parameter, "rust".

SNIPPET-FUNCTION is a function that transforms a hash table representing the CompletionItem message to a snippet string or nil. Below is an example on how to extact a snippet for Rust function parameters:

(defun company-lsp--rust-completion-snippet (item)
  "Function providing snippet with the rust language.
It parses the function's signature in ITEM (a CompletionItem)
to expand its arguments."
  (-when-let* ((kind (gethash "kind" item))
               (is-function (= kind 3)))
    (let* ((detail (gethash "detail" item))
           (snippet (when (and detail (s-matches? "^\\(pub \\)?\\(unsafe \\)?fn " detail))
                      (-some--> (substring detail (1+ (s-index-of "(" detail)) (s-index-of ")" detail))
                                (replace-regexp-in-string "^[^,]*self\\(, \\)?" "" it)
                                (s-split ", " it)
                                (mapconcat (lambda (x) (format "${%s}" x)) it ", ")))))
      (concat "(" (or snippet "$1") ")$0"))))