Closed stardiviner closed 2 years ago
Oh, I mis-read the emoji-backend example code, it use cape-company-to-capf
adapter.
Hmm, this question goes a bit too far for me to help. I suggest you either use cape-company-to-capf
and wrap company-yasnippet
. Really, there is nothing wrong with that! We just reuse existing Company backends in normal Capf completion (Corfu, default completion). The Company frontend will not be used, but the mere presence of the Company frontend code will not hurt your Emacs installation. Alternatively create a package capf-yasnippet or add a Capf directly to yasnippet. You can take the Cape Capfs for inspiration but I recommend to not depend on cape. See also #17 where cape-yasnippet was proposed. Furthermore maybe you are interested in my Tempel package, which I use instead of Yasnippet?
I have writed a simple cape-yasnippet backend which can display snippet now. But need to add some extra features like:
I will reference code in cape-company-to-capf
etc functions about how it hands this properties.
Here is the first version workable code:
(defun cape--yasnippet-snippets (prefix)
"Return all snippets from yasnippet matching PREFIX"
(require 'yasnippet)
;; `company-yasnippet--candidates'
(cl-loop with tables = (yas--get-snippet-tables)
for key-prefix in (company-yasnippet--key-prefixes)
;; Only consider keys at least as long as the symbol at point.
when (>= (length key-prefix) (length prefix))
thereis (company-yasnippet--completions-for-prefix prefix
key-prefix
tables)))
(defvar cape--yasnippet-properties
(list :annotation-function (lambda (_) " snippet")
:company-kind (lambda (_) 'snippet)
:exclusive 'no)
"Completion extra properties for `cape-yasnippet'.")
(defun cape-yasnippet (&optional interactive)
"Complete snippet at point with yasnippet.
If INTERACTIVE is nil the function acts like a Capf."
(interactive (list t))
(if interactive
(cape--interactive #'cape-yasnippet)
(let ((bounds (cape--bounds 'word)))
`(,(car bounds) ,(cdr bounds)
,(cape--table-with-properties
(cape--cached-table (car bounds) (cdr bounds) #'cape--yasnippet-snippets 'substring)
:category 'cape-yasnippet)
,@cape--yasnippet-properties))))
(setq-local completion-at-point-functions '(cape-yasnippet cape-symbol))
Thanks for your suggestion. I read them recently and try to study out a solution.
I suggest you either use cape-company-to-capf and wrap company-yasnippet. Really, there is nothing wrong with that! We just reuse existing Company backends in normal Capf completion (Corfu, default completion).
I already tried this method, but it's difficult to customize the completion-at-point-functions
then. For example:
(setq-local completion-at-point-functions
(list
(mapcar #'cape-company-to-capf (list #'company-yasnippet #'company-elisp))
#'cape-file #'cape-keyword #'cape-abbrev #'cape-dabbrev #'cape-ispell
))
or like this:
(setq-local completion-at-point-functions
(list
(cape-company-to-capf
(apply-partially #'company--multi-backend-adapter
'(company-yasnippet company-elisp)))
#'cape-file #'cape-keyword #'cape-abbrev #'cape-dabbrev #'cape-ispell
))
They can't archive what I want.
See also https://github.com/minad/cape/issues/17 where cape-yasnippet was proposed. Furthermore maybe you are interested in my Tempel package, which I use instead of Yasnippet?
I indeed checked out temple package, but porting yasnippet snippets is a big work. So I try to stick on yasnippet for now.
They can't archive what I want.
Why not?
They can't archive what I want.
Why not?
My upper first completion-at-point-functions
setting has problem. The second setting works fine.
I will take a little time to figure out the :exit-function
for yasnippet expanding. Once figured out, I can lose Emacs config weight of company dependency. If not, I will take the cape-company-to-capf
solution.
Might some user want to do same thing, just keep some process here.
They can't archive what I want.
Why not?
My upper first
completion-at-point-functions
setting has problem. The second setting works fine. I will take a little time to figure out the:exit-function
for yasnippet expanding. Once figured out, I can lose Emacs config weight of company dependency. If not, I will take thecape-company-to-capf
solution.Might some user want to do same thing, just keep some process here.
I managed to come up with something, copyed half your code and half company's code (the wonders of free software). This only depends on cape and yasnippet
(defun cape-yasnippet--key-prefixes ()
;; Copied from `company-yasnippet--key-prefixes'.
(defvar yas-key-syntaxes)
(save-excursion
(let ((original (point))
(methods yas-key-syntaxes)
prefixes
method)
(while methods
(unless (eq method (car methods))
(goto-char original))
(setq method (car methods))
(cond ((stringp method)
(skip-syntax-backward method)
(setq methods (cdr methods)))
((functionp method)
(unless (eq (funcall method original)
'again)
(setq methods (cdr methods))))
(t
(setq methods (cdr methods))
(yas--warning "Invalid element `%s' in `yas-key-syntaxes'" method)))
(let ((prefix (buffer-substring-no-properties (point) original)))
(unless (equal prefix (car prefixes))
(push prefix prefixes))))
prefixes)))
(defun cape-yasnippet--completions-for-prefix (prefix key-prefix tables)
;; Copied from `cape-yasnippet--completions-for-prefix'.
(cl-mapcan
(lambda (table)
(let ((keyhash (yas--table-hash table))
(requirement (yas--require-template-specific-condition-p))
res)
(when keyhash
(maphash
(lambda (key value)
(when (and (stringp key)
(string-prefix-p key-prefix key))
(maphash
(lambda (name template)
(when (yas--template-can-expand-p
(yas--template-condition template) requirement)
(push
(propertize key
'yas-annotation name
'yas-template template
'yas-prefix-offset (- (length key-prefix)
(length prefix)))
res)))
value)))
keyhash))
res))
tables))
(defun cape--yasnippet-snippets (prefix)
"Return all snippets from yasnippet matching PREFIX"
(require 'yasnippet)
(cl-loop with tables = (yas--get-snippet-tables)
for key-prefix in (cape-yasnippet--key-prefixes)
;; Only consider keys at least as long as the symbol at point.
when (>= (length key-prefix) (length prefix))
thereis (cape-yasnippet--completions-for-prefix prefix
key-prefix
tables)))
(defvar cape--yasnippet-properties
(list :annotation-function (lambda (_) " snippet")
:company-kind (lambda (_) 'snippet)
:exit-function (lambda (_ status)
(when (eq status 'finished)
(yas-expand)))
:exclusive 'no)
"Completion extra properties for `cape-yasnippet'.")
(defun cape-yasnippet (&optional interactive)
"Complete snippet at point with yasnippet.
If INTERACTIVE is nil the function acts like a Capf."
(interactive (list t))
(if interactive
(cape--interactive #'cape-yasnippet)
(let ((bounds (cape--bounds 'word)))
`(,(car bounds) ,(cdr bounds)
,(cape--table-with-properties
(cape--cached-table (car bounds) (cdr bounds) #'cape--yasnippet-snippets 'substring)
:category 'cape-yasnippet)
,@cape--yasnippet-properties))))
Solved your issue with the :exit-function
with:
(lambda (_ status)
(when (eq status 'finished)
(yas-expand)))
Basicaly if I accept the completion on corfu it expands, don't know if it's the right way to do it, I tested it for a solid 2 minutes and have any idea on what I'm doing.
this maybe help
Thanks, already marked.
I tried to following guide section "Company adapter" on README.
README guide section example code
I tested this example code, and it works fine so that I can confirm cape is fine.
company-yasnippet
source codeI copied most code from
company-yasnippet
original source code as reference:first try by extracting code from
company-yasnippet
This report error:
second try with directly invoke from
company-yasnippet
internal APIThis still got same error:
my question
I confirmed the function
cape-yasnippet
arguments(action &optional arg &rest _)
it is same withemoji-backend
. I don't understand whywrong-number-of-arguments
.