1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-02-20 07:00:31 -08:00

Allow using xref-find-references without visiting a tags table

* lisp/progmodes/xref.el (xref-find-backend):
Allow returning nil (bug#43086).
(xref-backend-definitions, xref-backend-apropos):
Signal user-error when no backend is available.  The error text
suggests a few built-in Xref backends.
(xref-backend-identifier-completion-table): Default to nil.
(xref--no-backend-available): New helper function.

* lisp/progmodes/etags.el (etags--xref-backend):
Return nil when no tags table is visited.
This commit is contained in:
Dmitry Gutov 2026-02-06 05:56:31 +02:00
parent ec5479f0b5
commit 90d3fdaffc
3 changed files with 22 additions and 10 deletions

View file

@ -3701,6 +3701,11 @@ So now it is even more important that any calls to 'with-help-window'
(recommended) to 'with-output-to-temp-buffer' are done after. It was the
recommended way to use it previously as well, but less critically so.
** Xref commands don't automatically suggest to visit a tags table anymore.
When no tags file is loaded, symbol completion just won't provide any
suggestions. So the 'M-?' command now works without a tags table. And
the 'M-.' will show a message describing the several built-in options
that will provide an Xref backend when used.
* Lisp Changes in Emacs 31.1

View file

@ -2115,7 +2115,9 @@ file name, add `tag-partial-file-name-match-p' to the list value.")
:version "28.1")
;;;###autoload
(defun etags--xref-backend () 'etags)
(defun etags--xref-backend ()
(when (or tags-table-list tags-file-name)
'etags))
(cl-defmethod xref-backend-identifier-at-point ((_backend (eql 'etags)))
(find-tag--default))

View file

@ -247,11 +247,9 @@ generic functions.")
;;;###autoload
(defun xref-find-backend ()
(or
(run-hook-with-args-until-success 'xref-backend-functions)
(user-error "No Xref backend available")))
(run-hook-with-args-until-success 'xref-backend-functions))
(cl-defgeneric xref-backend-definitions (backend identifier)
(cl-defgeneric xref-backend-definitions (_backend _identifier)
"Find definitions of IDENTIFIER.
The result must be a list of xref objects. If IDENTIFIER
@ -264,7 +262,8 @@ IDENTIFIER can be any string returned by
`xref-backend-identifier-at-point', or from the table returned by
`xref-backend-identifier-completion-table'.
To create an xref object, call `xref-make'.")
To create an xref object, call `xref-make'."
(xref--no-backend-available))
(cl-defgeneric xref-backend-references (_backend identifier)
"Find references of IDENTIFIER.
@ -285,12 +284,13 @@ The default implementation uses `xref-references-in-directory'."
(xref--project-root pr)
(project-external-roots pr))))))
(cl-defgeneric xref-backend-apropos (backend pattern)
(cl-defgeneric xref-backend-apropos (_backend _pattern)
"Find all symbols that match PATTERN string.
The second argument has the same meaning as in `apropos'.
If BACKEND is implemented in Lisp, it can use
`xref-apropos-regexp' to convert the pattern to regexp.")
`xref-apropos-regexp' to convert the pattern to regexp."
(xref--no-backend-available))
(cl-defgeneric xref-backend-identifier-at-point (_backend)
"Return the relevant identifier at point.
@ -306,8 +306,9 @@ recognize and then delegate the work to an external process."
(let ((thing (thing-at-point 'symbol)))
(and thing (substring-no-properties thing))))
(cl-defgeneric xref-backend-identifier-completion-table (backend)
"Return the completion table for identifiers.")
(cl-defgeneric xref-backend-identifier-completion-table (_backend)
"Return the completion table for identifiers."
nil)
(cl-defgeneric xref-backend-identifier-completion-ignore-case (_backend)
"Return t if case is not significant in identifier completion."
@ -329,6 +330,10 @@ KEY extracts the key from an element."
(cl-loop for key being hash-keys of table using (hash-values value)
collect (cons key (nreverse value)))))
(defun xref--no-backend-available ()
(user-error
"No Xref backend. Try `M-x eglot', `M-x visit-tags-table', or `M-x etags-regen-mode'."))
(defun xref--insert-propertized (props &rest strings)
"Insert STRINGS with text properties PROPS."
(let ((start (point)))