Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

< character in company-yasnippet is not working #1268

Closed
rdbeni0 opened this issue Nov 25, 2021 · 15 comments
Closed

< character in company-yasnippet is not working #1268

rdbeni0 opened this issue Nov 25, 2021 · 15 comments
Milestone

Comments

@rdbeni0
Copy link

rdbeni0 commented Nov 25, 2021

Describe the issue

please see screenshot.

this is connected with yasnippets and company-yasnippet.el
when i insert <e , then only completions with e are showed

the same for <v or <i or <c

so in summary:
< character is ignored (and probably other similar characters like # or ^ or >)

Expected behavior

completion (suggestions) should appear also for special characters like < * % #

Screenshots

screenshot:
https://imgur.com/yyBRKZS.png

but <ex is working - but only after insertion of whole <ex (should be suggested earlier)

info

my whole config is here:
https://github.com/rdbeni0/emacs.d/blob/main/elisp/cfg-company-yasnippets.el

@dgutov
Copy link
Member

dgutov commented Nov 26, 2021

Thanks, can repro.

It's actually more difficult to fix than I initially imagined because yasnippet supports having multiple keys (starting at different positions) at the same time.

So one solution would be to bring "per-completion prefixes" support to Companyy, and another - to add some fuzziness in matching and forget about aligning completions to the text. And fix the prefix<->key mismatch in post-completion.

Neither is exactly trivial, so I'm going to let this simmer for a little while. Thanks for the report, either way.

@dgutov
Copy link
Member

dgutov commented Oct 5, 2023

Continuing on from #1407

If we were to make this scenario a little bit easier, some details could help.

@zhenhua-wang First and foremost, how do you use company-yasnippet? Do you group it with other backends, or put it in front, or just bind to a key?

It's easy to add a customization that would work well the the last kind of usage, but it's harder when we talk about grouping.

@zhenhua-wang
Copy link

zhenhua-wang commented Oct 5, 2023

Thanks for checking this! In my config, I have (setq company-backends '(company-files company-capf company-yasnippet)). So it's at the end of the company-backends.

I also tried to call company-yasnippet directly in org-mode. While it successfully displays the completion menu, it still fails to remove the "<" character when inserting the completion.

In any case, it seems that the issue may be related to the functions looking-at and skip-syntax-backward, as they do not correctly recognize the "<" character in org-mode.

The use case specific to Org users, I suppose?

Yes, as far as i know, this only happens in org-mode.

@dgutov
Copy link
Member

dgutov commented Oct 5, 2023

If you're okay with this usage only successful when company-yasnippet is used alone (e.g. through key binding), I can add an option to have < considered too.

Maybe with some future changes other situations will improve too, but I can't promise when.

@zhenhua-wang
Copy link

I see. That sounds good for now. Thank you.

@dgutov dgutov added this to the 1.0 milestone Oct 12, 2023
@dgutov dgutov closed this as completed in bc3e0fd Nov 23, 2023
dgutov added a commit that referenced this issue Nov 23, 2023
Should help in scenarios related to #1268.  Made possible by #1405.
@dgutov
Copy link
Member

dgutov commented Nov 23, 2023

All right, I've looked at the existing workaround inside company-yasnippet for working inside a group and just improved it. Having multiple keys allowed by yasnippet isn't a problem because we can take the longest one which has any matches. I think that's what the expected behavior would be for most people.

So this should take care of the problems that have been mentioned here, although some edge cases might remain (please report).

@erusyd
Copy link

erusyd commented Nov 28, 2023

commit bc3e0fd results in error in org-mode when typing #+begin_src
Company: An error occurred in auto-begin
Company: backend (company-capf :with company-yasnippet) error "Company: backend company-yasnippet error "Wrong type argument: listp, 3" with args (prefix)" with args (candidates beg)

@erusyd
Copy link

erusyd commented Nov 28, 2023

My emacs config:

(setq company-backends '((company-capf :with company-yasnippet)
                         (company-dabbrev-code company-keywords company-files)
                         company-dabbrev))

@dgutov
Copy link
Member

dgutov commented Nov 28, 2023

@erusyd Could you M-x toggle-debug-on-error and show the full backtrace?

The output of M-x company-diag would also help.

@erusyd
Copy link

erusyd commented Nov 28, 2023

Debugger entered--Lisp error: (wrong-type-argument listp 3)
length((#("+beg" 0 4 (face org-meta-line font-lock-fontified t wrap-prefix "" line-prefix "" fontified t)) . 3))
(- (point) (length prefix))
(char-before (- (point) (length prefix)))
(memq (char-before (- (point) (length prefix))) '(32 46 58 60 62 40 41 91 123 125 36 34 39 96))
(if (memq (char-before (- (point) (length prefix))) '(32 46 58 60 62 40 41 91 123 125 36 34 39 96)) nil prefix)
(if prefix (if (memq (char-before (- (point) (length prefix))) '(32 46 58 60 62 40 41 91 123 125 36 34 39 96)) nil prefix) nil)
(let* ((prefix (and t (funcall fn 'prefix)))) (if prefix (if (memq (char-before (- (point) (length prefix))) '(32 46 58 60 62 40 41 91 123 125 36 34 39 96)) nil prefix) nil))
(if (eq cmd 'prefix) (let* ((prefix (and t (funcall fn 'prefix)))) (if prefix (if (memq (char-before (- (point) (length prefix))) '(32 46 58 60 62 40 41 91 123 125 36 34 39 96)) nil prefix) nil)) (progn (if (and (and (boundp 'lsp-mode) lsp-mode) arg (not (get-text-property 0 'yas-annotation-patch arg))) (progn (let* ((name (get-text-property 0 ... arg)) (snip (format "%s (Snippet)" name)) (len (length arg))) (put-text-property 0 len 'yas-annotation snip arg) (put-text-property 0 len 'yas-annotation-patch t arg)))) (funcall fn cmd arg)))
my-company-yasnippet-disable-inline(# prefix)
apply(my-company-yasnippet-disable-inline # prefix)
company-yasnippet(prefix)
apply(company-yasnippet prefix)
company-call-backend-raw(prefix)
company--force-sync(company-call-backend-raw (prefix) company-yasnippet)
company-call-backend(prefix)
company--multi-backend-adapter-candidates((company-capf company-yasnippet) "beg" 3 nil)
company--multi-backend-adapter((company-capf :with company-yasnippet) candidates "beg")
apply(company--multi-backend-adapter (company-capf :with company-yasnippet) (candidates "beg"))
company-call-backend-raw(candidates "beg")
company--fetch-candidates("beg")
company-calculate-candidates("beg" nil)
company--begin-new()
company--perform()
company-auto-begin()
company-idle-begin(# #<window 3 on test.org> 142 6)
apply(company-idle-begin (# #<window 3 on test.org> 142 6))
timer-event-handler([t 25957 27765 143263 nil company-idle-begin (# #<window 3 on test.org> 142 6) nil 785000 nil])

@erusyd
Copy link

erusyd commented Nov 28, 2023

M-x company-diag gives:
Emacs 29.1.90 (x86_64-pc-linux-gnu) of 2023-11-24 on T7920
Company 0.10.2

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

Used backend: (company-capf :with company-yasnippet)

Value of c-a-p-f: (pcomplete-completions-at-point t)
Major mode: org-mode
Prefix: "beg"
Completions: none(error fetching)

@dgutov
Copy link
Member

dgutov commented Nov 28, 2023 via email

@erusyd
Copy link

erusyd commented Nov 28, 2023

Oh, that's my own elisp function

(defun my-company-yasnippet-disable-inline (fn cmd &optional arg &rest _ignore)
      "Enable yasnippet but disable it inline."
      (if (eq cmd 'prefix)
          (when-let ((prefix (funcall fn 'prefix)))
            (unless (memq (char-before (- (point) (length prefix)))
                          '(?\s ?. ?: ?< ?> ?\( ?\) ?\[ ?{ ?} ?$ ?\" ?' ?`))
              prefix))
        (progn
          (when (and (bound-and-true-p lsp-mode)
                     arg (not (get-text-property 0 'yas-annotation-patch arg)))
            (let* ((name (get-text-property 0 'yas-annotation arg))
                   (snip (format "%s (Snippet)" name))
                   (len (length arg)))
              (put-text-property 0 len 'yas-annotation snip arg)
              (put-text-property 0 len 'yas-annotation-patch t arg)))
          (funcall fn cmd arg))))

@dgutov
Copy link
Member

dgutov commented Nov 28, 2023

Okay, so this is where it errors out:

            (unless (memq (char-before (- (point) (length prefix)))

because prefix returned by company-yasnippet can now also be a cons cell (its other valid shape described in company-backends's docstring). The string itself in such case resides in the car.

BTW, what is the main purpose of this advice? The distinguish yasnippet's snippets from the others by lsp-mode? Otherwise, the "kind" icon should already indicate that it is in fact a snippet.

@erusyd
Copy link

erusyd commented Nov 29, 2023

I added this function long time ago, I've forgotten why. So I choose to comment it out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants