Better auto complete behavior with company-mode

Currently, doom configured company-backends seems would lose some completions when work with lsp-mode. Let’s say my customized company-backends are:

  (defvar my-company-backends
	  '(company-files company-dabbrev-code
      company-keywords company-dict company-dabbrev))
  (add-to-list 'company-backends my-company-backends t))

So in emacs-lisp-mode, buffer-local company-backends will be:

(company-capf company-yasnippet
              (company-files company-dabbrev-code company-keywords company-dict company-dabbrev))

And if we enabled lsp-mode in, like c++-mode, company-backends will be:

((:separate company-capf company-yasnippet)
 company-yasnippet
 (company-files company-dabbrev-code company-keywords company-dict company-dabbrev))

we will have 3 company backends here:

  1. (:separate company-capf company-yasnippet)
  2. company-yasnippet (yes, we have a duplicate company-yasnippet here)
  3. user customized grouped company backends

company-mode will try these 3 backends, take prefix as argument one by one, if any backends return completions, it will stop to try next backends.

For example, if company-mode get any completion from company-yasnippet, we will lose the chance to try user customized company backends.

Also, in first company backend we are using :separate, so if company-capf failed to complete, and company-yasnippet do, again we will lose the user customized backends. (I’m afraid that we should use :with here instead of :separate, although we’ll lose the sort order :separate provide.)

I’d rather re-configured the lsp-mode and company-mode in as below:

(remove-hook 'lsp-completion-mode-hook '+lsp-init-company-backends-h)
(add-hook 'lsp-completion-mode-hook
          (defun +lsp-init-company-backends-h ()
            (if lsp-completion-mode
                (progn
                  (setq +lsp-company-backends '(company-capf :with company-yasnippet))
                  (set
                   (make-local-variable 'company-backends)
                   (cons +lsp-company-backends
                         (remove +lsp-company-backends
                                 (->> company-backends
                                      (remq 'company-yasnippet)
                                      (remq 'company-capf)))))))))

When lsp-mode enabled, we’ll get:

((company-capf :with company-yasnippet)
 (company-files company-dabbrev-code company-keywords company-dict company-dabbrev))

when lsp server stop working somehow, we can still get dabbrev completion. Besides, we will get file path completion in comments.

(I also found a packaged called company-fuzz, maybe we can use it to improve doom-emacs auto complete)