From b92631bf71bb029af7a5b4bcf3acd6b4484a4afa Mon Sep 17 00:00:00 2001 From: Martin Rudalics Date: Sun, 16 Mar 2014 10:26:58 +0100 Subject: [PATCH] Fix behavior of with-temp-buffer-window (Bug#16816, Bug#17007). * window.el (with-temp-buffer-window): Don't make BUFFER-OR-NAME current (Bug#16816, Bug#17007). (with-current-buffer-window): New macro doing the same as `with-temp-buffer-window' but with BUFFER-OR-NAME current. * help.el (help-print-return-message): Warn in doc-string to not use this in `with-help-window'. (describe-bindings-internal): Call `describe-buffer-bindings' from within help buffer. See Juanma's scenario in (Bug#16816). (with-help-window): Update doc-string. * dired.el (dired-mark-pop-up): * files.el (save-buffers-kill-emacs): * register.el (register-preview): Use `with-current-buffer-window' instead of `with-temp-buffer-window'. * display.texi (Temporary Displays): Rewrite descriptions of `with-output-to-temp-buffer' and `with-temp-buffer-window'. * help.texi (Help Functions): Rewrite description of `with-help-window'. --- doc/lispref/ChangeLog | 9 ++++- doc/lispref/display.texi | 74 ++++++++++++++++++++++------------------ doc/lispref/help.texi | 17 +++++---- lisp/ChangeLog | 17 +++++++++ lisp/dired.el | 2 +- lisp/files.el | 2 +- lisp/help.el | 36 ++++++++++--------- lisp/register.el | 2 +- lisp/window.el | 40 ++++++++++++++++------ 9 files changed, 127 insertions(+), 72 deletions(-) diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index 13b96b4ba5e..6e89c0d489b 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,3 +1,10 @@ +2014-03-16 Martin Rudalics + + * display.texi (Temporary Displays): Rewrite descriptions of + `with-output-to-temp-buffer' and `with-temp-buffer-window'. + * help.texi (Help Functions): Rewrite description of + `with-help-window'. + 2014-03-15 Dmitry Gutov * display.texi (Blinking): Update WRT to the new @@ -6,7 +13,7 @@ 2014-03-14 Martin Rudalics * display.texi (Temporary Displays): Say that - with-temp-buffer-window makes its buffer current. + `with-temp-buffer-window' makes its buffer current. * frames.texi (Size and Position): Describe new option `frame-resize-pixelwise'. Rewrite descriptions of `set-frame-size', `set-frame-height' and `set-frame-width'. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 27f002fe5fe..8bd657b5a9b 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -1094,29 +1094,29 @@ You can use a display table to substitute other text for the ellipsis buffer and then present it to the user for perusal rather than for editing. Many help commands use this feature. -@defmac with-output-to-temp-buffer buffer-name forms@dots{} -This function executes @var{forms} while arranging to insert any output -they print into the buffer named @var{buffer-name}, which is first -created if necessary, and put into Help mode. Finally, the buffer is -displayed in some window, but not selected. (See the similar -form @code{with-temp-buffer-window} below.) - -If the @var{forms} do not change the major mode in the output buffer, -so that it is still Help mode at the end of their execution, then -@code{with-output-to-temp-buffer} makes this buffer read-only at the -end, and also scans it for function and variable names to make them -into clickable cross-references. @xref{Docstring hyperlinks, , Tips -for Documentation Strings}, in particular the item on hyperlinks in +@defmac with-output-to-temp-buffer buffer-name body@dots{} +This function executes the forms in @var{body} while arranging to insert +any output they print into the buffer named @var{buffer-name}, which is +first created if necessary, and put into Help mode. (See the similar +form @code{with-temp-buffer-window} below.) Finally, the buffer is +displayed in some window, but that window is not selected. + +If the forms in @var{body} do not change the major mode in the output +buffer, so that it is still Help mode at the end of their execution, +then @code{with-output-to-temp-buffer} makes this buffer read-only at +the end, and also scans it for function and variable names to make them +into clickable cross-references. @xref{Docstring hyperlinks, , Tips for +Documentation Strings}, in particular the item on hyperlinks in documentation strings, for more details. -The string @var{buffer-name} specifies the temporary buffer, which -need not already exist. The argument must be a string, not a buffer. -The buffer is erased initially (with no questions asked), and it is -marked as unmodified after @code{with-output-to-temp-buffer} exits. +The string @var{buffer-name} specifies the temporary buffer, which need +not already exist. The argument must be a string, not a buffer. The +buffer is erased initially (with no questions asked), and it is marked +as unmodified after @code{with-output-to-temp-buffer} exits. @code{with-output-to-temp-buffer} binds @code{standard-output} to the -temporary buffer, then it evaluates the forms in @var{forms}. Output -using the Lisp output functions within @var{forms} goes by default to +temporary buffer, then it evaluates the forms in @var{body}. Output +using the Lisp output functions within @var{body} goes by default to that buffer (but screen display and messages in the echo area, although they are ``output'' in the general sense of the word, are not affected). @xref{Output Functions}. @@ -1124,7 +1124,7 @@ they are ``output'' in the general sense of the word, are not affected). Several hooks are available for customizing the behavior of this construct; they are listed below. -The value of the last form in @var{forms} is returned. +The value of the last form in @var{body} is returned. @example @group @@ -1174,28 +1174,34 @@ displaying the temporary buffer. When the hook runs, the temporary buffer is current, and the window it was displayed in is selected. @end defvar -@defmac with-temp-buffer-window buffer-or-name action quit-function forms@dots{} +@defmac with-temp-buffer-window buffer-or-name action quit-function body@dots{} This macro is similar to @code{with-output-to-temp-buffer}. Like that -construct, it executes @var{forms} while arranging to insert any output -they print into the buffer named @var{buffer-or-name} and displays the +construct, it executes @var{body} while arranging to insert any output +it prints into the buffer named @var{buffer-or-name} and displays that buffer in some window. Unlike @code{with-output-to-temp-buffer}, -however, this makes the buffer current and does not switch to Help mode. +however, it does not automatically switch that buffer to Help mode. -The argument @var{buffer-or-name} specifies the temporary buffer. -It can be either a buffer, which must already exist, or a string, -in which case a buffer of that name is created if necessary. -The buffer is marked as unmodified and read-only when -@code{with-temp-buffer-window} exits. +Like @code{with-output-to-temp-buffer} it neither makes the buffer +specified by @var{buffer-or-name} current when executing @var{body}. +@findex with-current-buffer-window +The otherwise identical macro @code{with-current-buffer-window} can be +used to execute @var{body} with that buffer current. + +The argument @var{buffer-or-name} specifies the temporary buffer. It +can be either a buffer, which must already exist, or a string, in which +case a buffer of that name is created, if necessary. The buffer is +marked as unmodified and read-only when @code{with-temp-buffer-window} +exits. This macro does not call @code{temp-buffer-show-function}. Rather, it passes the @var{action} argument to @code{display-buffer} in order to display the buffer. -The value of the last form in @var{forms} is returned, unless the -argument @var{quit-function} is specified. In that case, -it is called with two arguments: the window showing the buffer -and the result of @var{forms}. The final return value is then -whatever @var{quit-function} returns. +The value of the last form in @var{body} is returned, unless the +argument @var{quit-function} is specified. In that case, it is called +with two arguments: the window showing the buffer and the result of +@var{body}. The final return value is then whatever +@var{quit-function} returns. @vindex temp-buffer-window-setup-hook @vindex temp-buffer-window-show-hook diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi index 50103d3a8b3..9a763b60938 100644 --- a/doc/lispref/help.texi +++ b/doc/lispref/help.texi @@ -649,14 +649,17 @@ This function returns the name of the help buffer, which is normally @file{*Help*}; if such a buffer does not exist, it is first created. @end defun +@vindex help-window-select @defmac with-help-window buffer-name body@dots{} -This macro evaluates the @var{body} forms, inserting any output they -produce into a buffer named @var{buffer-name} like -@code{with-output-to-temp-buffer} (@pxref{Temporary Displays}). -(Usually, @var{buffer-name} should be the value returned by the -function @code{help-buffer}.) It also puts the specified buffer into -Help mode and displays a message telling the user how to quit and -scroll the help window. +This macro evaluates @var{body} like @code{with-output-to-temp-buffer} +(@pxref{Temporary Displays}), inserting any output produced by its forms +into a buffer named @var{buffer-name}. (Usually, @var{buffer-name} +should be the value returned by the function @code{help-buffer}.) It +also puts the specified buffer into Help mode and displays a message +telling the user how to quit and scroll the help window. It selects the +help window if the current value of the user option +@code{help-window-select} has been set accordingly. It returns the last +value in @var{body}. @end defmac @defun help-setup-xref item interactive-p diff --git a/lisp/ChangeLog b/lisp/ChangeLog index f800d0f24af..cf42e8ccef6 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,20 @@ +2014-03-16 Martin Rudalics + + Fix behavior of with-temp-buffer-window (Bug#16816, Bug#17007). + * window.el (with-temp-buffer-window): Don't make BUFFER-OR-NAME + current (Bug#16816, Bug#17007). + (with-current-buffer-window): New macro doing the same as + `with-temp-buffer-window' but with BUFFER-OR-NAME current. + * help.el (help-print-return-message): Warn in doc-string to not + use this in `with-help-window'. + (describe-bindings-internal): Call `describe-buffer-bindings' + from within help buffer. See Juanma's scenario in (Bug#16816). + (with-help-window): Update doc-string. + * dired.el (dired-mark-pop-up): + * files.el (save-buffers-kill-emacs): + * register.el (register-preview): Use `with-current-buffer-window' + instead of `with-temp-buffer-window'. + 2014-03-16 Juanma Barranquero * textmodes/rst.el (rst-arabic-to-roman, rst-roman-to-arabic): diff --git a/lisp/dired.el b/lisp/dired.el index 2bf9f7456fe..162c9beb0c0 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -3087,7 +3087,7 @@ argument or confirmation)." (apply function args) (let ((buffer (get-buffer-create (or buffer-or-name " *Marked Files*")))) (with-current-buffer buffer - (with-temp-buffer-window + (with-current-buffer-window buffer (cons 'display-buffer-below-selected '((window-height . fit-window-to-buffer))) diff --git a/lisp/files.el b/lisp/files.el index 029872506e3..6d0be9234e6 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -6534,7 +6534,7 @@ if any returns nil. If `confirm-kill-emacs' is non-nil, calls it." (setq active t)) (setq processes (cdr processes))) (or (not active) - (with-temp-buffer-window + (with-current-buffer-window (get-buffer-create "*Process List*") nil #'(lambda (window _value) (with-selected-window window diff --git a/lisp/help.el b/lisp/help.el index 46094e9f6b0..14dda6456cf 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -133,7 +133,9 @@ This function assumes that `standard-output' is the help buffer. It computes a message, and applies the optional argument FUNCTION to it. If FUNCTION is nil, it applies `message', thus displaying the message. In addition, this function sets up `help-return-method', which see, that -specifies what to do when the user exits the help buffer." +specifies what to do when the user exits the help buffer. + +Do not call this in the scope of `with-help-window'." (and (not (get-buffer-window standard-output)) (let ((first-message (cond ((or @@ -498,7 +500,10 @@ The optional argument PREFIX, if non-nil, should be a key sequence; then we display only bindings that start with that prefix." (let ((buf (current-buffer))) (with-help-window (help-buffer) - (describe-buffer-bindings buf prefix menus)))) + ;; Be aware that `describe-buffer-bindings' puts its output into + ;; the current buffer. + (with-current-buffer (help-buffer) + (describe-buffer-bindings buf prefix menus))))) (defun where-is (definition &optional insert) "Print message listing key sequences that invoke the command DEFINITION. @@ -1180,28 +1185,25 @@ Return VALUE." ;; providing the following additional twists: ;; (1) It puts the buffer in `help-mode' (via `help-mode-setup') and -;; adds cross references (via `help-mode-finish'). +;; adds cross references (via `help-mode-finish'). ;; (2) It issues a message telling how to scroll and quit the help -;; window (via `help-window-setup'). +;; window (via `help-window-setup'). ;; (3) An option (customizable via `help-window-select') to select the -;; help window automatically. +;; help window automatically. ;; (4) A marker (`help-window-point-marker') to move point in the help -;; window to an arbitrary buffer position. - -;; Note: It's usually always wrong to use `help-print-return-message' in -;; the body of `with-help-window'. +;; window to an arbitrary buffer position. (defmacro with-help-window (buffer-name &rest body) - "Display buffer with name BUFFER-NAME in a help window. -Evaluate the forms in BODY with the buffer specified by -BUFFER-NAME current, put that buffer in `help-mode', display the -buffer in a window (see `with-temp-buffer-window' for details) -and issue a message how to deal with that \"help\" window when -it's no more needed. Select the help window if the current value -of the user option `help-window-select' says so. Return last -value in BODY." + "Display buffer named BUFFER-NAME in a help window. +Evaluate the forms in BODY with standard output bound to a buffer +called BUFFER-NAME (creating it if it does not exist), put that +buffer in `help-mode', display the buffer in a window (see +`with-temp-buffer-window' for details) and issue a message how to +deal with that \"help\" window when it's no more needed. Select +the help window if the current value of the user option +`help-window-select' says so. Return last value in BODY." (declare (indent 1) (debug t)) `(progn ;; Make `help-window-point-marker' point nowhere. The only place diff --git a/lisp/register.el b/lisp/register.el index bfe3e35223f..1c64a9a8e64 100644 --- a/lisp/register.el +++ b/lisp/register.el @@ -134,7 +134,7 @@ Returns a string.") If SHOW-EMPTY is non-nil show the window even if no registers. Format of each entry is controlled by the variable `register-preview-function'." (when (or show-empty (consp register-alist)) - (with-temp-buffer-window + (with-current-buffer-window buffer (cons 'display-buffer-below-selected '((window-height . fit-window-to-buffer))) diff --git a/lisp/window.el b/lisp/window.el index fc2accebba8..60f13e65c4e 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -143,21 +143,22 @@ to `display-buffer'." window)))) (defmacro with-temp-buffer-window (buffer-or-name action quit-function &rest body) - "Evaluate BODY in a buffer BUFFER-OR-NAME and show that buffer. + "Bind `standard-output' to BUFFER-OR-NAME, eval BODY, show the buffer. BUFFER-OR-NAME must specify either a live buffer, or the name of a buffer (if it does not exist, this macro creates it). Make the buffer specified by BUFFER-OR-NAME empty before running -BODY and make that buffer current for running the forms in BODY. -In addition, bind `standard-output' to that buffer, so that -output generated with `prin1' and similar functions in BODY goes -into that buffer. +BODY and bind `standard-output' to that buffer, so that output +generated with `prin1' and similar functions in BODY goes into +that buffer. Do not make that buffer current for running the +forms in BODY. Use `with-current-buffer-window' instead if you +need to run BODY with that buffer current. At the end of BODY, mark the specified buffer unmodified and read-only, and display it in a window (but do not select it). The display happens by calling `display-buffer' passing it the ACTION argument. If `temp-buffer-resize-mode' is enabled, the -corresponding window may shrink automatically. +corresponding window may be resized automatically. Return the value returned by BODY, unless QUIT-FUNCTION specifies a function. In that case, run that function with two arguments - @@ -177,10 +178,29 @@ that buffer temporarily current, and the window that was used to display it temporarily selected. This construct is similar to `with-output-to-temp-buffer' but, -unlike that, makes BUFFER-OR-NAME current when running BODY. -Also, it neither runs `temp-buffer-setup-hook' which usually puts -the buffer in Help mode, nor `temp-buffer-show-function' (the -ACTION argument replaces this)." +neither runs `temp-buffer-setup-hook' which usually puts the +buffer in Help mode, nor `temp-buffer-show-function' (the ACTION +argument replaces this)." + (declare (debug t)) + (let ((buffer (make-symbol "buffer")) + (window (make-symbol "window")) + (value (make-symbol "value"))) + `(let* ((,buffer (temp-buffer-window-setup ,buffer-or-name)) + (standard-output ,buffer) + ,window ,value) + (setq ,value (progn ,@body)) + (with-current-buffer ,buffer + (setq ,window (temp-buffer-window-show ,buffer ,action))) + + (if (functionp ,quit-function) + (funcall ,quit-function ,window ,value) + ,value)))) + +(defmacro with-current-buffer-window (buffer-or-name action quit-function &rest body) + "Evaluate BODY with a buffer BUFFER-OR-NAME current and show that buffer. +This construct is like `with-temp-buffer-window' but unlike that +makes the buffer specified by BUFFER-OR-NAME current for running +BODY." (declare (debug t)) (let ((buffer (make-symbol "buffer")) (window (make-symbol "window")) -- 2.39.5