1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-06 06:20:55 -08:00

Inhibit buffer hooks in temporary buffers

Give get-buffer-create an optional argument to inhibit buffer hooks
in internal or temporary buffers for efficiency (bug#34765).

* etc/NEWS: Announce new parameter of get-buffer-create and
generate-new-buffer, and that with-temp-buffer and with-temp-file
now inhibit buffer hooks.

* doc/lispref/buffers.texi (Buffer Names): Fix typo.
(Creating Buffers): Document new parameter of get-buffer-create and
generate-new-buffer.
(Buffer List, Killing Buffers): Document when buffer hooks are
inhibited.
(Current Buffer):
* doc/lispref/files.texi (Writing to Files): Document that
with-temp-buffer and with-temp-file inhibit buffer hooks.
* doc/lispref/internals.texi (Buffer Internals): Document
inhibit_buffer_hooks flag.  Remove stale comment.
* doc/misc/gnus-faq.texi (FAQ 5-8):
* lisp/simple.el (shell-command-on-region): Fix indentation.

* lisp/files.el (kill-buffer-hook): Document when hook is inhibited.
(create-file-buffer):
* lisp/gnus/gnus-uu.el (gnus-uu-unshar-article):
* lisp/international/mule.el (load-with-code-conversion):
* lisp/mh-e/mh-xface.el (mh-x-image-url-fetch-image):
* lisp/net/imap.el (imap-open):
* lisp/net/mailcap.el (mailcap-maybe-eval):
* lisp/progmodes/flymake-proc.el
(flymake-proc--read-file-to-temp-buffer)
(flymake-proc--copy-buffer-to-temp-buffer): Simplify.

* lisp/subr.el (generate-new-buffer): Forward new optional argument
to inhibit buffer hooks to get-buffer-create.
(with-temp-file, with-temp-buffer, with-output-to-string):
* lisp/json.el (json-encode-string): Inhibit buffer hooks in buffer
used.

* src/buffer.c (run_buffer_list_update_hook): New helper function.
(Fget_buffer_create): Use it.  Add optional argument to set
inhibit_buffer_hooks flag instead of comparing the buffer name to
Vcode_conversion_workbuf_name.  All callers changed.
(Fmake_indirect_buffer, Frename_buffer, Fbury_buffer_internal)
(record_buffer): Use run_buffer_list_update_hook.
(Fkill_buffer): Document when buffer hooks are inhibited.  Use
run_buffer_list_update_hook.
(init_buffer_once): Inhibit buffer hooks in Vprin1_to_string_buffer.
(Vkill_buffer_query_functions, Vbuffer_list_update_hook): Document
when hooks are inhibited.
* src/buffer.h (struct buffer): Update inhibit_buffer_hooks
commentary.
* src/coding.h (Vcode_conversion_workbuf_name):
* src/coding.c (Vcode_conversion_workbuf_name): Make static again
since it is no longer needed in src/buffer.c.
(code_conversion_restore, code_conversion_save, syms_of_coding):
Prefer boolean over integer constants.
* src/fileio.c (Finsert_file_contents): Inhibit buffer hooks in
" *code-converting-work*" buffer.
* src/window.c (Fselect_window): Fix grammar.  Mention
window-selection-change-functions alongside buffer-list-update-hook.

* test/src/buffer-tests.el: Fix requires.
(buffer-tests-inhibit-buffer-hooks): New test.
This commit is contained in:
Basil L. Contovounesios 2020-12-19 12:39:45 +00:00
parent 409a9dbe9d
commit 1a0a11f7d2
30 changed files with 221 additions and 129 deletions

View file

@ -225,13 +225,22 @@ current buffer is restored even in case of an abnormal exit via
@defmac with-temp-buffer body@dots{} @defmac with-temp-buffer body@dots{}
@anchor{Definition of with-temp-buffer} @anchor{Definition of with-temp-buffer}
The @code{with-temp-buffer} macro evaluates the @var{body} forms The @code{with-temp-buffer} macro evaluates the @var{body} forms with
with a temporary buffer as the current buffer. It saves the identity of a temporary buffer as the current buffer. It saves the identity of
the current buffer, creates a temporary buffer and makes it current, the current buffer, creates a temporary buffer and makes it current,
evaluates the @var{body} forms, and finally restores the previous evaluates the @var{body} forms, and finally restores the previous
current buffer while killing the temporary buffer. By default, undo current buffer while killing the temporary buffer.
information (@pxref{Undo}) is not recorded in the buffer created by
this macro (but @var{body} can enable that, if needed). @cindex undo in temporary buffers
@cindex @code{kill-buffer-hook} in temporary buffers
@cindex @code{kill-buffer-query-functions} in temporary buffers
@cindex @code{buffer-list-update-hook} in temporary buffers
By default, undo information (@pxref{Undo}) is not recorded in the
buffer created by this macro (but @var{body} can enable that, if
needed). The temporary buffer also does not run the hooks
@code{kill-buffer-hook}, @code{kill-buffer-query-functions}
(@pxref{Killing Buffers}), and @code{buffer-list-update-hook}
(@pxref{Buffer List}).
The return value is the value of the last form in @var{body}. You can The return value is the value of the last form in @var{body}. You can
return the contents of the temporary buffer by using return the contents of the temporary buffer by using
@ -345,9 +354,9 @@ incrementing the number until it is not the name of an existing buffer.
If the optional second argument @var{ignore} is non-@code{nil}, it If the optional second argument @var{ignore} is non-@code{nil}, it
should be a string, a potential buffer name. It means to consider should be a string, a potential buffer name. It means to consider
that potential buffer acceptable, if it is tried, even it is the name that potential buffer acceptable, if it is tried, even if it is the
of an existing buffer (which would normally be rejected). Thus, if name of an existing buffer (which would normally be rejected). Thus,
buffers named @samp{foo}, @samp{foo<2>}, @samp{foo<3>} and if buffers named @samp{foo}, @samp{foo<2>}, @samp{foo<3>} and
@samp{foo<4>} exist, @samp{foo<4>} exist,
@example @example
@ -932,13 +941,17 @@ window.
@defvar buffer-list-update-hook @defvar buffer-list-update-hook
This is a normal hook run whenever the buffer list changes. Functions This is a normal hook run whenever the buffer list changes. Functions
(implicitly) running this hook are @code{get-buffer-create} (implicitly) running this hook are @code{get-buffer-create}
(@pxref{Creating Buffers}), @code{rename-buffer} (@pxref{Buffer Names}), (@pxref{Creating Buffers}), @code{rename-buffer} (@pxref{Buffer
@code{kill-buffer} (@pxref{Killing Buffers}), @code{bury-buffer} (see Names}), @code{kill-buffer} (@pxref{Killing Buffers}),
above) and @code{select-window} (@pxref{Selecting Windows}). @code{bury-buffer} (see above), and @code{select-window}
(@pxref{Selecting Windows}). This hook is not run for internal or
temporary buffers created by @code{get-buffer-create} or
@code{generate-new-buffer} with a non-@code{nil} argument
@var{inhibit-buffer-hooks}.
Functions run by this hook should avoid calling @code{select-window} Functions run by this hook should avoid calling @code{select-window}
with a nil @var{norecord} argument or @code{with-temp-buffer} since with a @code{nil} @var{norecord} argument since this may lead to
either may lead to infinite recursion. infinite recursion.
@end defvar @end defvar
@node Creating Buffers @node Creating Buffers
@ -951,12 +964,20 @@ either may lead to infinite recursion.
with the specified name; @code{generate-new-buffer} always creates a new with the specified name; @code{generate-new-buffer} always creates a new
buffer and gives it a unique name. buffer and gives it a unique name.
Both functions accept an optional argument @var{inhibit-buffer-hooks}.
If it is non-@code{nil}, the buffer they create does not run the hooks
@code{kill-buffer-hook}, @code{kill-buffer-query-functions}
(@pxref{Killing Buffers}), and @code{buffer-list-update-hook}
(@pxref{Buffer List}). This avoids slowing down internal or temporary
buffers that are never presented to users or passed on to other
applications.
Other functions you can use to create buffers include Other functions you can use to create buffers include
@code{with-output-to-temp-buffer} (@pxref{Temporary Displays}) and @code{with-output-to-temp-buffer} (@pxref{Temporary Displays}) and
@code{create-file-buffer} (@pxref{Visiting Files}). Starting a @code{create-file-buffer} (@pxref{Visiting Files}). Starting a
subprocess can also create a buffer (@pxref{Processes}). subprocess can also create a buffer (@pxref{Processes}).
@defun get-buffer-create buffer-or-name @defun get-buffer-create buffer-or-name &optional inhibit-buffer-hooks
This function returns a buffer named @var{buffer-or-name}. The buffer This function returns a buffer named @var{buffer-or-name}. The buffer
returned does not become the current buffer---this function does not returned does not become the current buffer---this function does not
change which buffer is current. change which buffer is current.
@ -980,7 +1001,7 @@ level; see @ref{Auto Major Mode}.) If the name begins with a space, the
buffer initially disables undo information recording (@pxref{Undo}). buffer initially disables undo information recording (@pxref{Undo}).
@end defun @end defun
@defun generate-new-buffer name @defun generate-new-buffer name &optional inhibit-buffer-hooks
This function returns a newly created, empty buffer, but does not make This function returns a newly created, empty buffer, but does not make
it current. The name of the buffer is generated by passing @var{name} it current. The name of the buffer is generated by passing @var{name}
to the function @code{generate-new-buffer-name} (@pxref{Buffer to the function @code{generate-new-buffer-name} (@pxref{Buffer
@ -1092,6 +1113,10 @@ with no arguments. The buffer being killed is the current buffer when
they are called. The idea of this feature is that these functions will they are called. The idea of this feature is that these functions will
ask for confirmation from the user. If any of them returns @code{nil}, ask for confirmation from the user. If any of them returns @code{nil},
@code{kill-buffer} spares the buffer's life. @code{kill-buffer} spares the buffer's life.
This hook is not run for internal or temporary buffers created by
@code{get-buffer-create} or @code{generate-new-buffer} with a
non-@code{nil} argument @var{inhibit-buffer-hooks}.
@end defvar @end defvar
@defvar kill-buffer-hook @defvar kill-buffer-hook
@ -1100,6 +1125,10 @@ questions it is going to ask, just before actually killing the buffer.
The buffer to be killed is current when the hook functions run. The buffer to be killed is current when the hook functions run.
@xref{Hooks}. This variable is a permanent local, so its local binding @xref{Hooks}. This variable is a permanent local, so its local binding
is not cleared by changing major modes. is not cleared by changing major modes.
This hook is not run for internal or temporary buffers created by
@code{get-buffer-create} or @code{generate-new-buffer} with a
non-@code{nil} argument @var{inhibit-buffer-hooks}.
@end defvar @end defvar
@defopt buffer-offer-save @defopt buffer-offer-save

View file

@ -701,8 +701,11 @@ in @var{body}.
The current buffer is restored even in case of an abnormal exit via The current buffer is restored even in case of an abnormal exit via
@code{throw} or error (@pxref{Nonlocal Exits}). @code{throw} or error (@pxref{Nonlocal Exits}).
See also @code{with-temp-buffer} in @ref{Definition of Like @code{with-temp-buffer} (@pxref{Definition of with-temp-buffer,,
with-temp-buffer,, The Current Buffer}. Current Buffer}), the temporary buffer used by this macro does not run
the hooks @code{kill-buffer-hook}, @code{kill-buffer-query-functions}
(@pxref{Killing Buffers}), and @code{buffer-list-update-hook}
(@pxref{Buffer List}).
@end defmac @end defmac
@node File Locks @node File Locks

View file

@ -2391,6 +2391,15 @@ This flag indicates that narrowing has changed in the buffer.
This flag indicates that redisplay optimizations should not be used to This flag indicates that redisplay optimizations should not be used to
display this buffer. display this buffer.
@item inhibit_buffer_hooks
This flag indicates that the buffer should not run the hooks
@code{kill-buffer-hook}, @code{kill-buffer-query-functions}
(@pxref{Killing Buffers}), and @code{buffer-list-update-hook}
(@pxref{Buffer List}). It is set at buffer creation (@pxref{Creating
Buffers}), and avoids slowing down internal or temporary buffers, such
as those created by @code{with-temp-buffer} (@pxref{Definition of
with-temp-buffer,, Current Buffer}).
@item overlay_center @item overlay_center
This field holds the current overlay center position. @xref{Managing This field holds the current overlay center position. @xref{Managing
Overlays}. Overlays}.
@ -2404,8 +2413,6 @@ after the current overlay center. @xref{Managing Overlays}.
and @code{overlays_after} is sorted in order of increasing beginning and @code{overlays_after} is sorted in order of increasing beginning
position. position.
@c FIXME? the following are now all Lisp_Object BUFFER_INTERNAL_FIELD (foo).
@item name @item name
A Lisp string that names the buffer. It is guaranteed to be unique. A Lisp string that names the buffer. It is guaranteed to be unique.
@xref{Buffer Names}. This and the following fields have their names @xref{Buffer Names}. This and the following fields have their names

View file

@ -1821,6 +1821,13 @@ modifies the string's text properties; instead, it uses and returns
a copy of the string. This helps avoid trouble when strings are a copy of the string. This helps avoid trouble when strings are
shared or constants. shared or constants.
+++
** Temporary buffers no longer run certain buffer hooks.
The macros 'with-temp-buffer' and 'with-temp-file' no longer run the
hooks 'kill-buffer-hook', 'kill-buffer-query-functions', and
'buffer-list-update-hook' for the temporary buffers they create. This
avoids slowing them down when a lot of these hooks are defined.
--- ---
** The obsolete function 'thread-alive-p' has been removed. ** The obsolete function 'thread-alive-p' has been removed.
@ -2177,6 +2184,15 @@ Until it is solved you could ignore such errors by performing
** The error 'ftp-error' belongs also to category 'remote-file-error'. ** The error 'ftp-error' belongs also to category 'remote-file-error'.
+++
** Buffers can now be created with certain hooks disabled.
The functions 'get-buffer-create' and 'generate-new-buffer' accept a
new optional argument 'inhibit-buffer-hooks'. If non-nil, the new
buffer does not run the hooks 'kill-buffer-hook',
'kill-buffer-query-functions', and 'buffer-list-update-hook'. This
avoids slowing down internal or temporary buffers that are never
presented to users or passed on to other applications.
* Changes in Emacs 28.1 on Non-Free Operating Systems * Changes in Emacs 28.1 on Non-Free Operating Systems

View file

@ -1850,6 +1850,10 @@ expand wildcards (if any) and replace the file with multiple files."
The buffer being killed is current while the hook is running. The buffer being killed is current while the hook is running.
See `kill-buffer'. See `kill-buffer'.
This hook is not run for internal or temporary buffers created by
`get-buffer-create' or `generate-new-buffer' with argument
INHIBIT-BUFFER-HOOKS non-nil.
Note: Be careful with let-binding this hook considering it is Note: Be careful with let-binding this hook considering it is
frequently used for cleanup.") frequently used for cleanup.")
@ -1951,7 +1955,7 @@ this function prepends a \"|\" to the final result if necessary."
(let ((lastname (file-name-nondirectory filename))) (let ((lastname (file-name-nondirectory filename)))
(if (string= lastname "") (if (string= lastname "")
(setq lastname filename)) (setq lastname filename))
(generate-new-buffer (if (string-match-p "\\` " lastname) (generate-new-buffer (if (string-prefix-p " " lastname)
(concat "|" lastname) (concat "|" lastname)
lastname)))) lastname))))

View file

@ -1587,8 +1587,7 @@ Gnus might fail to display all of it.")
(save-excursion (save-excursion
(switch-to-buffer (current-buffer)) (switch-to-buffer (current-buffer))
(delete-other-windows) (delete-other-windows)
(let ((buffer (get-buffer-create (generate-new-buffer-name (let ((buffer (generate-new-buffer "*Warning*")))
"*Warning*"))))
(unless (unless
(unwind-protect (unwind-protect
(with-current-buffer buffer (with-current-buffer buffer

View file

@ -307,12 +307,9 @@ Return t if file exists."
(and (null noerror) (and (null noerror)
(signal 'file-error (list "Cannot open load file" file))) (signal 'file-error (list "Cannot open load file" file)))
;; Read file with code conversion, and then eval. ;; Read file with code conversion, and then eval.
(let* ((buffer (let ((buffer (generate-new-buffer " *load*"))
;; We can't use `generate-new-buffer' because files.el
;; is not yet loaded.
(get-buffer-create (generate-new-buffer-name " *load*")))
(load-in-progress t) (load-in-progress t)
(source (save-match-data (string-match "\\.el\\'" fullname)))) (source (string-suffix-p ".el" fullname)))
(unless nomessage (unless nomessage
(if source (if source
(message "Loading %s (source)..." file) (message "Loading %s (source)..." file)

View file

@ -435,7 +435,7 @@ Initialized lazily by `json-encode-string'.")
(concat "\"" (substring-no-properties string) "\"") (concat "\"" (substring-no-properties string) "\"")
(with-current-buffer (with-current-buffer
(or json--string-buffer (or json--string-buffer
(with-current-buffer (generate-new-buffer " *json-string*") (with-current-buffer (generate-new-buffer " *json-string*" t)
;; This seems to afford decent performance gains. ;; This seems to afford decent performance gains.
(setq-local inhibit-modification-hooks t) (setq-local inhibit-modification-hooks t)
(setq json--string-buffer (current-buffer)))) (setq json--string-buffer (current-buffer))))

View file

@ -425,8 +425,7 @@ After the image is fetched, it is stored in CACHE-FILE. It will
be displayed in a buffer and position specified by MARKER. The be displayed in a buffer and position specified by MARKER. The
actual display is carried out by the SENTINEL function." actual display is carried out by the SENTINEL function."
(if mh-wget-executable (if mh-wget-executable
(let ((buffer (get-buffer-create (generate-new-buffer-name (let ((buffer (generate-new-buffer mh-temp-fetch-buffer))
mh-temp-fetch-buffer)))
(filename (or (mh-funcall-if-exists make-temp-file "mhe-fetch") (filename (or (mh-funcall-if-exists make-temp-file "mhe-fetch")
(expand-file-name (make-temp-name "~/mhe-fetch"))))) (expand-file-name (make-temp-name "~/mhe-fetch")))))
(with-current-buffer buffer (with-current-buffer buffer

View file

@ -1033,8 +1033,7 @@ necessary. If nil, the buffer name is generated."
(when (funcall (nth 1 (assq stream imap-stream-alist)) buffer) (when (funcall (nth 1 (assq stream imap-stream-alist)) buffer)
;; Stream changed? ;; Stream changed?
(if (not (eq imap-default-stream stream)) (if (not (eq imap-default-stream stream))
(with-current-buffer (get-buffer-create (with-current-buffer (generate-new-buffer " *temp*")
(generate-new-buffer-name " *temp*"))
(mapc 'make-local-variable imap-local-variables) (mapc 'make-local-variable imap-local-variables)
(set-buffer-multibyte nil) (set-buffer-multibyte nil)
(buffer-disable-undo) (buffer-disable-undo)

View file

@ -386,8 +386,7 @@ Gnus might fail to display all of it.")
(when (when
(save-window-excursion (save-window-excursion
(delete-other-windows) (delete-other-windows)
(let ((buffer (get-buffer-create (generate-new-buffer-name (let ((buffer (generate-new-buffer "*Warning*")))
"*Warning*"))))
(unwind-protect (unwind-protect
(with-current-buffer buffer (with-current-buffer buffer
(insert (substitute-command-keys (insert (substitute-command-keys

View file

@ -431,16 +431,15 @@ instead of reading master file from disk."
(defun flymake-proc--read-file-to-temp-buffer (file-name) (defun flymake-proc--read-file-to-temp-buffer (file-name)
"Insert contents of FILE-NAME into newly created temp buffer." "Insert contents of FILE-NAME into newly created temp buffer."
(let* ((temp-buffer (get-buffer-create (generate-new-buffer-name (concat "flymake:" (file-name-nondirectory file-name)))))) (with-current-buffer (generate-new-buffer
(with-current-buffer temp-buffer (concat "flymake:" (file-name-nondirectory file-name)))
(insert-file-contents file-name)) (insert-file-contents file-name)
temp-buffer)) (current-buffer)))
(defun flymake-proc--copy-buffer-to-temp-buffer (buffer) (defun flymake-proc--copy-buffer-to-temp-buffer (buffer)
"Copy contents of BUFFER into newly created temp buffer." "Copy contents of BUFFER into newly created temp buffer."
(with-current-buffer (with-current-buffer (generate-new-buffer
(get-buffer-create (generate-new-buffer-name (concat "flymake:" (buffer-name buffer)))
(concat "flymake:" (buffer-name buffer))))
(insert-buffer-substring buffer) (insert-buffer-substring buffer)
(current-buffer))) (current-buffer)))

View file

@ -4307,8 +4307,7 @@ characters."
(defun shell-command-to-string (command) (defun shell-command-to-string (command)
"Execute shell command COMMAND and return its output as a string." "Execute shell command COMMAND and return its output as a string."
(with-output-to-string (with-output-to-string
(with-current-buffer (with-current-buffer standard-output
standard-output
(shell-command command t)))) (shell-command command t))))
(defun process-file (program &optional infile buffer display &rest args) (defun process-file (program &optional infile buffer display &rest args)

View file

@ -3701,10 +3701,11 @@ also `with-temp-buffer'."
(when (window-live-p (nth 1 state)) (when (window-live-p (nth 1 state))
(select-window (nth 1 state) 'norecord))) (select-window (nth 1 state) 'norecord)))
(defun generate-new-buffer (name) (defun generate-new-buffer (name &optional inhibit-buffer-hooks)
"Create and return a buffer with a name based on NAME. "Create and return a buffer with a name based on NAME.
Choose the buffer's name using `generate-new-buffer-name'." Choose the buffer's name using `generate-new-buffer-name'.
(get-buffer-create (generate-new-buffer-name name))) See `get-buffer-create' for the meaning of INHIBIT-BUFFER-HOOKS."
(get-buffer-create (generate-new-buffer-name name) inhibit-buffer-hooks))
(defmacro with-selected-window (window &rest body) (defmacro with-selected-window (window &rest body)
"Execute the forms in BODY with WINDOW as the selected window. "Execute the forms in BODY with WINDOW as the selected window.
@ -3866,12 +3867,14 @@ See the related form `with-temp-buffer-window'."
(defmacro with-temp-file (file &rest body) (defmacro with-temp-file (file &rest body)
"Create a new buffer, evaluate BODY there, and write the buffer to FILE. "Create a new buffer, evaluate BODY there, and write the buffer to FILE.
The value returned is the value of the last form in BODY. The value returned is the value of the last form in BODY.
The buffer does not run the hooks `kill-buffer-hook',
`kill-buffer-query-functions', and `buffer-list-update-hook'.
See also `with-temp-buffer'." See also `with-temp-buffer'."
(declare (indent 1) (debug t)) (declare (indent 1) (debug t))
(let ((temp-file (make-symbol "temp-file")) (let ((temp-file (make-symbol "temp-file"))
(temp-buffer (make-symbol "temp-buffer"))) (temp-buffer (make-symbol "temp-buffer")))
`(let ((,temp-file ,file) `(let ((,temp-file ,file)
(,temp-buffer (generate-new-buffer " *temp file*"))) (,temp-buffer (generate-new-buffer " *temp file*" t)))
(unwind-protect (unwind-protect
(prog1 (prog1
(with-current-buffer ,temp-buffer (with-current-buffer ,temp-buffer
@ -3906,10 +3909,12 @@ Use a MESSAGE of \"\" to temporarily clear the echo area."
(defmacro with-temp-buffer (&rest body) (defmacro with-temp-buffer (&rest body)
"Create a temporary buffer, and evaluate BODY there like `progn'. "Create a temporary buffer, and evaluate BODY there like `progn'.
The buffer does not run the hooks `kill-buffer-hook',
`kill-buffer-query-functions', and `buffer-list-update-hook'.
See also `with-temp-file' and `with-output-to-string'." See also `with-temp-file' and `with-output-to-string'."
(declare (indent 0) (debug t)) (declare (indent 0) (debug t))
(let ((temp-buffer (make-symbol "temp-buffer"))) (let ((temp-buffer (make-symbol "temp-buffer")))
`(let ((,temp-buffer (generate-new-buffer " *temp*"))) `(let ((,temp-buffer (generate-new-buffer " *temp*" t)))
;; `kill-buffer' can change current-buffer in some odd cases. ;; `kill-buffer' can change current-buffer in some odd cases.
(with-current-buffer ,temp-buffer (with-current-buffer ,temp-buffer
(unwind-protect (unwind-protect
@ -3944,7 +3949,7 @@ of that nature."
(defmacro with-output-to-string (&rest body) (defmacro with-output-to-string (&rest body)
"Execute BODY, return the text it sent to `standard-output', as a string." "Execute BODY, return the text it sent to `standard-output', as a string."
(declare (indent 0) (debug t)) (declare (indent 0) (debug t))
`(let ((standard-output (generate-new-buffer " *string-output*"))) `(let ((standard-output (generate-new-buffer " *string-output*" t)))
(unwind-protect (unwind-protect
(progn (progn
(let ((standard-output standard-output)) (let ((standard-output standard-output))

View file

@ -37,7 +37,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "window.h" #include "window.h"
#include "commands.h" #include "commands.h"
#include "character.h" #include "character.h"
#include "coding.h"
#include "buffer.h" #include "buffer.h"
#include "region-cache.h" #include "region-cache.h"
#include "indent.h" #include "indent.h"
@ -514,16 +513,33 @@ get_truename_buffer (register Lisp_Object filename)
return Qnil; return Qnil;
} }
DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 1, 0, /* Run buffer-list-update-hook if Vrun_hooks is non-nil, and BUF is NULL
or does not have buffer hooks inhibited. BUF is NULL when called by
make-indirect-buffer, since it does not inhibit buffer hooks. */
static void
run_buffer_list_update_hook (struct buffer *buf)
{
if (! (NILP (Vrun_hooks) || (buf && buf->inhibit_buffer_hooks)))
call1 (Vrun_hooks, Qbuffer_list_update_hook);
}
DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 2, 0,
doc: /* Return the buffer specified by BUFFER-OR-NAME, creating a new one if needed. doc: /* Return the buffer specified by BUFFER-OR-NAME, creating a new one if needed.
If BUFFER-OR-NAME is a string and a live buffer with that name exists, If BUFFER-OR-NAME is a string and a live buffer with that name exists,
return that buffer. If no such buffer exists, create a new buffer with return that buffer. If no such buffer exists, create a new buffer with
that name and return it. If BUFFER-OR-NAME starts with a space, the new that name and return it.
buffer does not keep undo information.
If BUFFER-OR-NAME starts with a space, the new buffer does not keep undo
information. If optional argument INHIBIT-BUFFER-HOOKS is non-nil, the
new buffer does not run the hooks `kill-buffer-hook',
`kill-buffer-query-functions', and `buffer-list-update-hook'. This
avoids slowing down internal or temporary buffers that are never
presented to users or passed on to other applications.
If BUFFER-OR-NAME is a buffer instead of a string, return it as given, If BUFFER-OR-NAME is a buffer instead of a string, return it as given,
even if it is dead. The return value is never nil. */) even if it is dead. The return value is never nil. */)
(register Lisp_Object buffer_or_name) (register Lisp_Object buffer_or_name, Lisp_Object inhibit_buffer_hooks)
{ {
register Lisp_Object buffer, name; register Lisp_Object buffer, name;
register struct buffer *b; register struct buffer *b;
@ -598,11 +614,7 @@ even if it is dead. The return value is never nil. */)
set_string_intervals (name, NULL); set_string_intervals (name, NULL);
bset_name (b, name); bset_name (b, name);
b->inhibit_buffer_hooks b->inhibit_buffer_hooks = !NILP (inhibit_buffer_hooks);
= (STRINGP (Vcode_conversion_workbuf_name)
&& strncmp (SSDATA (name), SSDATA (Vcode_conversion_workbuf_name),
SBYTES (Vcode_conversion_workbuf_name)) == 0);
bset_undo_list (b, SREF (name, 0) != ' ' ? Qnil : Qt); bset_undo_list (b, SREF (name, 0) != ' ' ? Qnil : Qt);
reset_buffer (b); reset_buffer (b);
@ -614,9 +626,8 @@ even if it is dead. The return value is never nil. */)
/* Put this in the alist of all live buffers. */ /* Put this in the alist of all live buffers. */
XSETBUFFER (buffer, b); XSETBUFFER (buffer, b);
Vbuffer_alist = nconc2 (Vbuffer_alist, list1 (Fcons (name, buffer))); Vbuffer_alist = nconc2 (Vbuffer_alist, list1 (Fcons (name, buffer)));
/* And run buffer-list-update-hook. */
if (!NILP (Vrun_hooks) && !b->inhibit_buffer_hooks) run_buffer_list_update_hook (b);
call1 (Vrun_hooks, Qbuffer_list_update_hook);
return buffer; return buffer;
} }
@ -890,9 +901,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
set_buffer_internal_1 (old_b); set_buffer_internal_1 (old_b);
} }
/* Run buffer-list-update-hook. */ run_buffer_list_update_hook (NULL);
if (!NILP (Vrun_hooks))
call1 (Vrun_hooks, Qbuffer_list_update_hook);
return buf; return buf;
} }
@ -1536,9 +1545,7 @@ This does not change the name of the visited file (if any). */)
&& !NILP (BVAR (current_buffer, auto_save_file_name))) && !NILP (BVAR (current_buffer, auto_save_file_name)))
call0 (intern ("rename-auto-save-file")); call0 (intern ("rename-auto-save-file"));
/* Run buffer-list-update-hook. */ run_buffer_list_update_hook (current_buffer);
if (!NILP (Vrun_hooks) && !current_buffer->inhibit_buffer_hooks)
call1 (Vrun_hooks, Qbuffer_list_update_hook);
/* Refetch since that last call may have done GC. */ /* Refetch since that last call may have done GC. */
return BVAR (current_buffer, name); return BVAR (current_buffer, name);
@ -1612,7 +1619,7 @@ exists, return the buffer `*scratch*' (creating it if necessary). */)
buf = Fget_buffer (scratch); buf = Fget_buffer (scratch);
if (NILP (buf)) if (NILP (buf))
{ {
buf = Fget_buffer_create (scratch); buf = Fget_buffer_create (scratch, Qnil);
Fset_buffer_major_mode (buf); Fset_buffer_major_mode (buf);
} }
return buf; return buf;
@ -1636,7 +1643,7 @@ other_buffer_safely (Lisp_Object buffer)
buf = Fget_buffer (scratch); buf = Fget_buffer (scratch);
if (NILP (buf)) if (NILP (buf))
{ {
buf = Fget_buffer_create (scratch); buf = Fget_buffer_create (scratch, Qnil);
Fset_buffer_major_mode (buf); Fset_buffer_major_mode (buf);
} }
@ -1713,7 +1720,9 @@ buffer to be killed as the current buffer. If any of them returns nil,
the buffer is not killed. The hook `kill-buffer-hook' is run before the the buffer is not killed. The hook `kill-buffer-hook' is run before the
buffer is actually killed. The buffer being killed will be current buffer is actually killed. The buffer being killed will be current
while the hook is running. Functions called by any of these hooks are while the hook is running. Functions called by any of these hooks are
supposed to not change the current buffer. supposed to not change the current buffer. Neither hook is run for
internal or temporary buffers created by `get-buffer-create' or
`generate-new-buffer' with argument INHIBIT-BUFFER-HOOKS non-nil.
Any processes that have this buffer as the `process-buffer' are killed Any processes that have this buffer as the `process-buffer' are killed
with SIGHUP. This function calls `replace-buffer-in-windows' for with SIGHUP. This function calls `replace-buffer-in-windows' for
@ -1973,9 +1982,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
bset_width_table (b, Qnil); bset_width_table (b, Qnil);
unblock_input (); unblock_input ();
/* Run buffer-list-update-hook. */ run_buffer_list_update_hook (b);
if (!NILP (Vrun_hooks) && !b->inhibit_buffer_hooks)
call1 (Vrun_hooks, Qbuffer_list_update_hook);
return Qt; return Qt;
} }
@ -2015,9 +2022,7 @@ record_buffer (Lisp_Object buffer)
fset_buffer_list (f, Fcons (buffer, Fdelq (buffer, f->buffer_list))); fset_buffer_list (f, Fcons (buffer, Fdelq (buffer, f->buffer_list)));
fset_buried_buffer_list (f, Fdelq (buffer, f->buried_buffer_list)); fset_buried_buffer_list (f, Fdelq (buffer, f->buried_buffer_list));
/* Run buffer-list-update-hook. */ run_buffer_list_update_hook (XBUFFER (buffer));
if (!NILP (Vrun_hooks) && !XBUFFER (buffer)->inhibit_buffer_hooks)
call1 (Vrun_hooks, Qbuffer_list_update_hook);
} }
@ -2054,9 +2059,7 @@ DEFUN ("bury-buffer-internal", Fbury_buffer_internal, Sbury_buffer_internal,
fset_buried_buffer_list fset_buried_buffer_list
(f, Fcons (buffer, Fdelq (buffer, f->buried_buffer_list))); (f, Fcons (buffer, Fdelq (buffer, f->buried_buffer_list)));
/* Run buffer-list-update-hook. */ run_buffer_list_update_hook (XBUFFER (buffer));
if (!NILP (Vrun_hooks) && !XBUFFER (buffer)->inhibit_buffer_hooks)
call1 (Vrun_hooks, Qbuffer_list_update_hook);
return Qnil; return Qnil;
} }
@ -5349,10 +5352,11 @@ init_buffer_once (void)
Fput (Qkill_buffer_hook, Qpermanent_local, Qt); Fput (Qkill_buffer_hook, Qpermanent_local, Qt);
/* Super-magic invisible buffer. */ /* Super-magic invisible buffer. */
Vprin1_to_string_buffer = Fget_buffer_create (build_pure_c_string (" prin1")); Vprin1_to_string_buffer =
Fget_buffer_create (build_pure_c_string (" prin1"), Qt);
Vbuffer_alist = Qnil; Vbuffer_alist = Qnil;
Fset_buffer (Fget_buffer_create (build_pure_c_string ("*scratch*"))); Fset_buffer (Fget_buffer_create (build_pure_c_string ("*scratch*"), Qnil));
inhibit_modification_hooks = 0; inhibit_modification_hooks = 0;
} }
@ -5397,7 +5401,7 @@ init_buffer (void)
#endif /* USE_MMAP_FOR_BUFFERS */ #endif /* USE_MMAP_FOR_BUFFERS */
AUTO_STRING (scratch, "*scratch*"); AUTO_STRING (scratch, "*scratch*");
Fset_buffer (Fget_buffer_create (scratch)); Fset_buffer (Fget_buffer_create (scratch, Qnil));
if (NILP (BVAR (&buffer_defaults, enable_multibyte_characters))) if (NILP (BVAR (&buffer_defaults, enable_multibyte_characters)))
Fset_buffer_multibyte (Qnil); Fset_buffer_multibyte (Qnil);
@ -6300,9 +6304,14 @@ Use Custom to set this variable and update the display. */);
DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions, DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions,
doc: /* List of functions called with no args to query before killing a buffer. doc: /* List of functions called with no args to query before killing a buffer.
The buffer being killed will be current while the functions are running. The buffer being killed will be current while the functions are running.
See `kill-buffer'.
If any of them returns nil, the buffer is not killed. Functions run by If any of them returns nil, the buffer is not killed. Functions run by
this hook are supposed to not change the current buffer. */); this hook are supposed to not change the current buffer.
This hook is not run for internal or temporary buffers created by
`get-buffer-create' or `generate-new-buffer' with argument
INHIBIT-BUFFER-HOOKS non-nil. */);
Vkill_buffer_query_functions = Qnil; Vkill_buffer_query_functions = Qnil;
DEFVAR_LISP ("change-major-mode-hook", Vchange_major_mode_hook, DEFVAR_LISP ("change-major-mode-hook", Vchange_major_mode_hook,
@ -6315,9 +6324,12 @@ The function `kill-all-local-variables' runs this before doing anything else. *
doc: /* Hook run when the buffer list changes. doc: /* Hook run when the buffer list changes.
Functions (implicitly) running this hook are `get-buffer-create', Functions (implicitly) running this hook are `get-buffer-create',
`make-indirect-buffer', `rename-buffer', `kill-buffer', `bury-buffer' `make-indirect-buffer', `rename-buffer', `kill-buffer', `bury-buffer'
and `select-window'. Functions run by this hook should avoid calling and `select-window'. This hook is not run for internal or temporary
`select-window' with a nil NORECORD argument or `with-temp-buffer' buffers created by `get-buffer-create' or `generate-new-buffer' with
since either may lead to infinite recursion. */); argument INHIBIT-BUFFER-HOOKS non-nil.
Functions run by this hook should avoid calling `select-window' with a
nil NORECORD argument since it may lead to infinite recursion. */);
Vbuffer_list_update_hook = Qnil; Vbuffer_list_update_hook = Qnil;
DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook"); DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook");

View file

@ -663,11 +663,11 @@ struct buffer
/* Non-zero whenever the narrowing is changed in this buffer. */ /* Non-zero whenever the narrowing is changed in this buffer. */
bool_bf clip_changed : 1; bool_bf clip_changed : 1;
/* Non-zero for internally used temporary buffers that don't need to /* Non-zero for internal or temporary buffers that don't need to
run hooks kill-buffer-hook, buffer-list-update-hook, and run hooks kill-buffer-hook, kill-buffer-query-functions, and
kill-buffer-query-functions. This is used in coding.c to avoid buffer-list-update-hook. This is used in coding.c to avoid
slowing down en/decoding when there are a lot of these hooks slowing down en/decoding when a lot of these hooks are
defined. */ defined, as well as by with-temp-buffer, for example. */
bool_bf inhibit_buffer_hooks : 1; bool_bf inhibit_buffer_hooks : 1;
/* List of overlays that end at or before the current center, /* List of overlays that end at or before the current center,

View file

@ -405,9 +405,8 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
if (! (NILP (buffer) || EQ (buffer, Qt) || FIXNUMP (buffer))) if (! (NILP (buffer) || EQ (buffer, Qt) || FIXNUMP (buffer)))
{ {
Lisp_Object spec_buffer; Lisp_Object spec_buffer = buffer;
spec_buffer = buffer; buffer = Fget_buffer_create (buffer, Qnil);
buffer = Fget_buffer_create (buffer);
/* Mention the buffer name for a better error message. */ /* Mention the buffer name for a better error message. */
if (NILP (buffer)) if (NILP (buffer))
CHECK_BUFFER (spec_buffer); CHECK_BUFFER (spec_buffer);

View file

@ -7821,7 +7821,7 @@ encode_coding (struct coding_system *coding)
/* A string that serves as name of the reusable work buffer, and as base /* A string that serves as name of the reusable work buffer, and as base
name of temporary work buffers used for code-conversion operations. */ name of temporary work buffers used for code-conversion operations. */
Lisp_Object Vcode_conversion_workbuf_name; static Lisp_Object Vcode_conversion_workbuf_name;
/* The reusable working buffer, created once and never killed. */ /* The reusable working buffer, created once and never killed. */
static Lisp_Object Vcode_conversion_reused_workbuf; static Lisp_Object Vcode_conversion_reused_workbuf;
@ -7839,7 +7839,7 @@ code_conversion_restore (Lisp_Object arg)
if (! NILP (workbuf)) if (! NILP (workbuf))
{ {
if (EQ (workbuf, Vcode_conversion_reused_workbuf)) if (EQ (workbuf, Vcode_conversion_reused_workbuf))
reused_workbuf_in_use = 0; reused_workbuf_in_use = false;
else else
Fkill_buffer (workbuf); Fkill_buffer (workbuf);
} }
@ -7857,13 +7857,13 @@ code_conversion_save (bool with_work_buf, bool multibyte)
{ {
Lisp_Object name Lisp_Object name
= Fgenerate_new_buffer_name (Vcode_conversion_workbuf_name, Qnil); = Fgenerate_new_buffer_name (Vcode_conversion_workbuf_name, Qnil);
workbuf = Fget_buffer_create (name); workbuf = Fget_buffer_create (name, Qt);
} }
else else
{ {
if (NILP (Fbuffer_live_p (Vcode_conversion_reused_workbuf))) if (NILP (Fbuffer_live_p (Vcode_conversion_reused_workbuf)))
Vcode_conversion_reused_workbuf Vcode_conversion_reused_workbuf
= Fget_buffer_create (Vcode_conversion_workbuf_name); = Fget_buffer_create (Vcode_conversion_workbuf_name, Qt);
workbuf = Vcode_conversion_reused_workbuf; workbuf = Vcode_conversion_reused_workbuf;
} }
} }
@ -7881,7 +7881,7 @@ code_conversion_save (bool with_work_buf, bool multibyte)
bset_undo_list (current_buffer, Qt); bset_undo_list (current_buffer, Qt);
bset_enable_multibyte_characters (current_buffer, multibyte ? Qt : Qnil); bset_enable_multibyte_characters (current_buffer, multibyte ? Qt : Qnil);
if (EQ (workbuf, Vcode_conversion_reused_workbuf)) if (EQ (workbuf, Vcode_conversion_reused_workbuf))
reused_workbuf_in_use = 1; reused_workbuf_in_use = true;
set_buffer_internal (current); set_buffer_internal (current);
} }
@ -11639,7 +11639,7 @@ syms_of_coding (void)
staticpro (&Vcode_conversion_workbuf_name); staticpro (&Vcode_conversion_workbuf_name);
Vcode_conversion_workbuf_name = build_pure_c_string (" *code-conversion-work*"); Vcode_conversion_workbuf_name = build_pure_c_string (" *code-conversion-work*");
reused_workbuf_in_use = 0; reused_workbuf_in_use = false;
PDUMPER_REMEMBER_SCALAR (reused_workbuf_in_use); PDUMPER_REMEMBER_SCALAR (reused_workbuf_in_use);
DEFSYM (Qcharset, "charset"); DEFSYM (Qcharset, "charset");

View file

@ -97,9 +97,6 @@ enum define_coding_undecided_arg_index
extern Lisp_Object Vcoding_system_hash_table; extern Lisp_Object Vcoding_system_hash_table;
/* Name (or base name) of work buffer for code conversion. */
extern Lisp_Object Vcode_conversion_workbuf_name;
/* Enumeration of index to an attribute vector of a coding system. */ /* Enumeration of index to an attribute vector of a coding system. */
enum coding_attr_index enum coding_attr_index

View file

@ -4004,7 +4004,7 @@ by calling `format-decode', which see. */)
record_unwind_current_buffer (); record_unwind_current_buffer ();
workbuf = Fget_buffer_create (name); workbuf = Fget_buffer_create (name, Qt);
buf = XBUFFER (workbuf); buf = XBUFFER (workbuf);
delete_all_overlays (buf); delete_all_overlays (buf);

View file

@ -809,7 +809,7 @@ get_minibuffer (EMACS_INT depth)
static char const name_fmt[] = " *Minibuf-%"pI"d*"; static char const name_fmt[] = " *Minibuf-%"pI"d*";
char name[sizeof name_fmt + INT_STRLEN_BOUND (EMACS_INT)]; char name[sizeof name_fmt + INT_STRLEN_BOUND (EMACS_INT)];
AUTO_STRING_WITH_LEN (lname, name, sprintf (name, name_fmt, depth)); AUTO_STRING_WITH_LEN (lname, name, sprintf (name, name_fmt, depth));
buf = Fget_buffer_create (lname); buf = Fget_buffer_create (lname, Qnil);
/* Although the buffer's name starts with a space, undo should be /* Although the buffer's name starts with a space, undo should be
enabled in it. */ enabled in it. */

View file

@ -562,7 +562,7 @@ temp_output_buffer_setup (const char *bufname)
record_unwind_current_buffer (); record_unwind_current_buffer ();
Fset_buffer (Fget_buffer_create (build_string (bufname))); Fset_buffer (Fget_buffer_create (build_string (bufname), Qnil));
Fkill_all_local_variables (); Fkill_all_local_variables ();
delete_all_overlays (current_buffer); delete_all_overlays (current_buffer);

View file

@ -1731,7 +1731,7 @@ usage: (make-process &rest ARGS) */)
buffer = Fplist_get (contact, QCbuffer); buffer = Fplist_get (contact, QCbuffer);
if (!NILP (buffer)) if (!NILP (buffer))
buffer = Fget_buffer_create (buffer); buffer = Fget_buffer_create (buffer, Qnil);
/* Make sure that the child will be able to chdir to the current /* Make sure that the child will be able to chdir to the current
buffer's current directory, or its unhandled equivalent. We buffer's current directory, or its unhandled equivalent. We
@ -1768,7 +1768,7 @@ usage: (make-process &rest ARGS) */)
QCname, QCname,
concat2 (name, build_string (" stderr")), concat2 (name, build_string (" stderr")),
QCbuffer, QCbuffer,
Fget_buffer_create (xstderr), Fget_buffer_create (xstderr, Qnil),
QCnoquery, QCnoquery,
query_on_exit ? Qnil : Qt); query_on_exit ? Qnil : Qt);
} }
@ -2443,7 +2443,7 @@ usage: (make-pipe-process &rest ARGS) */)
buffer = Fplist_get (contact, QCbuffer); buffer = Fplist_get (contact, QCbuffer);
if (NILP (buffer)) if (NILP (buffer))
buffer = name; buffer = name;
buffer = Fget_buffer_create (buffer); buffer = Fget_buffer_create (buffer, Qnil);
pset_buffer (p, buffer); pset_buffer (p, buffer);
pset_childp (p, contact); pset_childp (p, contact);
@ -3173,7 +3173,7 @@ usage: (make-serial-process &rest ARGS) */)
buffer = Fplist_get (contact, QCbuffer); buffer = Fplist_get (contact, QCbuffer);
if (NILP (buffer)) if (NILP (buffer))
buffer = name; buffer = name;
buffer = Fget_buffer_create (buffer); buffer = Fget_buffer_create (buffer, Qnil);
pset_buffer (p, buffer); pset_buffer (p, buffer);
pset_childp (p, contact); pset_childp (p, contact);
@ -4188,7 +4188,7 @@ usage: (make-network-process &rest ARGS) */)
open_socket: open_socket:
if (!NILP (buffer)) if (!NILP (buffer))
buffer = Fget_buffer_create (buffer); buffer = Fget_buffer_create (buffer, Qnil);
/* Unwind bind_polling_period. */ /* Unwind bind_polling_period. */
unbind_to (count, Qnil); unbind_to (count, Qnil);
@ -4961,7 +4961,7 @@ server_accept_connection (Lisp_Object server, int channel)
if (!NILP (buffer)) if (!NILP (buffer))
{ {
args[1] = buffer; args[1] = buffer;
buffer = Fget_buffer_create (Fformat (nargs, args)); buffer = Fget_buffer_create (Fformat (nargs, args), Qnil);
} }
} }

View file

@ -7372,7 +7372,7 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
tip_f = XFRAME (tip_frame); tip_f = XFRAME (tip_frame);
window = FRAME_ROOT_WINDOW (tip_f); window = FRAME_ROOT_WINDOW (tip_f);
tip_buf = Fget_buffer_create (tip); tip_buf = Fget_buffer_create (tip, Qnil);
/* We will mark the tip window a "pseudo-window" below, and such /* We will mark the tip window a "pseudo-window" below, and such
windows cannot have display margins. */ windows cannot have display margins. */
bset_left_margin_cols (XBUFFER (tip_buf), make_fixnum (0)); bset_left_margin_cols (XBUFFER (tip_buf), make_fixnum (0));

View file

@ -617,11 +617,12 @@ equals the special symbol `mark-for-redisplay'.
Run `buffer-list-update-hook' unless NORECORD is non-nil. Note that Run `buffer-list-update-hook' unless NORECORD is non-nil. Note that
applications and internal routines often select a window temporarily for applications and internal routines often select a window temporarily for
various purposes; mostly, to simplify coding. As a rule, such various purposes; mostly, to simplify coding. As a rule, such
selections should be not recorded and therefore will not pollute selections should not be recorded and therefore will not pollute
`buffer-list-update-hook'. Selections that "really count" are those `buffer-list-update-hook'. Selections that "really count" are those
causing a visible change in the next redisplay of WINDOW's frame and causing a visible change in the next redisplay of WINDOW's frame and
should be always recorded. So if you think of running a function each should always be recorded. So if you think of running a function each
time a window gets selected put it on `buffer-list-update-hook'. time a window gets selected, put it on `buffer-list-update-hook' or
`window-selection-change-functions'.
Also note that the main editor command loop sets the current buffer to Also note that the main editor command loop sets the current buffer to
the buffer of the selected window before each command. */) the buffer of the selected window before each command. */)

View file

@ -10880,7 +10880,7 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
/* Ensure the Messages buffer exists, and switch to it. /* Ensure the Messages buffer exists, and switch to it.
If we created it, set the major-mode. */ If we created it, set the major-mode. */
bool newbuffer = NILP (Fget_buffer (Vmessages_buffer_name)); bool newbuffer = NILP (Fget_buffer (Vmessages_buffer_name));
Fset_buffer (Fget_buffer_create (Vmessages_buffer_name)); Fset_buffer (Fget_buffer_create (Vmessages_buffer_name, Qnil));
if (newbuffer if (newbuffer
&& !NILP (Ffboundp (intern ("messages-buffer-mode")))) && !NILP (Ffboundp (intern ("messages-buffer-mode"))))
call0 (intern ("messages-buffer-mode")); call0 (intern ("messages-buffer-mode"));
@ -11366,7 +11366,7 @@ ensure_echo_area_buffers (void)
static char const name_fmt[] = " *Echo Area %d*"; static char const name_fmt[] = " *Echo Area %d*";
char name[sizeof name_fmt + INT_STRLEN_BOUND (int)]; char name[sizeof name_fmt + INT_STRLEN_BOUND (int)];
AUTO_STRING_WITH_LEN (lname, name, sprintf (name, name_fmt, i)); AUTO_STRING_WITH_LEN (lname, name, sprintf (name, name_fmt, i));
echo_buffer[i] = Fget_buffer_create (lname); echo_buffer[i] = Fget_buffer_create (lname, Qnil);
bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil); bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
/* to force word wrap in echo area - /* to force word wrap in echo area -
it was decided to postpone this*/ it was decided to postpone this*/

View file

@ -7041,7 +7041,7 @@ Text larger than the specified size is clipped. */)
tip_f = XFRAME (tip_frame); tip_f = XFRAME (tip_frame);
window = FRAME_ROOT_WINDOW (tip_f); window = FRAME_ROOT_WINDOW (tip_f);
tip_buf = Fget_buffer_create (tip); tip_buf = Fget_buffer_create (tip, Qnil);
/* We will mark the tip window a "pseudo-window" below, and such /* We will mark the tip window a "pseudo-window" below, and such
windows cannot have display margins. */ windows cannot have display margins. */
bset_left_margin_cols (XBUFFER (tip_buf), make_fixnum (0)); bset_left_margin_cols (XBUFFER (tip_buf), make_fixnum (0));

View file

@ -100,7 +100,8 @@ Returns the newly constructed xwidget, or nil if construction fails. */)
Lisp_Object val; Lisp_Object val;
xw->type = type; xw->type = type;
xw->title = title; xw->title = title;
xw->buffer = NILP (buffer) ? Fcurrent_buffer () : Fget_buffer_create (buffer); xw->buffer = (NILP (buffer) ? Fcurrent_buffer ()
: Fget_buffer_create (buffer, Qnil));
xw->height = XFIXNAT (height); xw->height = XFIXNAT (height);
xw->width = XFIXNAT (width); xw->width = XFIXNAT (width);
xw->kill_without_query = false; xw->kill_without_query = false;

View file

@ -19,9 +19,7 @@
;;; Code: ;;; Code:
(require 'ert) (require 'cl-lib)
(require 'seq)
(eval-when-compile (require 'cl-lib))
(ert-deftest overlay-modification-hooks-message-other-buf () (ert-deftest overlay-modification-hooks-message-other-buf ()
"Test for bug#21824. "Test for bug#21824.
@ -1334,4 +1332,33 @@ with parameters from the *Messages* buffer modification."
(with-temp-buffer (with-temp-buffer
(should (assq 'buffer-undo-list (buffer-local-variables))))) (should (assq 'buffer-undo-list (buffer-local-variables)))))
(ert-deftest buffer-tests-inhibit-buffer-hooks ()
"Test `get-buffer-create' argument INHIBIT-BUFFER-HOOKS."
(let* (run-bluh (bluh (lambda () (setq run-bluh t))))
(unwind-protect
(let* ( run-kbh (kbh (lambda () (setq run-kbh t)))
run-kbqf (kbqf (lambda () (setq run-kbqf t))) )
;; Inhibited.
(add-hook 'buffer-list-update-hook bluh)
(with-current-buffer (generate-new-buffer " foo" t)
(add-hook 'kill-buffer-hook kbh nil t)
(add-hook 'kill-buffer-query-functions kbqf nil t)
(kill-buffer))
(with-temp-buffer)
(with-output-to-string)
(should-not run-bluh)
(should-not run-kbh)
(should-not run-kbqf)
;; Not inhibited.
(with-current-buffer (generate-new-buffer " foo")
(should run-bluh)
(add-hook 'kill-buffer-hook kbh nil t)
(add-hook 'kill-buffer-query-functions kbqf nil t)
(kill-buffer))
(should run-kbh)
(should run-kbqf))
(remove-hook 'buffer-list-update-hook bluh))))
;;; buffer-tests.el ends here ;;; buffer-tests.el ends here