Subject: Re: bug#52328: 27.2; [DOC] Paragraph about quit-restore-window

From: martin rudalics <[email-masked]>
Date: Wed, 8 Dec 2021 12:02:21 +0100

> So I rewrote the whole node.  I started with Master from Nov 1.  It is
 > still hard to read, but much less so than before.

Thank you.  Note that at the time I coded 'quit-restore-window' I didn't
want to describe the 'quit-restore' parameter at all.  It is an internal
object that "others" shouldn't mess with, at least that's my conviction.

Then, in Bug#12158,

https://debbugs.gnu.org/cgi/bugreport.cgi?bug=12158

Drew talked me into adding a description, something I still regret.

It took some time until Eric here

https://lists.gnu.org/archive/html/emacs-devel/2017-03/msg00085.html

explained his view of that parameter and added the text that is the
subject of the present report.

But I agree that if we do want to describe the 'quit-restore' parameter,
we should do better and your text certainly does that.

 > I left some loose ends where it is necessary to study the source code
 > to know what to say.  I marked them with @c ???.
 >
 > ======================================================================
 > @node Quitting Windows
 > @section Quitting Windows
 > @cindex quitting a window
 >
 > After a command uses @code{display-buffer} to put buffer on the

... "to put a buffer", I suppose ...

 > screen, the user may decide to hide it and return to the previous
 > screen configuration.

There is no such thing as "the previous screen configuration".
Otherwise we could simply call 'set-window-configuration' here but that
could fail, in particular, when multiple frames are involved.  The basic
aim of 'quit-restore-window' was to avoid window configurations and
still intuitively DTRT when the user hits "q" in such a window.

 > We call that @dfn{quitting the window}.  The
 > way to do this is to call @code{quit-window}.

It's the "way to do this" only if the window used by 'display-buffer' is
selected at the time the user wants to get rid of it.  Otherwise, the
options you now do not mention should be used.

 > The right way to restore the old screen configuration depends on what
 > was done to the window where the buffer now appears.  It might be
 > right to delete that window, or delete its frame, or just display
 > another buffer in that window.  One complication is that the user may
 > have changed the window configuration since the act of displaying that
 > buffer, and it would be undesirable to undo the user's explicitly
 > requested changes.
 >
 > To enable @code{quit-window} to do the right thing,
 > @code{display-buffer} saves information about what it did in the
 > window's @code{quit-restore} parameter (@pxref{Window Parameters}).
 > @c ??? Should quit-restore be in some index?

It is in windows.texi as

@vindex quit-restore@r{, a window parameter}

 > @deffn Command quit-window &optional kill window
 > This command quits @var{window} and buries its buffer.  The argument
 > @var{window} must be a live window and defaults to the selected one.
 > With prefix argument @var{kill} non-@code{nil}, it kills the buffer
 > instead of burying it.
 >
 > @c ??? Does quit-restore-window call this hook?

No.  We had some disagreement with Lars about this at the time he added
that hook.  I think that adding 'quit-window-hook' was a bad idea.

 > @vindex quit-window-hook
 > The function @code{quit-window} first runs @code{quit-window-hook}.
 > Then it calls the function @code{quit-restore-window} described next,
 > which does the hard work.
 > @end deffn
 >
 > You can get more control by calling @code{quit-restore-window} instead.

Note that you have to finish the description of 'quit-window' before
describing 'quit-restore-window'.  The arguments you describe below
(like 'bury-or-kill') belong to 'quit-window'.

 > @defun quit-restore-window &optional window bury-or-kill
 > This function handles @var{window} and its buffer after quitting.  The
 > optional argument @var{window} must be a live window and defaults to
 > the selected one.  The function taks account of the @var{window}'s

... takes ...

 > @code{quit-restore} parameter.
 >
 > The optional argument @var{bury-or-kill} specifies how to deal with
 > @var{window}'s buffer.  The following values are meaningful:
 >
 > @table @code
 > @item nil
 > This means to not deal with the buffer in any particular way.  As a
 > consequence, if @var{window} is not deleted, invoking
 > @code{switch-to-prev-buffer} will usually show the buffer again.
 >
 > @item append
 > This means that if @var{window} is not deleted, its buffer is moved to
 > the end of @var{window}'s list of previous buffers, so it's less likely
 > that future invocations of @code{switch-to-prev-buffer} will switch to
 > it.  Also, it moves the buffer to the end of the frame's buffer list.
 >
 > @item bury
 > This means that if @var{window} is not deleted, its buffer is removed
 > from @var{window}'s list of previous buffers.  Also, it moves the
 > buffer to the end of the frame's buffer list.  This is the most
 > reliable way to prevent @code{switch-to-prev-buffer} from switching to
 > this buffer buffer again, short of killing the buffer.

... buffer buffer ...

 >
 > @item kill
 > This means to kill @var{window}'s buffer.
 > @end table
 >
 > The argument @var{bury-or-kill} also specifies what to do with
 > @var{window}'s frame when @var{window} should be deleted, if it is the
 > only window on its frame, and there are other frames on that frame's
 > terminal.  If @var{bury-or-kill} equals @code{kill}, it means to
 > delete the frame.  Otherwise, the fate of the frame is determined by
 > calling @code{frame-auto-hide-function} (see below) with that frame as
 > sole argument.
 >
 > This function always sets @var{window}'s @code{quit-restore} parameter
 > to @code{nil} unless it deletes the window.
 > @end defun
 >
 > The window @var{window}'s @code{quit-restore} parameter (@pxref{Window
 > Parameters}) should be @code{nil} or a list of four elements:
 > @c ??? What does quit-restore-window do if this is nil?  Nothing?

No.  For example, a dedicated window is deleted without consulting the
'quit-restore' parameter in the first place.  Handling dedicated windows
was always a mystery for me, so the prior description might be far from
accurate.  One idea of the 'quit-restore' parameter was to get rid of
dedicated windows but that was an obstacle I never succeeded to handle.

 > @lisp
 > (@var{method} @var{obuffer} @var{owindow} @var{thisbuffer})
 > @end lisp
 >
 > The first element, @var{method}, is one of the four symbols
 > @code{window}, @code{frame}, @code{same} and @code{other}.
 > @code{frame} and @code{window} control how to delete @var{window},
 > while @code{same} and @code{other} control displaying some other
 > buffer in it.
 >
 > Specifically, @code{window} means that the window has been specially
 > created by @code{display-buffer}; @code{frame} means that a separate
 > frame has been created; @code{same}, that the window has only ever
 > displayed this buffer; @code{other}, that the window showed another
 > buffer before.
 >
 > The second element, @var{obuffer}, is either one of the symbols
 > @code{window} or @code{frame}, or a list of the form
 >
 > @lisp
 > (@var{prev-buffer} @var{prev-window-start} @var{prev-window-point} @var{height})
 > @end lisp
 >
 > @noindent
 > which says which buffer was shown in @var{window} before, that
 > buffer's window start and window point positions at that time, and
 > @var{window}'s height at that time.  If @var{prev-buffer} is still
 > live when quitting @var{window}, quitting the window may reuse
 > @var{window} to display @var{prev-buffer}.
 >
 > The third element, @var{owindow}, is the window that was selected
 > just before the displaying was done.  If quitting deletes
 > @var{window}, it tries to select @var{owindow}.
 >
 > The fourth element, @var{this-buffer}, the buffer whose displaying set

.. is the buffer ...

 > the @code{quit-restore} parameter.  Quitting @var{window} may delete
 > that window only if it still shows that buffer.
 >
 > Quitting @var{window} tries to delete it if and only if (1)
 > @var{method} is either @code{window} or @code{frame}, (2) the window
 > has no history of previously-displayed buffers and (3)
 > @var{this-buffer} equals the buffer currently displayed in
 > @var{window}.  If @var{window} is part of an atomic window
 > (@pxref{Atomic Windows}), quitting will try to delete the root of that
 > atomic window instead.  In either case, it tries to avoid signaling an
 > error when @var{window} cannot be deleted.
 >
 > If @var{obuffer} is a list, and @var{prev-buffer} is still live,
 > quitting displays @var{prev-buffer} in @var{window} according to the
 > rest of the elements of @var{obuffer}.  This includes resizing the
 > window to @var{height} if it was temporarily resized to display
 > @var{thisbuffer}.

... this-buffer ...

 > @c ??? Is this controlled by @var{method} ?

Only in the sense that "method" did not provide anything useful.

 > Otherwise, if @var{window} was previously used for displaying other
 > buffers (@pxref{Window History}), the most recent buffer in that
 > history will be displayed.
 >
 > @ignore
 > This fails to follow the manual's style conventions.
 > If we document display-buffer-record-window, it should be with @defun.
 > And maybe not here.

Probably.  Maybe Eric finds a solution.

 > Typically, the display routines run by @code{display-buffer} will set
 > the @code{quit-restore} window parameter correctly.  You can also set
 > it manually, using the following code for displaying @var{buffer} in
 > @var{window}:
 >
 > @example
 > @group
 > (display-buffer-record-window type window buffer)
 >
 > (set-window-buffer window buffer)
 >
 > (set-window-prev-buffers window nil)
 > @end group
 > @end example
 >
 > Setting the window history to @code{nil} ensures that a future call to
 > @code{quit-window} can delete the window altogether.
 > @end ignore
 >
 >
 > @c ??? Is this fully correct?

I think that saying "to do the right thing" is a way to work around
answering that question.  For me 'frame-auto-hide-function' was a
misguided attempt to work around a request by Drew to not iconify a
frame after quitting its only window (IIRC).  Since it deals with
dedicated windows I cannot say much about it.

 > The following option specifies a function to do the right thing with a
 > frame containing one window when quitting that window.
 >
 > @defopt frame-auto-hide-function
 > The function specified by this option is called to automatically hide
 > frames.  This function is called with one argument---a frame.
 >
 > The function specified here is called by @code{bury-buffer}
 > (@pxref{Buffer List}) when the selected window is dedicated and shows
 > the buffer to bury.  It is also called by @code{quit-restore-window}
 > (see above) when the frame of the window to quit has been specially
 > created for displaying that window's buffer and the buffer is not
 > killed.
 >
 > The default is to call @code{iconify-frame} (@pxref{Visibility of
 > Frames}).  Alternatively, you may specify either @code{delete-frame}
 > (@pxref{Deleting Frames}) to remove the frame from its display,
 > @code{make-frame-invisible} to make the frame invisible, @code{ignore}
 > to leave the frame unchanged, or any other function that can take a
 > frame as its sole argument.
 >
 > Note that the function specified by this option is called only if the
 > specified frame contains just one live window and there is at least one
 > other frame on the same terminal.
 >
 > For a particular frame, the value specified here may be overridden by
 > that frame's @code{auto-hide-function} frame parameter (@pxref{Frame
 > Interaction Parameters}).
 > @end defopt

martin