Hi Arash and Keita, I'm away from my machine for a while, but a docstring seems a good idea. How about something like:
"Find the next or previous \ref to a given \label. The search follows the order in the *xref* buffer produced by `xref-find-apropos'." I can provide a new patch when I return, or please modify as you see fit. Best, David. On Wed, 17 Jun 2026, 16:36 Arash Esbati, <[email protected]> wrote: > Hi David, > > David Fussner <[email protected]> writes: > > > Apologies for the delay > > No need to apologize; thanks for working on this. > > > you were quite right that replicating `find-tag' using `xref' commands > > wasn't straightforward. I also found that `bib-find-next' was a > > little unreliable as it stood, so I'm hoping that the patch I'm > > attaching will be more robust. > > > > There have been fairly extensive changes made to `etags' itself in v31, > > so I think that version will work best, but I did test also with v30 and > > I couldn't see any obvious problems. (I had to customize > > `bib-etags-command' and `bib-etags-append-command' to run v31 with an > > emacs from the repo.) > > > > Let me know what you think, and > > I admit I don't use bib-cite.el and I'm not familiar with the code, so I > trust your code works. I have only some minor comments, see below. > > @Keita: WDYT? > > > From 377cdad78b216bd71f14c3d65307b42607bd622b Mon Sep 17 00:00:00 2001 > > From: David Fussner <[email protected]> > > Date: Sat, 13 Jun 2026 15:36:00 +0100 > > Subject: [PATCH] Modify `bib-find-next' to use xref commands > > > > * bib-cite.el (bib-cite--next-ref): New helper function to replicate the > > behavior of the obsolete `find-tag'. > > (bib-find-next): Replace `find-tag' with previous. > > --- > > bib-cite.el | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++--- > > 1 file changed, 71 insertions(+), 3 deletions(-) > > > > diff --git a/bib-cite.el b/bib-cite.el > > index ebcfbe63..b1635690 100644 > > --- a/bib-cite.el > > +++ b/bib-cite.el > > @@ -593,6 +593,8 @@ > > (declare-function reftex-view-crossref "ext:reftex-dcr" > > (&optional arg auto-how fail-quietly)) > > (declare-function outline-show-entry "ext:outline" ()) > > +(declare-function xref-quit-and-pop-marker-stack "xref" ()) > > +(declare-function xref-quit-and-goto-xref "xref" ()) > > > > (defgroup bib-cite nil > > "bib-cite, LaTeX minor-mode to display \\cite, \\ref and \\label > commands." > > @@ -931,6 +933,74 @@ A TAGS file is created and used for multi-file > documents under auctex." > > (defvar bib-cite-search-ring nil > > "Bib-cite intenal variable to hold last \\ref or \\eqref find.") > > > > +(defun bib-cite--next-ref (str &optional bkwd) > > Can we add a docstring for this new function, even if it's an internal > one? > > > + (if str > > + (let* (notag > > + (lino (concat (number-to-string (line-number-at-pos nil t)) > ":")) > > + (file (buffer-file-name)) > > + (tag (substring-no-properties str)) > > + (xrtag (seq-subseq tag (1+ (seq-position tag ?{)) > ?\{ > > + (seq-position tag ?}))) > ?\} > > + (re (concat bib-ref-regexpc xrtag "}")) > > + (buf (xref-find-apropos xrtag))) > > + (if bkwd > > + (with-current-buffer buf > > + (search-forward file nil t) > > + (re-search-forward "^[^[:digit:][:space:][:cntrl:]]" nil 1) > > + (beginning-of-line) > > + (condition-case nil > > + (search-backward lino) > > + (error (progn > > + (while > > + (and > > + (re-search-backward > > + (concat > > + > "\\(?1:^[^[:digit:][:space:][:cntrl:]]\\)\\|" > > + "^[[:space:]]*\\(?1:[[:digit:]]+:\\)") > > + nil 1) > > + (string-match > > + "[[:digit:]]+:" > > + (match-string-no-properties 1) nil t) > > + (setq notag t) > > + (string-version-lessp > > + lino (match-string-no-properties 1)) > > + (setq notag 1))) > > + (end-of-line)))) > > + (unless (or (re-search-backward re nil 1) (eq notag t) > (bobp)) > > + (forward-line -1)) > > + (condition-case nil > > + (xref-quit-and-goto-xref) > > + (user-error (progn > > + (xref-quit-and-pop-marker-stack) > > + (message "No previous occurrence of %s" > re))))) > > + (with-current-buffer buf > > + (search-forward file nil t) > > + (condition-case nil > > + (search-forward lino) > > + (error (progn > > + (setq notag t) > > + (while > > + (and > > + (re-search-forward > > + (concat > > + "\\(?1:^[^[:digit:][:space:][:cntrl:]]\\)\\|" > > + "^[[:space:]]*\\(?1:[[:digit:]]+:\\)") > > + nil 1) > > + (string-match > > + "[[:digit:]]+:" > > + (match-string-no-properties 1) nil t) > > + (string-version-lessp > > + (match-string-no-properties 1) lino)))))) > > + (unless notag > > + (forward-line)) > > + (re-search-forward re nil 1) > > + (condition-case nil > > + (xref-quit-and-goto-xref) > > + (user-error (progn > > + (xref-quit-and-pop-marker-stack) > > + (message "No next occurrence of %s" re))))))) > > + (message "Sorry, no previous reference to find. Use bib-find?"))) > > + > > (defun bib-find-next (&optional prev-p) > > "Find next occurrence of a \\ref or \\eqref. > > This is made necessary because we now use a regexp to find tags in > multi-file > > @@ -938,9 +1008,7 @@ documents, and the Emacs command `find-tag' doesn't > allow to interactively > > find the next occurrence of a regexp." > > (interactive "P") > > (if (bib-master-file) ;Multi-file document > > - ;; FIXME: `find-tag' is replaced by `xref-find-definitions' in > > - ;; Emacs 25.1. AUCTeX should track this change, sometime ... > > - (find-tag t (if prev-p '- t) t) > > + (bib-cite--next-ref (if (boundp 'last-tag) last-tag nil) prev-p) > > (if bib-cite-search-ring > > ;;FIXME: Should first make sure I move off initial \ref{}. > > (let ((regexp (concat bib-ref-regexpc bib-cite-search-ring > "}"))) >
