Subject: bug#54133: 29.0.50; Buffer-menu-visit-tags-table disrupts non-tags buffers

From: Bob Rogers <[email-masked]>
Date: Wed, 23 Feb 2022 16:37:11 -0500

In GNU Emacs 29.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.20, cairo version 1.16.0)
 of 2022-02-19 built on orion
Repository revision: 563bb08c5998f82e034a0aa1b48dce29fb9bc375
Repository branch: rgr-smtpmail-env-from
Windowing system distributor 'The X.Org Foundation', version 11.0.12003000
System Description: openSUSE Leap 15.3

Configured using:
 'configure --with-dbus=no --with-gsettings=no --with-gif=ifavailable
 --with-tiff=no --with-gnutls=yes --with-gconf=no'

Configured features:
ACL CAIRO FREETYPE GIF GLIB GMP GNUTLS HARFBUZZ JPEG LIBSELINUX LIBXML2
MODULES NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS
TOOLKIT_SCROLL_BARS X11 XDBE XIM XPM GTK3 ZLIB

To reproduce:

   In master ecaedf2117cb015ad4028e4d6fc7058608c98096:

   1.  "emacs -Q &"

   2.  Visit pretty much any random file that is NOT a tags file; for
this purpose, lisp/abbrev.el from the source tree will do nicely.

   3.  Type "C-x C-b" to get the "*Buffer List*" window to appear.

   4.  Type "C-x o" to move the to the buffer list, then move to the
abbrev.el line, and type "t" to invoke Buffer-menu-visit-tags-table on
it (which I seem to do accidentally more often than I care to admit).
This produces the error message:

	user-error: File /scratch/rogers/emacs/lisp/abbrev.el is not a valid tags table

but the abbrev.el buffer is left in tags-table-mode, and any undo
information is thrown away.

   The attached patch addresses the problem in a straightforward way by
making Buffer-menu-visit-tags-table prompt the user for buffers not
already in tags-table-mode.

   The real problem is that visit-tags-table assumes that the user knows
what they're doing, and makes these irreversible changes before being
sure of having a valid tags table.  That would be a harder thing to fix,
though -- and might not deal as well with my buffer-menu typos.  ;-}

					-- Bob Rogers
					   http://www.rgrjr.com/

From 05d2d1855cddc8d5c310d718c07d91ae861b8436 Mon Sep 17 00:00:00 2001
From: Bob Rogers <[email-masked]>
Date: Wed, 23 Feb 2022 16:23:17 -0500
Subject: [PATCH] Make Buffer-menu-visit-tags-table more circumspect

* lisp/buff-menu.el:
   + (Buffer-menu-visit-tags-table):  Ask before visit-tags-table on a
     buffer not already in tags-table-mode, lest it destroy state.
---
 lisp/buff-menu.el | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el
index 50c2c155ca..0bed539008 100644
--- a/lisp/buff-menu.el
+++ b/lisp/buff-menu.el
@@ -530,10 +530,21 @@ Buffer-menu-multi-occur
 (defun Buffer-menu-visit-tags-table ()
   "Visit the tags table in the buffer on this line.  See `visit-tags-table'."
   (interactive nil Buffer-menu-mode)
-  (let ((file (buffer-file-name (Buffer-menu-buffer t))))
-    (if file
-	(visit-tags-table file)
-      (error "Specified buffer has no file"))))
+  (let* ((buffer (Buffer-menu-buffer t))
+         (file (buffer-file-name buffer)))
+    (or file
+        (error "Specified buffer has no file"))
+    ;; Ensure that it's really a tags file buffer (or the user at
+    ;; least believes it should be).  Otherwise, visit-tags-table will
+    ;; change the mode and discard any undo information.
+    (if (not (or (eq (with-current-buffer buffer
+                       major-mode)
+                     'tags-table-mode)
+                 (yes-or-no-p
+                  (format "%s is not a tags table; visit as such anyway? "
+                          buffer))))
+        (error "Aborted."))
+    (visit-tags-table file)))
 
 (defun Buffer-menu-1-window ()
   "Select this line's buffer, alone, in full frame."
-- 
2.34.1