Many thanks for your comments.  I attach the updated patch, which
contains a few other corrections and hopefully not too many regressions.

> AFAICT it should be safe in the sense that it should not affect behavior
> in file buffers.  See comments below.

That's indeed the plan.

> Should we push it to `master`?

I'm curious what Arash/Ikumi think -- if they don't like the idea, then
I'm happy to put this in the wastebin and regard it as an exercise.

Also, if we're going to proceed with this, then I'd like to take the
opportunity to add support for indirect buffers to RefTeX, which
requires modifications to the same parts of the code as this patch.

Thanks, best,

Paul

>From d921b6fd64bb93387c42ff133a0f185624a096e1 Mon Sep 17 00:00:00 2001
From: Paul Nelson <[email protected]>
Date: Wed, 2 Apr 2025 21:38:48 +0200
Subject: [PATCH] Add RefTeX support for non-file buffers

* lisp/textmodes/reftex.el (reftex-get-buffer-identifier)
(reftex-get-buffer-for-master, reftex-get-directory-for-master)
(reftex-file-or-buffer-name, reftex-abbreviate-or-get-name)
(reftex-get-basename-for-master, reftex-get-truename-for-master):
New helper functions that handle both files and buffer objects.
(reftex-tie-multifile-symbols): Support non-file buffers.
(reftex-TeX-master-file): Return current buffer when no file.
(reftex-access-scan-info): Remove check requiring file buffers.
(reftex-access-parse-file, reftex-check-parse-consistency): Skip
for non-file buffers.
(reftex-select-external-document): Use new helper function.
(reftex-locate-file): Return buffer objects directly.
(reftex-get-file-buffer-force): Handle buffer objects and
special 'buffer:' strings.
* lisp/textmodes/reftex-global.el (reftex-create-tags-file): Add
error handling for non-file buffers.  We leave TAGS unsupported
in non-file buffers.
(reftex-find-duplicate-labels)
(reftex-isearch-switch-to-next-file): Use new helper functions
that handle both files and buffer objects.
* lisp/textmodes/reftex-index.el (reftex-display-index): Use new
helper functions.
(reftex-index-visit-phrases-buffer): Add error handling for
non-file buffers.  We leave phrases unsupported in non-file
buffers.
* lisp/textmodes/reftex-parse.el (reftex-do-parse): Add support
for non-file buffers.
(reftex-all-document-files, reftex-where-am-I)
(reftex-notice-new): Use new helper functions.
* lisp/textmodes/reftex-ref.el (reftex-label-info-update):
Support non-file buffers.
(reftex-label-info, reftex-replace-prefix-escapes, reftex-label)
(reftex-replace-prefix-escapes, reftex-offer-label-menu): Use new
helper functions.
* lisp/textmodes/reftex-sel.el (reftex-insert-docstruct): Use
new helper function.
* lisp/textmodes/reftex-toc.el (reftex-toc)
(reftex-recenter-toc-when-idle): Support non-file buffers.

RefTeX historically assumed that the buffers it operates on
visit files.  For non-file buffers, we follow Stefan Monnier's
suggestion of modifying reftex-TeX-master-file so that it
returns the buffer object itself.  We then modify each caller to
handle buffer objects, aided by some helper functions added to
reftex.el.
---
 lisp/textmodes/reftex-global.el |  20 +-
 lisp/textmodes/reftex-index.el  |  20 +-
 lisp/textmodes/reftex-parse.el  |  26 +-
 lisp/textmodes/reftex-ref.el    |  22 +-
 lisp/textmodes/reftex-sel.el    |   2 +-
 lisp/textmodes/reftex-toc.el    |  10 +-
 lisp/textmodes/reftex.el        | 464 +++++++++++++++++++-------------
 7 files changed, 332 insertions(+), 232 deletions(-)

diff --git a/lisp/textmodes/reftex-global.el b/lisp/textmodes/reftex-global.el
index 20abd36192d..d706d3e9fd2 100644
--- a/lisp/textmodes/reftex-global.el
+++ b/lisp/textmodes/reftex-global.el
@@ -38,15 +38,17 @@ reftex-create-tags-file
   (interactive)
   (reftex-access-scan-info current-prefix-arg)
   (let* ((master (reftex-TeX-master-file))
-         (files  (reftex-all-document-files))
-         (cmd    (format "%s %s"
+         (files  (reftex-all-document-files)))
+    (if (bufferp master)
+        (user-error "Cannot create TAGS file for non-file buffers")
+      (let ((cmd (format "%s %s"
                          etags-program-name
                          (mapconcat #'shell-quote-argument
-				    files " "))))
-    (with-current-buffer (reftex-get-file-buffer-force master)
-      (message "Running etags to create TAGS file...")
-      (shell-command cmd)
-      (visit-tags-table "TAGS"))))
+                                    files " "))))
+        (with-current-buffer (reftex-get-file-buffer-force master)
+          (message "Running etags to create TAGS file...")
+          (shell-command cmd)
+          (visit-tags-table "TAGS"))))))
 
 ;; History of grep commands.
 (defvar reftex-grep-history nil)
@@ -144,7 +146,7 @@ reftex-find-duplicate-labels
                 (if (< 1 (length x1))
                     (append (list (car x))
                             (mapcar (lambda(x)
-                                      (abbreviate-file-name (nth 3 x)))
+                                      (reftex-abbreviate-or-get-name (nth 3 x)))
                                     x1))
                   (list nil))))))
           (reftex-uniquify-by-car (symbol-value reftex-docstruct-symbol)))))
@@ -456,7 +458,7 @@ reftex-isearch-isearch-search
 ;; beginning/end of the file list, depending of the search direction.
 (defun reftex-isearch-switch-to-next-file (crt-buf &optional wrapp)
   (reftex-access-scan-info)
-  (let ((cb (buffer-file-name crt-buf))
+  (let ((cb (reftex-get-buffer-identifier crt-buf))
 	(flist (reftex-all-document-files)))
     (when flist
       (if wrapp
diff --git a/lisp/textmodes/reftex-index.el b/lisp/textmodes/reftex-index.el
index db6ebb4caf8..47a389500f1 100644
--- a/lisp/textmodes/reftex-index.el
+++ b/lisp/textmodes/reftex-index.el
@@ -531,7 +531,7 @@ reftex-display-index
 SPC=view TAB=goto RET=goto+hide [e]dit [q]uit [r]escan [f]ollow [?]Help
 ------------------------------------------------------------------------------
 "
-               index-tag (abbreviate-file-name master)
+               index-tag (reftex-abbreviate-or-get-name master)
                (if (eq (car (car reftex-index-restriction-data)) 'toc)
                    (nth 2 (car reftex-index-restriction-data))
                  reftex-index-restriction-indicator)))
@@ -1281,14 +1281,16 @@ reftex-index-visit-phrases-buffer
   (interactive)
   (reftex-access-scan-info)
   (set-marker reftex-index-return-marker (point))
-  (let* ((master (reftex-TeX-master-file))
-         (name (concat (file-name-sans-extension master)
-                       reftex-index-phrase-file-extension)))
-    (find-file name)
-    (unless (eq major-mode 'reftex-index-phrases-mode)
-      (reftex-index-phrases-mode))
-    (if (= (buffer-size) 0)
-        (reftex-index-initialize-phrases-buffer master))))
+  (let* ((master (reftex-TeX-master-file)))
+    (when (bufferp master)
+      (user-error "RefTeX phrases buffer requires a file buffer.  Cannot create phrases for non-file buffers"))
+    (let ((name (concat (file-name-sans-extension master)
+                        reftex-index-phrase-file-extension)))
+      (find-file name)
+      (unless (eq major-mode 'reftex-index-phrases-mode)
+        (reftex-index-phrases-mode))
+      (if (= (buffer-size) 0)
+          (reftex-index-initialize-phrases-buffer master)))))
 
 (defun reftex-index-initialize-phrases-buffer (&optional master)
   "Initialize the phrases buffer by creating the header.
diff --git a/lisp/textmodes/reftex-parse.el b/lisp/textmodes/reftex-parse.el
index 7795c583076..f089536c40a 100644
--- a/lisp/textmodes/reftex-parse.el
+++ b/lisp/textmodes/reftex-parse.el
@@ -74,10 +74,10 @@ reftex-do-parse
 
   (let* ((old-list (symbol-value reftex-docstruct-symbol))
          (master (reftex-TeX-master-file))
-         (true-master (file-truename master))
-         (master-dir (file-name-as-directory (file-name-directory master)))
-         (file (or file (buffer-file-name)))
-         (true-file (file-truename file))
+         (true-master (reftex-get-truename-for-master master))
+         (master-dir (file-name-as-directory (reftex-get-directory-for-master master)))
+         (file (or file (reftex-get-buffer-identifier)))
+         (true-file (if file (file-truename file) (buffer-name)))
          (bibview-cache (assq 'bibview-cache old-list))
          (reftex--index-tags (cdr (assq 'index-tags old-list)))
          from-file appendix docstruct tmp)
@@ -88,7 +88,7 @@ reftex-do-parse
                          (member (list 'eof file) old-list))))
       ;; Scan whole document because no such file section exists
       (setq rescan 1))
-    (when (string= true-file true-master)
+    (when (equal true-file true-master)
       ;; Scan whole document because this file is the master
       (setq rescan 1))
 
@@ -186,7 +186,7 @@ reftex-all-document-files
 When RELATIVE is non-nil, give file names relative to directory
 of master file."
   (let* ((all (symbol-value reftex-docstruct-symbol))
-         (master-dir (file-name-directory (reftex-TeX-master-file)))
+         (master-dir (reftex-get-directory-for-master (reftex-TeX-master-file)))
          (re (concat "\\`" (regexp-quote master-dir)))
         file-list tmp file)
     (while (setq tmp (assoc 'bof all))
@@ -638,7 +638,7 @@ reftex-where-am-I
                ((not found)
                 ;; no match
                 (or
-                 (car (member (list 'bof (buffer-file-name)) docstruct))
+                 (car (member (list 'bof (reftex-get-buffer-identifier)) docstruct))
                  (not (setq cnt 2))
                  (assq 'bof docstruct)  ;; for safety reasons
                  'corrupted))
@@ -649,14 +649,15 @@ reftex-where-am-I
                ((match-end 3)
                 ;; Section
                 (goto-char (1- (match-beginning 3)))
-                (let* ((list (member (list 'bof (buffer-file-name))
+                (let* ((buffile (reftex-get-buffer-identifier))
+                       (list (member (list 'bof buffile)
                                      docstruct))
-                       (endelt (car (member (list 'eof (buffer-file-name))
+                       (endelt (car (member (list 'eof buffile)
                                             list)))
                        rtn1)
                   (while (and list (not (eq endelt (car list))))
                     (if (and (eq (car (car list)) 'toc)
-                             (string= (buffer-file-name)
+                             (string= buffile
                                       (nth 3 (car list))))
                         (cond
                          ((equal (point)
@@ -758,12 +759,13 @@ reftex-notice-new
          (when (re-search-forward (reftex-everything-regexp) nil t)
            (cond
             ((match-end 1)
-             (push (reftex-label-info (reftex-match-string 1) buffer-file-name)
+             (push (reftex-label-info (reftex-match-string 1)
+                                  (reftex-get-buffer-identifier))
                    (cdr tail)))
 
             ((match-end 3)
              (setq star (= ?* (char-after (match-end 3)))
-                   entry (reftex-section-info (buffer-file-name))
+                   entry (reftex-section-info (reftex-get-buffer-identifier))
                    level (nth 5 entry))
              ;; Insert the section info
              (push entry (cdr tail))
diff --git a/lisp/textmodes/reftex-ref.el b/lisp/textmodes/reftex-ref.el
index 30e9968a8e5..a495a06ce37 100644
--- a/lisp/textmodes/reftex-ref.el
+++ b/lisp/textmodes/reftex-ref.el
@@ -73,8 +73,10 @@ reftex-label-info-update
          (file    (nth 3 cell))
          (comment (nth 4 cell))
          (note    (nth 5 cell))
-         (buf (reftex-get-file-buffer-force
-               file (not (eq t reftex-keep-temporary-buffers)))))
+         (buf (if (bufferp file)
+                  file
+                (reftex-get-file-buffer-force
+                 file (not (eq t reftex-keep-temporary-buffers))))))
     (if (not buf)
         (list label typekey "" file comment "LOST LABEL.  RESCAN TO FIX.")
       (with-current-buffer buf
@@ -102,7 +104,7 @@ reftex-label-info
   (let* ((prefix (if (string-match "^[a-zA-Z0-9]+:" label)
                      (match-string 0 label)))
          (typekey (cdr (assoc prefix reftex-prefix-to-typekey-alist)))
-         (file (or file (buffer-file-name)))
+         (file (or file (reftex-get-buffer-identifier)))
          (trust reftex-trust-label-prefix)
          (in-comment (reftex-in-comment)))
     (if (and typekey
@@ -249,7 +251,7 @@ reftex-label
              (note (if (cdr here-I-am-info)
                        ""
                      "POSITION UNCERTAIN.  RESCAN TO FIX."))
-             (file (buffer-file-name))
+             (file (reftex-get-buffer-identifier))
              ;; (text nil)
              (tail (memq here-I-am (symbol-value reftex-docstruct-symbol))))
 
@@ -314,19 +316,19 @@ reftex-replace-prefix-escapes
               (save-match-data
                 (cond
                  ((equal letter "f")
-                  (file-name-base (buffer-file-name)))
+                  (file-name-base (reftex-get-buffer-identifier)))
                  ((equal letter "F")
-                  (let ((masterdir (file-name-directory (reftex-TeX-master-file)))
-                        (file (file-name-sans-extension (buffer-file-name))))
+                  (let ((masterdir (reftex-get-directory-for-master (reftex-TeX-master-file)))
+                        (file (file-name-sans-extension (reftex-get-buffer-identifier))))
                     (if (string-match (concat "\\`" (regexp-quote masterdir))
                                       file)
                         (substring file (length masterdir))
                       file)))
                  ((equal letter "m")
-                  (file-name-base (reftex-TeX-master-file)))
+                  (reftex-get-basename-for-master (reftex-TeX-master-file)))
                  ((equal letter "M")
                   (file-name-nondirectory
-                   (substring (file-name-directory (reftex-TeX-master-file))
+                   (substring (reftex-get-directory-for-master (reftex-TeX-master-file))
                               0 -1)))
                  ((equal letter "u")
                   (or (user-login-name) ""))
@@ -536,7 +538,7 @@ reftex-offer-label-menu
   ;; Offer a menu with the appropriate labels.
   (let* ((buf (current-buffer))
          (xr-data (assq 'xr (symbol-value reftex-docstruct-symbol)))
-         (xr-alist (cons (cons "" (buffer-file-name)) (nth 1 xr-data)))
+         (xr-alist (cons (cons "" (reftex-get-buffer-identifier)) (nth 1 xr-data)))
          (xr-index 0)
          (here-I-am (car (reftex-where-am-I)))
          (here-I-am1 here-I-am)
diff --git a/lisp/textmodes/reftex-sel.el b/lisp/textmodes/reftex-sel.el
index 1f1c74550a5..813a9b17532 100644
--- a/lisp/textmodes/reftex-sel.el
+++ b/lisp/textmodes/reftex-sel.el
@@ -234,7 +234,7 @@ reftex-insert-docstruct
             reftex-active-toc nil
             master-dir-re
             (concat "\\`" (regexp-quote
-                           (file-name-directory (reftex-TeX-master-file))))))
+                           (reftex-get-directory-for-master (reftex-TeX-master-file))))))
 
     (setq-local reftex-docstruct-symbol docstruct-symbol)
     (setq-local reftex-prefix
diff --git a/lisp/textmodes/reftex-toc.el b/lisp/textmodes/reftex-toc.el
index d8d09da5ed0..3a1bc2d3d10 100644
--- a/lisp/textmodes/reftex-toc.el
+++ b/lisp/textmodes/reftex-toc.el
@@ -184,14 +184,14 @@ reftex-toc
 
   (interactive)
 
-  (if (or (not (string= reftex-last-toc-master (reftex-TeX-master-file)))
+  (if (or (not (equal reftex-last-toc-master (reftex-TeX-master-file)))
           ;; FIXME: use (interactive "P") to receive current-prefix-arg as
           ;; an argument instead of using the var here, which forces us to set
           ;; current-prefix-arg in the callers.
           current-prefix-arg)
       (reftex-erase-buffer "*toc*"))
 
-  (setq reftex-last-toc-file   (buffer-file-name))
+  (setq reftex-last-toc-file   (reftex-get-buffer-identifier))
   (setq reftex-last-toc-master (reftex-TeX-master-file))
 
   (set-marker reftex-toc-return-marker (point))
@@ -211,7 +211,7 @@ reftex-toc
   (let* ((this-buf (current-buffer))
          (docstruct-symbol reftex-docstruct-symbol)
          (xr-data (assq 'xr (symbol-value reftex-docstruct-symbol)))
-         (xr-alist (cons (cons "" (buffer-file-name)) (nth 1 xr-data)))
+         (xr-alist (cons (cons "" (reftex-get-buffer-identifier)) (nth 1 xr-data)))
          (here-I-am (if reftex--rebuilding-toc
                         (get 'reftex-toc :reftex-data)
                       (car (reftex-where-am-I))))
@@ -261,7 +261,7 @@ reftex-toc
 "TABLE-OF-CONTENTS on %s
 SPC=view TAB=goto RET=goto+hide [q]uit [r]escan [l]abels [f]ollow [x]r [?]Help
 ------------------------------------------------------------------------------
-" (abbreviate-file-name reftex-last-toc-master)))
+" (reftex-abbreviate-or-get-name reftex-last-toc-master)))
 
       (if reftex-use-fonts
           (put-text-property (point-min) (point) 'font-lock-face reftex-toc-header-face))
@@ -997,7 +997,7 @@ reftex-recenter-toc-when-idle
        (not (active-minibuffer-window))
        (fboundp 'reftex-toc-mode)
        (get-buffer-window "*toc*" 'visible)
-       (string= reftex-last-toc-master (reftex-TeX-master-file))
+       (equal reftex-last-toc-master (reftex-TeX-master-file))
        (let (current-prefix-arg)
          (reftex-toc-recenter))))
 
diff --git a/lisp/textmodes/reftex.el b/lisp/textmodes/reftex.el
index fda506a6d87..67a7b120200 100644
--- a/lisp/textmodes/reftex.el
+++ b/lisp/textmodes/reftex.el
@@ -251,6 +251,58 @@ LaTeX-label-function
 (defvar tex-main-file)
 (defvar outline-minor-mode)
 
+;;; =========================================================================
+;;;
+;;; Helper functions for handling both file paths and buffer objects
+;;;
+
+(defun reftex-get-buffer-identifier (&optional buffer)
+  "Return the base buffer's file name or buffer identifier.
+For file buffers, returns the file name of the base buffer.
+For non-file buffers, return the base buffer object itself.
+When BUFFER is nil, use the current buffer."
+  (with-current-buffer (or (buffer-base-buffer buffer) buffer (current-buffer))
+    (or (buffer-file-name) (current-buffer))))
+
+(defun reftex-get-buffer-for-master (master)
+  "Get the buffer associated with MASTER.
+MASTER can be a file path or a buffer object."
+  (if (bufferp master)
+      master
+    (find-file-noselect master)))
+
+(defun reftex-get-directory-for-master (master)
+  "Get the directory associated with MASTER.
+MASTER can be a file path or a buffer object."
+  (if (bufferp master)
+      (with-current-buffer master default-directory)
+    (file-name-directory master)))
+
+(defun reftex-abbreviate-or-get-name (master)
+  "Get a nice display name for MASTER.
+For files, returns the abbreviated file name.
+For buffers, returns the buffer name."
+  (if (bufferp master)
+      (prin1-to-string master)
+    (abbreviate-file-name master)))
+
+(defun reftex-get-basename-for-master (master)
+  "Get the base name (without extension) for MASTER.
+For file masters, returns the file name without directory and extension.
+For buffer objects, returns a sanitized version of the buffer name
+suitable for use in LaTeX labels."
+  (if (bufferp master)
+      (file-name-base (buffer-name master))
+    (file-name-base master)))
+
+(defun reftex-get-truename-for-file (file)
+  "Get the canonical form of FILE's identity.
+For files, returns the result of file-truename.
+For buffer objects, returns the buffer object itself."
+  (if (bufferp file)
+      file
+    (file-truename file)))
+
 ;;; =========================================================================
 ;;;
 ;;; Multibuffer Variables
@@ -282,7 +334,8 @@ reftex-next-multifile-index
 (defun reftex-tie-multifile-symbols ()
   "Tie the buffer-local symbols to globals connected with the master file.
 If the symbols for the current master file do not exist, they are created."
-  (let* ((master (file-truename (reftex-TeX-master-file)))
+  (let* ((master (reftex-TeX-master-file))
+         (master (reftex-get-truename-for-file master))
          (index (assoc master reftex-master-index-list))
          (symlist reftex-multifile-symbols)
          symbol symname newflag)
@@ -293,7 +346,13 @@ reftex-tie-multifile-symbols
       ;; Get a new index and add info to the alist.
       (setq index (reftex-next-multifile-index)
             newflag t)
-      (push (cons master index) reftex-master-index-list))
+      (push (cons master index) reftex-master-index-list)
+      (when (bufferp master)
+        (add-hook
+         'kill-buffer-hook
+         (lambda ()
+           (setq reftex-master-index-list
+                 (assq-delete-all master reftex-master-index-list))))))
 
     ;; Get/create symbols and tie them.
     (while symlist
@@ -326,70 +385,73 @@ reftex-TeX-master-file
   ;; When AUCTeX is loaded, we will use it's more sophisticated method.
   ;; We also support the default TeX and LaTeX modes by checking for a
   ;; variable tex-main-file.
-  (let
-      ((master
-        (cond
-	 ;; Test if we're in a subfile using the subfiles document
-	 ;; class, e.g., \documentclass[main.tex]{subfiles}.  It's
-	 ;; argument is the main file, however it's not really the
-	 ;; master file in `TeX-master-file' or `tex-main-file's
-	 ;; sense.  It should be used for references but not for
-	 ;; compilation, thus subfiles use a setting of
-	 ;; `TeX-master'/`tex-main-file' being themselves.
-	 ((save-excursion
-            (goto-char (point-min))
-            (re-search-forward
-             "^[[:space:]]*\\\\documentclass\\[\\([^]]+\\)\\]{subfiles}"
-             nil t))
-          (match-string-no-properties 1))
-         ;; AUCTeX is loaded.  Use its mechanism.
-         ((fboundp 'TeX-master-file)
-          (condition-case nil
-              (TeX-master-file t)
-            (error (buffer-file-name))))
-         ;; Emacs LaTeX mode
-         ((fboundp 'tex-main-file) (tex-main-file))
-         ;; Check the `TeX-master' variable.
-         ((boundp 'TeX-master)
-          (cond
-           ((eq TeX-master t)
-            (buffer-file-name))
-           ((eq TeX-master 'shared)
-            (setq TeX-master (read-file-name "Master file: "
-                                             nil nil t nil)))
-           (TeX-master)
-           (t
-            (setq TeX-master (read-file-name "Master file: "
-                                             nil nil t nil)))))
-         ;; Check the `tex-main-file' variable.
-         ((boundp 'tex-main-file)
-          ;; This is the variable from the default TeX modes.
+  (with-current-buffer (or (buffer-base-buffer) (current-buffer))
+    (let
+        ;; Set master to a file name (possibly non-existent), or nil:
+        ((master
           (cond
-           ((stringp tex-main-file)
-            ;; ok, this must be it
-            tex-main-file)
+	   ;; Test if we're in a subfile using the subfiles document
+	   ;; class, e.g., \documentclass[main.tex]{subfiles}.  It's
+	   ;; argument is the main file, however it's not really the
+	   ;; master file in `TeX-master-file' or `tex-main-file's
+	   ;; sense.  It should be used for references but not for
+	   ;; compilation, thus subfiles use a setting of
+	   ;; `TeX-master'/`tex-main-file' being themselves.
+	   ((save-excursion
+              (goto-char (point-min))
+              (re-search-forward
+               "^[[:space:]]*\\\\documentclass\\[\\([^]]+\\)\\]{subfiles}"
+               nil t))
+            (match-string-no-properties 1))
+           ;; AUCTeX is loaded.  Use its mechanism.
+           ((fboundp 'TeX-master-file)
+            (condition-case nil
+                (TeX-master-file t)
+              (error (buffer-file-name))))
+           ;; Emacs LaTeX mode
+           ((fboundp 'tex-main-file) (tex-main-file))
+           ;; Check the `TeX-master' variable.
+           ((boundp 'TeX-master)
+            (cond
+             ((eq TeX-master t)
+              (buffer-file-name))
+             ((eq TeX-master 'shared)
+              (setq TeX-master (read-file-name "Master file: "
+                                               nil nil t nil)))
+             (TeX-master)
+             (t
+              (setq TeX-master (read-file-name "Master file: "
+                                               nil nil t nil)))))
+           ;; Check the `tex-main-file' variable.
+           ((boundp 'tex-main-file)
+            ;; This is the variable from the default TeX modes.
+            (cond
+             ((stringp tex-main-file)
+              ;; ok, this must be it
+              tex-main-file)
+             (t
+              ;; In this case, the buffer is its own master.
+              (buffer-file-name))))
+           ;; We know nothing about master file.  Assume this is a
+           ;; master file.
            (t
-            ;; In this case, the buffer is its own master.
-            (buffer-file-name))))
-         ;; We know nothing about master file.  Assume this is a
-         ;; master file.
-         (t
-          (buffer-file-name)))))
-    (cond
-     ((null master)
-      (error "Need a filename for this buffer, please save it first"))
-     ((or (file-exists-p (concat master ".tex"))
-          (find-buffer-visiting (concat master ".tex")))
-      ;; Ahh, an extra .tex was missing...
-      (setq master (concat master ".tex")))
-     ((or (file-exists-p master)
-          (find-buffer-visiting master))
-      ;; We either see the file, or have a buffer on it.  OK.
-      )
-     (t
-      ;; Use buffer file name.
-      (setq master (buffer-file-name))))
-    (expand-file-name master)))
+            (buffer-file-name)))))
+      (cond
+       ((null master))
+       ((or (file-exists-p (concat master ".tex"))
+            (find-buffer-visiting (concat master ".tex")))
+        ;; Ahh, an extra .tex was missing...
+        (setq master (concat master ".tex")))
+       ((or (file-exists-p master)
+            (find-buffer-visiting master))
+        ;; We either see the file, or have a buffer on it.  OK.
+        )
+       (t
+        ;; Use buffer file name.
+        (setq master (buffer-file-name))))
+      (if master
+          (expand-file-name master)
+        (current-buffer)))))
 
 (defun reftex-is-multi ()
   ;; Tell if this is a multifile document.  When not sure, say yes.
@@ -1105,11 +1167,6 @@ reftex-access-scan-info
   ;; But, when RESCAN is -1, don't rescan even if docstruct is empty.
   ;; When FILE is non-nil, parse only from that file.
 
-  ;; Error out in a buffer without a file.
-  (if (and reftex-mode
-	   (not (buffer-file-name)))
-      (error "RefTeX works only in buffers visiting a file"))
-
   ;; Make sure we have the symbols tied
   (if (eq reftex-docstruct-symbol nil)
       ;; Symbols are not yet tied: Tie them.
@@ -1157,81 +1214,103 @@ reftex-silence-toc-markers
 
 (defun reftex-access-parse-file (action)
   "Perform ACTION on the parse file (the .rel file).
-Valid actions are: readable, restore, read, kill, write."
+Valid actions are: readable, restore, read, kill, write.
+For non-file buffers, persistence operations are skipped."
   (let* ((list (symbol-value reftex-docstruct-symbol))
          (docstruct-symbol reftex-docstruct-symbol)
          (master (reftex-TeX-master-file))
          (enable-local-variables nil)
-         (file (if (string-match "\\.[a-zA-Z]+\\'" master)
-                   (concat (substring master 0 (match-beginning 0))
-                           reftex-parse-file-extension)
-                 (concat master reftex-parse-file-extension))))
+         (is-buffer (bufferp master))
+         (file (if is-buffer
+                   nil
+                 (if (string-match "\\.[a-zA-Z]+\\'" master)
+                     (concat (substring master 0 (match-beginning 0))
+                             reftex-parse-file-extension)
+                   (concat master reftex-parse-file-extension)))))
     (cond
+     ;; For non-file buffers, skip file operations but allow initialization
+     ((and is-buffer (memq action '(readable read kill)))
+      ;; Return appropriate values for buffer objects
+      (cond ((eq action 'readable) nil)
+            ((eq action 'read) nil)
+            ((eq action 'kill) t)))
+
      ((eq action 'readable)
-      (file-readable-p file))
+      (and file (file-readable-p file)))
+
      ((eq action 'restore)
       (put reftex-docstruct-symbol 'modified nil)
       (if (eq reftex-docstruct-symbol nil)
           ;; Symbols are not yet tied: Tie them.
           (reftex-tie-multifile-symbols))
-      (if (file-exists-p file)
-          ;; load the file and return t for success
-          (condition-case nil
-              (progn (load-file file) t)
-            (error (set reftex-docstruct-symbol nil)
-                   (error "Error while loading file %s" file)))
+      (cond
+       (is-buffer
+        (error "Cannot restore for non-file buffer"))
+       ((file-exists-p file)
+        ;; load the file and return t for success
+        (condition-case nil
+            (progn (load-file file) t)
+          (error (set reftex-docstruct-symbol nil)
+                 (error "Error while loading file %s" file))))
+       (t
         ;; Throw an exception if the file does not exist
-        (error "No restore file %s" file)))
+        (error "No restore file %s" file))))
+
      ((eq action 'read)
       (put reftex-docstruct-symbol 'modified nil)
-      (if (file-exists-p file)
-          ;; load the file and return t for success
-          (condition-case nil
-              (progn
-                (load-file file)
-                (reftex-check-parse-consistency)
-                t)
-            (error (message "Error while restoring file %s" file)
-                   (set reftex-docstruct-symbol nil)
-                   nil))
-        ;; return nil for failure, but no exception
-        nil))
+      (cond
+       (is-buffer nil)
+       ((file-exists-p file)
+        ;; load the file and return t for success
+        (condition-case nil
+            (progn
+              (load-file file)
+              (reftex-check-parse-consistency)
+              t)
+          (error (message "Error while restoring file %s" file)
+                 (set reftex-docstruct-symbol nil)
+                 nil)))
+       (t nil))) ; return nil for failure, but no exception
+
      ((eq action 'kill)
       ;; Remove the file
-      (when (and (file-exists-p file) (file-writable-p file))
+      (when (and file (file-exists-p file) (file-writable-p file))
         (message "Unlinking file %s" file)
         (delete-file file)))
-     (t
+
+     (t ; write
       (put docstruct-symbol 'modified nil)
-      (save-excursion
-        (if (file-writable-p file)
-            (with-temp-file file
-              (message "Writing parse file %s" (abbreviate-file-name file))
-              (insert ";; RefTeX parse info file\n")
-              (insert (format ";; File: %s\n" master))
-              (insert (format ";; User: %s (%s)\n\n"
-                              (user-login-name) (user-full-name)))
-              (insert "(set reftex-docstruct-symbol '(\n\n")
-              (let ((standard-output (current-buffer)))
-                (mapc
-                 (lambda (x)
-                   (cond ((eq (car x) 'toc)
-                          ;; A toc entry. Do not save the marker.
-                          ;; Save the markers  position at position 8
-                          (print (list 'toc "toc" (nth 2 x) (nth 3 x)
-                                       nil (nth 5 x) (nth 6 x) (nth 7 x)
-                                       (or (and (markerp (nth 4 x))
-                                                (marker-position (nth 4 x)))
-                                           (nth 8 x)))))
-                         ((and (not (eq t reftex-support-index))
-                               (eq (car x) 'index))
-                          ;; Don't save index entries
-                          )
-                         (t (print x))))
-                 list))
-              (insert "))\n\n"))
-          (error "Cannot write to file %s" file)))
-      t))))
+      (if is-buffer
+          t
+        (save-excursion
+          (if (and file (file-writable-p file))
+              (with-temp-file file
+                (message "Writing parse file %s" (abbreviate-file-name file))
+                (insert ";; RefTeX parse info file\n")
+                (insert (format ";; File: %s\n" master))
+                (insert (format ";; User: %s (%s)\n\n"
+                                (user-login-name) (user-full-name)))
+                (insert "(set reftex-docstruct-symbol '(\n\n")
+                (let ((standard-output (current-buffer)))
+                  (mapc
+                   (lambda (x)
+                     (cond ((eq (car x) 'toc)
+                            ;; A toc entry. Do not save the marker.
+                            ;; Save the markers  position at position 8
+                            (print (list 'toc "toc" (nth 2 x) (nth 3 x)
+                                         nil (nth 5 x) (nth 6 x) (nth 7 x)
+                                         (or (and (markerp (nth 4 x))
+                                                  (marker-position (nth 4 x)))
+                                             (nth 8 x)))))
+                           ((and (not (eq t reftex-support-index))
+                                 (eq (car x) 'index))
+                            ;; Don't save index entries
+                            )
+                           (t (print x))))
+                   list))
+                (insert "))\n\n"))
+            (error "Cannot write to file %s" file)))
+        t)))))
 
 (defun reftex-check-parse-consistency ()
   ;; Check if parse file is consistent, throw an error if not.
@@ -1240,10 +1319,13 @@ reftex-check-parse-consistency
   (let* ((real-master (reftex-TeX-master-file))
          (parsed-master
           (nth 1 (assq 'bof (symbol-value reftex-docstruct-symbol)))))
-    (unless (string= (file-truename real-master) (file-truename parsed-master))
-      (message "Master file name in load file is different: %s versus %s"
-               parsed-master real-master)
-      (error "Master file name error")))
+    ;; Skip this check for buffer objects since they don't need saved parse info
+    (when (and (stringp real-master) (stringp parsed-master))
+      (unless (string= (file-truename real-master)
+                       (file-truename parsed-master))
+        (message "Master file name in load file is different: %s versus %s"
+                 parsed-master real-master)
+        (error "Master file name error"))))
 
   ;; Check for the existence of all document files
 ;;;  (let* ((all (symbol-value reftex-docstruct-symbol)))
@@ -1281,7 +1363,7 @@ reftex-select-external-document
                   (mapconcat
                    (lambda (x)
                      (format fmt (incf n) (or (car x) "")
-                             (abbreviate-file-name (cdr x))))
+                             (reftex-abbreviate-or-get-name (cdr x))))
                    xr-alist ""))
                  nil t))
           (cond
@@ -1299,21 +1381,24 @@ reftex-locate-file
   "Find FILE of type TYPE in MASTER-DIR or on the path associated with TYPE.
 If the file does not have any of the valid extensions for TYPE,
 try first the default extension and only then the naked file name.
-When DIE is non-nil, throw an error if file not found."
-  (let* ((rec-values (if reftex-search-unrecursed-path-first '(nil t) '(t)))
-         (extensions (cdr (assoc type reftex-file-extensions)))
-         (def-ext (car extensions))
-         (ext-re (concat "\\("
-                         (mapconcat #'regexp-quote extensions "\\|")
-                         "\\)\\'"))
-         (files (if (string-match ext-re file)
-                    (cons file nil)
-		  (if reftex-try-all-extensions
-		      (append (mapcar (lambda (x) (concat file x))
-				      extensions)
-			      (list file))
-		    (list (concat file def-ext) file))))
-         path old-path file1 f fs)
+When DIE is non-nil, throw an error if file not found.
+When FILE is a buffer object, return that buffer."
+  (if (bufferp file)
+      file
+    (let* ((rec-values (if reftex-search-unrecursed-path-first '(nil t) '(t)))
+           (extensions (cdr (assoc type reftex-file-extensions)))
+           (def-ext (car extensions))
+           (ext-re (concat "\\("
+                          (mapconcat #'regexp-quote extensions "\\|")
+                          "\\)\\'"))
+           (files (if (string-match ext-re file)
+                     (cons file nil)
+                   (if reftex-try-all-extensions
+                       (append (mapcar (lambda (x) (concat file x))
+                                      extensions)
+                              (list file))
+                     (list (concat file def-ext) file))))
+           path old-path file1 f fs)
     (cond
      ((file-name-absolute-p file)
       (while (setq f (pop files))
@@ -1335,7 +1420,7 @@ reftex-locate-file
 	    (setq file1 (reftex-find-file-on-path f path master-dir)))))))
     (cond (file1 file1)
           (die (error "No such file: %s" file) nil)
-          (t (message "No such file: %s (ignored)" file) nil))))
+          (t (message "No such file: %s (ignored)" file) nil)))))
 
 (defun reftex-find-file-externally (file type &optional master-dir)
   ;; Use external program to find FILE.
@@ -1741,47 +1826,54 @@ reftex-get-file-buffer-force
   ;; If MARK-TO-KILL is t and there is no live buffer, visit the file with
   ;; initializations according to `reftex-initialize-temporary-buffers',
   ;; and mark the buffer to be killed after use.
+  ;; If FILE is actually a buffer object, just return that buffer.
 
-  (let ((buf (find-buffer-visiting file)))
-
-    (cond (buf
-           ;; We have it already as a buffer - just return it
-           buf)
-
-          ((file-readable-p file)
-           ;; At least there is such a file and we can read it.
-
-           (if (or (not mark-to-kill)
-                   (eq t reftex-initialize-temporary-buffers))
-
-               ;; Visit the file with full magic
-               (setq buf (find-file-noselect file))
-
-             ;; Else: Visit the file just briefly, without or
-             ;;       with limited Magic
-
-             ;; The magic goes away
-             (cl-letf ((format-alist nil)
-                       (auto-mode-alist (reftex-auto-mode-alist))
-                       ((default-value 'major-mode) 'fundamental-mode)
-                       (enable-local-variables nil)
-                       (after-insert-file-functions nil))
-               (setq buf (find-file-noselect file)))
-
-             ;; Is there a hook to run?
-             (when (listp reftex-initialize-temporary-buffers)
-               (with-current-buffer buf
-                 (run-hooks 'reftex-initialize-temporary-buffers))))
-
-           ;; Let's see if we got a license to kill :-|
-           (and mark-to-kill
-                (cl-pushnew buf reftex-buffers-to-kill))
-
-           ;; Return the new buffer
-           buf)
-
-          ;; If no such file exists, return nil
-          (t nil))))
+  (cond
+   ((bufferp file) file)
+
+   ;; Normal file path handling
+   ((stringp file)
+    (let ((buf (find-buffer-visiting file)))
+      (cond (buf
+             ;; We have it already as a buffer - just return it
+             buf)
+
+            ((file-readable-p file)
+             ;; At least there is such a file and we can read it.
+
+             (if (or (not mark-to-kill)
+                     (eq t reftex-initialize-temporary-buffers))
+
+                 ;; Visit the file with full magic
+                 (setq buf (find-file-noselect file))
+
+               ;; Else: Visit the file just briefly, without or
+               ;;       with limited Magic
+
+               ;; The magic goes away
+               (cl-letf ((format-alist nil)
+                         (auto-mode-alist (reftex-auto-mode-alist))
+                         ((default-value 'major-mode) 'fundamental-mode)
+                         (enable-local-variables nil)
+                         (after-insert-file-functions nil))
+                 (setq buf (find-file-noselect file)))
+
+               ;; Is there a hook to run?
+               (when (listp reftex-initialize-temporary-buffers)
+                 (with-current-buffer buf
+                   (run-hooks 'reftex-initialize-temporary-buffers))))
+
+             ;; Let's see if we got a license to kill :-|
+             (and mark-to-kill
+                  (cl-pushnew buf reftex-buffers-to-kill))
+
+             ;; Return the new buffer
+             buf)
+
+            ;; If no such file exists, return nil
+            (t nil))))
+   ;;
+   (t nil)))
 
 (defun reftex-kill-temporary-buffers (&optional buffer)
   ;; Kill all buffers in the list reftex-kill-temporary-buffers.
-- 
2.39.3 (Apple Git-145)

_______________________________________________
bug-auctex mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/bug-auctex
  • bug#76615:... Paul D. Nelson
    • bug#7... Ikumi Keita
      • b... Paul D. Nelson
        • ... Ikumi Keita
          • ... Paul D. Nelson
          • ... Ikumi Keita
          • ... Paul D. Nelson
          • ... Stefan Monnier via bug-auctex via Bug reporting list for AUCTeX
          • ... Paul D. Nelson
          • ... Stefan Monnier via bug-auctex via Bug reporting list for AUCTeX
          • ... Paul D. Nelson
          • ... Ikumi Keita
          • ... Stefan Monnier via bug-auctex via Bug reporting list for AUCTeX
          • ... Paul D. Nelson
          • ... Arash Esbati
          • ... Arash Esbati
          • ... Paul D. Nelson
          • ... Arash Esbati
          • ... Paul D. Nelson
          • ... Paul D. Nelson
          • ... Stefan Monnier via bug-auctex via Bug reporting list for AUCTeX

Reply via email to