From: "Basil L. Contovounesios" <contovob@tcd.ie>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: 34765@debbugs.gnu.org, larsi@gnus.org, alexanderm@web.de
Subject: bug#34765: 26.1; with-temp-buffer should not run buffer-list-update-hook
Date: Fri, 18 Dec 2020 18:49:52 +0000 [thread overview]
Message-ID: <87eejnaqzz.fsf@tcd.ie> (raw)
In-Reply-To: <jwvwnxfruwy.fsf-monnier+emacs@gnu.org> (Stefan Monnier's message of "Fri, 18 Dec 2020 10:36:22 -0500")
[-- Attachment #1: Type: text/plain, Size: 369 bytes --]
Stefan Monnier <monnier@iro.umontreal.ca> writes:
> You lost the `(with-current-buffer ,temp-buffer` around `write-region`
> so your new code will break if `body` doesn't preserve current-buffer.
Ugh, I thought the caller couldn't kill the buffer because it's later
written, but I didn't think of excursions. I've now attached an updated
patch.
Thanks,
--
Basil
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Inhibit-buffer-hooks-in-temporary-buffers.patch --]
[-- Type: text/x-diff, Size: 45329 bytes --]
From d2b2648efa51343a3b7dd84ada89110e84aa8658 Mon Sep 17 00:00:00 2001
From: "Basil L. Contovounesios" <contovob@tcd.ie>
Date: Tue, 1 Dec 2020 01:12:32 +0000
Subject: [PATCH] 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).
* .dir-locals.el (c-mode): Enforce existing indent-tabs-mode policy.
* 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.
---
.dir-locals.el | 1 +
doc/lispref/buffers.texi | 55 +++++++++++++++------
doc/lispref/files.texi | 7 ++-
doc/lispref/internals.texi | 11 ++++-
doc/misc/gnus-faq.texi | 8 ++--
etc/NEWS | 16 +++++++
lisp/files.el | 6 ++-
lisp/gnus/gnus-uu.el | 3 +-
lisp/international/mule.el | 9 ++--
lisp/json.el | 2 +-
lisp/mh-e/mh-xface.el | 3 +-
lisp/net/imap.el | 3 +-
lisp/net/mailcap.el | 3 +-
lisp/progmodes/flymake-proc.el | 13 +++--
lisp/simple.el | 3 +-
lisp/subr.el | 17 ++++---
src/buffer.c | 87 +++++++++++++++++++---------------
src/buffer.h | 10 ++--
src/callproc.c | 5 +-
src/coding.c | 12 ++---
src/coding.h | 3 --
src/fileio.c | 2 +-
src/minibuf.c | 2 +-
src/print.c | 2 +-
src/process.c | 12 ++---
src/w32fns.c | 2 +-
src/window.c | 7 +--
src/xdisp.c | 4 +-
src/xfns.c | 2 +-
src/xwidget.c | 3 +-
test/src/buffer-tests.el | 33 +++++++++++--
31 files changed, 217 insertions(+), 129 deletions(-)
diff --git a/.dir-locals.el b/.dir-locals.el
index 27d50c6069..b313945936 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -9,6 +9,7 @@
(c-noise-macro-names . ("INLINE" "ATTRIBUTE_NO_SANITIZE_UNDEFINED" "UNINIT" "CALLBACK" "ALIGN_STACK"))
(electric-quote-comment . nil)
(electric-quote-string . nil)
+ (indent-tabs-mode . t)
(mode . bug-reference-prog)))
(objc-mode . ((c-file-style . "GNU")
(electric-quote-comment . nil)
diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi
index 2860343628..c8c4852e30 100644
--- a/doc/lispref/buffers.texi
+++ b/doc/lispref/buffers.texi
@@ -225,13 +225,18 @@ Current Buffer
@defmac with-temp-buffer body@dots{}
@anchor{Definition of with-temp-buffer}
-The @code{with-temp-buffer} macro evaluates the @var{body} forms
-with a temporary buffer as the current buffer. It saves the identity of
+The @code{with-temp-buffer} macro evaluates the @var{body} forms with
+a temporary buffer as the current buffer. It saves the identity of
the current buffer, creates a temporary buffer and makes it current,
evaluates the @var{body} forms, and finally restores the previous
-current buffer while killing the temporary buffer. By default, undo
-information (@pxref{Undo}) is not recorded in the buffer created by
-this macro (but @var{body} can enable that, if needed).
+current buffer while killing the temporary buffer.
+
+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
return the contents of the temporary buffer by using
@@ -345,9 +350,9 @@ Buffer Names
If the optional second argument @var{ignore} is non-@code{nil}, it
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
-of an existing buffer (which would normally be rejected). Thus, if
-buffers named @samp{foo}, @samp{foo<2>}, @samp{foo<3>} and
+that potential buffer acceptable, if it is tried, even if it is the
+name of an existing buffer (which would normally be rejected). Thus,
+if buffers named @samp{foo}, @samp{foo<2>}, @samp{foo<3>} and
@samp{foo<4>} exist,
@example
@@ -932,13 +937,17 @@ Buffer List
@defvar buffer-list-update-hook
This is a normal hook run whenever the buffer list changes. Functions
(implicitly) running this hook are @code{get-buffer-create}
-(@pxref{Creating Buffers}), @code{rename-buffer} (@pxref{Buffer Names}),
-@code{kill-buffer} (@pxref{Killing Buffers}), @code{bury-buffer} (see
-above) and @code{select-window} (@pxref{Selecting Windows}).
+(@pxref{Creating Buffers}), @code{rename-buffer} (@pxref{Buffer
+Names}), @code{kill-buffer} (@pxref{Killing Buffers}),
+@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}
-with a nil @var{norecord} argument or @code{with-temp-buffer} since
-either may lead to infinite recursion.
+with a @code{nil} @var{norecord} argument since this may lead to
+infinite recursion.
@end defvar
@node Creating Buffers
@@ -951,12 +960,20 @@ Creating Buffers
with the specified name; @code{generate-new-buffer} always creates a new
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
@code{with-output-to-temp-buffer} (@pxref{Temporary Displays}) and
@code{create-file-buffer} (@pxref{Visiting Files}). Starting a
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
returned does not become the current buffer---this function does not
change which buffer is current.
@@ -980,7 +997,7 @@ Creating Buffers
buffer initially disables undo information recording (@pxref{Undo}).
@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
it current. The name of the buffer is generated by passing @var{name}
to the function @code{generate-new-buffer-name} (@pxref{Buffer
@@ -1092,6 +1109,10 @@ Killing Buffers
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},
@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
@defvar kill-buffer-hook
@@ -1100,6 +1121,10 @@ Killing Buffers
The buffer to be killed is current when the hook functions run.
@xref{Hooks}. This variable is a permanent local, so its local binding
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
@defopt buffer-offer-save
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index d49ac42bb4..6949ca29c6 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -701,8 +701,11 @@ Writing to Files
The current buffer is restored even in case of an abnormal exit via
@code{throw} or error (@pxref{Nonlocal Exits}).
-See also @code{with-temp-buffer} in @ref{Definition of
-with-temp-buffer,, The Current Buffer}.
+Like @code{with-temp-buffer} (@pxref{Definition of with-temp-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
@node File Locks
diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi
index 28a5fdb349..757368bc98 100644
--- a/doc/lispref/internals.texi
+++ b/doc/lispref/internals.texi
@@ -2391,6 +2391,15 @@ Buffer Internals
This flag indicates that redisplay optimizations should not be used to
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
This field holds the current overlay center position. @xref{Managing
Overlays}.
@@ -2404,8 +2413,6 @@ Buffer Internals
and @code{overlays_after} is sorted in order of increasing beginning
position.
-@c FIXME? the following are now all Lisp_Object BUFFER_INTERNAL_FIELD (foo).
-
@item name
A Lisp string that names the buffer. It is guaranteed to be unique.
@xref{Buffer Names}. This and the following fields have their names
diff --git a/doc/misc/gnus-faq.texi b/doc/misc/gnus-faq.texi
index adb812f572..c30e80ff56 100644
--- a/doc/misc/gnus-faq.texi
+++ b/doc/misc/gnus-faq.texi
@@ -1523,10 +1523,10 @@ FAQ 5-8
@example
(setq message-default-headers
- (with-temp-buffer
- (insert "X-Face: ")
- (insert-file-contents "~/.xface")
- (buffer-string)))
+ (with-temp-buffer
+ (insert "X-Face: ")
+ (insert-file-contents "~/.xface")
+ (buffer-string)))
@end example
@noindent
diff --git a/etc/NEWS b/etc/NEWS
index 87463372d5..217b0b76a1 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1817,6 +1817,13 @@ modifies the string's text properties; instead, it uses and returns
a copy of the string. This helps avoid trouble when strings are
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.
@@ -2173,6 +2180,15 @@ Until it is solved you could ignore such errors by performing
** 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.
+
\f
* Changes in Emacs 28.1 on Non-Free Operating Systems
diff --git a/lisp/files.el b/lisp/files.el
index 093b5f92e5..70d451cccf 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -1850,6 +1850,10 @@ kill-buffer-hook
The buffer being killed is current while the hook is running.
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
frequently used for cleanup.")
@@ -1951,7 +1955,7 @@ create-file-buffer
(let ((lastname (file-name-nondirectory filename)))
(if (string= lastname "")
(setq lastname filename))
- (generate-new-buffer (if (string-match-p "\\` " lastname)
+ (generate-new-buffer (if (string-prefix-p " " lastname)
(concat "|" lastname)
lastname))))
diff --git a/lisp/gnus/gnus-uu.el b/lisp/gnus/gnus-uu.el
index 70aeac00d7..00ca430cc5 100644
--- a/lisp/gnus/gnus-uu.el
+++ b/lisp/gnus/gnus-uu.el
@@ -1587,8 +1587,7 @@ gnus-uu-unshar-article
(save-excursion
(switch-to-buffer (current-buffer))
(delete-other-windows)
- (let ((buffer (get-buffer-create (generate-new-buffer-name
- "*Warning*"))))
+ (let ((buffer (generate-new-buffer "*Warning*")))
(unless
(unwind-protect
(with-current-buffer buffer
diff --git a/lisp/international/mule.el b/lisp/international/mule.el
index 212e7232b4..6571454dff 100644
--- a/lisp/international/mule.el
+++ b/lisp/international/mule.el
@@ -307,12 +307,9 @@ load-with-code-conversion
(and (null noerror)
(signal 'file-error (list "Cannot open load file" file)))
;; Read file with code conversion, and then eval.
- (let* ((buffer
- ;; 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)
- (source (save-match-data (string-match "\\.el\\'" fullname))))
+ (let ((buffer (generate-new-buffer " *load*"))
+ (load-in-progress t)
+ (source (string-suffix-p ".el" fullname)))
(unless nomessage
(if source
(message "Loading %s (source)..." file)
diff --git a/lisp/json.el b/lisp/json.el
index c2fc1574fa..5f512b94cd 100644
--- a/lisp/json.el
+++ b/lisp/json.el
@@ -435,7 +435,7 @@ json-encode-string
(concat "\"" (substring-no-properties string) "\"")
(with-current-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.
(setq-local inhibit-modification-hooks t)
(setq json--string-buffer (current-buffer))))
diff --git a/lisp/mh-e/mh-xface.el b/lisp/mh-e/mh-xface.el
index 909f1fe95d..65039310e7 100644
--- a/lisp/mh-e/mh-xface.el
+++ b/lisp/mh-e/mh-xface.el
@@ -425,8 +425,7 @@ mh-x-image-url-fetch-image
be displayed in a buffer and position specified by MARKER. The
actual display is carried out by the SENTINEL function."
(if mh-wget-executable
- (let ((buffer (get-buffer-create (generate-new-buffer-name
- mh-temp-fetch-buffer)))
+ (let ((buffer (generate-new-buffer mh-temp-fetch-buffer))
(filename (or (mh-funcall-if-exists make-temp-file "mhe-fetch")
(expand-file-name (make-temp-name "~/mhe-fetch")))))
(with-current-buffer buffer
diff --git a/lisp/net/imap.el b/lisp/net/imap.el
index 0394f0efea..50b08d9612 100644
--- a/lisp/net/imap.el
+++ b/lisp/net/imap.el
@@ -1033,8 +1033,7 @@ imap-open
(when (funcall (nth 1 (assq stream imap-stream-alist)) buffer)
;; Stream changed?
(if (not (eq imap-default-stream stream))
- (with-current-buffer (get-buffer-create
- (generate-new-buffer-name " *temp*"))
+ (with-current-buffer (generate-new-buffer " *temp*")
(mapc 'make-local-variable imap-local-variables)
(set-buffer-multibyte nil)
(buffer-disable-undo)
diff --git a/lisp/net/mailcap.el b/lisp/net/mailcap.el
index d0f8c1272d..bc99f02fe3 100644
--- a/lisp/net/mailcap.el
+++ b/lisp/net/mailcap.el
@@ -386,8 +386,7 @@ mailcap-maybe-eval
(when
(save-window-excursion
(delete-other-windows)
- (let ((buffer (get-buffer-create (generate-new-buffer-name
- "*Warning*"))))
+ (let ((buffer (generate-new-buffer "*Warning*")))
(unwind-protect
(with-current-buffer buffer
(insert (substitute-command-keys
diff --git a/lisp/progmodes/flymake-proc.el b/lisp/progmodes/flymake-proc.el
index 152dc725c7..e9d5018f30 100644
--- a/lisp/progmodes/flymake-proc.el
+++ b/lisp/progmodes/flymake-proc.el
@@ -429,16 +429,15 @@ flymake-proc--replace-region
(defun flymake-proc--read-file-to-temp-buffer (file-name)
"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 temp-buffer
- (insert-file-contents file-name))
- temp-buffer))
+ (with-current-buffer (generate-new-buffer
+ (concat "flymake:" (file-name-nondirectory file-name)))
+ (insert-file-contents file-name)
+ (current-buffer)))
(defun flymake-proc--copy-buffer-to-temp-buffer (buffer)
"Copy contents of BUFFER into newly created temp buffer."
- (with-current-buffer
- (get-buffer-create (generate-new-buffer-name
- (concat "flymake:" (buffer-name buffer))))
+ (with-current-buffer (generate-new-buffer
+ (concat "flymake:" (buffer-name buffer)))
(insert-buffer-substring buffer)
(current-buffer)))
diff --git a/lisp/simple.el b/lisp/simple.el
index 090162b973..aab650e98a 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -4306,8 +4306,7 @@ shell-command-on-region
(defun shell-command-to-string (command)
"Execute shell command COMMAND and return its output as a string."
(with-output-to-string
- (with-current-buffer
- standard-output
+ (with-current-buffer standard-output
(shell-command command t))))
(defun process-file (program &optional infile buffer display &rest args)
diff --git a/lisp/subr.el b/lisp/subr.el
index 77c19c5bbf..6d5d7b4bac 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -3701,10 +3701,11 @@ internal--after-with-selected-window
(when (window-live-p (nth 1 state))
(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.
-Choose the buffer's name using `generate-new-buffer-name'."
- (get-buffer-create (generate-new-buffer-name name)))
+Choose the buffer's name using `generate-new-buffer-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)
"Execute the forms in BODY with WINDOW as the selected window.
@@ -3866,12 +3867,14 @@ with-output-to-temp-buffer
(defmacro with-temp-file (file &rest body)
"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 buffer does not run the hooks `kill-buffer-hook',
+`kill-buffer-query-functions', and `buffer-list-update-hook'.
See also `with-temp-buffer'."
(declare (indent 1) (debug t))
(let ((temp-file (make-symbol "temp-file"))
(temp-buffer (make-symbol "temp-buffer")))
`(let ((,temp-file ,file)
- (,temp-buffer (generate-new-buffer " *temp file*")))
+ (,temp-buffer (generate-new-buffer " *temp file*" t)))
(unwind-protect
(prog1
(with-current-buffer ,temp-buffer
@@ -3906,10 +3909,12 @@ with-temp-message
(defmacro with-temp-buffer (&rest body)
"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'."
(declare (indent 0) (debug t))
(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.
(with-current-buffer ,temp-buffer
(unwind-protect
@@ -3944,7 +3949,7 @@ with-silent-modifications
(defmacro with-output-to-string (&rest body)
"Execute BODY, return the text it sent to `standard-output', as a string."
(declare (indent 0) (debug t))
- `(let ((standard-output (generate-new-buffer " *string-output*")))
+ `(let ((standard-output (generate-new-buffer " *string-output*" t)))
(unwind-protect
(progn
(let ((standard-output standard-output))
diff --git a/src/buffer.c b/src/buffer.c
index dfc34faf6e..9564f66096 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -37,7 +37,6 @@ Copyright (C) 1985-1989, 1993-1995, 1997-2020 Free Software Foundation,
#include "window.h"
#include "commands.h"
#include "character.h"
-#include "coding.h"
#include "buffer.h"
#include "region-cache.h"
#include "indent.h"
@@ -514,16 +513,32 @@ get_truename_buffer (register Lisp_Object filename)
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
+ either NULL or does not have buffer hooks inhibited. */
+
+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.
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
-that name and return it. If BUFFER-OR-NAME starts with a space, the new
-buffer does not keep undo information.
+that name and return it.
+
+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,
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 struct buffer *b;
@@ -598,11 +613,7 @@ DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 1, 0,
set_string_intervals (name, NULL);
bset_name (b, name);
- b->inhibit_buffer_hooks
- = (STRINGP (Vcode_conversion_workbuf_name)
- && strncmp (SSDATA (name), SSDATA (Vcode_conversion_workbuf_name),
- SBYTES (Vcode_conversion_workbuf_name)) == 0);
-
+ b->inhibit_buffer_hooks = !NILP (inhibit_buffer_hooks);
bset_undo_list (b, SREF (name, 0) != ' ' ? Qnil : Qt);
reset_buffer (b);
@@ -614,9 +625,8 @@ DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 1, 0,
/* Put this in the alist of all live buffers. */
XSETBUFFER (buffer, b);
Vbuffer_alist = nconc2 (Vbuffer_alist, list1 (Fcons (name, buffer)));
- /* And run buffer-list-update-hook. */
- if (!NILP (Vrun_hooks) && !b->inhibit_buffer_hooks)
- call1 (Vrun_hooks, Qbuffer_list_update_hook);
+
+ run_buffer_list_update_hook (b);
return buffer;
}
@@ -890,9 +900,7 @@ DEFUN ("make-indirect-buffer", Fmake_indirect_buffer, Smake_indirect_buffer,
set_buffer_internal_1 (old_b);
}
- /* Run buffer-list-update-hook. */
- if (!NILP (Vrun_hooks))
- call1 (Vrun_hooks, Qbuffer_list_update_hook);
+ run_buffer_list_update_hook (NULL);
return buf;
}
@@ -1536,9 +1544,7 @@ DEFUN ("rename-buffer", Frename_buffer, Srename_buffer, 1, 2,
&& !NILP (BVAR (current_buffer, auto_save_file_name)))
call0 (intern ("rename-auto-save-file"));
- /* Run buffer-list-update-hook. */
- if (!NILP (Vrun_hooks) && !current_buffer->inhibit_buffer_hooks)
- call1 (Vrun_hooks, Qbuffer_list_update_hook);
+ run_buffer_list_update_hook (current_buffer);
/* Refetch since that last call may have done GC. */
return BVAR (current_buffer, name);
@@ -1612,7 +1618,7 @@ DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0,
buf = Fget_buffer (scratch);
if (NILP (buf))
{
- buf = Fget_buffer_create (scratch);
+ buf = Fget_buffer_create (scratch, Qnil);
Fset_buffer_major_mode (buf);
}
return buf;
@@ -1636,7 +1642,7 @@ other_buffer_safely (Lisp_Object buffer)
buf = Fget_buffer (scratch);
if (NILP (buf))
{
- buf = Fget_buffer_create (scratch);
+ buf = Fget_buffer_create (scratch, Qnil);
Fset_buffer_major_mode (buf);
}
@@ -1713,7 +1719,9 @@ DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ",
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
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
with SIGHUP. This function calls `replace-buffer-in-windows' for
@@ -1973,9 +1981,7 @@ DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ",
bset_width_table (b, Qnil);
unblock_input ();
- /* Run buffer-list-update-hook. */
- if (!NILP (Vrun_hooks) && !b->inhibit_buffer_hooks)
- call1 (Vrun_hooks, Qbuffer_list_update_hook);
+ run_buffer_list_update_hook (b);
return Qt;
}
@@ -2015,9 +2021,7 @@ record_buffer (Lisp_Object buffer)
fset_buffer_list (f, Fcons (buffer, Fdelq (buffer, f->buffer_list)));
fset_buried_buffer_list (f, Fdelq (buffer, f->buried_buffer_list));
- /* Run buffer-list-update-hook. */
- if (!NILP (Vrun_hooks) && !XBUFFER (buffer)->inhibit_buffer_hooks)
- call1 (Vrun_hooks, Qbuffer_list_update_hook);
+ run_buffer_list_update_hook (XBUFFER (buffer));
}
@@ -2054,9 +2058,7 @@ DEFUN ("bury-buffer-internal", Fbury_buffer_internal, Sbury_buffer_internal,
fset_buried_buffer_list
(f, Fcons (buffer, Fdelq (buffer, f->buried_buffer_list)));
- /* Run buffer-list-update-hook. */
- if (!NILP (Vrun_hooks) && !XBUFFER (buffer)->inhibit_buffer_hooks)
- call1 (Vrun_hooks, Qbuffer_list_update_hook);
+ run_buffer_list_update_hook (XBUFFER (buffer));
return Qnil;
}
@@ -5349,10 +5351,11 @@ init_buffer_once (void)
Fput (Qkill_buffer_hook, Qpermanent_local, Qt);
/* 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;
- 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;
}
@@ -5397,7 +5400,7 @@ init_buffer (void)
#endif /* USE_MMAP_FOR_BUFFERS */
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)))
Fset_buffer_multibyte (Qnil);
@@ -6300,9 +6303,14 @@ from (abs POSITION). If POSITION is positive, point was at the front
DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions,
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.
+See `kill-buffer'.
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;
DEFVAR_LISP ("change-major-mode-hook", Vchange_major_mode_hook,
@@ -6315,9 +6323,12 @@ from (abs POSITION). If POSITION is positive, point was at the front
doc: /* Hook run when the buffer list changes.
Functions (implicitly) running this hook are `get-buffer-create',
`make-indirect-buffer', `rename-buffer', `kill-buffer', `bury-buffer'
-and `select-window'. Functions run by this hook should avoid calling
-`select-window' with a nil NORECORD argument or `with-temp-buffer'
-since either may lead to infinite recursion. */);
+and `select-window'. 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.
+
+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;
DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook");
diff --git a/src/buffer.h b/src/buffer.h
index fe549c5dac..b8c5162be4 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -663,11 +663,11 @@ #define BVAR(buf, field) ((buf)->field ## _)
/* Non-zero whenever the narrowing is changed in this buffer. */
bool_bf clip_changed : 1;
- /* Non-zero for internally used temporary buffers that don't need to
- run hooks kill-buffer-hook, buffer-list-update-hook, and
- kill-buffer-query-functions. This is used in coding.c to avoid
- slowing down en/decoding when there are a lot of these hooks
- defined. */
+ /* Non-zero for internal or temporary buffers that don't need to
+ run hooks kill-buffer-hook, kill-buffer-query-functions, and
+ buffer-list-update-hook. This is used in coding.c to avoid
+ slowing down en/decoding when a lot of these hooks are
+ defined, as well as by with-temp-buffer, for example. */
bool_bf inhibit_buffer_hooks : 1;
/* List of overlays that end at or before the current center,
diff --git a/src/callproc.c b/src/callproc.c
index e3346e2eab..4bca1e5ebd 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -405,9 +405,8 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
if (! (NILP (buffer) || EQ (buffer, Qt) || FIXNUMP (buffer)))
{
- Lisp_Object spec_buffer;
- spec_buffer = buffer;
- buffer = Fget_buffer_create (buffer);
+ Lisp_Object spec_buffer = buffer;
+ buffer = Fget_buffer_create (buffer, Qnil);
/* Mention the buffer name for a better error message. */
if (NILP (buffer))
CHECK_BUFFER (spec_buffer);
diff --git a/src/coding.c b/src/coding.c
index 2142e7fa51..1afa4aa474 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -7821,7 +7821,7 @@ encode_coding (struct coding_system *coding)
/* A string that serves as name of the reusable work buffer, and as base
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. */
static Lisp_Object Vcode_conversion_reused_workbuf;
@@ -7839,7 +7839,7 @@ code_conversion_restore (Lisp_Object arg)
if (! NILP (workbuf))
{
if (EQ (workbuf, Vcode_conversion_reused_workbuf))
- reused_workbuf_in_use = 0;
+ reused_workbuf_in_use = false;
else
Fkill_buffer (workbuf);
}
@@ -7857,13 +7857,13 @@ code_conversion_save (bool with_work_buf, bool multibyte)
{
Lisp_Object name
= Fgenerate_new_buffer_name (Vcode_conversion_workbuf_name, Qnil);
- workbuf = Fget_buffer_create (name);
+ workbuf = Fget_buffer_create (name, Qt);
}
else
{
if (NILP (Fbuffer_live_p (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;
}
}
@@ -7881,7 +7881,7 @@ code_conversion_save (bool with_work_buf, bool multibyte)
bset_undo_list (current_buffer, Qt);
bset_enable_multibyte_characters (current_buffer, multibyte ? Qt : Qnil);
if (EQ (workbuf, Vcode_conversion_reused_workbuf))
- reused_workbuf_in_use = 1;
+ reused_workbuf_in_use = true;
set_buffer_internal (current);
}
@@ -11639,7 +11639,7 @@ syms_of_coding (void)
staticpro (&Vcode_conversion_workbuf_name);
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);
DEFSYM (Qcharset, "charset");
diff --git a/src/coding.h b/src/coding.h
index 4973cf89eb..9ad1e954f8 100644
--- a/src/coding.h
+++ b/src/coding.h
@@ -97,9 +97,6 @@ #define EMACS_CODING_H
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. */
enum coding_attr_index
diff --git a/src/fileio.c b/src/fileio.c
index c97f4daf20..51f12e104e 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -4004,7 +4004,7 @@ because (1) it preserves some marker positions (in unchanged portions
record_unwind_current_buffer ();
- workbuf = Fget_buffer_create (name);
+ workbuf = Fget_buffer_create (name, Qt);
buf = XBUFFER (workbuf);
delete_all_overlays (buf);
diff --git a/src/minibuf.c b/src/minibuf.c
index fc3fd92a88..1940564a80 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -809,7 +809,7 @@ get_minibuffer (EMACS_INT depth)
static char const name_fmt[] = " *Minibuf-%"pI"d*";
char name[sizeof name_fmt + INT_STRLEN_BOUND (EMACS_INT)];
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
enabled in it. */
diff --git a/src/print.c b/src/print.c
index 008bf5e639..ec271d914c 100644
--- a/src/print.c
+++ b/src/print.c
@@ -562,7 +562,7 @@ temp_output_buffer_setup (const char *bufname)
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 ();
delete_all_overlays (current_buffer);
diff --git a/src/process.c b/src/process.c
index 4fe8ac7fc0..9efefb1de7 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1731,7 +1731,7 @@ DEFUN ("make-process", Fmake_process, Smake_process, 0, MANY, 0,
buffer = Fplist_get (contact, QCbuffer);
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
buffer's current directory, or its unhandled equivalent. We
@@ -1768,7 +1768,7 @@ DEFUN ("make-process", Fmake_process, Smake_process, 0, MANY, 0,
QCname,
concat2 (name, build_string (" stderr")),
QCbuffer,
- Fget_buffer_create (xstderr),
+ Fget_buffer_create (xstderr, Qnil),
QCnoquery,
query_on_exit ? Qnil : Qt);
}
@@ -2443,7 +2443,7 @@ DEFUN ("make-pipe-process", Fmake_pipe_process, Smake_pipe_process,
buffer = Fplist_get (contact, QCbuffer);
if (NILP (buffer))
buffer = name;
- buffer = Fget_buffer_create (buffer);
+ buffer = Fget_buffer_create (buffer, Qnil);
pset_buffer (p, buffer);
pset_childp (p, contact);
@@ -3173,7 +3173,7 @@ DEFUN ("make-serial-process", Fmake_serial_process, Smake_serial_process,
buffer = Fplist_get (contact, QCbuffer);
if (NILP (buffer))
buffer = name;
- buffer = Fget_buffer_create (buffer);
+ buffer = Fget_buffer_create (buffer, Qnil);
pset_buffer (p, buffer);
pset_childp (p, contact);
@@ -4188,7 +4188,7 @@ DEFUN ("make-network-process", Fmake_network_process, Smake_network_process,
open_socket:
if (!NILP (buffer))
- buffer = Fget_buffer_create (buffer);
+ buffer = Fget_buffer_create (buffer, Qnil);
/* Unwind bind_polling_period. */
unbind_to (count, Qnil);
@@ -4961,7 +4961,7 @@ server_accept_connection (Lisp_Object server, int channel)
if (!NILP (buffer))
{
args[1] = buffer;
- buffer = Fget_buffer_create (Fformat (nargs, args));
+ buffer = Fget_buffer_create (Fformat (nargs, args), Qnil);
}
}
diff --git a/src/w32fns.c b/src/w32fns.c
index a840f0e122..36bee0676b 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -7372,7 +7372,7 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
tip_f = XFRAME (tip_frame);
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
windows cannot have display margins. */
bset_left_margin_cols (XBUFFER (tip_buf), make_fixnum (0));
diff --git a/src/window.c b/src/window.c
index bcc989b5a7..5db166e345 100644
--- a/src/window.c
+++ b/src/window.c
@@ -617,11 +617,12 @@ DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
Run `buffer-list-update-hook' unless NORECORD is non-nil. Note that
applications and internal routines often select a window temporarily for
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
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
-time a window gets selected put it on `buffer-list-update-hook'.
+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' or
+`window-selection-change-functions'.
Also note that the main editor command loop sets the current buffer to
the buffer of the selected window before each command. */)
diff --git a/src/xdisp.c b/src/xdisp.c
index 0fd5ec5ec5..b5adee5105 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -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.
If we created it, set the major-mode. */
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
&& !NILP (Ffboundp (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*";
char name[sizeof name_fmt + INT_STRLEN_BOUND (int)];
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);
/* to force word wrap in echo area -
it was decided to postpone this*/
diff --git a/src/xfns.c b/src/xfns.c
index 46e4bd73a6..abe293e903 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -7041,7 +7041,7 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
tip_f = XFRAME (tip_frame);
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
windows cannot have display margins. */
bset_left_margin_cols (XBUFFER (tip_buf), make_fixnum (0));
diff --git a/src/xwidget.c b/src/xwidget.c
index e078a28a35..accde65b52 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -100,7 +100,8 @@ DEFUN ("make-xwidget",
Lisp_Object val;
xw->type = type;
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->width = XFIXNAT (width);
xw->kill_without_query = false;
diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el
index 0db66f9751..dd8927457a 100644
--- a/test/src/buffer-tests.el
+++ b/test/src/buffer-tests.el
@@ -19,9 +19,7 @@
;;; Code:
-(require 'ert)
-(require 'seq)
-(eval-when-compile (require 'cl-lib))
+(require 'cl-lib)
(ert-deftest overlay-modification-hooks-message-other-buf ()
"Test for bug#21824.
@@ -1334,4 +1332,33 @@ buffer-tests-buffer-local-variables-undo
(with-temp-buffer
(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
--
2.29.2
next prev parent reply other threads:[~2020-12-18 18:49 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-05 22:57 bug#34765: 26.1; with-temp-buffer should not run buffer-list-update-hook Alexander Miller
2019-03-06 9:39 ` martin rudalics
2019-03-06 11:29 ` Alexander Miller
2019-03-06 14:13 ` martin rudalics
2019-03-06 15:41 ` Eli Zaretskii
2019-03-06 17:57 ` martin rudalics
2019-04-23 9:21 ` martin rudalics
2019-04-23 10:36 ` Eli Zaretskii
2019-04-24 7:27 ` martin rudalics
2019-04-24 11:12 ` Eli Zaretskii
2019-04-24 12:55 ` Stefan Monnier
2019-04-25 8:06 ` martin rudalics
2019-04-25 8:50 ` Eli Zaretskii
2019-04-25 10:31 ` martin rudalics
2019-04-25 10:49 ` Eli Zaretskii
2019-04-26 7:40 ` martin rudalics
2019-04-26 8:09 ` Eli Zaretskii
2019-04-25 13:01 ` Stefan Monnier
2019-04-25 14:34 ` Eli Zaretskii
2019-04-26 7:41 ` martin rudalics
2019-04-26 8:10 ` Eli Zaretskii
2019-04-26 7:41 ` martin rudalics
2019-04-26 8:10 ` Eli Zaretskii
2019-04-26 11:00 ` martin rudalics
2019-04-26 11:26 ` Eli Zaretskii
2019-04-27 8:30 ` martin rudalics
2019-04-26 17:14 ` Basil L. Contovounesios
2019-04-27 8:31 ` martin rudalics
2019-05-20 13:42 ` Basil L. Contovounesios
2019-05-21 7:32 ` martin rudalics
2019-05-21 7:58 ` Basil L. Contovounesios
2019-05-21 10:04 ` martin rudalics
2019-05-22 7:29 ` Eli Zaretskii
2019-05-22 8:32 ` martin rudalics
2019-05-22 10:06 ` Eli Zaretskii
2019-05-23 8:38 ` martin rudalics
2019-05-23 14:37 ` Eli Zaretskii
2019-05-24 8:01 ` martin rudalics
2019-05-22 14:12 ` Stefan Monnier
2019-05-22 15:50 ` Eli Zaretskii
2019-05-22 7:21 ` Eli Zaretskii
2020-08-26 11:06 ` Lars Ingebrigtsen
2020-09-05 7:05 ` Eli Zaretskii
2020-10-07 3:27 ` Lars Ingebrigtsen
2020-10-07 7:58 ` martin rudalics
2020-11-29 21:03 ` Basil L. Contovounesios
2020-11-30 9:05 ` martin rudalics
2020-11-30 18:07 ` Basil L. Contovounesios
2020-11-30 19:01 ` martin rudalics
2020-11-30 20:33 ` Basil L. Contovounesios
2020-12-01 9:34 ` martin rudalics
2020-11-30 19:42 ` Eli Zaretskii
2020-11-30 20:34 ` Basil L. Contovounesios
2020-12-07 22:16 ` Basil L. Contovounesios
2020-12-07 22:37 ` Basil L. Contovounesios
2020-12-08 8:09 ` martin rudalics
2020-12-14 21:03 ` Basil L. Contovounesios
2020-12-15 16:03 ` Eli Zaretskii
2020-12-15 16:24 ` Basil L. Contovounesios
2020-12-18 14:57 ` Basil L. Contovounesios
2020-12-18 15:36 ` Stefan Monnier
2020-12-18 18:49 ` Basil L. Contovounesios [this message]
2020-12-19 10:33 ` Eli Zaretskii
2020-12-19 14:15 ` Basil L. Contovounesios
2020-12-19 16:06 ` Eli Zaretskii
2020-12-19 21:10 ` Basil L. Contovounesios
2020-12-20 15:05 ` Eli Zaretskii
2019-03-07 6:18 ` Alexander Miller
2019-03-07 8:29 ` martin rudalics
2019-03-07 9:44 ` Alexander Miller
2019-03-07 13:46 ` martin rudalics
2020-12-20 17:57 ` Basil L. Contovounesios
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87eejnaqzz.fsf@tcd.ie \
--to=contovob@tcd.ie \
--cc=34765@debbugs.gnu.org \
--cc=alexanderm@web.de \
--cc=larsi@gnus.org \
--cc=monnier@iro.umontreal.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).