minad / cape

🦸cape.el - Completion At Point Extensions
GNU General Public License v3.0
584 stars 20 forks source link

Error when using `company-yasnippet` with the `cape-company-to-capf` #22

Closed galeo closed 2 years ago

galeo commented 2 years ago

Thanks for the company adapter cape-company-to-capf. I tried to use it with company-yasnippet after reading #17, but encountered an error.

In *scratch* buffer, turn on corfu and execute code:

(setq completion-at-point-functions (list (cape-company-to-capf #'company-yasnippet))) 

Type auto and select the completion candidate (auto→autoload), it reports the error:

yas--template-content: Wrong type argument: yas--template, nil

Here is the Backtrace log:

Debugger entered--Lisp error: (wrong-type-argument yas--template nil)
  signal(wrong-type-argument (yas--template nil))
  yas--template-content(nil)
  (yas-expand-snippet (yas--template-content template) (- (point) (length arg) prefix-offset) (point) (yas--template-expand-env template))
  (let ((template (get-text-property 0 'yas-template arg)) (prefix-offset (get-text-property 0 'yas-prefix-offset arg))) (yas-expand-snippet (yas--template-content template) (- (point) (length arg) prefix-offset) (point) (yas--template-expand-env template)))
  (cond ((eql command 'interactive) (company-begin-backend 'company-yasnippet)) ((eql command 'prefix) (and (bound-and-true-p yas-minor-mode) (company-grab-symbol))) ((eql command 'annotation) (funcall company-yasnippet-annotation-fn (get-text-property 0 'yas-annotation arg))) ((eql command 'candidates) (company-yasnippet--candidates arg)) ((eql command 'doc-buffer) (company-yasnippet--doc arg)) ((eql command 'no-cache) t) ((eql command 'kind) 'snippet) ((eql command 'post-completion) (let ((template (get-text-property 0 'yas-template arg)) (prefix-offset (get-text-property 0 'yas-prefix-offset arg))) (yas-expand-snippet (yas--template-content template) (- (point) (length arg) prefix-offset) (point) (yas--template-expand-env template)))))
  (cl-case command (interactive (company-begin-backend 'company-yasnippet)) (prefix (and (bound-and-true-p yas-minor-mode) (company-grab-symbol))) (annotation (funcall company-yasnippet-annotation-fn (get-text-property 0 'yas-annotation arg))) (candidates (company-yasnippet--candidates arg)) (doc-buffer (company-yasnippet--doc arg)) (no-cache t) (kind 'snippet) (post-completion (let ((template (get-text-property 0 'yas-template arg)) (prefix-offset (get-text-property 0 'yas-prefix-offset arg))) (yas-expand-snippet (yas--template-content template) (- (point) (length arg) prefix-offset) (point) (yas--template-expand-env template)))))
  company-yasnippet(post-completion "auto→")
  cape--company-call(company-yasnippet post-completion "auto→")
  #f(compiled-function (x status) #<bytecode -0x7414ad4fba0232a>)("auto→" finished)
  corfu--done("auto→" finished)
  corfu--insert(finished)
  corfu-insert()
  funcall-interactively(corfu-insert)
  command-execute(corfu-insert)

The snippet can not be auto expanded in post completion action. It can be expanded manually.

minad commented 2 years ago

Oh it seems we call the post completion action with a wrong argument. Maybe a text property is missing? I've tested other Company backends but didn't try yasnippet. The adapter is still experimental. Personally I am not using yasnippet. Maybe you can help me figure this out?

According to company.el:

`post-completion': Called after a completion candidate has been inserted into the buffer. The second argument is the candidate. Can be used to modify it, e.g. to expand a snippet.

minad commented 2 years ago

I pushed a potential fix in https://github.com/minad/cape/commit/9db78299616bab3c601ace2bcab205c9fbff8dd0. Instead of calling post-completion with the actual candidate, I called it with the buffer contents like the Capf does. Therefore we missed the text property as I suspected. Please give the patch a try. I didn't test it.

galeo commented 2 years ago

It works well now. Thanks.