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
> "}")))
>

Reply via email to