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

no applicable method reported from xref-find-definitions #148

Open
wanghaiqiangk opened this issue Feb 3, 2023 · 3 comments
Open

no applicable method reported from xref-find-definitions #148

wanghaiqiangk opened this issue Feb 3, 2023 · 3 comments

Comments

@wanghaiqiangk
Copy link

wanghaiqiangk commented Feb 3, 2023

When invoking xref-find-definitions which is bound to M-. at a symbol, the echo area says no applicable method: xref-backend-definitions, citre, <symbol-name-here>.

This happens after I updated citre from a relative old release to the latest version.

The backtrace after enabling debug-on-entry is shown below:

Debugger entered--entering a function:
* cl-no-applicable-method(#s(cl--generic :name xref-backend-definitions :dispatches ((1 #s(cl--generic-generalizer :name cl--generic-t-generalizer :priority 0 :tagcode-function #f(compiled-function (name &rest _) #<bytecode 0x1fcdee8ad43f>) :specializers-function #f(compiled-function (tag &rest _) #<bytecode 0x1fcdee8ad42f>))) (0 #s(cl--generic-generalizer :name cl--generic-eql-generalizer :priority 100 :tagcode-function #f(compiled-function (name &rest _) #<bytecode 0x1fcdee8ac19d>) :specializers-function #f(compiled-function (tag &rest _) #<bytecode 0x1fcdee8ac17d>)) #s(cl--generic-generalizer :name cl--generic-t-generalizer :priority 0 :tagcode-function #f(compiled-function (name &rest _) #<bytecode 0x1fcdee8ad43f>) :specializers-function #f(compiled-function (tag &rest _) #<bytecode 0x1fcdee8ad42f>)))) :method-table (#s(cl--generic-method :specializers ((eql 'citre) t) :qualifiers nil :uses-cnm nil :function #f(compiled-function (backend symbol) "Method for xref to find definitions of SYMBOL." #<bytecode 0xed7061>)) #s(cl--generic-method :specializers ((eql etags) t) :qualifiers nil :uses-cnm nil :function #f(compiled-function (backend symbol) #<bytecode 0xe9c25d>)) #s(cl--generic-method :specializers ((eql eglot) t) :qualifiers nil :uses-cnm nil :function #f(compiled-function (backend id) #<bytecode 0xed59e1>)) #s(cl--generic-method :specializers ((eql dumb-jump) t) :qualifiers nil :uses-cnm nil :function #f(compiled-function (backend prompt) #<bytecode 0xe32c29>)) #s(cl--generic-method :specializers ((eql elisp) t) :qualifiers nil :uses-cnm nil :function #f(compiled-function (backend identifier) #<bytecode 0x1fcdeea1cd6d>))) :options nil) citre "comm_init")
* apply(cl-no-applicable-method #s(cl--generic :name xref-backend-definitions :dispatches ((1 #s(cl--generic-generalizer :name cl--generic-t-generalizer :priority 0 :tagcode-function #f(compiled-function (name &rest _) #<bytecode 0x1fcdee8ad43f>) :specializers-function #f(compiled-function (tag &rest _) #<bytecode 0x1fcdee8ad42f>))) (0 #s(cl--generic-generalizer :name cl--generic-eql-generalizer :priority 100 :tagcode-function #f(compiled-function (name &rest _) #<bytecode 0x1fcdee8ac19d>) :specializers-function #f(compiled-function (tag &rest _) #<bytecode 0x1fcdee8ac17d>)) #s(cl--generic-generalizer :name cl--generic-t-generalizer :priority 0 :tagcode-function #f(compiled-function (name &rest _) #<bytecode 0x1fcdee8ad43f>) :specializers-function #f(compiled-function (tag &rest _) #<bytecode 0x1fcdee8ad42f>)))) :method-table (#s(cl--generic-method :specializers ((eql 'citre) t) :qualifiers nil :uses-cnm nil :function #f(compiled-function (backend symbol) "Method for xref to find definitions of SYMBOL." #<bytecode 0xed7061>)) #s(cl--generic-method :specializers ((eql etags) t) :qualifiers nil :uses-cnm nil :function #f(compiled-function (backend symbol) #<bytecode 0xe9c25d>)) #s(cl--generic-method :specializers ((eql eglot) t) :qualifiers nil :uses-cnm nil :function #f(compiled-function (backend id) #<bytecode 0xed59e1>)) #s(cl--generic-method :specializers ((eql dumb-jump) t) :qualifiers nil :uses-cnm nil :function #f(compiled-function (backend prompt) #<bytecode 0xe32c29>)) #s(cl--generic-method :specializers ((eql elisp) t) :qualifiers nil :uses-cnm nil :function #f(compiled-function (backend identifier) #<bytecode 0x1fcdeea1cd6d>))) :options nil) (citre "comm_init"))
* #f(compiled-function (&rest args) #<bytecode 0x10ab7f1>)(citre "comm_init")
* apply(#f(compiled-function (&rest args) #<bytecode 0x10ab7f1>) citre "comm_init")
* xref-backend-definitions(citre "comm_init")
* #f(compiled-function () #<bytecode 0x221f90d>)()
* xref-show-definitions-buffer(#f(compiled-function () #<bytecode 0x221f90d>) ((window . #<window 3 on core.c>) (display-action) (auto-jump)))
* xref--show-defs(#f(compiled-function () #<bytecode 0x221f90d>) nil)
* xref--find-definitions("comm_init" nil)
* #f(compiled-function (identifier) "Find the definition of the identifier at point.\nWith prefix argument or when there's no identifier at point,\nprompt for it.\n\nIf sufficient information is available to determine a unique\ndefinition for IDENTIFIER, display it in the selected window.\nOtherwise, display the list of the possible definitions in a\nbuffer where the user can select from the list.\n\nUse \\[xref-go-back] to return back to where you invoked this command." (interactive #f(compiled-function () #<bytecode 0x1693925>)) #<bytecode 0xe19335>)("comm_init")
* apply(#f(compiled-function (identifier) "Find the definition of the identifier at point.\nWith prefix argument or when there's no identifier at point,\nprompt for it.\n\nIf sufficient information is available to determine a unique\ndefinition for IDENTIFIER, display it in the selected window.\nOtherwise, display the list of the possible definitions in a\nbuffer where the user can select from the list.\n\nUse \\[xref-go-back] to return back to where you invoked this command." (interactive #f(compiled-function () #<bytecode 0x1fdd6bd>)) #<bytecode 0xe19335>) "comm_init")
* xref-find-definitions("comm_init")
  funcall-interactively(xref-find-definitions "comm_init")
  call-interactively(xref-find-definitions nil nil)
  command-execute(xref-find-definitions)

Besides, the xref-backend-functions variable has the value of (citre-xref-backend t). Manual calls to citre-jump work fine.

Any idea what's the problem here?


Citre config

(use-package citre
  :defer t
  :init
  (require 'citre-config)
  :config
  (setq
   citre-peek-fill-fringe nil
   citre-completion-case-sensitive nil
   ;; citre-project-root-function #'projectile-project-root
   citre-use-project-root-when-creating-tags t
   citre-prompt-language-for-ctags-command t))

Update Found that it's the 84bf573 refactor: pluggable backend design caused the problem.

@AmaiKinono
Copy link
Member

Using your config in $ emacs -Q, I can't reproduce the problem. I'm on Arch Linux and Emacs 28.2.

@zhongweiy
Copy link

zhongweiy commented Apr 24, 2023

I also have this issue. And find it can be solved by:

modified   citre.el
@@ -422,7 +422,7 @@ The returned value is a valid return value for
   "The Citre backend for xref."
   'citre)
 
-(cl-defmethod xref-backend-identifier-at-point ((_backend (eql 'citre)))
+(cl-defmethod xref-backend-identifier-at-point ((_backend (eql citre)))
   "Define method for xref to get symbol at point."
   (when-let ((symbol (symbol-at-point)))
     ;; The symbol name doesn't matter for us.  We record the buffer in the text
@@ -432,7 +432,7 @@ The returned value is a valid return value for
                         'xref-symbol-buffer (current-buffer))))
 
 (cl-defmethod xref-backend-identifier-completion-table
-  ((_backend (eql 'citre)))
+  ((_backend (eql citre)))
   "Return a function for xref to find all completions of a prefix."
   (lambda (str pred action)
     ;; We need this since Xref calls this function in minibuffer.
@@ -441,7 +441,7 @@ The returned value is a valid return value for
                      (citre-get-backend-and-id-list))))
       (complete-with-action action (cdr result) str pred))))
 
-(cl-defmethod xref-backend-definitions ((_backend (eql 'citre)) symbol)
+(cl-defmethod xref-backend-definitions ((_backend (eql citre)) symbol)
   "Method for xref to find definitions of SYMBOL."
   (if-let ((buf (citre-get-property 'xref-symbol-buffer symbol)))
       ;; If true, the symbol is grabbed from a buffer, not identifier
@@ -451,7 +451,7 @@ The returned value is a valid return value for
     (let ((defs (citre-get-definitions-of-id symbol)))
       (citre-xref--make-collection defs))))
 
-(cl-defmethod xref-backend-references ((_backend (eql 'citre)) symbol)
+(cl-defmethod xref-backend-references ((_backend (eql citre)) symbol)
   "Method for xref to find references of SYMBOL."
   (if-let ((buf (citre-get-property 'xref-symbol-buffer symbol)))
       (with-current-buffer buf

I don't know why sometime (eql 'citre) also works.

@AmaiKinono
Copy link
Member

I don't know why sometime (eql 'citre) also works.

This may be a wrong behavior in Emacs 27, see https://emacs-china.org/t/topic/6620/7. Are you using Emacs 27?

I was following the elisp xref backend when implementing citre xref backend. See xref-backend-definitions in elisp-mode.el:

(cl-defmethod xref-backend-definitions ((_backend (eql 'elisp)) identifier) ...

Does it look different in Emacs 27?

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

3 participants