diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi index 6d156ef861..dd09ddf931 100644 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi @@ -2969,7 +2969,7 @@ Switching Buffers @code{display-buffer} will affect it as well. @xref{Choosing Window}, for the documentation of @code{display-buffer}. -@deffn Command pop-to-buffer buffer-or-name &optional action norecord +@deffn Command pop-to-buffer buffer-or-name &optional action norecord label This function makes @var{buffer-or-name} the current buffer and displays it in some window, preferably not the window currently selected. It then selects the displaying window. If that window is @@ -2990,6 +2990,9 @@ Switching Buffers window other than the selected one---even if the buffer is already displayed in the selected window. +If @var{label} is non-@code{nil}, it should specify the name of a buffer +display label and is passed on unaltered to @code{display-buffer}. + Like @code{switch-to-buffer}, this function updates the buffer list unless @var{norecord} is non-@code{nil}. @end deffn @@ -3065,7 +3068,7 @@ Choosing Window of them manages to display the buffer and returns a non-@code{nil} value. -@deffn Command display-buffer buffer-or-name &optional action frame +@deffn Command display-buffer buffer-or-name &optional action frame label This command makes @var{buffer-or-name} appear in some window, without selecting the window or making the buffer current. The argument @var{buffer-or-name} must be a buffer or the name of an existing @@ -3139,6 +3142,11 @@ Choosing Window . @var{frame})}} to the action alist of @var{action} (@pxref{Buffer Display Action Alists}). The @var{frame} argument is provided for compatibility reasons, Lisp programs should not use it. + +The optional argument @var{label}, if non-@code{nil}, should specify the +name of a buffer display label (@pxref{Buffer Display Action Alists}) +and is prepended as a cons of that name and the value @code{t} to the +action alist specified of @var{action}. @end deffn @defvar display-buffer-overriding-action @@ -3150,11 +3158,15 @@ Choosing Window @defopt display-buffer-alist The value of this option is an alist mapping conditions to display actions. Each condition may be either a regular expression matching a -buffer name or a function that takes two arguments: a buffer name and -the @var{action} argument passed to @code{display-buffer}. If either -the name of the buffer passed to @code{display-buffer} matches a -regular expression in this alist, or the function specified by a -condition returns non-@code{nil}, then @code{display-buffer} uses the +buffer name; a function that takes two arguments: a buffer name and the +@var{action} argument passed to @code{display-buffer}; or a symbol +naming a buffer display label (@pxref{Buffer Display Action Alists}). + +If either the name of the buffer passed to @code{display-buffer} matches +a regular expression in this alist, the function specified by a +condition returns non-@code{nil}, or the symbol specified by a condition +has a non-nil association found via @code{eq} in the action alist passed +to @code{display-buffer}, then @code{display-buffer} uses the corresponding display action to display the buffer. @end defopt @@ -3770,7 +3782,7 @@ Buffer Display Action Alists buffer and never was used to show another buffer until it was reused by the current invocation of @code{display-buffer}. -If no @code{window-height}, @code{window-width} or @code{window-size} + If no @code{window-height}, @code{window-width} or @code{window-size} entry was specified, the window may still be resized automatically when the buffer is temporary and @code{temp-buffer-resize-mode} has been enabled, @ref{Temporary Displays}. In that case, the @sc{cdr} of a @@ -3779,6 +3791,45 @@ Buffer Display Action Alists @code{temp-buffer-resize-mode} for specific buffers or invocations of @code{display-buffer}. +@cindex buffer display label + In addition, action alists may contain @dfn{buffer display label}s - +entries handled and passed on by @code{display-buffer} as described +above. The @sc{car} of a label - a symbol - is the label's name and its +@sc{cdr} is its value. If that value is non-@code{nil}, it will advise +@code{display-buffer} to handle this call specially, provided it finds a +matching entry in @code{display-buffer-alist}. + + If, for example, a call to @code{pop-to-buffer} is coded as + +@example +(pop-to-buffer "foo" '(nil . ((*foo* . t)))) +@end example + +@noindent +specifying a label named @code{*foo*} whose value is @code{t} and +@code{display-buffer-alist} was customized as + +@example +@group +(customize-set-variable + 'display-buffer-alist + '((*foo* display-buffer-same-window (nil)))) +@end group +@end example + +@noindent +then @code{display-buffer} will try to pop to @code{foo} in the selected +window and not in a new window as originally proposed by +@code{pop-to-buffer}. + + Lisp programmers should be careful when choosing the name for a buffer +display label to avoid that it matches any of the other entries +mentioned in this section (including entries that may be added to it in +the future) or the name of a function that could be used as condition in +@code{display-buffer-alist}. In our example, the use of asterisks in +@code{*foo*} is an attempt to avoid such confusions. + + @node Choosing Window Options @subsection Additional Options for Displaying Buffers diff --git a/lisp/window.el b/lisp/window.el index 57861b091f..7f9983b998 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -8169,9 +8169,10 @@ display-buffer-alist If non-nil, this is an alist of elements (CONDITION . ACTION), where: - CONDITION is either a regexp matching buffer names, or a - function that takes two arguments - a buffer name and the - ACTION argument of `display-buffer' - and returns a boolean. + CONDITION is either a regexp matching buffer names; a function + that takes two arguments - a buffer name and the ACTION + argument of `display-buffer' - and returns a boolean; or a + symbol that is interpreted as a label. ACTION is a cons cell (FUNCTIONS . ALIST), where FUNCTIONS is an action function or a list of action functions and ALIST is an @@ -8180,13 +8181,16 @@ display-buffer-alist ALIST. See `display-buffer' for details. `display-buffer' scans this alist until it either finds a -matching regular expression or the function specified by a -condition returns non-nil. In any of these cases, it adds the -associated action to the list of actions it will try." +matching regular expression, the function specified by a +condition returns non-nil, or the label specified by a condition +has an non-nil association found via `eq' in the action alist +passed to this `display-buffer' call. In any of these cases, it +adds the associated action to the list of actions it will try." :type `(alist :key-type (choice :tag "Condition" regexp - (function :tag "Matcher function")) + (function :tag "Matcher function") + (symbol :tag "Label")) :value-type ,display-buffer--action-custom-type) :risky t :version "24.1" @@ -8238,15 +8242,21 @@ display-buffer-assq-regexp is a string that matches BUFFER-NAME, as reported by `string-match-p'; or if the key is a function that returns non-nil when called with three arguments: the ALIST key, -BUFFER-NAME and ACTION. ACTION should have the form of the -action argument passed to `display-buffer'." +BUFFER-NAME and ACTION; or if the key is a symbol for which +'assq' finds an non-nil association in the action alist specified +by ACTION. + +ACTION should have the form of the action argument passed to +`display-buffer'." (catch 'match (dolist (entry alist) (let ((key (car entry))) (when (or (and (stringp key) (string-match-p key buffer-name)) (and (functionp key) - (funcall key buffer-name action))) + (funcall key buffer-name action)) + (and (symbolp key) + (cdr (assq key (cdr action))))) (throw 'match (cdr entry))))))) (defvar display-buffer--same-window-action @@ -8266,7 +8276,7 @@ display-buffer--other-frame-action fails, call `display-buffer-pop-up-frame'.") (put 'display-buffer--other-frame-action 'risky-local-variable t) -(defun display-buffer (buffer-or-name &optional action frame) +(defun display-buffer (buffer-or-name &optional action frame label) "Display BUFFER-OR-NAME in some window, without selecting it. To change which window is used, set `display-buffer-alist' to an expression containing one of these \"action\" functions: @@ -8390,6 +8400,13 @@ display-buffer `preserve-size' are applied only when the window used for displaying the buffer never showed another buffer before. +An action alist entry may also specify a buffer display label - a +cons cell whose car specifies the name of the label and whose cdr +its value. If `display-buffer-alist' contains an member whose +car names that label and the value of that label is non-nil, the +cdr of the `display-buffer-alist' specifies the action to +perform. + The ACTION argument can also have a non-nil and non-list value. This means to display the buffer in a window other than the selected one, even if it is already displayed in the selected @@ -8398,12 +8415,14 @@ display-buffer The optional third argument FRAME, if non-nil, acts like a \(reusable-frames . FRAME) entry appended to the action alist -specified by the ACTION argument." +specified by the ACTION argument. + +The optional argument LABEL, if non-nil, specifies the name of a +buffer display label and is prepended as a cons of that name and +the value t to the action alist." (interactive (list (read-buffer "Display buffer: " (other-buffer)) (if current-prefix-arg t))) - (let ((buffer (if (bufferp buffer-or-name) - buffer-or-name - (get-buffer buffer-or-name))) + (let ((buffer (get-buffer buffer-or-name)) ;; Make sure that when we split windows the old window keeps ;; point, bug#14829. (split-window-keep-point t) @@ -8416,7 +8435,10 @@ display-buffer ;; Otherwise, use the defined actions. (let* ((user-action (display-buffer-assq-regexp - (buffer-name buffer) display-buffer-alist action)) + (buffer-name buffer) display-buffer-alist + (if label + (cons (car action) (cons `(,label . t) (cdr action))) + action))) (special-action (display-buffer--special-action buffer)) ;; Extra actions from the arguments to this function: (extra-action @@ -9288,7 +9310,7 @@ display-buffer-no-window 'fail)) ;;; Display + selection commands: -(defun pop-to-buffer (buffer-or-name &optional action norecord) +(defun pop-to-buffer (buffer-or-name &optional action norecord label) "Display buffer specified by BUFFER-OR-NAME and select its window. BUFFER-OR-NAME may be a buffer, a string (a buffer name), or nil. If it is a string not naming an existent buffer, create a buffer @@ -9307,12 +9329,15 @@ pop-to-buffer input focus. Optional third arg NORECORD non-nil means do not put this buffer -at the front of the list of recently selected ones." +at the front of the list of recently selected ones. + +Optional fourth argument LABEL, if non-nil, must specify the name of a +buffer display label and is passed on to `display-buffer'." (interactive (list (read-buffer "Pop to buffer: " (other-buffer)) (if current-prefix-arg t))) (let* ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)) (old-frame (selected-frame)) - (window (display-buffer buffer action))) + (window (display-buffer buffer action nil label))) ;; Don't assume that `display-buffer' has supplied us with a window ;; (Bug#24332). (if window @@ -9328,7 +9353,7 @@ pop-to-buffer ;; Return BUFFER even when we got no window. buffer)) -(defun pop-to-buffer-same-window (buffer &optional norecord) +(defun pop-to-buffer-same-window (buffer &optional norecord label) "Select buffer BUFFER in some window, preferably the same one. BUFFER may be a buffer, a string (a buffer name), or nil. If it is a string not naming an existent buffer, create a buffer with @@ -9338,6 +9363,9 @@ pop-to-buffer-same-window Optional argument NORECORD, if non-nil means do not put this buffer at the front of the list of recently selected ones. +Optional fourth argument LABEL, if non-nil, must specify the name +of a buffer display label and is passed on to `pop-to-buffer'. + 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 @@ -9345,7 +9373,8 @@ pop-to-buffer-same-window (see `window-dedicated-p'), BUFFER will be displayed in the currently selected window; otherwise it will be displayed in another window." - (pop-to-buffer buffer display-buffer--same-window-action norecord)) + (pop-to-buffer + buffer display-buffer--same-window-action norecord label)) (defun read-buffer-to-switch (prompt) "Read the name of a buffer to switch to, prompting with PROMPT.