Subject: Re: bug#75828: [PATCH] Correct make-frame docstring vis-a-vis make_frame.c

From: martin rudalics <[email-masked]>
Date: Tue, 28 Jan 2025 12:00:42 +0100

> Hmm. make-frame-may-show-it doesn't really capture the nature of
 > make-frame's hidden buffer name check, though. How about
 > make-frame-show-hidden-buffer?

In a new version I called it 'expose-hidden-buffer' so it can be used
also, for example, when switching to the previous or next buffer in a
window if we eventually want that.

martin

diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index c71b977550e..7b2fe9e0246 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -162,6 +162,12 @@ Creating Frames
 @xref{Input Focus}.  The previously selected frame remains selected.
 On graphical terminals, however, the window system may select the
 new frame for its own reasons.
+
+By default this function does not display the current buffer in the new
+frame if the buffer is hidden, that is, if its name starts with a space.
+However, if the variable @code{expose-hidden-buffer} is either @code{t}
+or equals the symbol @code{make-frame}, it will display the current
+buffer even if it is hidden.
 @end deffn
 
 @defvar before-make-frame-hook
diff --git a/lisp/frame.el b/lisp/frame.el
index 091e84f09c4..cda5fe4cfb4 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -949,7 +949,12 @@ make-frame
 
 On graphical displays, this function does not itself make the new
 frame the selected frame.  However, the window system may select
-the new frame according to its own rules."
+the new frame according to its own rules.
+
+By default do not display the current buffer in the new frame if the
+buffer is hidden, that is, if the buffer's name starts with a space.
+However, if `expose-hidden-buffer' is either t or equals the symbol
+`make-frame', display the current buffer even if it is hidden."
   (interactive)
   (let* ((display (cdr (assq 'display parameters)))
          (w (cond
diff --git a/src/frame.c b/src/frame.c
index d59b4045c00..c320515dfbd 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1094,8 +1094,11 @@ make_frame (bool mini_p)
   {
     Lisp_Object buf = Fcurrent_buffer ();
 
-    /* If current buffer is hidden, try to find another one.  */
-    if (BUFFER_HIDDEN_P (XBUFFER (buf)))
+    /* If current buffer is hidden and shall not be exposed, try to find
+       another one.  */
+    if (BUFFER_HIDDEN_P (XBUFFER (buf))
+	&& !EQ (expose_hidden_buffer, Qt)
+	&& !EQ (expose_hidden_buffer, Qmake_frame))
       buf = other_buffer_safely (buf);
 
     /* Use set_window_buffer, not Fset_window_buffer, and don't let
@@ -6810,6 +6813,7 @@ syms_of_frame (void)
   DEFSYM (Qleft_only, "left-only");
   DEFSYM (Qtop_only, "top-only");
   DEFSYM (Qiconify_top_level, "iconify-top-level");
+  DEFSYM (Qmake_frame, "make-frame");
   DEFSYM (Qmake_invisible, "make-invisible");
   DEFSYM (Quse_frame_synchronization, "use-frame-synchronization");
   DEFSYM (Qfont_parameter, "font-parameter");
@@ -7164,6 +7168,21 @@ focus (where a frame immediately loses focus when it's left by the mouse
 iconify the top level frame instead.  */);
   iconify_child_frame = Qiconify_top_level;
 
+  DEFVAR_LISP ("expose-hidden-buffer", expose_hidden_buffer,
+	       doc: /* Non-nil means to make a hidden buffer more visible.
+A buffer is considered "hidden" if its name starts with a space.  By
+default, many functions do not consider hidden buffers, for example,
+when displaying them in buffer lists or considering them for switching
+to in a window.  Also, `make-frame' does not show the current buffer in
+the new frame's selected window if it is hidden.
+
+If this variable is t or equals the symbol `make-frame', it will
+override the default behavior and allow `make-frame' to show it.  Other
+non-nil values are reserved for future use.  */);
+  expose_hidden_buffer = Qnil;
+  DEFSYM (Qexpose_hidden_buffer, "expose-hidden-buffer");
+  Fmake_variable_buffer_local (Qexpose_hidden_buffer);
+
   DEFVAR_LISP ("frame-internal-parameters", frame_internal_parameters,
 	       doc: /* Frame parameters specific to every frame.  */);
 #ifdef HAVE_X_WINDOWS