unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Documenting buffer display
@ 2018-10-20 12:20 martin rudalics
  2018-10-20 13:21 ` Eli Zaretskii
                   ` (2 more replies)
  0 siblings, 3 replies; 32+ messages in thread
From: martin rudalics @ 2018-10-20 12:20 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 207 bytes --]

Attached find a rewrite of the documentation of buffer display
functions to be applied against the release branch.

Work in progress.  Proofreading and suggestions welcome.

Thanks for the attention, martin

[-- Attachment #2: display-buffer.texi --]
[-- Type: text/plain, Size: 77789 bytes --]

diff --git a/doc/emacs/windows.texi b/doc/emacs/windows.texi
index 7dbd680..7ad9a77 100644
--- a/doc/emacs/windows.texi
+++ b/doc/emacs/windows.texi
@@ -48,8 +48,8 @@ Basic Window
 @kbd{C-x 4 b} that select a different window and switch buffers in it.
 Also, all commands that display information in a window, including
 (for example) @kbd{C-h f} (@code{describe-function}) and @kbd{C-x C-b}
-(@code{list-buffers}), work by switching buffers in a nonselected
-window without affecting the selected window.
+(@code{list-buffers}), usually work by displaying buffers in a
+nonselected window without affecting the selected window.

   When multiple windows show the same buffer, they can have different
 regions, because they can have different values of point.  However,
@@ -340,11 +340,9 @@ Displaying Buffers
 in response to a user command.  There are several different ways in
 which commands do this.

-  Many commands, like @kbd{C-x C-f} (@code{find-file}), display the
-buffer by ``taking over'' the selected window, expecting that the
-user's attention will be diverted to that buffer.  These commands
-usually work by calling @code{switch-to-buffer} internally
-(@pxref{Select Buffer}).
+  Many commands, like @kbd{C-x C-f} (@code{find-file}), by default
+display the buffer by ``taking over'' the selected window, expecting
+that the user's attention will be diverted to that buffer.

   Some commands try to display intelligently, trying not to take
 over the selected window, e.g., by splitting off a new window and
@@ -367,10 +365,9 @@ Displaying Buffers

   Commands with names ending in @code{-other-frame} behave like
 @code{display-buffer}, except that they (i) never display in the
-selected window and (ii) prefer to create a new frame to display the
-desired buffer instead of splitting a window---as though the variable
-@code{pop-up-frames} is set to @code{t} (@pxref{Window Choice}).
-Several of these commands are bound in the @kbd{C-x 5} prefix key.
+selected window and (ii) prefer to either create a new frame or use a
+window on some other frame to display the desired buffer.  Several of
+these commands are bound in the @kbd{C-x 5} prefix key.

 @menu
 * Window Choice::   How @code{display-buffer} works.
@@ -388,28 +385,56 @@ Window Choice
 sequence of steps.

 @itemize
-@vindex same-window-buffer-names
-@vindex same-window-regexps
 @item
 First, check if the buffer should be displayed in the selected window
 regardless of other considerations.  You can tell Emacs to do this by
-adding the desired buffer's name to the list
-@code{same-window-buffer-names}, or adding a matching regular
-expression to the list @code{same-window-regexps}.  By default, these
-variables are @code{nil}, so this step is skipped.
+adding a regular expression matching the buffer's name together with a
+reference to the @code{display-buffer-same-window} action function
+(@pxref{Action Functions,,Action Functions for Buffer Display, elisp,
+The Emacs Lisp Reference Manual}) to the option
+@code{display-buffer-alist} (@pxref{Choosing Window,,Choosing a Window
+for Display, elisp, The Emacs Lisp Reference Manual}).  For example,
+to display the buffer @file{*scratch*} preferably in the selected
+window write:
+
+@example
+@group
+(customize-set-variable
+ 'display-buffer-alist
+ '("\\*scratch\\*" (display-buffer-same-window)))
+@end group
+@end example
+
+By default, @code{display-buffer-alist} is @code{nil}, so this step is
+skipped.

 @item
 Otherwise, if the buffer is already displayed in an existing window,
-reuse that window.  Normally, only windows on the selected frame
-are considered, but windows on other frames are also reusable if you
-change @code{pop-up-frames} (see below) to @code{t}.
+reuse that window.  Normally, only windows on the selected frame are
+considered, but windows on other frames are also reusable if a
+corresponding @code{reusable-frames} action alist entry (@pxref{Action
+Alists,,Action Alists for Buffer Display, elisp, The Emacs Lisp
+Reference Manual}) is used (see the next step for an example of how to
+do that).

-@vindex pop-up-frames
 @item
 Otherwise, optionally create a new frame and display the buffer there.
-By default, this step is skipped.  To enable it, change the variable
-@code{pop-up-frames} to a non-@code{nil} value.  The special value
-@code{graphic-only} means to do this only on graphical displays.
+By default, this step is skipped.  To enable it, change the value of
+the option @code{display-buffer-base-action} (@pxref{Choosing
+Window,,Choosing a Window for Display, elisp, The Emacs Lisp Reference
+Manual}) as follows:
+
+@example
+@group
+(customize-set-variable
+ 'display-buffer-base-action
+ '((display-buffer-reuse-window display-buffer-pop-up-frame)
+   (reusable-frames . 0)))
+@end group
+@end example
+
+This customization will also try to make the preceding step search for
+a reusable window on all visible of iconified frames

 @item
 Otherwise, try to create a new window by splitting a window on the
@@ -429,9 +454,9 @@ Window Choice

 @item
 Otherwise, display the buffer in a window previously showing it.
-Normally, only windows on the selected frame are considered, but if
-@code{pop-up-frames} is non-@code{nil} the window may be also on another
-frame.
+Normally, only windows on the selected frame are considered, but with
+a suitable @code{reusable-frames} action alist entry (see above) the
+window may be also on another frame.

 @item
 Otherwise, display the buffer in an existing window on the selected
@@ -442,14 +467,9 @@ Window Choice
 and display the buffer there.
 @end itemize

-A more advanced and flexible way to customize the behavior of
-@code{display-buffer} is by using the option @code{display-buffer-alist}
-mentioned in the next section.
-

 @node Temporary Displays
 @subsection Displaying non-editable buffers.
-@cindex pop-up windows
 @cindex temporary windows

 Some buffers are shown in windows for perusal rather than for editing.
@@ -459,24 +479,23 @@ Temporary Displays
 displayed only for a short period of time.

   Normally, Emacs chooses the window for such temporary displays via
-@code{display-buffer} as described above.  The @file{*Completions*}
-buffer, on the other hand, is normally displayed in a window at the
-bottom of the selected frame, regardless of the number of windows
-already shown on that frame.
+@code{display-buffer} as described in the previous subsection.  The
+@file{*Completions*} buffer, on the other hand, is normally displayed
+in a window at the bottom of the selected frame, regardless of the
+number of windows already shown on that frame.

   If you prefer Emacs to display a temporary buffer in a different
 fashion, we recommend customizing the variable
 @code{display-buffer-alist} (@pxref{Choosing Window,,Choosing a Window
 for Display, elisp, The Emacs Lisp Reference Manual}).  For example,
-to display @file{*Completions*} by splitting a window as described in
-the previous section, use the following form in your initialization
-file (@pxref{Init File}):
+to display @file{*Completions*} always below the selected window, use
+the following form in your initialization file (@pxref{Init File}):

 @example
 @group
 (customize-set-variable
  'display-buffer-alist
- '(("\\*Completions\\*" display-buffer-pop-up-window)))
+ '(("\\*Completions\\*" display-buffer-below-selected)))
 @end group
 @end example

diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi
index 6c3182b..e0939e5 100644
--- a/doc/lispref/elisp.texi
+++ b/doc/lispref/elisp.texi
@@ -1043,9 +1043,7 @@ Top
 * Cyclic Window Ordering::  Moving around the existing windows.
 * Buffers and Windows::     Each window displays the contents of a buffer.
 * Switching Buffers::       Higher-level functions for switching to a buffer.
-* Choosing Window::         How to choose a window for displaying a buffer.
-* Display Action Functions:: Subroutines for @code{display-buffer}.
-* Choosing Window Options:: Extra options affecting how buffers are displayed.
+* Displaying Buffers::      Displaying a buffer in a suitable window.
 * Window History::          Each window remembers the buffers displayed in it.
 * Dedicated Windows::       How to avoid displaying another buffer in
                               a specific window.
@@ -1067,6 +1065,18 @@ Top
                               redisplay going past a certain point,
                               or window configuration changes.

+Displaying Buffers
+
+* Choosing Window::         How to choose a window for displaying a buffer.
+* Action Functions::        Support functions for buffer display.
+* Action Alists::           Alists for fine-tuning buffer display
+                              action functions.
+* Choosing Window Options:: Extra options affecting how buffers are displayed.
+* Precedence of Action Functions:: A tutorial explaining the precedence of
+                              buffer display action functions.
+* The Zen of Buffer Display:: How to avoid that buffers get lost in between
+                              windows.
+
 Side Windows

 * Displaying Buffers in Side Windows:: An action function for displaying
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index 1e008da..31fb7ce 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -3198,11 +3198,10 @@ Child Frames
 @code{drag-with-mode-line} parameter.

   When a child frame is used for displaying a buffer via
-@code{display-buffer-in-child-frame} (@pxref{Display Action Functions}),
-the frame's @code{auto-hide-function} parameter (@pxref{Frame
-Interaction Parameters}) can be set to a function, in order to
-appropriately deal with the frame when the window displaying the buffer
-shall be quit.
+@code{display-buffer-in-child-frame} (@pxref{Action Functions}), the
+frame's @code{auto-hide-function} parameter (@pxref{Frame Interaction
+Parameters}) can be set to a function, in order to appropriately deal
+with the frame when the window displaying the buffer shall be quit.

   When a child frame is used during minibuffer interaction, for example,
 to display completions in a separate window, the @code{minibuffer-exit}
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 2650671..c14c441 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -25,9 +25,7 @@ Windows
 * Cyclic Window Ordering::  Moving around the existing windows.
 * Buffers and Windows::     Each window displays the contents of a buffer.
 * Switching Buffers::       Higher-level functions for switching to a buffer.
-* Choosing Window::         How to choose a window for displaying a buffer.
-* Display Action Functions:: Subroutines for @code{display-buffer}.
-* Choosing Window Options:: Extra options affecting how buffers are displayed.
+* Displaying Buffers::      Displaying a buffer in a suitable window.
 * Window History::          Each window remembers the buffers displayed in it.
 * Dedicated Windows::       How to avoid displaying another buffer in
                               a specific window.
@@ -162,6 +160,7 @@ Basic Windows
 in the group).
 @end defun

+
 @node Windows and Frames
 @section Windows and Frames

@@ -1542,11 +1541,11 @@ Recombining Windows
 window is created anyway).

 @item window-size
-This means that @code{display-buffer} makes a new parent window when it
-splits a window and is passed a @code{window-height} or
-@code{window-width} entry in the @var{alist} argument (@pxref{Display
-Action Functions}).  Otherwise, window splitting behaves as for a value
-of @code{nil}.
+This means that @code{display-buffer} makes a new parent window when
+it splits a window and is passed a @code{window-height} or
+@code{window-width} entry in the @var{alist} argument (@pxref{Action
+Functions}).  Otherwise, window splitting behaves as for a value of
+@code{nil}.

 @item temp-buffer-resize
 In this case @code{with-temp-buffer-window} makes a new parent window
@@ -1879,7 +1878,7 @@ Cyclic Window Ordering
 @cindex ordering of windows, cyclic
 @cindex window ordering, cyclic

-  When you use the command @kbd{C-x o} (@code{other-window}) to select
+  When you use the command @w{@kbd{C-x o}} (@code{other-window}) to select
 some other window, it moves through live windows in a specific order.
 For any given configuration of windows, this order never varies.  It
 is called the @dfn{cyclic ordering of windows}.
@@ -1899,7 +1898,7 @@ Cyclic Window Ordering
 The optional argument @var{minibuf} specifies whether minibuffer windows
 should be included in the cyclic ordering.  Normally, when @var{minibuf}
 is @code{nil}, a minibuffer window is included only if it is currently
-active; this matches the behavior of @kbd{C-x o}.  (Note that a
+active; this matches the behavior of @w{@kbd{C-x o}}.  (Note that a
 minibuffer window is active as long as its minibuffer is in use; see
 @ref{Minibuffers}).

@@ -2327,10 +2326,39 @@ Switching Buffers
 @end deffn


+@node Displaying Buffers
+@section Displaying a Buffer in a Suitable Window
+
+In this section we describe how Emacs finds or creates a window
+suitable for displaying a buffer.  We first introduce the function
+@code{display-buffer}---the workhorse for choosing such a window.
+Next, action functions---auxiliary functions called by
+@code{display-buffer} to find or create a suitable window---are
+presented.  Then we describe action alists---special association lists
+used to fine-tune the behavior of action functions.
+
+   We continue with the description of additional options to customize
+the behavior of @code{display-buffer}.  Then a series of examples will
+try to explain the precedence among action functions in a single call
+of @code{display-buffer}.  We conclude this section with some
+guidelines for managing the complexity of buffer display.
+
+@menu
+* Choosing Window::         How to choose a window for displaying a buffer.
+* Action Functions::        Support functions for buffer display.
+* Action Alists::           Alists for fine-tuning buffer display.
+* Choosing Window Options:: Extra options affecting how buffers are displayed.
+* Precedence of Action Functions:: Examples to explain the precedence of
+                              action functions.
+* The Zen of Buffer Display:: How to avoid that buffers get lost in between
+                              windows.
+@end menu
+
+
 @node Choosing Window
-@section Choosing a Window for Display
+@subsection Choosing a Window for Displaying a Buffer

-  The command @code{display-buffer} flexibly chooses a window for
+The command @code{display-buffer} flexibly chooses a window for
 display, and displays a specified buffer in that window.  It can be
 called interactively, via the key binding @kbd{C-x 4 C-o}.  It is also
 used as a subroutine by many functions and commands, including
@@ -2351,8 +2379,9 @@ Choosing Window
 an action alist.  It attempts to display the buffer in some window,
 picking or creating a window according to its own criteria.  If
 successful, it returns the window; otherwise, it returns @code{nil}.
-@xref{Display Action Functions}, for a list of predefined action
-functions.
+@xref{Action Functions}, for a list of predefined action functions.
+@xref{Action Alists}, for a list of action alist entries recognized by
+these functions.

   @code{display-buffer} works by combining display actions from
 several sources, and calling the action functions in turn, until one
@@ -2364,11 +2393,13 @@ Choosing Window
 selecting the window or making the buffer current.  The argument
 @var{buffer-or-name} must be a buffer or the name of an existing
 buffer.  The return value is the window chosen to display the buffer.
+It is @code{nil} if no suitable window was found.

 The optional argument @var{action}, if non-@code{nil}, should normally
 be a display action (described above).  @code{display-buffer} builds a
 list of action functions and an action alist, by consolidating display
-actions from the following sources (in order):
+actions from the following sources (in order of their precedence,
+highest ranking first):

 @itemize
 @item
@@ -2388,12 +2419,35 @@ Choosing Window
 @end itemize

 @noindent
-Each action function is called in turn, passing the buffer as the
-first argument and the combined action alist as the second argument,
-until one of the functions returns non-@code{nil}.  The caller can
-pass @code{(allow-no-window . t)} as an element of the action alist to
-indicate its readiness to handle the case of not displaying the
-buffer in a window.
+In practice this means that @code{display-buffer} builds a list of all
+action functions specified by these display actions.  The first
+element of this list is the first action function specified by
+@code{display-buffer-overriding-action}, if any.  The last element of
+this list is @code{display-buffer-pop-up-frame}---the last action
+function specified by @code{display-buffer-fallback-action}.
+Duplicates are not removed from this list---hence the same action
+function may be called multiple times during one call of
+@code{display-buffer}.
+
+@code{display-buffer} calls the action functions specified by this
+list in turn, passing the buffer as the first argument and the
+combined action alist as the second argument, until one of the
+functions returns non-@code{nil}.
+
+Note that the second argument is always the list of @emph{all} action
+alist entries specified by the sources named above.  Hence, the first
+element of this list is the first action alist entry specified by
+@code{display-buffer-overriding-action}, if any.  The last element of
+this list is the last alist entry specified by
+@code{display-buffer-base-action}, if any (the action alist specified
+by @code{display-buffer-fallback-action} is empty).
+
+Note also, that the combined action alist may contain duplicate
+entries and entries for the same key with different values.  As a
+rule, action functions always use the first association for each key
+so users may not expect that the association found by the action
+function is the one provided by the same display action,
+see @ref{Precedence of Action Functions} for an example.

 The argument @var{action} can also have a non-@code{nil}, non-list
 value.  This has the special meaning that the buffer should be
@@ -2404,8 +2458,8 @@ Choosing Window
 The optional argument @var{frame}, if non-@code{nil}, specifies which
 frames to check when deciding whether the buffer is already displayed.
 It is equivalent to adding an element @code{(reusable-frames
-. @var{frame})} to the action alist of @var{action}.  @xref{Display
-Action Functions}.
+. @var{frame})} to the action alist of @var{action} (@pxref{Action
+Alists}).
 @end deffn

 @defvar display-buffer-overriding-action
@@ -2437,13 +2491,16 @@ Choosing Window
 @end defvr


-@node Display Action Functions
-@section Action Functions for @code{display-buffer}
+@node Action Functions
+@subsection Action Functions for Buffer Display

 The following basic action functions are defined in Emacs.  Each of
 these functions takes two arguments: @var{buffer}, the buffer to
-display, and @var{alist}, an action alist.  Each action function
-returns the window if it succeeds, and @code{nil} if it fails.
+display, and @var{alist}, an action alist.  As a rule, each action
+function is supposed to return a window displaying @var{buffer} if it
+succeeds and @code{nil} if it fails (for the sole exception to this
+rule see the last function listed
+below---@code{display-buffer-no-window}).

 @defun display-buffer-same-window buffer alist
 This function tries to display @var{buffer} in the selected window.
@@ -2453,57 +2510,103 @@ Display Action Functions
 @end defun

 @defun display-buffer-reuse-window buffer alist
-This function tries to display @var{buffer} by finding a window
-that is already displaying it.
+This function tries to display @var{buffer} by finding a window that
+is already displaying it.

 If @var{alist} has a non-@code{nil} @code{inhibit-same-window} entry,
-the selected window is not eligible for reuse.  If @var{alist}
-contains a @code{reusable-frames} entry, its value determines which
-frames to search for a reusable window:
-
-@itemize @bullet
-@item
-@code{nil} means consider windows on the selected frame.
-(Actually, the last non-minibuffer frame.)
-@item
-@code{t} means consider windows on all frames.
-@item
-@code{visible} means consider windows on all visible frames.
-@item
-0 means consider windows on all visible or iconified frames.
-@item
-A frame means consider windows on that frame only.
-@end itemize
-
-Note that these meanings differ slightly from those of the
-@var{all-frames} argument to @code{next-window} (@pxref{Cyclic Window
-Ordering}).
-
-If @var{alist} contains no @code{reusable-frames} entry, this function
-normally searches just the selected frame; however, if the variable
-@code{pop-up-frames} is non-@code{nil}, it searches all frames on the
-current terminal.  @xref{Choosing Window Options}.
+the selected window is not eligible for reuse.  The set of frames to
+search for a window already displaying @var{buffer} can be specified
+with the help of a @code{reusable-frames} action alist entry
+(@pxref{Action Alists}).  If @var{alist} contains no
+@code{reusable-frames} entry, this function searches just the selected
+frame.

-If this function chooses a window on another frame, it makes that frame
-visible and, unless @var{alist} contains an @code{inhibit-switch-frame}
-entry (@pxref{Choosing Window Options}), raises that frame if necessary.
+If this function chooses a window on another frame, it makes that
+frame visible and, unless @var{alist} contains an
+@code{inhibit-switch-frame} entry (@pxref{Action Alists}), raises that
+frame if necessary.
 @end defun

 @defun display-buffer-reuse-mode-window buffer alist
 This function tries to display @var{buffer} by finding a window
 that is displaying a buffer in a given mode.

-If @var{alist} contains a @code{mode} entry, its value is a major mode
-(a symbol) or a list of major modes.  If @var{alist} contains no
-@code{mode} entry, the current major mode of @var{buffer} is used.  A
-window is a candidate if it displays a buffer that derives from one of
-the given modes.
+If @var{alist} contains a @code{mode} entry, its value specifes a
+major mode (a symbol) or a list of major modes.  If @var{alist}
+contains no @code{mode} entry, the current major mode of @var{buffer}
+is used instead.  A window is a candidate if it displays a buffer
+whose mode derives from one of the modes specified thusly.

-The behavior is also controlled by entries for
+The behavior is also controlled by alist entries for
 @code{inhibit-same-window}, @code{reusable-frames} and
-@code{inhibit-switch-frame} as is done in the function
-@code{display-buffer-reuse-window}.
+@code{inhibit-switch-frame} (@pxref{Action Alists}) as is done in the
+function @code{display-buffer-reuse-window}.
+@end defun

+@defun display-buffer-pop-up-window buffer alist
+This function tries to display @var{buffer} by splitting the largest
+or least recently-used window (typically one on the selected frame).
+It actually performs the split by calling the function specified by
+@code{split-window-preferred-function} (@pxref{Choosing Window
+Options}).
+
+The size of the new window can be adjusted by supplying
+@code{window-height} and @code{window-width} entries in @var{alist}
+(@pxref{Action Alists}).  If @var{alist} contains a
+@code{preserve-size} entry (@pxref{Action Alists}), Emacs will try to
+preserve the size of the new window during future resize operations
+(@pxref{Preserving Window Sizes}).
+
+This function fails if no window can be split.  More often than not
+this happens because no window is large enough to allow splitting.
+Setting @code{split-height-threshold} or @code{split-width-threshold}
+(@pxref{Choosing Window Options}) to a lower value may help in this
+regard.  It also happens when the selected frame has an
+@code{unsplittable} frame parameter; @pxref{Buffer Parameters}.
+@end defun
+
+@defun display-buffer-in-previous-window buffer alist
+This function tries to display @var{buffer} in a window previously
+showing it.  If @var{alist} has a non-@code{nil}
+@code{inhibit-same-window} entry, the selected window is not eligible
+for reuse.  If @var{alist} contains a @code{reusable-frames} entry,
+its value determines which frames to search for a suitable window
+(@pxref{Action Alists}).
+
+If @var{alist} has a @code{previous-window} entry and the window
+specified by that entry is live and not dedicated to another buffer,
+that window will be preferred, even if it never showed @var{buffer}
+before.
+@end defun
+
+@defun display-buffer-use-some-window buffer alist
+This function tries to display @var{buffer} by choosing an existing
+window and displaying the buffer in that window.  It can fail if all
+windows are dedicated to another buffer (@pxref{Dedicated Windows}).
+@end defun
+
+@defun display-buffer-below-selected buffer alist
+This function tries to display @var{buffer} in a window below the
+selected window.  If there is a window below the selected one and that
+window already displays @var{buffer}, it reuses that window.
+
+If there is no such window, this function tries to create a new window
+by splitting the selected one and display @var{buffer} there.  It will
+also adjust that window's size provided @var{alist} contains a suitable
+@code{window-height} or @code{window-width} entry, see above.
+
+If splitting the selected window fails and there is a non-dedicated
+window below the selected one showing some other buffer, it uses that
+window for showing @var{buffer}.
+@end defun
+
+@defun display-buffer-at-bottom buffer alist
+This function tries to display @var{buffer} in a window at the bottom
+of the selected frame.
+
+This either splits the window at the bottom of the frame or the
+frame's root window, or reuses an existing window at the bottom of the
+selected frame.
 @end defun

 @defun display-buffer-pop-up-frame buffer alist
@@ -2537,11 +2640,12 @@ Display Action Functions
 @defun display-buffer-use-some-frame buffer alist
 This function tries to display @var{buffer} by trying to find a
 frame that meets a predicate (by default any frame other than the
-current frame).
+selected frame).

-If this function chooses a window on another frame, it makes that frame
-visible and, unless @var{alist} contains an @code{inhibit-switch-frame}
-entry (@pxref{Choosing Window Options}), raises that frame if necessary.
+If this function chooses a window on another frame, it makes that
+frame visible and, unless @var{alist} contains an
+@code{inhibit-switch-frame} entry (@pxref{Action Alists}), raises that
+frame if necessary.

 If @var{alist} has a non-@code{nil} @code{frame-predicate} entry, its
 value is a function taking one argument (a frame), returning
@@ -2549,207 +2653,220 @@ Display Action Functions
 default predicate.

 If @var{alist} has a non-@code{nil} @code{inhibit-same-window} entry,
-the selected window is used; thus if the selected frame has a single
-window, it is not used.
+the selected window is not used; thus if the selected frame has a
+single window, it is not used.
 @end defun

-@defun display-buffer-pop-up-window buffer alist
-This function tries to display @var{buffer} by splitting the largest
-or least recently-used window (typically one on the selected frame).
-It actually performs the split by calling the function specified in
-@code{split-window-preferred-function} (@pxref{Choosing Window
-Options}).
+@defun display-buffer-no-window buffer alist
+If @var{alist} has a non-@code{nil} @code{allow-no-window} entry, then
+this function does not display @code{buffer} and returns the symbol
+@code{fail}.  This will skip the excution of any further display
+actions and cause @code{display-buffer} to return @code{nil}.

-The size of the new window can be adjusted by supplying
-@code{window-height} and @code{window-width} entries in @var{alist}.  To
-adjust the window's height, use an entry whose @sc{car} is
-@code{window-height} and whose @sc{cdr} is one of:
+   It is assumed that when a call of @code{display-buffer} specifies a
+non-@code{nil} @code{allow-no-window} entry, the caller can handle a
+@code{nil} return value.
+@end defun
+
+If the @var{alist} argument of any of these functions contains a
+@code{window-parameters} entry, @code{display-buffer} assigns the
+elements of the associated value as window parameters of the chosen
+window.
+
+
+@node Action Alists
+@subsection Action Alists for Buffer Display
+
+An action alist (@pxref{Choosing Window}) is an association list
+mapping predefined symbols recognized by action functions to values
+these functions are supposed to interpret accordingly.  In each call,
+@code{display-buffer} builds a new, possibly empty, action alist and
+passes that entire list on to the action functions it calls.
+
+   By design, action functions are free in their interpretation of
+action alist entries.  In fact, some entries like
+@code{allow-no-window} or @code{previous-window} have a meaning only
+for one or a few action functions and are ignored by the rest.  Other
+entries, like @code{inhibit-same-window} or @code{window-parameters},
+are supposed to be respected by most action functions including those
+provided by application programs and external packages.
+
+   In the previous subsection we have described in detail how
+individual action functions interpret the action alist entries they
+care about.  Here we give a reference list of all known action alist
+entries according to their symbols, together with their values and
+action functions that recognize them.  Throughout this list, the terms
+``buffer'' will refer to the buffer @code{display-buffer} is supposed
+to display and ``value'' to the entry's value.
+
+@table @code
+@item allow-no-window
+If the value is non-@code{nil}, @code{display-buffer} does not
+necessarily have to display the buffer and the caller is prepared to
+accept that.  This entry is not intended for user customizations since
+there is no guarantee that an arbitrary caller of
+@code{display-buffer} will be able to handle the case that no window
+will display the buffer.  @code{display-buffer-no-window} is the only
+action function that cares about this entry.
+
+@item inhibit-same-window
+If the value is non-@code{nil}, this signals that the selected window
+must not be used for displaying the buffer.  All action functions that
+(re-)use an existing window respect this entry.
+
+@item previous-window
+The value must specify a window that may have displayed the buffer
+previously.  @code{display-buffer-in-previous-window} will give
+preference to such a window provided it is still live and not
+dedicated to another buffer.
+
+@item mode
+The value is either a major mode or a list of major modes.
+@code{display-buffer-reuse-mode-window} may reuse a window whenever
+the value specified by this entry matches the major mode of that
+window's buffer.  Other action functions ignore such entries.
+
+@item frame-predicate
+The value must be a function taking one argument (a frame), supposed
+to return non-@code{nil} if that frame is a candidate for displaying
+the buffer.  This entry is used by
+@code{display-buffer-use-some-frame}.
+
+@item pop-up-frame-parameters
+The value specifies an alist of frame parameters to give a new frame,
+if one is created.  @code{display-buffer-pop-up-frame} is its one and
+only one addressee.
+
+@item reusable-frames
+The value specifies the frame(s) to search for a window that can be
+reused because it already displays the buffer.  It can be set as
+follows:
+
+@itemize @bullet
+@item
+@code{nil} means consider only windows on the selected frame.
+(Actually, the last frame used that is not a minibuffer-only frame.)
+@item
+@code{t} means consider windows on all frames.
+@item
+@code{visible} means consider windows on all visible frames.
+@item
+0 means consider windows on all visible or iconified frames.
+@item
+A frame means consider windows on that frame only.
+@end itemize
+
+Note that the meaning of @code{nil} differs slightly from that of the
+@var{all-frames} argument to @code{next-window} (@pxref{Cyclic Window
+Ordering}).
+
+A major client of this is @code{display-buffer-reuse-window} but all
+other action functions that try to reuse a window are affected as
+well.
+
+@item inhibit-switch-frame
+A non-@code{nil} value prevents another frame from being raised or
+selected, if the window chosen by @code{display-buffer} is displayed
+there.  Primarily affected by this are
+@code{display-buffer-use-some-frame} and
+@code{display-buffer-reuse-window}.
+@code{display-buffer-pop-up-frame} should be affected as well but
+there is no guarantee that the window manager will not override it.
+
+@item window-parameters
+The value specifies an alist of window parameters to give the chosen
+window.  All action functions that choose a window should process this
+entry.
+
+@item window-height
+The value specifies whether and how to adjust the height of the chosen
+window and can be provided as follows:

 @itemize @bullet
 @item
-@code{nil} means to leave the height of the new window alone.
+@code{nil} means to leave the height of the chosen window alone.

 @item
-A number specifies the desired height of the new window.  An integer
-specifies the number of lines of the window.  A floating-point
+A number specifies the desired height of the chosen window.  An
+integer specifies the number of lines of the window.  A floating-point
 number gives the fraction of the window's height with respect to the
 height of the frame's root window.

 @item
-If the @sc{cdr} specifies a function, that function is called with one
-argument: the new window.  The function is supposed to adjust the
+If the value specifies a function, that function is called with one
+argument---the chosen window.  The function is supposed to adjust the
 height of the window; its return value is ignored.  Suitable functions
 are @code{shrink-window-if-larger-than-buffer} and
 @code{fit-window-to-buffer}, see @ref{Resizing Windows}.
 @end itemize

-To adjust the window's width, use an entry whose @sc{car} is
-@code{window-width} and whose @sc{cdr} is one of:
+All action functions that choose a window should process this entry.
+
+@item window-width
+This entry is similar to the @code{window-height} entry described
+before but can be used to adjust the chosen window's width instead.
+The value can be one of the following:

 @itemize @bullet
 @item
-@code{nil} means to leave the width of the new window alone.
+@code{nil} means to leave the width of the chosen window alone.

 @item
-A number specifies the desired width of the new window.  An integer
+A number specifies the desired width of the chosen window.  An integer
 specifies the number of columns of the window.  A floating-point
 number gives the fraction of the window's width with respect to the
 width of the frame's root window.

 @item
-If the @sc{cdr} specifies a function, that function is called with one
-argument: the new window.  The function is supposed to adjust the width
-of the window; its return value is ignored.
+If the value specifies a function, that function is called with one
+argument---the chosen window.  The function is supposed to adjust the
+width of the window; its return value is ignored.
 @end itemize

-If @var{alist} contains a @code{preserve-size} entry, Emacs will try to
-preserve the size of the new window during future resize operations
-(@pxref{Preserving Window Sizes}).  The @sc{cdr} of that entry must be a
-cons cell whose @sc{car}, if non-@code{nil}, means to preserve the width
-of the window and whose @sc{cdr}, if non-@code{nil}, means to preserve
-the height of the window.
-
-This function can fail if no window splitting can be performed for some
-reason (e.g., if the selected frame has an @code{unsplittable} frame
-parameter; @pxref{Buffer Parameters}).
-@end defun
-
-@defun display-buffer-below-selected buffer alist
-This function tries to display @var{buffer} in a window below the
-selected window.  If there is a window below the selected one and that
-window already displays @var{buffer}, it reuses that window.
-
-If there is no such window, this function tries to create a new window
-by splitting the selected one and display @var{buffer} there.  It will
-also adjust that window's size provided @var{alist} contains a suitable
-@code{window-height} or @code{window-width} entry, see above.
-
-If splitting the selected window fails and there is a non-dedicated
-window below the selected one showing some other buffer, it uses that
-window for showing @var{buffer}.
-@end defun
+All action functions that choose a window should process this entry.

-@defun display-buffer-in-previous-window buffer alist
-This function tries to display @var{buffer} in a window previously
-showing it.  If @var{alist} has a non-@code{nil}
-@code{inhibit-same-window} entry, the selected window is not eligible
-for reuse.  If @var{alist} contains a @code{reusable-frames} entry, its
-value determines which frames to search for a suitable window as with
-@code{display-buffer-reuse-window}.
+@item preserve-size
+If non-@code{nil} such an entry tells Emacs to preserve the size of
+the window chosen (@pxref{Preserving Window Sizes}).  The value should
+be either @code{(t . nil)} to preserve the width of the window,
+@code{(nil . t)} to preserve its height or @code{(t . t)} to preserve
+both, its width and its height.  All action functions that choose a
+window should process this entry.

-If @var{alist} has a @code{previous-window} entry, the window
-specified by that entry will override any other window found by the
-methods above, even if that window never showed @var{buffer} before.
-@end defun
+@item child-frame-parameters
+The value specifies an alist of frame parameters used when the buffer
+is displayed on a child frame.  This entry is used by
+@code{display-buffer-in-child-frame} only.

-@defun display-buffer-at-bottom buffer alist
-This function tries to display @var{buffer} in a window at the bottom
-of the selected frame.
-
-This either splits the window at the bottom of the frame or the
-frame's root window, or reuses an existing window at the bottom of the
-selected frame.
-@end defun
-
-@defun display-buffer-use-some-window buffer alist
-This function tries to display @var{buffer} by choosing an existing
-window and displaying the buffer in that window.  It can fail if all
-windows are dedicated to another buffer (@pxref{Dedicated Windows}).
-@end defun
-
-@defun display-buffer-no-window buffer alist
-If @var{alist} has a non-@code{nil} @code{allow-no-window} entry, then
-this function does not display @code{buffer}.  This allows you to
-override the default action and avoid displaying the buffer.  It is
-assumed that when the caller specifies a non-@code{nil}
-@code{allow-no-window} value it can handle a @code{nil} value returned
-from @code{display-buffer} in this case.
-@end defun
-
-If the @var{alist} argument of any of these functions contains a
-@code{window-parameters} entry, @code{display-buffer} assigns the
-elements of the associated value as window parameters of the chosen
-window.
-
-   To illustrate the use of action functions, consider the following
-example.
-
-@example
-@group
-(display-buffer
- (get-buffer-create "*foo*")
- '((display-buffer-reuse-window
-    display-buffer-pop-up-window
-    display-buffer-pop-up-frame)
-   (reusable-frames . 0)
-   (window-height . 10) (window-width . 40)))
-@end group
-@end example
-
-@noindent
-Evaluating the form above will cause @code{display-buffer} to proceed as
-follows: If a buffer called *foo* already appears on a visible or
-iconified frame, it will reuse its window.  Otherwise, it will try to
-pop up a new window or, if that is impossible, a new frame and show the
-buffer there.  If all these steps fail, it will proceed using whatever
-@code{display-buffer-base-action} and
-@code{display-buffer-fallback-action} prescribe.
-
-   Furthermore, @code{display-buffer} will try to adjust a reused window
-(provided *foo* was put by @code{display-buffer} there before) or a
-popped-up window as follows: If the window is part of a vertical
-combination, it will set its height to ten lines.  Note that if, instead
-of the number 10, we specified the function
-@code{fit-window-to-buffer}, @code{display-buffer} would come up with a
-one-line window to fit the empty buffer.  If the window is part of a
-horizontal combination, it sets its width to 40 columns.  Whether a new
-window is vertically or horizontally combined depends on the shape of
-the window split and the values of
-@code{split-window-preferred-function}, @code{split-height-threshold}
-and @code{split-width-threshold} (@pxref{Choosing Window Options}).
-
-   Now suppose we combine this call with a preexisting setup for
-@code{display-buffer-alist} as follows.
-
-@example
-@group
-(let ((display-buffer-alist
-       (cons
-        '("\\*foo\\*"
-          (display-buffer-reuse-window display-buffer-below-selected)
-          (reusable-frames)
-          (window-height . 5))
-        display-buffer-alist)))
-  (display-buffer
-   (get-buffer-create "*foo*")
-   '((display-buffer-reuse-window
-      display-buffer-pop-up-window
-      display-buffer-pop-up-frame)
-     (reusable-frames . 0)
-     (window-height . 10) (window-width . 40))))
-@end group
-@end example
+@item side
+The value denotes the side of the frame or window where a new window
+displaying the buffer shall be created.  This entry is used by
+@code{display-buffer-in-side-window} to indicate the side of the frame
+where a new side window shall be placed (@pxref{Displaying Buffers in
+Side Windows}).  It is also used by
+@code{display-buffer-in-atom-window} to indicate the side of an
+existing window where the new window shall be located (@pxref{Atomic
+Windows}).

-@noindent
-This form will have @code{display-buffer} first try reusing a window
-that shows *foo* on the selected frame.  If there's no such window, it
-will try to split the selected window or, if that is impossible, use the
-window below the selected window.
+@item slot
+If non-@code{nil}, the value specifies the slot of the side window
+supposed to display the buffer.  This entry is used by
+@code{display-buffer-in-side-window} only (@pxref{Displaying Buffers
+in Side Windows}).

-   If there's no window below the selected one, or the window below the
-selected one is dedicated to its buffer, @code{display-buffer} will
-proceed as described in the previous example.  Note, however, that when
-it tries to adjust the height of any reused or popped-up window, it will
-in any case try to set its number of lines to 5 since that value
-overrides the corresponding specification in the @var{action} argument
-of @code{display-buffer}.
+@item window
+The value specifies a window that is in some way related to the window
+chosen by @code{display-buffer}.  This entry is currently used by
+@code{display-buffer-in-atom-window} to indicate the window on whose
+side the new window shall be created (@pxref{Atomic Windows}).
+@end table


 @node Choosing Window Options
-@section Additional Options for Displaying Buffers
+@subsection Additional Options for Displaying Buffers

-The behavior of the standard display actions of @code{display-buffer}
-(@pxref{Choosing Window}) can be modified by a variety of user
+The behavior of the display actions of @code{display-buffer}
+(@pxref{Choosing Window}) can be modified by the following user
 options.

 @defopt pop-up-windows
@@ -2757,10 +2874,10 @@ Choosing Window Options
 is allowed to split an existing window to make a new window for
 displaying in.  This is the default.

-This variable is provided mainly for backward compatibility.  It is
+This variable is provided for backward compatibility only.  It is
 obeyed by @code{display-buffer} via a special mechanism in
 @code{display-buffer-fallback-action}, which only calls the action
-function @code{display-buffer-pop-up-window} (@pxref{Display Action
+function @code{display-buffer-pop-up-window} (@pxref{Action
 Functions}) when the value is @code{nil}.  It is not consulted by
 @code{display-buffer-pop-up-window} itself, which the user may specify
 directly in @code{display-buffer-alist} etc.
@@ -2770,7 +2887,7 @@ Choosing Window Options
 This variable specifies a function for splitting a window, in order to
 make a new window for displaying a buffer.  It is used by the
 @code{display-buffer-pop-up-window} action function to actually split
-the window (@pxref{Display Action Functions}).
+the window (@pxref{Action Functions}).

 The default value is @code{split-window-sensibly}, which is documented
 below.  The value must be a function that takes one argument, a window,
@@ -2797,19 +2914,19 @@ Choosing Window Options
 @end defun

 @defopt split-height-threshold
-This variable, used by @code{split-window-sensibly}, specifies whether
-to split the window placing the new window below.  If it is an
+This variable specifies whether @code{split-window-sensibly} is
+allowed to split the window placing the new window below.  If it is an
 integer, that means to split only if the original window has at least
 that many lines.  If it is @code{nil}, that means not to split this
 way.
 @end defopt

 @defopt split-width-threshold
-This variable, used by @code{split-window-sensibly}, specifies whether
-to split the window placing the new window to the right.  If the value
-is an integer, that means to split only if the original window has at
-least that many columns.  If the value is @code{nil}, that means not
-to split this way.
+This variable specifies whether @code{split-window-sensibly} is
+allowed to split the window placing the new window to the right.  If
+the value is an integer, that means to split only if the original
+window has at least that many columns.  If the value is @code{nil},
+that means not to split this way.
 @end defopt

 @defopt even-window-sizes
@@ -2827,30 +2944,11 @@ Choosing Window Options
 of their combination.
 @end defopt

-@defopt pop-up-frames
-If the value of this variable is non-@code{nil}, that means
-@code{display-buffer} may display buffers by making new frames.  The
-default is @code{nil}.
-
-A non-@code{nil} value also means that when @code{display-buffer} is
-looking for a window already displaying @var{buffer-or-name}, it can
-search any visible or iconified frame, not just the selected frame.
-
-This variable is provided mainly for backward compatibility.  It is
-obeyed by @code{display-buffer} via a special mechanism in
-@code{display-buffer-fallback-action}, which calls the action function
-@code{display-buffer-pop-up-frame} (@pxref{Display Action Functions})
-if the value is non-@code{nil}.  (This is done before attempting to
-split a window.)  This variable is not consulted by
-@code{display-buffer-pop-up-frame} itself, which the user may specify
-directly in @code{display-buffer-alist} etc.
-@end defopt
-
 @defopt pop-up-frame-function
 This variable specifies a function for creating a new frame, in order
 to make a new window for displaying a buffer.  It is used by the
-@code{display-buffer-pop-up-frame} action function (@pxref{Display
-Action Functions}).
+@code{display-buffer-pop-up-frame} action function (@pxref{Action
+Functions}).

 The value should be a function that takes no arguments and returns a
 frame, or @code{nil} if no frame could be created.  The default value
@@ -2860,30 +2958,632 @@ Choosing Window Options

 @defopt pop-up-frame-alist
 This variable holds an alist of frame parameters (@pxref{Frame
-Parameters}), which is used by the default function in
+Parameters}), which is used by the function specified by
 @code{pop-up-frame-function} to make a new frame.  The default is
 @code{nil}.
-@end defopt

-@defopt same-window-buffer-names
-A list of buffer names for buffers that should be displayed in the
-selected window.  If a buffer's name is in this list,
-@code{display-buffer} handles the buffer by showing it in the selected
-window.
+This option is provided for backward compatibility only.  Note,
+however that when @code{display-buffer-pop-up-frame} calls the
+function specified by @code{pop-up-frame-function}, it prepends the
+value of all @code{pop-up-frame-parameters} action alist entries to
+@code{pop-up-frame-alist} so that the values specified by the action
+alist entry effectively override the corresponding values of
+@code{pop-up-frame-alist}.
+
+Hence, users should set up a @code{pop-up-frame-parameters} action
+alist entry in @code{display-buffer-alist} instead of customizing
+@code{pop-up-frame-alist}.  Only this will guarantee that the value of
+a parameter specified by the user overrides the value of that
+parameter specified by the caller of @code{display-buffer}.
 @end defopt

-@defopt same-window-regexps
-A list of regular expressions that specify buffers that should be
-displayed in the selected window.  If the buffer's name matches any of
-the regular expressions in this list, @code{display-buffer} handles the
-buffer by showing it in the selected window.
-@end defopt
+   Many efforts in the design of @code{display-buffer} have been given
+to maintain compatibility with code that uses older options like
+@code{pop-up-windows}, @code{pop-up-frames},
+@code{pop-up-frame-alist}, @code{same-window-buffer-names} and
+@code{same-window-regexps}.  Applications and users should refrain
+from using these options in future code.  Above we already warned
+against customizing @code{pop-up-frame-alist}.  Here we describe how
+to convert the remaining options to use display actions instead.
+
+@table @code
+@item pop-up-windows
+This variable is @code{nil} by default.  Instead of customizing it to
+@code{nil} and thus telling @code{display-buffer} what not to do, it's
+much better to list in @code{display-buffer-base-action} the actions
+@code{display-buffer} should do instead as, for example:
+
+@example
+@group
+(customize-set-variable
+ 'display-buffer-base-action
+ '((display-buffer-reuse-window display-buffer-pop-up-frame
+    display-buffer-in-previous-window display-buffer-use-some-window)))
+@end group
+@end example
+
+@item pop-up-frames
+Instead of customizing this variable to @code{t}, customize
+@code{display-buffer-base-action}, for example, as follows:
+
+@example
+@group
+(customize-set-variable
+ 'display-buffer-base-action
+ '((display-buffer-reuse-window display-buffer-pop-up-frame)
+   (reusable-frames . 0)))
+@end group
+@end example
+
+@item same-window-buffer-names
+@itemx same-window-regexps
+Instead of adding a buffer name or a regular expression to one of
+these options use a @code{display-buffer-alist} entry for that buffer
+specifying the action function @code{display-buffer-same-window}.
+@example
+@group
+(customize-set-variable
+ 'display-buffer-alist
+ (cons '("\\*foo\\*" (display-buffer-same-window)) display-buffer-alist))
+@end group
+@end example
+@end table
+
+
+@node Precedence of Action Functions
+@subsection Precedence of Action Functions
+
+From the past subsections we already know that @code{display-buffer}
+must be supplied with a number of display actions (@pxref{Choosing
+Window}) in order to display a buffer.  In a completely uncustomized
+Emacs, these actions are specified by
+@code{display-buffer-fallback-action} in the following order of
+precedence: Reuse a window, pop up a new window on the same frame, use
+a window previously showing the buffer, use some window and pop up a
+new frame.  (The remaining actions in the default value of
+@code{display-buffer-fallback-action} are void in an uncustomized
+Emacs).
+
+Let's now consider the following form:
+
+@example
+(display-buffer (get-buffer-create "*foo*"))
+@end example
+
+@noindent
+Put this form into the buffer @file{*scratch*} of an uncustomized
+Emacs session you just started and evaluate it: @code{display-buffer}
+will fail to reuse a window showing @file{*foo*} but succeed in
+popping up a new window.  If you evaluate the form again, nothing will
+change---@code{display-buffer} reused the window already showing
+@file{*foo*} because that action was applicable and had the highest
+precedence among all applicable actions.
+
+   Popping up a new window will fail if there is not enough space on
+the selected frame.  In an uncustomized Emacs it typically fails when
+there are already two windows on a frame.  For example, if you now
+type @w{@kbd{C-x 1}} followed by @w{@kbd{C-x 2}} and evaluate the form
+once more, @file{*foo*} should show up in the lower
+window---@code{display-buffer} just used ``some'' window.  If, before
+typing @w{@kbd{C-x 2}} you had typed @w{@kbd{C-x o}}, @file{*foo*}
+would have been shown in the upper window because ``some'' window
+stands for the ``least recently used'' window and the selected window
+has been least recently used if and only if it is alone on its frame.
+
+   Let's assume you did not type @w{@kbd{C-x o}} and @file{*foo*} is
+shown in the lower window.  Type @w{@kbd{C-x o}} to get there followed
+by @w{@kbd{C-x left}} and evaluate the form again.  This should
+display @file{*foo*} in the same, lower window because that window had
+already shown @file{*foo*} previously and was therefore chosen instead
+of some other window (remember the precedence order prescribed by
+@code{display-buffer-fallback-action} we sketched above).
+
+  So far we have only observed default behaviors in an uncustomized
+Emacs session.  Next let's see how these behaviors can be customized.
+The first option we consider is @code{display-buffer-base-action}.  It
+provides a very coarse customization which conceptually affects the
+display of @emph{any} buffer.  It can be used to supplement the
+actions supplied by @code{display-buffer-fallback-action} by
+reordering them or by adding actions that are not present there but
+fit more closely the user's editing practice.  It can be, however,
+also used to change the default behavior in a more profound way.
+
+   Let's consider a user who, as a rule, prefers to display buffers on
+another frame.  Such a user might provide the following customization:
+
+@example
+@group
+(customize-set-variable
+ 'display-buffer-base-action
+ '((display-buffer-reuse-window display-buffer-pop-up-frame)
+   (reusable-frames . 0)))
+@end group
+@end example
+
+@noindent
+This setting will cause@code{display-buffer} to first try to find a
+window showing the buffer on a visible or iconified frame and, if no
+such frame exists, pop up a new frame.  You can observe this behavior
+on a graphical system by typing @w{@kbd{C-x 1}} in the window showing
+@file{*scratch*} and evaluating the canonical @code{display-buffer}
+form.  This will usually create (and give focus to) a new frame whose
+root window shows @file{*foo*}.  Iconify that frame and evaluate the
+canonical form again: @code{display-buffer} will reuse the window on
+the new frame (usually raising the frame and giving it focus too).
+
+   Only if creating a new frame fails, @code{display-buffer} will
+apply the actions supplied by @code{display-buffer-fallback-action}
+which means to again try to reuse a window, pop up a new window and so
+on.  A trivial way to make frame creation fail is supplied by the
+following form:
+
+@example
+@group
+(let ((pop-up-frame-function 'ignore))
+  (display-buffer (get-buffer-create "*foo*")))
+@end group
+@end example
+
+@noindent
+We will forget about that form immediately after observing that it
+fails to create a new frame and uses a fallback action instead.
+
+   Note that @code{display-buffer-reuse-window} appears redundant in
+the customization of @code{display-buffer-base-action} because it is
+already part of @code{display-buffer-fallback-action} and should be
+tried there anyway.  However, that would fail because due to the
+precedence of @code{display-buffer-base-action} over
+@code{display-buffer-fallback-action}, at that time
+@code{display-buffer-pop-up-frame} would have already won the race.
+In fact
+
+@example
+@group
+(customize-set-variable
+ 'display-buffer-base-action
+ '(display-buffer-pop-up-frame (reusable-frames . 0)))
+@end group
+@end example
+
+@noindent
+would cause @code{display-buffer} to @emph{always} pop up a new frame
+which is probably not what our user wants.
+
+   So far, we have only shown how @emph{users} can customize the
+default behavior of @code{display-buffer}.  Let us now see how
+@emph{applications} can change the course of @code{display-buffer}.
+The canonical way to do that is to use the @var{action} argument of
+@code{display-buffer} or the function that eventually ends up calling
+it.
+
+   Suppose an application wants to display @file{*foo*} preferably
+below the selected window (to immediately attract the attention of the
+user to the new window) or, if that fails, in a window at the bottom
+of the frame.  It could do that with a call like
+
+@example
+@group
+(display-buffer
+ (get-buffer-create "*foo*")
+ '((display-buffer-below-selected display-buffer-at-bottom)))
+@end group
+@end example
+
+@noindent
+In order to see how this new, modified form works, delete any frame
+showing @file{*foo*}, type @w{@kbd{C-x 1}} followed by @w{@kbd{C-x 2}} in the
+window showing @file{*scratch*} and subsequently evaluate that form.
+@code{display-buffer} should split the upper window and show
+@file{*foo*} in the new window.  Alternatively, if after @w{@kbd{C-x 2}}
+you had typed @w{@kbd{C-x o}}, @code{display-buffer} would have split the
+window at the bottom instead.
+
+   Suppose now that, before evaluating the new form, you have made the
+selected window as small as possible, for example, by evaluating the
+form @code{(fit-window-to-buffer)} in that window.  In that case,
+@code{display-buffer} would have failed to split the selected window
+and would have split the frame's root window instead, effectively
+displaying @file{*foo*} at the bottom of the frame.
+
+   In either case, evaluating the new form a second time now should
+reuse the window already showing @file{*foo*} since both functions
+supplied by the @var{action} argument try to reuse such a window
+first.
+
+   By setting the @var{action} argument, an application effectively
+overrules any customization of @code{display-buffer-base-action}.  Our
+user can now either accept the choice of the application or redouble
+by customizing the option @code{display-buffer-alist} as follows:
+
+@example
+@group
+(customize-set-variable
+ 'display-buffer-alist
+ '(("\\*foo\\*"
+    (display-buffer-reuse-window display-buffer-pop-up-frame))))
+@end group
+@end example
+
+@noindent
+Trying this with the new, modified form above in a configuration that
+does not show @file{*foo*} anywhere, will display @file{*foo*} on a
+separate frame, completely ignoring the @var{action} argument of
+@code{display-buffer}.
+
+   Note that we didn't care to specify a @code{reusable-frames} action
+alist entry in our specification of @code{display-buffer-alist}.
+@code{display-buffer} always takes the first one it finds---in our
+case the one specified by @code{display-buffer-base-action}.  If we
+wanted to use a different specification, for example, to exclude
+iconified frames showing @file{*foo*} from the list of reusable ones,
+we would have to specify that separately, however:
+
+@example
+@group
+(customize-set-variable
+ 'display-buffer-alist
+ '(("\\*foo\\*"
+    (display-buffer-reuse-window display-buffer-pop-up-frame)
+    (reusable-frames . visible))))
+@end group
+@end example
+
+@noindent
+If you try this, you will notice that repeated attempts to display
+@file{*foo*} will succeed to reuse a frame only if that frame is
+visible.
+
+   The above example would allow the conclusion that users customize
+@code{display-buffer-alist} for the sole purpose to overrule the
+@var{action} argument chosen by applications.  Such a conclusion would
+be incorrect.  @code{display-buffer-alist} is the standard option for
+users to direct the course of display of specific buffers in a
+preferred way regardless of whether the display is also guided by an
+@var{action} argument.
+
+   We can, however, reasonably conclude that customizing
+@code{display-buffer-alist} differs from customizing
+@code{display-buffer-base-action} in two major aspects: It is stronger
+because it overrides the @var{action} argument of
+@code{display-buffer}.  And it allows to explicitly specify all
+affected buffers.  In fact displaying other buffers is not affected in
+any way by a customization for @file{*foo*}.  For example,
+
+@example
+(display-buffer (get-buffer-create "*bar*"))
+@end example
+
+@noindent
+continues being governed by the settings of
+@code{display-buffer-base-action} and
+@code{display-buffer-fallback-action} only.
+
+   We could stop with our examples here but applications still have an
+ace up their sleeves which they can use to overrule any customization
+of @code{display-buffer-alist}.  It's the variable
+@code{display-buffer-overriding-action} which they can bind around
+@code{display-buffer} calls as follows:
+
+@example
+@group
+(let ((display-buffer-overriding-action '((display-buffer-same-window))))
+  (display-buffer
+   (get-buffer-create "*foo*")
+   '((display-buffer-below-selected display-buffer-at-bottom))))
+@end group
+@end example
+
+@noindent
+Evaluating this form will usually display @file{*foo*} in the selected
+window regardless of the @var{action} argument and any user
+customizations.  It might be illustrative to look at the list of
+action functions @code{display-buffer} would have tried to display
+@file{*foo*} with the customizations we provided earlier.  The list
+(including comments explaining who added this and the subsequent
+elements) is:
+
+@example
+@group
+(display-buffer-same-window  ;; `display-buffer-overriding-action'
+ display-buffer-reuse-window ;; `display-buffer-alist'
+ display-buffer-pop-up-frame
+ display-buffer-below-selected ;; ACTION argument
+ display-buffer-at-bottom
+ display-buffer-reuse-window ;; `display-buffer-base-action'
+ display-buffer-pop-up-frame
+ display-buffer--maybe-same-window ;; `display-buffer-fallback-action'
+ display-buffer-reuse-window
+ display-buffer--maybe-pop-up-frame-or-window
+ display-buffer-in-previous-window
+ display-buffer-use-some-window
+ display-buffer-pop-up-frame)
+@end group
+@end example
+
+@noindent
+Among the internal functions listed here
+@code{display-buffer--maybe-same-window} is effectively ignored while
+@code{display-buffer--maybe-pop-up-frame-or-window} actually runs
+@code{display-buffer-pop-up-window}.
+
+The action alist passed in each function call is:
+
+@example
+@group
+((reusable-frames . visible)
+ (reusable-frames . 0))
+@end group
+@end example
+
+@noindent
+which shows that we have used the second specification of
+@code{display-buffer-alist} above.  Suppose our user had written that
+as
+
+@example
+@group
+(customize-set-variable
+ 'display-buffer-alist
+ '(("\\*foo\\*"
+    (display-buffer-reuse-window display-buffer-pop-up-frame)
+    (inhibit-same-window . t)
+    (reusable-frames . visible))))
+@end group
+@end example
+
+@noindent
+In this case the @code{inhibit-same-window} alist entry will
+successfully invalidate the @code{display-buffer-same-window}
+specification from @code{display-buffer-overriding-action} and
+@code{display-buffer} will show @file{*foo*} on another frame.
+
+   This last example shows that while the precedence order of action
+functions is fixed as described in @ref{Choosing Window}, an action
+alist entry specified by a display action ranked lower in that order
+can affect the execution of an higher ranked display action.
+
+
+@node The Zen of Buffer Display
+@subsection The Zen of Buffer Display
+
+In its most simplistic form, a frame accommodates always one single
+window that can be used for displaying a buffer.  As a consequence, it
+is always the latest call of @code{display-buffer} that will have
+succeeded in placing its buffer there.
+
+   Since working with such a frame is not very practical, Emacs by
+default allows for more complex frame layouts controlled by the
+default values of the frame size and the @code{split-height-threshold}
+and @code{split-width-threshold} options.  Displaying a buffer not yet
+shown on a frame then either splits the single window on that frame or
+(re-)uses one of its two windows.
+
+   The default behavior is abandoned as soon as the user customizes
+one of these thresholds or manually changes the frame's layout.  The
+default behavior is also abandoned when calling @code{display-buffer}
+with a non-@code{nil} @var{action} argument or the user customizes one
+of the options mentioned in the previous subsections.  Mastering
+@code{display-buffer} soon may become a frustrating experience due to
+the plethora of applicable display actions and the resulting frame
+layouts.
+
+   However, refraining from using buffer display functions and falling
+back on a split & delete windows metaphor is not a good idea either.
+Buffer display functions give applications and users a framework to
+reconcile their different needs; no comparable framework exists for
+splitting and deleting windows.  They also allow to at least partially
+restore the layout of a frame when removing a buffer from it later
+(@pxref{Quitting Windows}).
+
+   Below we will give a number of guidelines to redeem the frustration
+mentioned above and thus to avoid that buffers literally get lost in
+between the windows of a frame.
+
+@table @asis
+@item Write display actions without stress
+Writing display actions can be a pain because one has to lump together
+action functions and action alists in one huge list.  (Historical
+reasons prevented us from having @code{display-buffer} support
+separate arguments for these.)  It might help to memorize some basic
+forms like the ones listed below:
+
+@example
+'(nil (inhibit-same-window . t))
+@end example
+
+@noindent
+specifies an action alist entry only and no action function.  Its sole
+purpose is to inhibit a @code{display-buffer-same-window} function
+specified elsewhere from showing the buffer in the same window, see
+also the last example of the preceding subsection.
+
+@example
+'(display-buffer-below-selected)
+@end example
+
+on the other hand specifies one action function and an empty action
+alist.  To combine the effects of the above two specifications one
+would write the form
+
+@example
+'(display-buffer-below-selected (inhibit-same-window . t))
+@end example
+
+to add another action function one would write
+
+@example
+@group
+'((display-buffer-below-selected display-buffer-at-bottom)
+  (inhibit-same-window . t))
+@end group
+@end example
+
+and to add another alist entry one would write
+
+@example
+@group
+'((display-buffer-below-selected display-buffer-at-bottom)
+  (inhibit-same-window . t) (window-height . fit-window-to-buffer))
+@end group
+@end example
+
+That last form can be used as @var{action} argument of
+@code{display-buffer} in the following way:
+
+@example
+@group
+(display-buffer
+ (get-buffer-create "*foo*")
+ '((display-buffer-below-selected display-buffer-at-bottom)
+   (inhibit-same-window . t) (window-height . fit-window-to-buffer)))
+@end group
+@end example
+
+In a customization of @code{display-buffer-alist} it would be used as
+follows:
+
+@example
+@group
+(customize-set-variable
+ 'display-buffer-alist
+ '(("\\*foo\\*"
+    (display-buffer-below-selected display-buffer-at-bottom)
+    (inhibit-same-window . t) (window-height . fit-window-to-buffer))))
+@end group
+@end example
+
+To add a customization for a second buffer one would then write:
+
+@example
+@group
+(customize-set-variable
+ 'display-buffer-alist
+ '(("\\*foo\\*"
+    (display-buffer-below-selected display-buffer-at-bottom)
+    (inhibit-same-window . t) (window-height . fit-window-to-buffer))
+   ("\\*bar\\*"
+    (display-buffer-reuse-window display-buffer-pop-up-frame)
+    (reusable-frames . visible))))
+@end group
+@end example
+
+@item Treat each other with respect
+@code{display-buffer-alist} and @code{display-buffer-base-action} are
+user options---applications must never set or rebind them.
+@code{display-buffer-overriding-action}, on the other hand, is
+reserved for applications---who seldom use that option and if they use
+it, then with utmost care.
+
+   Older implementations of @code{display-buffer} frequently caused
+users and applications to fight over the settings of user options like
+@code{pop-up-frames} and @code{pop-up-windows} (@pxref{Choosing Window
+Options}).  This was one major reason for redesigning
+@code{display-buffer}---to provide a clear rule dividing what users
+and applications should be allowed to do.
+
+   Applications must be prepared that a user's customizations may
+cause buffers to get displayed in an unexpected way.  They should
+never assume in their subsequent behavior, that the buffer has been
+shown precisely the way they asked for in the @var{action} argument of
+@code{display-buffer}.
+
+   Users should not pose too many and too severe restrictions on how
+arbitrary buffers gets displayed.  Otherwise, they will risk to lose
+the characteristics of showing a buffer for a certain purpose.
+Suppose an application has been written to compare different versions
+of a buffer in two windows side-by-side.  If the customization of
+@code{display-buffer-alist} prescribes that any such buffer should be
+always shown in or below the selected window, the application will
+have a hard time to set up the desired window configuration via
+@code{display-buffer}.
+
+   To specify a preference for showing an arbitrary buffer, users
+should customize @code{display-buffer-base-action}.  An example of how
+users who prefer working with multiple frames would do that was given
+in the previous subsection.  @code{display-buffer-alist} should be
+reserved for displaying specific buffers in a specific way.
+
+@item Consider reusing a window that already shows the buffer
+Generally, it's always a good idea for users and application
+programmers to be prepared for the case that a window already shows
+the buffer in question and to reuse that window.  In the preceding
+subsection we have shown that failing to do so properly may cause
+@code{display-buffer} to continuously pop up a new frame although a
+frame showing that buffer existed already.  Only sometimes, it might
+be undesirable to reuse a window, for example, when a different
+portion of the buffer should be shown in that window.
+
+   Hence, @code{display-buffer-reuse-window} is one action function
+that should be used as often as possible, both in @var{action}
+arguments and customizations.  An @code{inhibit-same-window} entry in
+the @var{action} argument usually takes care of the most common case
+where reusing a window showing the buffer should be avoided---that
+where the window in question is the selected one.
+
+@item Attract focus to the window chosen
+This is a no-brainer for people working with multiple frames---the
+frame showing the buffer will automatically raise and get focus unless
+an @code{inhibit-switch-frame} entry forbids it.  For single frame
+users this task can be considerably more difficult.  In particular,
+@code{display-buffer-pop-up-window} and
+@code{display-buffer-use-some-window} can become obtrusive in this
+regard.  They split or use a seemingly arbitrary (often the largest or
+least recently used) window, distracting the user's attention.
+
+Some applications therefore try to choose a window at the bottom of
+the frame, for example, in order to display the buffer in vicinity of
+the minibuffer window where the user is expected to answer a question
+related to the new window.  For non-input related actions
+@code{display-buffer-below-selected} might be preferable because the
+selected window usually already has the user's attention.
+
+@item Handle subsequent invocations of @code{display-buffer}
+@code{display-buffer} is not overly well suited for displaying several
+buffers in sequence and making sure that all these buffers are shown
+orderly in the resulting window configuration.  Again, the standard
+action functions @code{display-buffer-pop-up-window} and
+@code{display-buffer-use-some-window} are not very suited for this
+purpose due to their somewhat chaotic nature in more complex
+configurations.
+
+   To produce a window configuration displaying multiple buffers (or
+different views of one and the same buffer) in one and the same
+display cycle, application programmers will unavoidably have to write
+their own action functions.  A few tricks listed below might help in
+this regard.
+
+@itemize @bullet
+@item
+Making windows atomic (@pxref{Atomic Windows}) avoids that an
+existing window composition gets broken when popping up a new window.
+The new window will pop up outside the composition instead.
+
+@item
+Temporarily dedicating windows to their buffers (@pxref{Dedicated
+Windows}) avoids that a window gets used for displaying a different
+buffer.  A non-dedicated window will be used instead.
+
+@item
+Calling @code{window-preserve-size} (@pxref{Preserving Window Sizes})
+will try to keep the size of the argument window unchanged when
+popping up a new window.  You have to make sure that another window in
+the same combination can be shrunk instead, though.
+
+@item
+Side windows (@pxref{Side Windows}) can be used for displaying
+specific buffers always in a window at the same position of a frame.
+This permits to group buffers that do not compete for being shown at
+the same time on a frame and show any such buffer in the same window
+without disrupting the display of other buffers.
+
+@item
+Child frames (@pxref{Child Frames}) can be used to display a buffer
+within the screen estate of the selected frame without disrupting that
+frame's window configuration and without the overhead associated with
+full-fledged frames as inflicted by @code{display-buffer-pop-up-frame}.
+@end itemize
+@end table

-@defun same-window-p buffer-name
-This function returns @code{t} if displaying a buffer
-named @var{buffer-name} with @code{display-buffer} would
-put it in the selected window.
-@end defun

 @node Window History
 @section Window History
@@ -3204,7 +3904,7 @@ Side Windows
    In their most simple form of use, side windows allow to display
 specific buffers always in the same area of a frame.  Hence they can be
 regarded as a generalization of the concept provided by
-@code{display-buffer-at-bottom} (@pxref{Display Action Functions}) to
+@code{display-buffer-at-bottom} (@pxref{Action Functions}) to
 the remaining sides of a frame.  With suitable customizations, however,
 side windows can be also used to provide frame layouts similar to those
 found in so-called integrated development environments (IDEs).
@@ -3221,8 +3921,8 @@ Side Windows
 @node Displaying Buffers in Side Windows
 @subsection Displaying Buffers in Side Windows

-The following action function for @code{display-buffer} (@pxref{Display
-Action Functions}) creates or reuses a side window for displaying the
+The following action function for @code{display-buffer} (@pxref{Action
+Functions}) creates or reuses a side window for displaying the
 specified buffer.

 @defun display-buffer-in-side-window buffer alist
@@ -3264,7 +3964,7 @@ Displaying Buffers in Side Windows

 By default, side windows cannot be split via @code{split-window}
 (@pxref{Splitting Windows}).  Also, a side window is not reused or split
-by any buffer display action (@pxref{Display Action Functions}) unless
+by any buffer display action (@pxref{Action Functions}) unless
 it is explicitly specified as target of that action.  Note also that
 @code{delete-other-windows} cannot make a side window the only window on
 its frame (@pxref{Deleting Windows}).
@@ -3453,9 +4153,9 @@ Frame Layouts with Side Windows
 @xref{Resizing Windows}.

    The last form also makes sure that none of the created side windows
-are accessible via @kbd{C-x o} by installing the @code{no-other-window}
+are accessible via @w{@kbd{C-x o}} by installing the @code{no-other-window}
 parameter for each of these windows.  In addition, it makes sure that
-side windows are not deleted via @kbd{C-x 1} by installing the
+side windows are not deleted via @w{@kbd{C-x 1}} by installing the
 @code{no-delete-other-windows} parameter for each of these windows.

    Since @code{dired} buffers have no fixed names, we use a special
@@ -3547,7 +4247,7 @@ Atomic Windows

 To create a new atomic window from an existing live window or to add a
 new window to an existing atomic window, the following buffer display
-action function (@pxref{Display Action Functions}) can be used:
+action function (@pxref{Action Functions}) can be used:

 @defun display-buffer-in-atom-window buffer alist
 This function tries to display @var{buffer} in a new window that will be
@@ -3679,6 +4379,7 @@ Window Point
 so @code{window-point} will stay behind text inserted there.
 @end defvar

+
 @node Window Start and End
 @section The Window Start and End Positions
 @cindex window start position
@@ -3925,6 +4626,7 @@ Window Start and End
 text line, @var{ypos} is negative.
 @end defun

+
 @node Textual Scrolling
 @section Textual Scrolling
 @cindex textual scrolling
@@ -4264,6 +4966,7 @@ Vertical Scrolling
 presence of large images.
 @end defvar

+
 @node Horizontal Scrolling
 @section Horizontal Scrolling
 @cindex horizontal scrolling
@@ -5145,6 +5848,7 @@ Window Parameters
 versions of Emacs.
 @end table

+
 @node Window Hooks
 @section Hooks for Window Scrolling and Changes
 @cindex hooks for window operations

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-20 12:20 Documenting buffer display martin rudalics
@ 2018-10-20 13:21 ` Eli Zaretskii
  2018-10-20 18:02   ` martin rudalics
  2018-10-22  1:39   ` Michael Welsh Duggan
  2018-10-20 15:22 ` Drew Adams
  2018-11-04  9:06 ` martin rudalics
  2 siblings, 2 replies; 32+ messages in thread
From: Eli Zaretskii @ 2018-10-20 13:21 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

> Date: Sat, 20 Oct 2018 14:20:18 +0200
> From: martin rudalics <rudalics@gmx.at>
> 
> Attached find a rewrite of the documentation of buffer display
> functions to be applied against the release branch.
> 
> Work in progress.  Proofreading and suggestions welcome.

Thanks, please find a few comments below.

> +@node Displaying Buffers
> +@section Displaying a Buffer in a Suitable Window

Please consider adding one or more @cindex entries here, so that
readers could get here when they look for topics described in this
section.  Similarly for each of the new subsections.

> +In this section we describe how Emacs finds or creates a window
> +suitable for displaying a buffer.  We first introduce the function
> +@code{display-buffer}---the workhorse for choosing such a window.
> +Next, action functions---auxiliary functions called by
> +@code{display-buffer} to find or create a suitable window---are
> +presented.  Then we describe action alists---special association lists
> +used to fine-tune the behavior of action functions.
> +
> +   We continue with the description of additional options to customize
> +the behavior of @code{display-buffer}.  Then a series of examples will
> +try to explain the precedence among action functions in a single call
> +of @code{display-buffer}.  We conclude this section with some
> +guidelines for managing the complexity of buffer display.

I suggest to rewrite this text in terms of what the reader might be
looking for, or as a list of tasks related to the material in the
section.  The way the text is written now, it is an overview of the
topics covered by the section, without any explicit relation to what
the reader may want to do or learn about.  Such "abstract" overviews
are IME much less useful.

> +
> +@menu
> +* Choosing Window::         How to choose a window for displaying a buffer.
> +* Action Functions::        Support functions for buffer display.
> +* Action Alists::           Alists for fine-tuning buffer display.

I question the wisdom of removing "Display" from the names of these
nodes.  "Action Functions" and "Action Alists" are IMO too general,
and might clash with some other kind of "actions".

> +see @ref{Precedence of Action Functions} for an example.

Please put a comma after the right brace here.

> +@node Action Functions
> +@subsection Action Functions for Buffer Display

I think @cindex entries here about "action functions" and "display
action functions" are in order.

>  The following basic action functions are defined in Emacs.  Each of

"Action function" is a term introduced in this section, right?  If so,
its first instance should be in @dfn, and this section should define
the term.

> +display, and @var{alist}, an action alist.  As a rule, each action
> +function is supposed to return a window displaying @var{buffer} if it
> +succeeds and @code{nil} if it fails (for the sole exception to this
> +rule see the last function listed
> +below---@code{display-buffer-no-window}).

I think this exception is better described with the function; here it
is just a distraction.  The general rule should be: describe the
normal case in detail, and leave the exceptional cases for note-like
text near the end.

> +If there is no such window, this function tries to create a new window
> +by splitting the selected one and display @var{buffer} there.  It will
> +also adjust that window's size provided @var{alist} contains a suitable
> +@code{window-height} or @code{window-width} entry, see above.

Here and elsewhere, you mix 2 different styles: one using present
tense ("tries", "fails"), the other using future tense ("will
adjust").  I think we prefer to use the former consistently.

> +@node Action Alists
> +@subsection Action Alists for Buffer Display
> +
> +An action alist (@pxref{Choosing Window}) is an association list
> +mapping predefined symbols recognized by action functions to values

Here you provide the definition of "action alist", so its first
instance should be in @dfn, and there should be a @cindex entry here.

> +   Many efforts in the design of @code{display-buffer} have been given
> +to maintain compatibility with code that uses older options like
> +@code{pop-up-windows}, @code{pop-up-frames},
> +@code{pop-up-frame-alist}, @code{same-window-buffer-names} and
> +@code{same-window-regexps}.  Applications and users should refrain

The text below this should have index entries for the obsolete
variables you describe.

> +Let's now consider the following form:
> +
> +@example
> +(display-buffer (get-buffer-create "*foo*"))
> +@end example
> +
> +@noindent
> +Put this form into the buffer @file{*scratch*} of an uncustomized
> +Emacs session you just started and evaluate it: @code{display-buffer}
> +will fail to reuse a window showing @file{*foo*} but succeed in
> +popping up a new window.  If you evaluate the form again, nothing will
> +change---@code{display-buffer} reused the window already showing
> +@file{*foo*} because that action was applicable and had the highest
> +precedence among all applicable actions.

FWIW, I find such tutorial-like style not really appropriate for a
reference manual.  For starters, it takes more space; more
importantly, it gets to the point only implicitly and requires the
reader to participate in the discovery.  It could even annoy, if the
reader is in a hurry.  Suggest to rewrite as reference text instead.
I'm sure this stuff can be described other than by example.

> +@node The Zen of Buffer Display
> +@subsection The Zen of Buffer Display

This section is also in dire need of useful index entries.

> +@example
> +'(display-buffer-below-selected)
> +@end example
> +
> +on the other hand specifies one action function and an empty action

@noindent is missing here.

> +alist.  To combine the effects of the above two specifications one
> +would write the form
> +
> +@example
> +'(display-buffer-below-selected (inhibit-same-window . t))
> +@end example
> +
> +to add another action function one would write

And here.

> +@example
> +@group
> +'((display-buffer-below-selected display-buffer-at-bottom)
> +  (inhibit-same-window . t))
> +@end group
> +@end example
> +
> +and to add another alist entry one would write

And here.

And a final remark: the last two subsections you added read like more
or less arbitrary collection of tips and tricks.  While it's okay to
do that, I wonder whether such a long list of tricks means there might
be some more meaningful organization of most of this material.  Just a
thought.

Thanks again for working on this.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* RE: Documenting buffer display
  2018-10-20 12:20 Documenting buffer display martin rudalics
  2018-10-20 13:21 ` Eli Zaretskii
@ 2018-10-20 15:22 ` Drew Adams
  2018-10-20 18:02   ` martin rudalics
  2018-11-04  9:06 ` martin rudalics
  2 siblings, 1 reply; 32+ messages in thread
From: Drew Adams @ 2018-10-20 15:22 UTC (permalink / raw)
  To: martin rudalics, emacs-devel

> Attached find a rewrite of the documentation of buffer display
> functions to be applied against the release branch.
> 
> Work in progress.  Proofreading and suggestions welcome.
> 
> Thanks for the attention, martin

Thanks very much for working on this area of the documentation!
This is an area where things have become more complicated and
could use clarification. Working on this really helps.

I only skimmed your patch, but I have at least this comment: I
object to the removal of doc for, and the downplay of support
for, `pop-up-frames' etc. Such variables are very handy; they
should continue to be fully supported and even touted, IMO.

Yes, I am perhaps a lone voice in this regard, but I wanted
to once again voice my disagreement about this, FWIW.

In addition to the wholesale removal of such doc, this, for
instance, is the wrong direction to take, IMHO:

+Many efforts in the design of @code{display-buffer} have been given
+to maintain compatibility with code that uses older options like
+@code{pop-up-windows}, @code{pop-up-frames},
+@code{pop-up-frame-alist}, @code{same-window-buffer-names} and
+@code{same-window-regexps}.  Applications and users should refrain
+from using these options in future code.  Above we already warned
+against customizing @code{pop-up-frame-alist}.  Here we describe how
+to convert the remaining options to use display actions instead.

(I don't object to the "many efforts...to maintain compatibility...".
In fact, I applaud such effort and compatibility. I object to it being
considered only backward compatibility. I object to discouraging
or phasing out such useful constructs. If they didn't exist then
we should want to invent them...)

Being able to simply bind an option such as `pop-up-frames',
to change the behavior of existing code, is very useful.

Richard's arguments why dynamic binding of variables (in _addition_
to lexical binding) is particularly useful for _Emacs_ is relevant here.
It is as relevant today as when it was written, decades ago:

https://www.gnu.org/software/emacs/emacs-paper.html#SEC17

https://www.gnu.org/software/emacs/emacs-paper.html#SEC18

Please keep supporting, and not at all discourage, `pop-up-frames'
and similar.

Thanks for listening, and thanks for the ton of careful work you've
put in for this documentation and to make buffer display more
configurable.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-20 13:21 ` Eli Zaretskii
@ 2018-10-20 18:02   ` martin rudalics
  2018-10-21 12:56     ` Eli Zaretskii
  2018-10-22  1:39   ` Michael Welsh Duggan
  1 sibling, 1 reply; 32+ messages in thread
From: martin rudalics @ 2018-10-20 18:02 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

 > Thanks, please find a few comments below.

Thanks for the comments.  Everything not cited below will be
corrected in your sense.

 > Please consider adding one or more @cindex entries here, so that
 > readers could get here when they look for topics described in this
 > section.  Similarly for each of the new subsections.

I haven't done any indexing yet.  Suggestions, like the ones you
provide below, are highly welcome.

 >> +In this section we describe how Emacs finds or creates a window
 >> +suitable for displaying a buffer.  We first introduce the function
 >> +@code{display-buffer}---the workhorse for choosing such a window.
 >> +Next, action functions---auxiliary functions called by
 >> +@code{display-buffer} to find or create a suitable window---are
 >> +presented.  Then we describe action alists---special association lists
 >> +used to fine-tune the behavior of action functions.
 >> +
 >> +   We continue with the description of additional options to customize
 >> +the behavior of @code{display-buffer}.  Then a series of examples will
 >> +try to explain the precedence among action functions in a single call
 >> +of @code{display-buffer}.  We conclude this section with some
 >> +guidelines for managing the complexity of buffer display.
 >
 > I suggest to rewrite this text in terms of what the reader might be
 > looking for, or as a list of tasks related to the material in the
 > section.  The way the text is written now, it is an overview of the
 > topics covered by the section, without any explicit relation to what
 > the reader may want to do or learn about.  Such "abstract" overviews
 > are IME much less useful.

Fully agreed but I ran out of ideas here.  It would be a great help if
you or anyone else came up with a rough sketch of what to do instead.

 >> +* Action Functions::        Support functions for buffer display.
 >> +* Action Alists::           Alists for fine-tuning buffer display.
 >
 > I question the wisdom of removing "Display" from the names of these
 > nodes.  "Action Functions" and "Action Alists" are IMO too general,
 > and might clash with some other kind of "actions".

Agreed.  But IMO "display action function" is even worse because
"display" has a very different connotation in Emacs.  So I can only
propose "buffer display action function" or "display buffer action
function" instead.  WDYT?

 >> +@node Action Functions
 >> +@subsection Action Functions for Buffer Display
 >
 > I think @cindex entries here about "action functions" and "display
 > action functions" are in order.

They are already indexed in Choosing Window thusly

@cindex display action
@cindex action function, for @code{display-buffer}
@cindex action alist, for @code{display-buffer}

so you suggest to move the indices to the corresponding sections?

 >>   The following basic action functions are defined in Emacs.  Each of
 >
 > "Action function" is a term introduced in this section, right?  If so,
 > its first instance should be in @dfn, and this section should define
 > the term.

They are defined in Choosing Window thusly

Here, @var{function} is either a function or a list of functions,
which we refer to as @dfn{action functions}; @var{alist} is an
association list, which we refer to as an @dfn{action alist}.

so you suggest to move the @dfns to the corresponding sections as well
and leave only the cross references in Choosing Window?

 >> +@node Action Alists
 >> +@subsection Action Alists for Buffer Display
 >> +
 >> +An action alist (@pxref{Choosing Window}) is an association list
 >> +mapping predefined symbols recognized by action functions to values
 >
 > Here you provide the definition of "action alist", so its first
 > instance should be in @dfn, and there should be a @cindex entry here.

Same as for "Action Functions" above.

 >> +   Many efforts in the design of @code{display-buffer} have been given
 >> +to maintain compatibility with code that uses older options like
 >> +@code{pop-up-windows}, @code{pop-up-frames},
 >> +@code{pop-up-frame-alist}, @code{same-window-buffer-names} and
 >> +@code{same-window-regexps}.  Applications and users should refrain
 >
 > The text below this should have index entries for the obsolete
 > variables you describe.

OK (they are not obsolete yet, BTW).

 > FWIW, I find such tutorial-like style

I initially wanted to call this section "A Tutorial for ...".

 > not really appropriate for a
 > reference manual.  For starters, it takes more space; more
 > importantly, it gets to the point only implicitly and requires the
 > reader to participate in the discovery.

Yes to all.  And I expect everyone who complained in the past about
how difficult it is to work with 'display-buffer' to do exactly that -
participate in the discovery (just as I did when I wrote those
examples).  Please keep in mind: I didn't invent the action functions,
frequently argued that people won't like them and that it will be hard
to document them.  In fact, writing action functions can be a pain and
examples are one way to relieve that pain.  Even if it takes space to
write the examples and time to read them.

 > It could even annoy, if the
 > reader is in a hurry.

Readers in a hurry are not supposed to read that section.  If
necessary, I can put an according warning at its start.

 > Suggest to rewrite as reference text instead.
 > I'm sure this stuff can be described other than by example.

On this list people have asked for examples quite often.  Roland
Winkler:

   The current discussion of 'display-buffer-alist' in the elisp manual
   appears rather technical, suited only for expert users.  On the
   other hand, the variable is declared with defcustom, as if
   individual users should customize it to their personal liking.

N. Jackson in the same thread:

   Perhaps `display-buffer-alist' is sufficient for the BBDB case. As
   its documentation is a little unclear (while recursive code is okay,
   recursive documentation is a little bit trying), it would be nice to
   see an example of how this might be done.

Honestly, I have no idea how to do if not with the help of a detailed
sequence of examples.  The "Precedence ..." section is IMO one way to
discover how 'display-buffer' works and why it works the way it does.
If anyone comes up with a better idea I'll be all ears.

 > And a final remark: the last two subsections you added read like more
 > or less arbitrary collection of tips and tricks.  While it's okay to
 > do that, I wonder whether such a long list of tricks means there might
 > be some more meaningful organization of most of this material.  Just a
 > thought.

Have a look at two recent threads.  This one is by Florian Weimer on
help-gnu-emacs:

   I see.  Further questions: How can I restore the window configuration
   after the process terminates?  Is there something similar to
   save-excursion?

To which Stefan Monnier answers:

   If you don't care about other people's configs and you only use a single
   frame, there's save-window-excursion (but for configs like mine, every
   use of save-window-excursion is generally a source of problems).
   A simpler solution to "undo" a pop-to-buffer is to (bury-buffer).

Now the canonical mechanism provided by 'pop-to-buffer' is to use
'quit-window' but how do I tell that to our former maintainer and how
do I put that in the manual?  So I mention it in the Zen section.

Or take this one by Alan:

   I've thought about this overnight.  And I think the answer is no, it
   would not be better to use pop-to-buffer.  At least, not if an ACTION
   argument needs to be constructed.

   The specification of the ACTION argument seems so arcane, so implicit, so
   difficult to use, that it will be simpler just to write a function such
   as edebug-pop-to-buffer.  edebug-pop-to-buffer will also be much easier
   to understand and maintain than an equivalent using pop-to-buffer with an
   ACTION.

   In short, pop-to-buffer and display-buffer with ACTION seem to be
   "pyrrhic functions".  At least, that's how I see it from reading the doc,
   not having yet tried to use them.  Also, edebug-pop-to-buffer already
   exists and works.

   There are around 479 calls to these two functions in the Emacs source.  A
   quick eyeballing of the grep results found just one single use of ACTION,
   in replace.el.  I dare say there are more, but very few altogether.

Maybe some of the tips and tricks I propose here will help Alan to
avoid sleepless nights (and Stefan when quitting an edebug session
will yet another time try to restore his window configuration on the
wrong frame).

martin



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-20 15:22 ` Drew Adams
@ 2018-10-20 18:02   ` martin rudalics
  2018-10-20 18:24     ` Drew Adams
  0 siblings, 1 reply; 32+ messages in thread
From: martin rudalics @ 2018-10-20 18:02 UTC (permalink / raw)
  To: Drew Adams, emacs-devel

 > Being able to simply bind an option such as `pop-up-frames',
 > to change the behavior of existing code, is very useful.

If it overrides a user's customization then that's not useful but bad.

 > Please keep supporting, and not at all discourage, `pop-up-frames'
 > and similar.

We do our best to support them in present code.  We have to discourage
their use because there's no guarantee that future code will support
them.

Have you read what I wrote about 'pop-up-frame-alist'?  Already now
there's no guarantee that we can maintain these old options properly.
And I never tried to probe very deep in this area.

martin



^ permalink raw reply	[flat|nested] 32+ messages in thread

* RE: Documenting buffer display
  2018-10-20 18:02   ` martin rudalics
@ 2018-10-20 18:24     ` Drew Adams
  2018-10-21  8:22       ` martin rudalics
  0 siblings, 1 reply; 32+ messages in thread
From: Drew Adams @ 2018-10-20 18:24 UTC (permalink / raw)
  To: martin rudalics, emacs-devel

>  > Being able to simply bind an option such as `pop-up-frames',
>  > to change the behavior of existing code, is very useful.
> 
> If it overrides a user's customization then that's not useful but bad.

I disagree. If the behavior is documented in the command's doc
string, as it should be, then the user is aware of it. Using a given
command is a user choice. There is no reason to put on the hair
shirt of not binding a user option in a user command, as long as
the behavior is documented and the command ends always by
restoring the user's preferred value for the option.

Secondly, users themselves define commands, and the ability
to bind such a variable - whether it is an option or not, is very
useful for users.

>  > Please keep supporting, and not at all discourage, `pop-up-frames'
>  > and similar.
> 
> We do our best to support them in present code. 

Thank you. That's all anyone can ask for. It's all I'm asking.

> We have to discourage their use because there's no
> guarantee that future code will support them.

Not a good argument, IMO. There's never a guarantee
that any future code will support anything.

That's not a reason to remove doc for useful behavior
and add doc that this or that useful feature is not
guaranteed to be supported forever. There's no need
for such a disclaimer - this applies to everything in Emacs. 

> Have you read what I wrote about 'pop-up-frame-alist'?  Already now
> there's no guarantee that we can maintain these old options properly.
> And I never tried to probe very deep in this area.

No guarantee is no reason to discourage their use.
If there are bugs and they get reported then that
shows that the features are used.

And I do appreciate that you have made an effort to
maintain the functionality (as well as introducing new
features).

Anyway, again, just one opinion.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-20 18:24     ` Drew Adams
@ 2018-10-21  8:22       ` martin rudalics
  0 siblings, 0 replies; 32+ messages in thread
From: martin rudalics @ 2018-10-21  8:22 UTC (permalink / raw)
  To: Drew Adams, emacs-devel

 > I disagree. If the behavior is documented in the command's doc
 > string, as it should be, then the user is aware of it. Using a given
 > command is a user choice. There is no reason to put on the hair
 > shirt of not binding a user option in a user command, as long as
 > the behavior is documented and the command ends always by
 > restoring the user's preferred value for the option.

A user option has to be respected.  If the designer of a command sees
no other way to have a command do what it is supposed to do than by
overriding a user option we have a severe design problem.

'display-buffer' has no design problem because programmers can always
ask it to do what they want by specifying the ACTION argument
appropriately.  Telling programmers to bind a user option instead is
an invitation to bad design.

 > Secondly, users themselves define commands, and the ability
 > to bind such a variable - whether it is an option or not, is very
 > useful for users.

And when such users become programmers we get our problems through the
backdoor, compare the recent "open bookmark in other frame" thread.

martin



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-20 18:02   ` martin rudalics
@ 2018-10-21 12:56     ` Eli Zaretskii
  2018-10-22  9:06       ` martin rudalics
  0 siblings, 1 reply; 32+ messages in thread
From: Eli Zaretskii @ 2018-10-21 12:56 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

> Date: Sat, 20 Oct 2018 20:02:22 +0200
> From: martin rudalics <rudalics@gmx.at>
> CC: emacs-devel@gnu.org
> 
>  > Please consider adding one or more @cindex entries here, so that
>  > readers could get here when they look for topics described in this
>  > section.  Similarly for each of the new subsections.
> 
> I haven't done any indexing yet.  Suggestions, like the ones you
> provide below, are highly welcome.

Will do as the time passes ;-)

>  > I suggest to rewrite this text in terms of what the reader might be
>  > looking for, or as a list of tasks related to the material in the
>  > section.  The way the text is written now, it is an overview of the
>  > topics covered by the section, without any explicit relation to what
>  > the reader may want to do or learn about.  Such "abstract" overviews
>  > are IME much less useful.
> 
> Fully agreed but I ran out of ideas here.  It would be a great help if
> you or anyone else came up with a rough sketch of what to do instead.

For that, I'd need to have a good understanding of the overall
structure of the material.  I don't have that now; I thought you, as
the author, did.  Failing that, we could postpone this issue to later,
it's relatively minor one.

>  >> +* Action Functions::        Support functions for buffer display.
>  >> +* Action Alists::           Alists for fine-tuning buffer display.
>  >
>  > I question the wisdom of removing "Display" from the names of these
>  > nodes.  "Action Functions" and "Action Alists" are IMO too general,
>  > and might clash with some other kind of "actions".
> 
> Agreed.  But IMO "display action function" is even worse because
> "display" has a very different connotation in Emacs.  So I can only
> propose "buffer display action function" or "display buffer action
> function" instead.  WDYT?

I'd go with "Buffer Display Actions" and "Buffer Display Functions".

>  >> +@node Action Functions
>  >> +@subsection Action Functions for Buffer Display
>  >
>  > I think @cindex entries here about "action functions" and "display
>  > action functions" are in order.
> 
> They are already indexed in Choosing Window thusly
> 
> @cindex display action
> @cindex action function, for @code{display-buffer}
> @cindex action alist, for @code{display-buffer}
> 
> so you suggest to move the indices to the corresponding sections?

Yes.  Index entries should be where the feature is described in the
most detailed way.  The other places should have cross-references to
that main description.

>  >>   The following basic action functions are defined in Emacs.  Each of
>  >
>  > "Action function" is a term introduced in this section, right?  If so,
>  > its first instance should be in @dfn, and this section should define
>  > the term.
> 
> They are defined in Choosing Window thusly
> 
> Here, @var{function} is either a function or a list of functions,
> which we refer to as @dfn{action functions}; @var{alist} is an
> association list, which we refer to as an @dfn{action alist}.
> 
> so you suggest to move the @dfns to the corresponding sections as well
> and leave only the cross references in Choosing Window?

Yes.

>  >> +to maintain compatibility with code that uses older options like
>  >> +@code{pop-up-windows}, @code{pop-up-frames},
>  >> +@code{pop-up-frame-alist}, @code{same-window-buffer-names} and
>  >> +@code{same-window-regexps}.  Applications and users should refrain
>  >
>  > The text below this should have index entries for the obsolete
>  > variables you describe.
> 
> OK (they are not obsolete yet, BTW).

I know.  I meant something like

  @vindex pop-up-windows@r{, replacement for}

>  > FWIW, I find such tutorial-like style
> 
> I initially wanted to call this section "A Tutorial for ...".

I'm not against tutorials; far from that.  I just think they should be
separate from Reference manuals.  Reference manuals can then point to
tutorials for examples.

But that doesn't mean a Reference manual can consider itself done by
providing a "lip service" in the form of such a tutorial reference.  A
good Reference manual should still describe the feature in a clear and
useful way.

Reference manual's main audience are people who already have some,
perhaps even good, idea about the feature, and need help in finding
exactly the right tools, out of those available, to do the jop at
hand.  Tutorials, by contrast, target newbies who have no clue:
walking those through a large enough set of well-explained examples
will bring them up to speed, so they could proceed to the Reference
manual.

> Readers in a hurry are not supposed to read that section.

I think it's a mistake to take that stand when writing a Reference
manual.

> On this list people have asked for examples quite often.  Roland
> Winkler:
> 
>    The current discussion of 'display-buffer-alist' in the elisp manual
>    appears rather technical, suited only for expert users.  On the
>    other hand, the variable is declared with defcustom, as if
>    individual users should customize it to their personal liking.
> 
> N. Jackson in the same thread:
> 
>    Perhaps `display-buffer-alist' is sufficient for the BBDB case. As
>    its documentation is a little unclear (while recursive code is okay,
>    recursive documentation is a little bit trying), it would be nice to
>    see an example of how this might be done.
> 
> Honestly, I have no idea how to do if not with the help of a detailed
> sequence of examples.

It's not easy, I will give you that.  But that doesn't mean we should
give up.

One thing to remember is that the manual is not the only place where
the documentation could live: there are doc strings as well.  Some of
the details might be better suited to doc strings.

> Maybe some of the tips and tricks I propose here will help Alan to
> avoid sleepless nights (and Stefan when quitting an edebug session
> will yet another time try to restore his window configuration on the
> wrong frame).

I didn't say those tips are useless, far from it.  I just ended up
having an impression that I've read a list of tips that I will have to
re-read again when I need to find something in it.  So I suggested to
think about some way of organizing them, so that similar and related
stuff is closer to one another.

Anyway, I don't want to discourage you by being my usual perfectionist
self.  I think it's great you are working on improving these docs, and
I think we are lucky to have you and your expertise on these matters.
So if you can take anything at all from my comments, I'm happy; the
rest can be improved later, if we find a how.

Thanks.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-20 13:21 ` Eli Zaretskii
  2018-10-20 18:02   ` martin rudalics
@ 2018-10-22  1:39   ` Michael Welsh Duggan
  2018-10-22  5:54     ` Eli Zaretskii
  1 sibling, 1 reply; 32+ messages in thread
From: Michael Welsh Duggan @ 2018-10-22  1:39 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: martin rudalics, emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

>> Date: Sat, 20 Oct 2018 14:20:18 +0200
>> From: martin rudalics <rudalics@gmx.at>
>> 
>> +see @ref{Precedence of Action Functions} for an example.
>
> Please put a comma after the right brace here.

Are you certain?  I just want to make sure you didn't misread the last
bit as "for example," which would need the comma.

-- 
Michael Welsh Duggan
(md5i@md5i.com)



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-22  1:39   ` Michael Welsh Duggan
@ 2018-10-22  5:54     ` Eli Zaretskii
  0 siblings, 0 replies; 32+ messages in thread
From: Eli Zaretskii @ 2018-10-22  5:54 UTC (permalink / raw)
  To: Michael Welsh Duggan; +Cc: rudalics, emacs-devel

> From: Michael Welsh Duggan <mwd@md5i.com>
> Cc: martin rudalics <rudalics@gmx.at>,  emacs-devel@gnu.org
> Date: Sun, 21 Oct 2018 21:39:48 -0400
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> >> Date: Sat, 20 Oct 2018 14:20:18 +0200
> >> From: martin rudalics <rudalics@gmx.at>
> >> 
> >> +see @ref{Precedence of Action Functions} for an example.
> >
> > Please put a comma after the right brace here.
> 
> Are you certain?

Yes.

> I just want to make sure you didn't misread the last bit as "for
> example," which would need the comma.

This has nothing to do with English grammar, it's a requirement of
Texinfo cross-references, which some versions of makeinfo still insist
on.  If the result is not legible enough, I suggest to change the
wording.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-21 12:56     ` Eli Zaretskii
@ 2018-10-22  9:06       ` martin rudalics
  2018-10-22 13:55         ` Eli Zaretskii
  0 siblings, 1 reply; 32+ messages in thread
From: martin rudalics @ 2018-10-22  9:06 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

 > I'm not against tutorials; far from that.  I just think they should be
 > separate from Reference manuals.  Reference manuals can then point to
 > tutorials for examples.

I could put the last two sections into the "Tips and Conventions"
chapter.  Or do we have another place where to put tutorial-like text?

 > But that doesn't mean a Reference manual can consider itself done by
 > providing a "lip service" in the form of such a tutorial reference.  A
 > good Reference manual should still describe the feature in a clear and
 > useful way.

My basic idea was to put the description proper into the first three,
four sections and leave the last two, three sections to those puzzled
by the technical level used in the decription.

 > Reference manual's main audience are people who already have some,
 > perhaps even good, idea about the feature, and need help in finding
 > exactly the right tools, out of those available, to do the jop at
 > hand.  Tutorials, by contrast, target newbies who have no clue:
 > walking those through a large enough set of well-explained examples
 > will bring them up to speed, so they could proceed to the Reference
 > manual.

That's why I chose the present style: The first three, four sections
address the main audience, the people who search for the right tools.
These sections try to be concise and use cross references to lead the
reader right to the tool in question.

The remaining sections are by design not intended for finding tools.
People are supposed to read these sections when they are confused by
the technicality of the previous sections.  The examples are
intentionally not concise - code like

      (display-buffer
       (get-buffer-create "*foo*")
       '((display-buffer-below-selected display-buffer-at-bottom)))

has been written for being evaluated in place so to not confuse
already confused people more by telling them how to create *foo*
first.  I repetitively employ calls of 'display-buffer' and
'customize-set-variable' to emphasize the distinction between how
programmers are supposed to use actions and how users are supposed to
customize them.  So occasionally text in these sections is repetitive.

But asking again: How else would you address a complaint like

   Telling someone that they must instead use
   `display-buffer' ACTION hoops to accomplish
   the same thing leads them down the garden path,
   on a wild goose chase, over the river & through
   the woods, and around Robin Hood's barn.  IMO.

if not with the help of an example where every single step can be
executed right in place and the effect of that step seen right away?

 >> Readers in a hurry are not supposed to read that section.
 >
 > I think it's a mistake to take that stand when writing a Reference
 > manual.

I disagree in this particular case.  Readers in a hurry will have
found the necessary information already in the preceding sections.  If
they didn't, we have to fix that in those sections.  Only if they did
but they are still uncertain about how to put their findings into
practice they would go on with the remaining sections.

 > One thing to remember is that the manual is not the only place where
 > the documentation could live: there are doc strings as well.  Some of
 > the details might be better suited to doc strings.

Well, Alan's impression was that

   The doc string of display-buffer is a bit of a heavy read at this time
   of night.

and I'm currently contemplating to remove the description of action
alist entries from it.  'display-buffer' is a function that delegates
its work to action functions (Drew's garden path) and guides the
latter with the help of action alists which have now their separate
entry in the Elisp manual.  The "further down" in the garden path an
information is found, the more Drew will complain.  The "further up"
everybody else will complain.

A couple of weeks ago Drew complained that the doc-string of
'pop-to-buffer-same-window' misses any information about how it
handles dedicated windows.  So you amended the doc-string as follows:

   Unlike `pop-to-buffer', this function prefers using the selected
   window over popping up a new window or frame.  Specifically, if
   the selected window is neither a minibuffer window (as reported
   by `window-minibuffer-p'), nor is dedicated to another buffer
   (see `window-dedicated-p'), BUFFER will be displayed in the
   currently selected window; otherwise it will be displayed in
   another window.

While this would be appropriate for 'switch-to-buffer-other-window' it
may be wrong for 'pop-to-buffer-same-window' as soon as the user has
customized 'display-buffer-alist'.  We can't avoid the garden path of
'display-buffer' here and elsewhere.

 > I didn't say those tips are useless, far from it.  I just ended up
 > having an impression that I've read a list of tips that I will have to
 > re-read again when I need to find something in it.  So I suggested to
 > think about some way of organizing them, so that similar and related
 > stuff is closer to one another.

I see what you mean and it's obvious that the text I wrote takes the
opposite direction.  It tries to segregate the tips from the technical
description rather than to combine them.  The intention was that
experienced readers should be allowed to read the technical sections
without having to study the tips at the same time (or at all).
Confused readers OTOH should be carefully guided to read on, as time
permits.

martin



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-22  9:06       ` martin rudalics
@ 2018-10-22 13:55         ` Eli Zaretskii
  2018-10-22 19:14           ` martin rudalics
  0 siblings, 1 reply; 32+ messages in thread
From: Eli Zaretskii @ 2018-10-22 13:55 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

> Date: Mon, 22 Oct 2018 11:06:07 +0200
> From: martin rudalics <rudalics@gmx.at>
> CC: emacs-devel@gnu.org
> 
>  > I'm not against tutorials; far from that.  I just think they should be
>  > separate from Reference manuals.  Reference manuals can then point to
>  > tutorials for examples.
> 
> I could put the last two sections into the "Tips and Conventions"
> chapter.  Or do we have another place where to put tutorial-like text?

No, I don't think we have any place for tutorial-like stuff.  Tips is
something different.

> My basic idea was to put the description proper into the first three,
> four sections and leave the last two, three sections to those puzzled
> by the technical level used in the decription.

I guess I'll have to re-read the text once it's installed, maybe I
failed to catch the spirit reading the diffs (which included a lot of
whitespace changes, so it wasn't always easy to find the real
changes).

> But asking again: How else would you address a complaint like
> 
>    Telling someone that they must instead use
>    `display-buffer' ACTION hoops to accomplish
>    the same thing leads them down the garden path,
>    on a wild goose chase, over the river & through
>    the woods, and around Robin Hood's barn.  IMO.
> 
> if not with the help of an example where every single step can be
> executed right in place and the effect of that step seen right away?

Was that complain before or after I reworked the doc strings?

> Well, Alan's impression was that
> 
>    The doc string of display-buffer is a bit of a heavy read at this time
>    of night.
> 
> and I'm currently contemplating to remove the description of action
> alist entries from it.

I recommend against the removal.  People who are tired at night
(myself included) are free not to read the doc string, but that
doesn't mean there's something wrong with it.  A flexible interface
always requires a long documentation.

> 'display-buffer' is a function that delegates
> its work to action functions (Drew's garden path) and guides the
> latter with the help of action alists which have now their separate
> entry in the Elisp manual.  The "further down" in the garden path an
> information is found, the more Drew will complain.  The "further up"
> everybody else will complain.

Complaints are not the only thing to guide us in this case.

>    Unlike `pop-to-buffer', this function prefers using the selected
>    window over popping up a new window or frame.  Specifically, if
>    the selected window is neither a minibuffer window (as reported
>    by `window-minibuffer-p'), nor is dedicated to another buffer
>    (see `window-dedicated-p'), BUFFER will be displayed in the
>    currently selected window; otherwise it will be displayed in
>    another window.
> 
> While this would be appropriate for 'switch-to-buffer-other-window' it
> may be wrong for 'pop-to-buffer-same-window' as soon as the user has
> customized 'display-buffer-alist'.  We can't avoid the garden path of
> 'display-buffer' here and elsewhere.

I don't think we cannot avoid it, we just need to qualify what I wrote
with the "not customized" caveat.  Nothing a single sentence couldn't
fix.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-22 13:55         ` Eli Zaretskii
@ 2018-10-22 19:14           ` martin rudalics
  2018-10-22 19:27             ` Eli Zaretskii
  0 siblings, 1 reply; 32+ messages in thread
From: martin rudalics @ 2018-10-22 19:14 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

 >> But asking again: How else would you address a complaint like
 >>
 >>     Telling someone that they must instead use
 >>     `display-buffer' ACTION hoops to accomplish
 >>     the same thing leads them down the garden path,
 >>     on a wild goose chase, over the river & through
 >>     the woods, and around Robin Hood's barn.  IMO.
 >>
 >> if not with the help of an example where every single step can be
 >> executed right in place and the effect of that step seen right away?
 >
 > Was that complain before or after I reworked the doc strings?

After, I suppose.  It's from a mail Drew posted yesterday.

 > I recommend against the removal.  People who are tired at night
 > (myself included) are free not to read the doc string, but that
 > doesn't mean there's something wrong with it.  A flexible interface
 > always requires a long documentation.

Sooner or later the number of recognized action alist entries will
become too large.

 >> 'display-buffer' is a function that delegates
 >> its work to action functions (Drew's garden path) and guides the
 >> latter with the help of action alists which have now their separate
 >> entry in the Elisp manual.  The "further down" in the garden path an
 >> information is found, the more Drew will complain.  The "further up"
 >> everybody else will complain.
 >
 > Complaints are not the only thing to guide us in this case.

Complaints are never a good guide.  But here it's hard to find the
right balance of correctness and completeness on the one side and
conciseness on the other.

 >> While this would be appropriate for 'switch-to-buffer-other-window' it
 >> may be wrong for 'pop-to-buffer-same-window' as soon as the user has
 >> customized 'display-buffer-alist'.  We can't avoid the garden path of
 >> 'display-buffer' here and elsewhere.
 >
 > I don't think we cannot avoid it, we just need to qualify what I wrote
 > with the "not customized" caveat.  Nothing a single sentence couldn't
 > fix.

Trevor Murphy on emacs-devel

   I just noticed that `find-dired' and friends use `switch-to-buffer' as
   a subroutine.  Since this does not go through the `display-buffer'
   mechanism, it’s really hard for me to control where Emacs displays the
   Find buffer.  I’m currently advising `find-dired' to use
   `pop-to-buffer' instead.

to which Stefan replied

   There's pop-to-buffer-same-window.

Which means that people want 'pop-to-buffer-same-window' instead
because they can customize it to display the buffer in _another_
window.  Which further means that a "not customized" caveat would be
counterproductive here.

Any explanation of what 'pop-to-buffer-same-window' does without
referring the reader to 'display-buffer' is misleading, at the very
least.

martin




^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-22 19:14           ` martin rudalics
@ 2018-10-22 19:27             ` Eli Zaretskii
  2018-10-23  8:58               ` martin rudalics
  0 siblings, 1 reply; 32+ messages in thread
From: Eli Zaretskii @ 2018-10-22 19:27 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

> Date: Mon, 22 Oct 2018 21:14:52 +0200
> From: martin rudalics <rudalics@gmx.at>
> CC: emacs-devel@gnu.org
> 
>  >> While this would be appropriate for 'switch-to-buffer-other-window' it
>  >> may be wrong for 'pop-to-buffer-same-window' as soon as the user has
>  >> customized 'display-buffer-alist'.  We can't avoid the garden path of
>  >> 'display-buffer' here and elsewhere.
>  >
>  > I don't think we cannot avoid it, we just need to qualify what I wrote
>  > with the "not customized" caveat.  Nothing a single sentence couldn't
>  > fix.
> 
> Trevor Murphy on emacs-devel
> 
>    I just noticed that `find-dired' and friends use `switch-to-buffer' as
>    a subroutine.  Since this does not go through the `display-buffer'
>    mechanism, it’s really hard for me to control where Emacs displays the
>    Find buffer.  I’m currently advising `find-dired' to use
>    `pop-to-buffer' instead.
> 
> to which Stefan replied
> 
>    There's pop-to-buffer-same-window.
> 
> Which means that people want 'pop-to-buffer-same-window' instead
> because they can customize it to display the buffer in _another_
> window.

I must be missing something: using pop-to-buffer-SAME-window to
display a buffer in ANOTHER window?  How can that make sense?

> Which further means that a "not customized" caveat would be
> counterproductive here.

All I meant was to add something like "by default" to the doc string.
I don't see how that could be wrong, all Stefan's advice
notwithstanding.

We shouldn't shoot ourselves in the foot by being afraid that complex
enough customizations could invalidate the documentation.

> Any explanation of what 'pop-to-buffer-same-window' does without
> referring the reader to 'display-buffer' is misleading, at the very
> least.

I obviously disagree, as I did just that, and I object calling the
current text "misleading".



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-22 19:27             ` Eli Zaretskii
@ 2018-10-23  8:58               ` martin rudalics
  2018-10-23 11:26                 ` Pierre-Yves Luyten
                                   ` (3 more replies)
  0 siblings, 4 replies; 32+ messages in thread
From: martin rudalics @ 2018-10-23  8:58 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

 > I must be missing something: using pop-to-buffer-SAME-window to
 > display a buffer in ANOTHER window?  How can that make sense?

Hysterical raisins. In the beginning, someone wrote a function called
'find-dired' to "Run `find' and go into Dired mode on a buffer of the
output".  In order to display that buffer, the author called
'switch-to-buffer' - probably because in his daily routine he
preferred to continue working on that dired buffer right away in the
selected window.

In the end, Trevor Murphy writes that

   Like, I could imagine an alternate world where that call to
   `switch-to-buffer' could be replaced with something as heavy-handed as
   …

      (pop-to-buffer (get-buffer-create "*Find*")    '(display-buffer-same-window (inhibit-same-window)))

   … so that Emacs would still try very hard to display the Find buffer
   in the current window, but I could nevertheless override that by
   customizing `display-buffer-alist'.

And that's where 'pop-to-buffer-same-window' kicks in by accomplishing
_two_ things at the same time: It allows the author of 'find-dired'
and its "normal" users to continue working as if nothing changed at
all.  And it allows users like Trevor to customize the way *Find* is
displayed at their discretion.

An earlier approach to provide such behavior was to add functions like
'find-dired-other-window' and 'find-dired-other-frame' maybe with
appropriate key bindings.  The shortcomings of that approach are:

(1) The number of predefined functions to display a buffer is usually
     tripled.

(2) The user may have to memorize key bindings for three functions
     instead of one.

(3) These three functions still do not cover the entire spectrum of
     behaviors users want like showing the buffer on a specific side of
     the selected window or frame.

With 'pop-to-buffer-same-window' all 'find-dired' does now is to
_propose_ the selected window as the most suitable candidate for
displaying *Find*.  OTOH there's no more guarantee that *Find* will
actually appear in the selected window.  The ultimate decision of
where *Find* will appear is left to the user.

 >> Which further means that a "not customized" caveat would be
 >> counterproductive here.
 >
 > All I meant was to add something like "by default" to the doc string.
 > I don't see how that could be wrong, all Stefan's advice
 > notwithstanding.
 >
 > We shouldn't shoot ourselves in the foot by being afraid that complex
 > enough customizations could invalidate the documentation.

The doc-string of 'pop-to-buffer-same-window' is not useful for people
who are happy with 'find-dired' behaving as it did before.  Such users
ideally will not even notice that something has changed and that they
have to react to that change in some way.

The doc-string of 'pop-to-buffer-same-window' is useful for two kinds
of persons:

(1) The author of 'find-dired' who now would be aware of the fact that
*Find* will not be necessarily shown in the selected window.  He will
be warned by the word "preferably" in

"Select buffer BUFFER in some window, preferably the same one."

but he won't care about whether the default behavior avoids the
selected window if its dedicated.  In fact, he has to be prepared for
the worst like *Find* popping up on a new frame or *Find* being
displayed in the selected window despite the fact that it is dedicated
to some other buffer.

(2) Users who want to know how to _change_ the default behavior by
customizing 'display-buffer-alist'.  Such people typically want to
show *Find* in some other window so they won't care about the
dedicated status of the selected window either.

I did not object to your changes when you made them because with Drew
such objections inevitably lead to discussions why 'display-buffer'
does it all wrong and why its earlier behavior was so much superior.
But your change strengthens the view that 'display-buffer' behaves as
requested by its caller.  That view inevitably leads to confusion.

 >> Any explanation of what 'pop-to-buffer-same-window' does without
 >> referring the reader to 'display-buffer' is misleading, at the very
 >> least.
 >
 > I obviously disagree, as I did just that, and I object calling the
 > current text "misleading".

Then why do we have all this dispute about 'display-buffer'?
According to the majority of people because its documentation is
confusing, wrong, incomplete, implicit, arcane or just bad.

martin




^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-23  8:58               ` martin rudalics
@ 2018-10-23 11:26                 ` Pierre-Yves Luyten
  2018-10-23 13:45                   ` martin rudalics
  2018-10-23 17:40                   ` Stefan Monnier
  2018-10-23 14:04                 ` Drew Adams
                                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 32+ messages in thread
From: Pierre-Yves Luyten @ 2018-10-23 11:26 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, Emacs-devel, emacs-devel

Le 2018-10-23 10:58, martin rudalics a écrit :

> 
> An earlier approach to provide such behavior was to add functions like
> 'find-dired-other-window' and 'find-dired-other-frame' maybe with
> appropriate key bindings.  The shortcomings of that approach are:
> 
> (1) The number of predefined functions to display a buffer is usually
>     tripled.
> 
> (2) The user may have to memorize key bindings for three functions
>     instead of one.
> 
> (3) These three functions still do not cover the entire spectrum of
>     behaviors users want like showing the buffer on a specific side of
>     the selected window or frame.
> 

Looks to me above shortcomings list assumes user always want (1) to 
invoke the same behavior, ie always use other-frame or always 
other-windows,  or (2) to customize behavior regarding specific buffers 
(buffer names).

While i rather assume user wants to invoke specific action based on the 
context. for example while working on email i would invoke other-frame ; 
while working on markdown i would most often call other-window, both for 
the same bookmark or the same file.

Regards
Pierre-Yves



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-23 11:26                 ` Pierre-Yves Luyten
@ 2018-10-23 13:45                   ` martin rudalics
  2018-10-23 17:40                   ` Stefan Monnier
  1 sibling, 0 replies; 32+ messages in thread
From: martin rudalics @ 2018-10-23 13:45 UTC (permalink / raw)
  To: Pierre-Yves Luyten; +Cc: Eli Zaretskii, Emacs-devel, emacs-devel

 > While i rather assume user wants to invoke specific action based on
 > the context. for example while working on email i would invoke
 > other-frame ; while working on markdown i would most often call
 > other-window, both for the same bookmark or the same file.

The most simple way to accomplish that with C-x r b is by specifying
in CONDITION of 'display-buffer-alist' a function which delegates the
buffer display to 'display-buffer-pop-up-frame' provided the major
mode of the buffer shown in 'minibuffer-selected-window' is a mail
mode and to 'display-buffer-pop-up-window' provided the major mode of
that buffer is a markdown mode.  No need for additional commands or
keybindings.

martin



^ permalink raw reply	[flat|nested] 32+ messages in thread

* RE: Documenting buffer display
  2018-10-23  8:58               ` martin rudalics
  2018-10-23 11:26                 ` Pierre-Yves Luyten
@ 2018-10-23 14:04                 ` Drew Adams
  2018-10-23 18:18                   ` martin rudalics
  2018-10-23 15:18                 ` Eli Zaretskii
  2018-10-23 15:52                 ` Alan Mackenzie
  3 siblings, 1 reply; 32+ messages in thread
From: Drew Adams @ 2018-10-23 14:04 UTC (permalink / raw)
  To: martin rudalics, Eli Zaretskii; +Cc: emacs-devel

> I did not object to your changes when you made them because with Drew
> such objections inevitably lead to discussions why 'display-buffer'
> does it all wrong and why its earlier behavior was so much superior.

Seriously?  This is what the discussion has devolved to?

I object to this personal characterization - which borders
on ad hominem attack.

I never said anything about `display-buffer' getting
anything wrong, let alone getting it all wrong.  And I
never said that its earlier behavior was so much superior,
or even that it was superior, or even that it was as good.

On the contrary, several times, including more than once
in the current discussion, I've thanked you for the work
you've done on `display-buffer' and its doc.  It is an
improvement that users have more fine-grained control over
buffer display.  I think I've been quite clear about this.

The points I made that you might want to characterize as
objections are (1) the doc can use some improvement (and
your trying to improve it now is a good thing, not a bad
thing) and (2) I would like to see the simple conveniences
of `pop-to-frames' and `special-display-*' continue to be
supported and not discouraged.

If someone can't make such points without being branded
in the way you just did then there is little hope for a
constructive discussion.  Do you want only an echo
chamber, or do you welcome input that might help even
if it might disagree with your point of view in some
regards?

> Then why do we have all this dispute about 'display-buffer'?
> According to the majority of people because its documentation is
> confusing, wrong, incomplete, implicit, arcane or just bad.

Dunno whether it is a majority, but it's helpful that
you agree that this is a difficulty for at least some
of us.  (And I've never doubted that you agree about
this.  I know you recognize that this stuff is
complicated - in both behavior and explanation/doc.)

I, for one, am still at the state of being relatively
confused and ignorant.  I can't say that anything in
the doc is incorrect.  I expect that attempts to
clarify it are worthwhile, and I applaud them.
That's all.

FWIW, though I generally agree that the Emacs manuals
are mostly reference, we (Emacs generally, whether
officially or not) could use some more tutorial-like
presentations of using the various features provided
by `display-buffer'.  It is a powerful, complicated
construct, and its various possibilities deserve
more lead-you-by-the-hand exposure.

Somewhere.  Blogs, whatever, wherever.  Common use
cases presented and explicated.  That's one opinion.
The same thing is true for other complex areas, some
of which I've mentioned.  It wouldn't hurt to have
additional material out there that helps people to
better understand `display-buffer'.

I'm not saying that this is something that you guys
need to do.  I'm saying only that it is an area
where Emacs users could use more help, I think.
I think you might agree about this.

Hardly a day goes by, that one or more questions
related to this don't appear on Emacs Stack
Exchange or Reddit, for example.  And when I say
`display-buffer' I include questions about windows:
placement, which buffers, etc.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-23  8:58               ` martin rudalics
  2018-10-23 11:26                 ` Pierre-Yves Luyten
  2018-10-23 14:04                 ` Drew Adams
@ 2018-10-23 15:18                 ` Eli Zaretskii
  2018-10-23 18:23                   ` martin rudalics
  2018-10-23 15:52                 ` Alan Mackenzie
  3 siblings, 1 reply; 32+ messages in thread
From: Eli Zaretskii @ 2018-10-23 15:18 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

> Date: Tue, 23 Oct 2018 10:58:29 +0200
> From: martin rudalics <rudalics@gmx.at>
> CC: emacs-devel@gnu.org
> 
>      (pop-to-buffer (get-buffer-create "*Find*")    
> '(display-buffer-same-window (inhibit-same-window)))
> 
>   … so that Emacs would still try very hard to display the Find buffer
>   in the current window, but I could nevertheless override that by
>   customizing `display-buffer-alist'.
> 
> And that's where 'pop-to-buffer-same-window' kicks in by accomplishing
> _two_ things at the same time: It allows the author of 'find-dired'
> and its "normal" users to continue working as if nothing changed at
> all.  And it allows users like Trevor to customize the way *Find* is
> displayed at their discretion.

"Customize", as in setting display-buffer-overriding-action or
display-buffer-alist, you mean?

> An earlier approach to provide such behavior was to add functions like
> 'find-dired-other-window' and 'find-dired-other-frame' maybe with
> appropriate key bindings.

Nothing's wrong with that, IMNSHO: we do that for many other commands,
so it is a kind-of de-facto Emacs tradition/standard.

> The shortcomings of that approach are:
> 
> (1) The number of predefined functions to display a buffer is usually
>     tripled.
> 
> (2) The user may have to memorize key bindings for three functions
>     instead of one.
> 
> (3) These three functions still do not cover the entire spectrum of
>     behaviors users want like showing the buffer on a specific side of
>     the selected window or frame.

But there's also a huge advantage: users who are not very proficient
in Lisp will both discover the functionality and use it much easier.
Especially since we have many other commands factored in that way.  By
contrast, constructing display-buffer actions is not for the faint at
heart.

> With 'pop-to-buffer-same-window' all 'find-dired' does now is to
> _propose_ the selected window as the most suitable candidate for
> displaying *Find*.  OTOH there's no more guarantee that *Find* will
> actually appear in the selected window.  The ultimate decision of
> where *Find* will appear is left to the user.

FWIW, I think it's wrong to advertise display-buffer-overriding-action,
and even display-buffer-alist, as the main way of user-level tweaking
commands into doing something completely different from what they were
coded to do.  I could argue that if such overrides are to be used as a
matter of routine, then the whole "middle layer" of
display-buffer-SOMETHING functions, including
pop-to-buffer-same-window, is entirely redundant, because many users
will override their preferences anyway.

My POV on this functionality is that the overriding action lists are
mainly for Lisp programs, not for users, and that those Lisp programs
don't abuse the feature to completely subvert certain display-buffer
function to do the opposite of what their names say.

But I digress.

> The doc-string of 'pop-to-buffer-same-window' is useful for two kinds
> of persons:
> 
> (1) The author of 'find-dired' who now would be aware of the fact that
> *Find* will not be necessarily shown in the selected window.  He will
> be warned by the word "preferably" in
> 
> "Select buffer BUFFER in some window, preferably the same one."
> 
> but he won't care about whether the default behavior avoids the
> selected window if its dedicated.  In fact, he has to be prepared for
> the worst like *Find* popping up on a new frame or *Find* being
> displayed in the selected window despite the fact that it is dedicated
> to some other buffer.
> 
> (2) Users who want to know how to _change_ the default behavior by
> customizing 'display-buffer-alist'.  Such people typically want to
> show *Find* in some other window so they won't care about the
> dedicated status of the selected window either.

So would adding to the doc string something like this:

  (This default behavior can be changed by customizing
  `display-buffer-overriding-action' and `display-buffer-alist'.)

take care of your concerns?  This is that "single sentence" I had in
mind a few messages back.

IOW, I assume that in 90% of the cases the *Find* buffer _will_ pop up
in the selected window, and that the other 10% are mostly due to users
who should be knowing what they are doing, and if they don't, it's
their funeral.  If *Find* does _not_ pop up in the selected window in
the vast majority of cases, then IMO find-dired has a bug that needs
to be fixed.

And I submit that you forget one very important class of readers:
those who are neither the author of find-dired nor those who want to
tweak the heck out of find-dired.  They are those who want to
understand _why_ find-dired works like it does, or _how_ does it cause
the buffer to be displayed in that particular window.  IOW, those who
see a call to pop-to-buffer-same-window and want to understand what
that does and which other variables/functions affect what it does.
This is the primary audience for doc strings.

> But your change strengthens the view that 'display-buffer' behaves as
> requested by its caller.

It usually does, or at least should, IMO.  It is IMO wrong to make the
documentation too complex in order to be 110% accurate, if that
accuracy comes at a price of leaving the reader without a more-or-less
clear mental picture regarding what a feature does in 90% of use case.
Rare corner cases should be "banished" to footnotes and parenthesized
notes, or even omitted altogether, if they complicate the main use
cases too much.  This is one such case: it makes little sense to me to
waste too much of the reader's prime time in order to explain how a
function designed to display a buffer in the selected window could be
tweaked into doing the opposite.

> That view inevitably leads to confusion.

Are you sure "confusion" is the right word here?  If so, please
elaborate, because I think you meant something like "inaccurate
information" (and IMO the inaccuracy is very minor).

In any case, would you agree that qualifications such as the one
proposed above will go a long way towards fixing those issues?

> >> Any explanation of what 'pop-to-buffer-same-window' does without
> >> referring the reader to 'display-buffer' is misleading, at the very
> >> least.
> >
> > I obviously disagree, as I did just that, and I object calling the
> > current text "misleading".
> 
> Then why do we have all this dispute about 'display-buffer'?

You mean, the discussion about the changes in the manual?  Because you
asked for review and comments.

> According to the majority of people because its documentation is
> confusing, wrong, incomplete, implicit, arcane or just bad.

Are you talking about the doc strings or about the manual?  If about
doc strings, then I'd like to hear or read those complaints, if they
are still valid after my recent changes.  I hope you trust me that I
wouldn't have left unfixed any doc strings matching any of the above
complaints.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-23  8:58               ` martin rudalics
                                   ` (2 preceding siblings ...)
  2018-10-23 15:18                 ` Eli Zaretskii
@ 2018-10-23 15:52                 ` Alan Mackenzie
  2018-10-23 18:25                   ` martin rudalics
  2018-11-08 19:25                   ` martin rudalics
  3 siblings, 2 replies; 32+ messages in thread
From: Alan Mackenzie @ 2018-10-23 15:52 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, emacs-devel

Hello, Martin.

On Tue, Oct 23, 2018 at 10:58:29 +0200, martin rudalics wrote:

[ .... ]

> Then why do we have all this dispute about 'display-buffer'?
> According to the majority of people because its documentation is
> confusing, wrong, incomplete, implicit, arcane or just bad.

I was one of the people recently criticising these things.  I think I
went over the top in what I said, so apologies for that.  The
documentation is difficult because the function does so much.  Yet
display-buffer is a coherent do-one-thing-and-do-it-well function, and I
think any replacement for it would not be as good.

All the same, there are some concrete things in display-buffer's doc
string I would like to comment on.

(i) PLEASE do not delete the extensive description of the ACTION
argument.  Without it, the function would be more difficult to
understand, even if the doc string were shorter.

(ii) The optional argument FRAME gets combined with other ALIST entries.
But where?  Is it considered before or after the other entries?

(iii) "If ACTION is non-nil .... where FUNCTION is either a function or
a list of functions ....".  Would it not be better to call this element
"FUNCTIONS" (plural)?

(iv) "If ACTION is non-nil .... ALIST is an arbitrary association
list...".  This is unfinished.  Could it not say, for example, "... an
arbitrary association list which FOO uses to BAR BAZ (see below)"?

(v) "Based on those arguments, it should display the buffer and return
the window.".  Possibly better would be "it should TRY TO display the
buffer and return the window.".  Maybe.

(vi) (Same paragraph): isn't there a missing "...otherwise the function
will throw an error" after the bit about (allow-no-window . t)?

(vii) `reusable frames': it sort of seems that a list of frames could be
given as the cdr of this entry.  That is not the case.  Maybe the text
could become: "value, AN ATOM, specifies frame(s) to search...".  This
will remove that uncertainty over the possibility of a list of frames,
forcing the reader to follow the hyperlink to get details.

(viii) `allow-no-window' is a little unclear on what happens when a
function fails to display and return a window.  The text implies that
the window remains undisplayed, whereas I think that instead the next
function is tried, and so on, until one returns a window.

> martin

-- 
Alan Mackenzie (Nuremberg, Germany).



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-23 11:26                 ` Pierre-Yves Luyten
  2018-10-23 13:45                   ` martin rudalics
@ 2018-10-23 17:40                   ` Stefan Monnier
  1 sibling, 0 replies; 32+ messages in thread
From: Stefan Monnier @ 2018-10-23 17:40 UTC (permalink / raw)
  To: emacs-devel

> While i rather assume user wants to invoke specific action based on the
> context. for example while working on email i would invoke other-frame ;
> while working on markdown i would most often call other-window, both for the
> same bookmark or the same file.

Which is why I like the other-frame-window package.
I *really* think Emacs would be improved by incorporating and replacing
its C-x 4 and C-x 5 keymaps with the corresponding bindings
in other-frame-window.


        Stefan




^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-23 14:04                 ` Drew Adams
@ 2018-10-23 18:18                   ` martin rudalics
  0 siblings, 0 replies; 32+ messages in thread
From: martin rudalics @ 2018-10-23 18:18 UTC (permalink / raw)
  To: Drew Adams, Eli Zaretskii; +Cc: emacs-devel

 >> I did not object to your changes when you made them because with Drew
 >> such objections inevitably lead to discussions why 'display-buffer'
 >> does it all wrong and why its earlier behavior was so much superior.
 >
 > Seriously?

Yes.  I'm afraid stating my opinion in the context of 'display-buffer'
because OT1H I do not feel responsible for its present implementation
and OTOH I feel obliged to defend it because its implementers won't.

 > This is what the discussion has devolved to?

Sadly, yes.

martin



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-23 15:18                 ` Eli Zaretskii
@ 2018-10-23 18:23                   ` martin rudalics
  2018-10-23 19:07                     ` Eli Zaretskii
  0 siblings, 1 reply; 32+ messages in thread
From: martin rudalics @ 2018-10-23 18:23 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

 >> And that's where 'pop-to-buffer-same-window' kicks in by accomplishing
 >> _two_ things at the same time: It allows the author of 'find-dired'
 >> and its "normal" users to continue working as if nothing changed at
 >> all.  And it allows users like Trevor to customize the way *Find* is
 >> displayed at their discretion.
 >
 > "Customize", as in setting display-buffer-overriding-action or
 > display-buffer-alist, you mean?

The latter.  'display-buffer-overriding-action' is a variable reserved
for applications as the manual should now state more clearly:

      `display-buffer-overriding-action', on the other hand, is reserved
      for applications - who seldom use that option and if they use it,
      then with utmost care.

 >> An earlier approach to provide such behavior was to add functions like
 >> 'find-dired-other-window' and 'find-dired-other-frame' maybe with
 >> appropriate key bindings.
 >
 > Nothing's wrong with that, IMNSHO: we do that for many other commands,
 > so it is a kind-of de-facto Emacs tradition/standard.

Our former maintainer strongly objected the introduction of such
commands and it's not very easy for me to adapt.  In particular
because I have absolutely no opinion in this regard - I never use such
commands consciously.

 > But there's also a huge advantage: users who are not very proficient
 > in Lisp will both discover the functionality and use it much easier.
 > Especially since we have many other commands factored in that way.  By
 > contrast, constructing display-buffer actions is not for the faint at
 > heart.

The problem is that in most buffer display cases no alternative
'-other-frame', '-other-window', '-same-window' constructs are
provided.  If there were a systematic way to provide them and if there
were suitably mnemonic key-bindings for such commands, things would be
certainly different.

 > FWIW, I think it's wrong to advertise display-buffer-overriding-action,

... as you can read above I advertise the opposite ...

 > and even display-buffer-alist, as the main way of user-level tweaking
 > commands into doing something completely different from what they were
 > coded to do.

And the manual should say now

      Users should not pose too many and too severe restrictions on how
      arbitrary buffers get displayed.  Otherwise, they will risk to
      lose the characteristics of showing a buffer for a certain purpose.

 > I could argue that if such overrides are to be used as a
 > matter of routine, then the whole "middle layer" of
 > display-buffer-SOMETHING functions, including
 > pop-to-buffer-same-window, is entirely redundant, because many users
 > will override their preferences anyway.

What do you suppose a user to do if 'pop-to-buffer-same-window' is the
_only_ alternative an application offers to display a buffer?

 > My POV on this functionality is that the overriding action lists are
 > mainly for Lisp programs,

Right.  But you should have read the manual before.

 > not for users, and that those Lisp programs
 > don't abuse the feature to completely subvert certain display-buffer
 > function to do the opposite of what their names say.
 >
 > But I digress.

Why.  You only repeated what the manual already should say now.

 > So would adding to the doc string something like this:
 >
 >    (This default behavior can be changed by customizing
 >    `display-buffer-overriding-action' and `display-buffer-alist'.)
 >
 > take care of your concerns?  This is that "single sentence" I had in
 > mind a few messages back.

That doc-string is not for users.  It could say that applications
cannot expect that the buffer is displayed in the selected window or
that the dedicatedness of that window is respected because a user's
customization may override everything that function specifies.

 > IOW, I assume that in 90% of the cases the *Find* buffer _will_ pop up
 > in the selected window, and that the other 10% are mostly due to users
 > who should be knowing what they are doing, and if they don't, it's
 > their funeral.  If *Find* does _not_ pop up in the selected window in
 > the vast majority of cases, then IMO find-dired has a bug that needs
 > to be fixed.

*Find* will continue to pop up in the selected window in the vast
majority of cases.  Just that an application cannot be sure that it
will pop up there in _all_ cases.

 > And I submit that you forget one very important class of readers:
 > those who are neither the author of find-dired nor those who want to
 > tweak the heck out of find-dired.  They are those who want to
 > understand _why_ find-dired works like it does, or _how_ does it cause
 > the buffer to be displayed in that particular window.  IOW, those who
 > see a call to pop-to-buffer-same-window and want to understand what
 > that does and which other variables/functions affect what it does.
 > This is the primary audience for doc strings.

Such users will have to read the documentation of 'display-buffer'.
It's their funeral if they don't.

 > It usually does, or at least should, IMO.  It is IMO wrong to make the
 > documentation too complex in order to be 110% accurate, if that
 > accuracy comes at a price of leaving the reader without a more-or-less
 > clear mental picture regarding what a feature does in 90% of use case.
 > Rare corner cases should be "banished" to footnotes and parenthesized
 > notes, or even omitted altogether, if they complicate the main use
 > cases too much.  This is one such case: it makes little sense to me to
 > waste too much of the reader's prime time in order to explain how a
 > function designed to display a buffer in the selected window could be
 > tweaked into doing the opposite.

Then why do you care to talk about the dedicatedness of windows in the
doc-string?  How many people use dedicated windows?  When and where do
you use them?

 >> That view inevitably leads to confusion.
 >
 > Are you sure "confusion" is the right word here?  If so, please
 > elaborate, because I think you meant something like "inaccurate
 > information" (and IMO the inaccuracy is very minor).

I don't think that "confusion" is the right word.  IMO the doc-string
is just wrong.  But I didn't want to say that.

 > In any case, would you agree that qualifications such as the one
 > proposed above will go a long way towards fixing those issues?

I sketched above what I would write instead.

 >> Then why do we have all this dispute about 'display-buffer'?
 >
 > You mean, the discussion about the changes in the manual?  Because you
 > asked for review and comments.

I meant the disputes excerpts of which I cited here in various
occasions and which amount to the next two lines.

 >> According to the majority of people because its documentation is
 >> confusing, wrong, incomplete, implicit, arcane or just bad.
 >
 > Are you talking about the doc strings or about the manual?  If about
 > doc strings, then I'd like to hear or read those complaints, if they
 > are still valid after my recent changes.  I hope you trust me that I
 > wouldn't have left unfixed any doc strings matching any of the above
 > complaints.

I'll remind you the next time this issue comes up.  At least Alan just
wrote about the doc-strings.

martin



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-23 15:52                 ` Alan Mackenzie
@ 2018-10-23 18:25                   ` martin rudalics
  2018-11-08 19:25                   ` martin rudalics
  1 sibling, 0 replies; 32+ messages in thread
From: martin rudalics @ 2018-10-23 18:25 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: Eli Zaretskii, emacs-devel

 > All the same, there are some concrete things in display-buffer's doc
 > string I would like to comment on.

Thanks for these comments.

 > (i) PLEASE do not delete the extensive description of the ACTION
 > argument.  Without it, the function would be more difficult to
 > understand, even if the doc string were shorter.

I would like to remove the description of the ALIST entries.  At least
these

  ‘window-height’ -- Value specifies either an integer (the number
     of lines of a new window), a floating point number (the
     fraction of a new window with respect to the height of the
     frame’s root window) or a function to be called with one
     argument - a new window.  The function is supposed to adjust
     the height of the window; its return value is ignored.
     Suitable functions are ‘shrink-window-if-larger-than-buffer’
     and ‘fit-window-to-buffer’.

  ‘window-width’ -- Value specifies either an integer (the number
     of columns of a new window), a floating point number (the
     fraction of a new window with respect to the width of the
     frame’s root window) or a function to be called with one
     argument - a new window.  The function is supposed to adjust
     the width of the window; its return value is ignored.

occupy too much space and are hardly indispensable for understanding
'display-buffer'.  WDYT?

 > (ii) The optional argument FRAME gets combined with other ALIST entries.
 > But where?  Is it considered before or after the other entries?

It's inserted into the list of 'reusable-frames' after "most of" the
other entries.  So any separate specification of 'reusable-frames'
will usually override it.  Something similar holds for a non-nil
non-list value of the ACTION argument.  Search for 'extra-action' in
the code.  Applications should use neither the one nor the other.

 > (iii) "If ACTION is non-nil .... where FUNCTION is either a function or
 > a list of functions ....".  Would it not be better to call this element
 > "FUNCTIONS" (plural)?

I have no opinion in this regard.  If you feel strongly about it,
please change it.

 > (iv) "If ACTION is non-nil .... ALIST is an arbitrary association
 > list...".  This is unfinished.  Could it not say, for example, "... an
 > arbitrary association list which FOO uses to BAR BAZ (see below)"?

I now try to say in the manual in more detail where and how ALIST is
constructed and used.  Inherently, an eventually fully constructed
ALIST is passed to all action functions 'display-buffer' eventually
calls.  But specifying how such an ALIST is constructed cannot be part
of the doc-string.  I now give one example of a fully constructed
ALIST in the manual.  And what an action function does with an entry
is described individually for each action function.

 > (v) "Based on those arguments, it should display the buffer and return
 > the window.".  Possibly better would be "it should TRY TO display the
 > buffer and return the window.".  Maybe.

Maybe.  There was a time when 'display-buffer' was considered to never
fail.  Even now it hardly ever fails to display a buffer.  You need
quite a couple of ropes to accomplish that.

 > (vi) (Same paragraph): isn't there a missing "...otherwise the function
 > will throw an error" after the bit about (allow-no-window . t)?

'display-buffer' doesn't throw an error, hopefully.  If it fails it
returns nil.

 > (vii) `reusable frames': it sort of seems that a list of frames could be
 > given as the cdr of this entry.  That is not the case.  Maybe the text
 > could become: "value, AN ATOM, specifies frame(s) to search...".  This
 > will remove that uncertainty over the possibility of a list of frames,
 > forcing the reader to follow the hyperlink to get details.

Please change this as you see fit.

 > (viii) `allow-no-window' is a little unclear on what happens when a
 > function fails to display and return a window.  The text implies that
 > the window remains undisplayed, whereas I think that instead the next
 > function is tried, and so on, until one returns a window.

Yes.  I'll try to fix this as soon as I understand the semantics.
(And please try my patch, read the new sections and send fixes for the more
embarrassing errors.)

Thanks, martin




^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-23 18:23                   ` martin rudalics
@ 2018-10-23 19:07                     ` Eli Zaretskii
  2018-10-24  9:44                       ` martin rudalics
  0 siblings, 1 reply; 32+ messages in thread
From: Eli Zaretskii @ 2018-10-23 19:07 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

> Date: Tue, 23 Oct 2018 20:23:38 +0200
> From: martin rudalics <rudalics@gmx.at>
> CC: emacs-devel@gnu.org
> 
>  >> An earlier approach to provide such behavior was to add functions like
>  >> 'find-dired-other-window' and 'find-dired-other-frame' maybe with
>  >> appropriate key bindings.
>  >
>  > Nothing's wrong with that, IMNSHO: we do that for many other commands,
>  > so it is a kind-of de-facto Emacs tradition/standard.
> 
> Our former maintainer strongly objected the introduction of such
> commands and it's not very easy for me to adapt.

I hope it isn't a scoop that our former maintainer's opinions are not
the only ones on the block.

>  > But there's also a huge advantage: users who are not very proficient
>  > in Lisp will both discover the functionality and use it much easier.
>  > Especially since we have many other commands factored in that way.  By
>  > contrast, constructing display-buffer actions is not for the faint at
>  > heart.
> 
> The problem is that in most buffer display cases no alternative
> '-other-frame', '-other-window', '-same-window' constructs are
> provided.

I'm not saying that we should provide such variants for every
buffer-display function.  I'm saying that if it makes sense in the
case of find-dired and other similar commands, there's nothing wrong
with having such variants.

> If there were a systematic way to provide them and if there were
> suitably mnemonic key-bindings for such commands, things would be
> certainly different.

Nor does every command have to have a keybinding by default.

>  > FWIW, I think it's wrong to advertise display-buffer-overriding-action,
> 
> ... as you can read above I advertise the opposite ...
> 
>  > and even display-buffer-alist, as the main way of user-level tweaking
>  > commands into doing something completely different from what they were
>  > coded to do.
> 
> And the manual should say now

I was mostly talking about doc strings.

>       Users should not pose too many and too severe restrictions on how
>       arbitrary buffers get displayed.  Otherwise, they will risk to
>       lose the characteristics of showing a buffer for a certain purpose.

Then we agree.  And consequently, the fact that what I wrote in the
doc string about pop-to-buffer-same-window doesn't cover such
customizations should not be a reason to say the doc string is
misleading or confusing, do we agree about that?

>  > I could argue that if such overrides are to be used as a
>  > matter of routine, then the whole "middle layer" of
>  > display-buffer-SOMETHING functions, including
>  > pop-to-buffer-same-window, is entirely redundant, because many users
>  > will override their preferences anyway.
> 
> What do you suppose a user to do if 'pop-to-buffer-same-window' is the
> _only_ alternative an application offers to display a buffer?

They should ask for a separate command, or for a user option to have
the buffer displayed not in the selected window.  That option could
(but doesn't have to) be implemented under the hood using action
lists, of course.

>  > So would adding to the doc string something like this:
>  >
>  >    (This default behavior can be changed by customizing
>  >    `display-buffer-overriding-action' and `display-buffer-alist'.)
>  >
>  > take care of your concerns?  This is that "single sentence" I had in
>  > mind a few messages back.
> 
> That doc-string is not for users.

??? Then for whom are they?

> It could say that applications cannot expect that the buffer is
> displayed in the selected window or that the dedicatedness of that
> window is respected because a user's customization may override
> everything that function specifies.

That is not a useful documentation, IMO.  It sacrifices usefulness on
the altar of 100% accuracy, instead of being much more useful for the
price of being only 99% accurate.

> *Find* will continue to pop up in the selected window in the vast
> majority of cases.  Just that an application cannot be sure that it
> will pop up there in _all_ cases.

The one-sentence qualification goes a long way towards warning of this
rare possibility.  I see no reason to expand more about that, as doing
that runs the risk of drowning the main scenario in the sea of
relatively unimportant details.

>  > And I submit that you forget one very important class of readers:
>  > those who are neither the author of find-dired nor those who want to
>  > tweak the heck out of find-dired.  They are those who want to
>  > understand _why_ find-dired works like it does, or _how_ does it cause
>  > the buffer to be displayed in that particular window.  IOW, those who
>  > see a call to pop-to-buffer-same-window and want to understand what
>  > that does and which other variables/functions affect what it does.
>  > This is the primary audience for doc strings.
> 
> Such users will have to read the documentation of 'display-buffer'.
> It's their funeral if they don't.

We disagree.  I specifically made the doc strings of intermediate
functions more explicit about what they say to avoid forcing the users
to go all the way to display-buffer.  The main reason was that it was
very non-trivial for me, having read the doc string of display-buffer,
to propagate the information back to the higher level functions I was
interested in.  And if it was non-trivial for me, it is certainly
non-trivial for less experienced Lispers and users.

>  > It usually does, or at least should, IMO.  It is IMO wrong to make the
>  > documentation too complex in order to be 110% accurate, if that
>  > accuracy comes at a price of leaving the reader without a more-or-less
>  > clear mental picture regarding what a feature does in 90% of use case.
>  > Rare corner cases should be "banished" to footnotes and parenthesized
>  > notes, or even omitted altogether, if they complicate the main use
>  > cases too much.  This is one such case: it makes little sense to me to
>  > waste too much of the reader's prime time in order to explain how a
>  > function designed to display a buffer in the selected window could be
>  > tweaked into doing the opposite.
> 
> Then why do you care to talk about the dedicatedness of windows in the
> doc-string?

Because that describes what the function does.

> How many people use dedicated windows?  When and where do you use
> them?

I don't see how this is relevant to the discussion.  If the code
honors dedicated windows, they are important enough to be mentioned in
the doc string.  If you think dedicated windows are not important, why
did you code their support?

> IMO the doc-string is just wrong.

I cannot disagree more, sorry.  And since we disagree so much, I guess
we should stop this part of the discussion, and I should probably
refrain from commenting on your manual work.

Thanks.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-23 19:07                     ` Eli Zaretskii
@ 2018-10-24  9:44                       ` martin rudalics
  2018-10-24 14:48                         ` Eli Zaretskii
  0 siblings, 1 reply; 32+ messages in thread
From: martin rudalics @ 2018-10-24  9:44 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

 >> What do you suppose a user to do if 'pop-to-buffer-same-window' is the
 >> _only_ alternative an application offers to display a buffer?
 >
 > They should ask for a separate command, or for a user option to have
 > the buffer displayed not in the selected window.  That option could
 > (but doesn't have to) be implemented under the hood using action
 > lists, of course.

That user option already exists as 'display-buffer-alist'.  That
option was invented precisely for that purpose.  That option has no
other purpose.

 >> That doc-string is not for users.
 >
 > ??? Then for whom are they?

For application programmers only.  If you look at the history of that
function you will see that I added it once, that Chong removed it
later and finally re-added it.  IIRC Stefan didn't like it for some
reason and wanted programmers to write out its specification directly.
In retrospect, he was right because 'pop-to-buffer-same-window' does
indeed create false assumptions.

In short

   (pop-to-buffer-same-window buffer norecord)

which can be rewritten as

   (pop-to-buffer buffer display-buffer--same-window-action norecord)

is _not_ semantically equivalent to

   (select-window (display-buffer-same-window buffer nil) norecord)

That last fact is what 'display-buffer' is all about.  'pop-to-buffer'
calls 'display-buffer' so users can customize its behavior.  An
application calls 'pop-to-buffer' so users can customize its behavior.

If we don't agree on this single central issue, it makes no sense to
discuss 'display-buffer' any further.  'display-buffer' does not offer
anything else.  Its sole purpose is to allow users to customize buffer
display.

 >> Such users will have to read the documentation of 'display-buffer'.
 >> It's their funeral if they don't.
 >
 > We disagree.  I specifically made the doc strings of intermediate
 > functions more explicit about what they say to avoid forcing the users
 > to go all the way to display-buffer.  The main reason was that it was
 > very non-trivial for me, having read the doc string of display-buffer,
 > to propagate the information back to the higher level functions I was
 > interested in.  And if it was non-trivial for me, it is certainly
 > non-trivial for less experienced Lispers and users.

Sadly we disagree here ...

 >> Then why do you care to talk about the dedicatedness of windows in the
 >> doc-string?
 >
 > Because that describes what the function does.

... and here ...

 >> How many people use dedicated windows?  When and where do you use
 >> them?
 >
 > I don't see how this is relevant to the discussion.  If the code
 > honors dedicated windows, they are important enough to be mentioned in
 > the doc string.  If you think dedicated windows are not important, why
 > did you code their support?

.. and here.  The code that honors dedicated windows is that of
'display-buffer-same-window' and the latter's doc-string describes
that.

 >> IMO the doc-string is just wrong.
 >
 > I cannot disagree more, sorry.  And since we disagree so much, I guess
 > we should stop this part of the discussion, and I should probably
 > refrain from commenting on your manual work.

At this moment I can only thank you for all the confidence and
patience you've shown in this thread.  I'm probably too categorical
and also feel too old and tired to go on further with this subject.
So let's call it off.  If people want to continue with it, feel free
to peruse the text I submitted any which way you like.

Thanks again, martin



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-24  9:44                       ` martin rudalics
@ 2018-10-24 14:48                         ` Eli Zaretskii
  2018-10-24 17:40                           ` martin rudalics
  0 siblings, 1 reply; 32+ messages in thread
From: Eli Zaretskii @ 2018-10-24 14:48 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

> Date: Wed, 24 Oct 2018 11:44:56 +0200
> From: martin rudalics <rudalics@gmx.at>
> CC: emacs-devel@gnu.org
> 
>  >> What do you suppose a user to do if 'pop-to-buffer-same-window' is the
>  >> _only_ alternative an application offers to display a buffer?
>  >
>  > They should ask for a separate command, or for a user option to have
>  > the buffer displayed not in the selected window.  That option could
>  > (but doesn't have to) be implemented under the hood using action
>  > lists, of course.
> 
> That user option already exists as 'display-buffer-alist'.  That
> option was invented precisely for that purpose.  That option has no
> other purpose.

Just to clarify what I meant: I did NOT mean display-buffer-alist.  I
meant something like this:

  find-dired is an interactive compiled function...
  [...]
  By default, display the buffer in the selected window;
  NO-SELECT non-nil (interactively, prefix argument) means display the
  buffer in a window other than the selected one instead.

or

  By default, display the buffer in the selected window, but if
  the value of `find-dired-no-select' is non-nil,  display the
  buffer in a window other than the selected one instead.

This is our usual method of letting users tweak some minor aspects of
how a command works, and I see no reason why users would instead have
to construct action lists to do the same for commands that happen to
use display-buffer internally.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-24 14:48                         ` Eli Zaretskii
@ 2018-10-24 17:40                           ` martin rudalics
  2018-10-24 18:25                             ` Eli Zaretskii
  2018-10-25 20:42                             ` Juri Linkov
  0 siblings, 2 replies; 32+ messages in thread
From: martin rudalics @ 2018-10-24 17:40 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

 > Just to clarify what I meant: I did NOT mean display-buffer-alist.  I
 > meant something like this:
 >
 >    find-dired is an interactive compiled function...
 >    [...]
 >    By default, display the buffer in the selected window;
 >    NO-SELECT non-nil (interactively, prefix argument) means display the
 >    buffer in a window other than the selected one instead.

NO-SELECT non-nil implies that the window to show the buffer will
not be selected which is probably not what the user wants here.

 > or
 >
 >    By default, display the buffer in the selected window, but if
 >    the value of `find-dired-no-select' is non-nil,  display the
 >    buffer in a window other than the selected one instead.
 >
 > This is our usual method of letting users tweak some minor aspects of
 > how a command works, and I see no reason why users would instead have
 > to construct action lists to do the same for commands that happen to
 > use display-buffer internally.

Applications have the choice: Prescribe where and how buffers should
be displayed or delegate that task to 'display-buffer'.  'ediff' uses
the former approach through a number of options like, for example,
'ediff-split-window-function'.  'edebug' uses 'edebug-pop-to-buffer'.
Users of the latter call 'pop-to-buffer' or 'display-buffer' directly.
Both approaches are valid.

'switch-to-buffer' belongs to the first group unless the selected
window is dedicated to some other buffer in which case
'switch-to-buffer' leaves the decision to 'pop-to-buffer' and we
already have a hybrid approach.  This is problematic and I always
advocate against the use of 'switch-to-buffer' in code: The
application should decide whether it wants one or the other.

Still, if we want users to tweak only "some minor aspects of how a
command works", the approach you sketch above is completely valid and
I think that Juri's recent proposal to allow the directional choice of
windows goes in the same direction and is even more universal.  We can
use 'display-buffer-overriding-action' for the prefix argument case
and I am all for it.  In either case, such a solution is not too
distinct from Stephen Leake's 'other-frame-window' approach so we
maybe should study that as well.

But once an application directly or indirectly calls 'display-buffer'
the latter's customizations may kick in and invalidate all assumptions
about the window used.  So if your NO-SELECT or Juri's directional
effort fail, 'display-buffer' will inevitably rule the game.

martin



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-24 17:40                           ` martin rudalics
@ 2018-10-24 18:25                             ` Eli Zaretskii
  2018-10-25 20:42                             ` Juri Linkov
  1 sibling, 0 replies; 32+ messages in thread
From: Eli Zaretskii @ 2018-10-24 18:25 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

> Date: Wed, 24 Oct 2018 19:40:02 +0200
> From: martin rudalics <rudalics@gmx.at>
> CC: emacs-devel@gnu.org
> 
> But once an application directly or indirectly calls 'display-buffer'
> the latter's customizations may kick in and invalidate all assumptions
> about the window used.  So if your NO-SELECT or Juri's directional
> effort fail, 'display-buffer' will inevitably rule the game.

As I said before, this is okay, IMO, if used only rarely and not
promoted as the main or even just important way of tweaking what
commands do.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-24 17:40                           ` martin rudalics
  2018-10-24 18:25                             ` Eli Zaretskii
@ 2018-10-25 20:42                             ` Juri Linkov
  1 sibling, 0 replies; 32+ messages in thread
From: Juri Linkov @ 2018-10-25 20:42 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, emacs-devel

> Still, if we want users to tweak only "some minor aspects of how a
> command works", the approach you sketch above is completely valid and
> I think that Juri's recent proposal to allow the directional choice of
> windows goes in the same direction and is even more universal.  We can
> use 'display-buffer-overriding-action' for the prefix argument case
> and I am all for it.  In either case, such a solution is not too
> distinct from Stephen Leake's 'other-frame-window' approach so we
> maybe should study that as well.

Both are useful: other-frame-window to support the prefixes C-x 4/5
and also S-left/S-right/S-up/S-down for relative window placement
to specify the direction in which to display the buffer.  Maybe for
non-interactive use we need new actions like display-buffer-in-direction,
and for interactive use also to support a prefix key modifier to specify
whether the displayed buffer should be selected afterwards or not.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-20 12:20 Documenting buffer display martin rudalics
  2018-10-20 13:21 ` Eli Zaretskii
  2018-10-20 15:22 ` Drew Adams
@ 2018-11-04  9:06 ` martin rudalics
  2 siblings, 0 replies; 32+ messages in thread
From: martin rudalics @ 2018-11-04  9:06 UTC (permalink / raw)
  To: emacs-devel

 > Attached find a rewrite of the documentation of buffer display
 > functions to be applied against the release branch.

Commited to the release branch now.  I tried to address most issues
raised in the discussion of this subject.  Feel free to revert or
improve any of the changes I made.  They are an attempt to rewrite the
documentation from my point of view which probably does not coincide
with that of the average reader.

Thanks for all suggestions, martin




^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Documenting buffer display
  2018-10-23 15:52                 ` Alan Mackenzie
  2018-10-23 18:25                   ` martin rudalics
@ 2018-11-08 19:25                   ` martin rudalics
  1 sibling, 0 replies; 32+ messages in thread
From: martin rudalics @ 2018-11-08 19:25 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: Eli Zaretskii, emacs-devel

 > All the same, there are some concrete things in display-buffer's doc
 > string I would like to comment on.

I hope I addressed all issues.  Please have a look.

 > (i) PLEASE do not delete the extensive description of the ACTION
 > argument.  Without it, the function would be more difficult to
 > understand, even if the doc string were shorter.
 >
 > (ii) The optional argument FRAME gets combined with other ALIST entries.
 > But where?  Is it considered before or after the other entries?

I think it says that now.

 > (iii) "If ACTION is non-nil .... where FUNCTION is either a function or
 > a list of functions ....".  Would it not be better to call this element
 > "FUNCTIONS" (plural)?
 >
 > (iv) "If ACTION is non-nil .... ALIST is an arbitrary association
 > list...".  This is unfinished.  Could it not say, for example, "... an
 > arbitrary association list which FOO uses to BAR BAZ (see below)"?
 >
 > (v) "Based on those arguments, it should display the buffer and return
 > the window.".  Possibly better would be "it should TRY TO display the
 > buffer and return the window.".  Maybe.
 >
 > (vi) (Same paragraph): isn't there a missing "...otherwise the function
 > will throw an error" after the bit about (allow-no-window . t)?

I'm not quite sure what you meant here.  'display-buffer' will return
nil after one of its action functions "successfully" processed the
'allow-no-window' entry and will also return nil if it didn't find a
window (which is quite difficult to achieve).  But by design it never
throws an error.

 > (vii) `reusable frames': it sort of seems that a list of frames could be
 > given as the cdr of this entry.  That is not the case.  Maybe the text
 > could become: "value, AN ATOM, specifies frame(s) to search...".  This
 > will remove that uncertainty over the possibility of a list of frames,
 > forcing the reader to follow the hyperlink to get details.

I use the tem "set" now.

 > (viii) `allow-no-window' is a little unclear on what happens when a
 > function fails to display and return a window.  The text implies that
 > the window remains undisplayed, whereas I think that instead the next
 > function is tried, and so on, until one returns a window.

The window remains undisplayed if this entry is actually processed by
an action function and 'display-buffer' returns immediately
thereafter.  No further action functions are tried in that case.

martin



^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2018-11-08 19:25 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-20 12:20 Documenting buffer display martin rudalics
2018-10-20 13:21 ` Eli Zaretskii
2018-10-20 18:02   ` martin rudalics
2018-10-21 12:56     ` Eli Zaretskii
2018-10-22  9:06       ` martin rudalics
2018-10-22 13:55         ` Eli Zaretskii
2018-10-22 19:14           ` martin rudalics
2018-10-22 19:27             ` Eli Zaretskii
2018-10-23  8:58               ` martin rudalics
2018-10-23 11:26                 ` Pierre-Yves Luyten
2018-10-23 13:45                   ` martin rudalics
2018-10-23 17:40                   ` Stefan Monnier
2018-10-23 14:04                 ` Drew Adams
2018-10-23 18:18                   ` martin rudalics
2018-10-23 15:18                 ` Eli Zaretskii
2018-10-23 18:23                   ` martin rudalics
2018-10-23 19:07                     ` Eli Zaretskii
2018-10-24  9:44                       ` martin rudalics
2018-10-24 14:48                         ` Eli Zaretskii
2018-10-24 17:40                           ` martin rudalics
2018-10-24 18:25                             ` Eli Zaretskii
2018-10-25 20:42                             ` Juri Linkov
2018-10-23 15:52                 ` Alan Mackenzie
2018-10-23 18:25                   ` martin rudalics
2018-11-08 19:25                   ` martin rudalics
2018-10-22  1:39   ` Michael Welsh Duggan
2018-10-22  5:54     ` Eli Zaretskii
2018-10-20 15:22 ` Drew Adams
2018-10-20 18:02   ` martin rudalics
2018-10-20 18:24     ` Drew Adams
2018-10-21  8:22       ` martin rudalics
2018-11-04  9:06 ` martin rudalics

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).