From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: "Basil L. Contovounesios" Newsgroups: gmane.emacs.bugs Subject: bug#34765: 26.1; with-temp-buffer should not run buffer-list-update-hook Date: Sat, 19 Dec 2020 21:10:13 +0000 Message-ID: <87zh2933ka.fsf@tcd.ie> References: <767e1b59-6ac2-cd11-076e-82a56ac53e29@gmx.at> <11be4631-b087-52a3-92fe-4cbd5248908d@gmx.at> <838svxxk41.fsf@gnu.org> <49c11920-0909-dcc2-4a39-4cdcfaf20453@gmx.at> <87h7sp1xay.fsf@gnus.org> <83r1rgpusx.fsf@gnu.org> <87pn5u7m0y.fsf@gnus.org> <5bdc73dd-af73-1b9a-9bb4-e154787e1976@gmx.at> <87a6uzan9s.fsf@tcd.ie> <71b78484-b0a7-3e0e-a999-afa07f8b4832@gmx.at> <87lfeioh0v.fsf@tcd.ie> <83tut6iqbp.fsf@gnu.org> <87360qoa6o.fsf@tcd.ie> <878sa9cle0.fsf@tcd.ie> <87eejnaqzz.fsf@tcd.ie> <831rfmultr.fsf@gnu.org> <878s9t6fwd.fsf@tcd.ie> <83mty9u6fn.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="7008"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) Cc: 34765@debbugs.gnu.org, larsi@gnus.org, monnier@iro.umontreal.ca, alexanderm@web.de To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Dec 19 22:11:37 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kqjVp-0001bi-2q for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 19 Dec 2020 22:11:37 +0100 Original-Received: from localhost ([::1]:57680 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kqjVl-0007Hg-VU for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 19 Dec 2020 16:11:35 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:32830) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kqjVG-0007GL-99 for bug-gnu-emacs@gnu.org; Sat, 19 Dec 2020 16:11:02 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:59981) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kqjVG-0003rb-1o for bug-gnu-emacs@gnu.org; Sat, 19 Dec 2020 16:11:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kqjVF-0007P8-Th for bug-gnu-emacs@gnu.org; Sat, 19 Dec 2020 16:11:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: "Basil L. Contovounesios" Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 19 Dec 2020 21:11:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 34765 X-GNU-PR-Package: emacs Original-Received: via spool by 34765-submit@debbugs.gnu.org id=B34765.160841222728420 (code B ref 34765); Sat, 19 Dec 2020 21:11:01 +0000 Original-Received: (at 34765) by debbugs.gnu.org; 19 Dec 2020 21:10:27 +0000 Original-Received: from localhost ([127.0.0.1]:43294 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kqjUf-0007OI-W9 for submit@debbugs.gnu.org; Sat, 19 Dec 2020 16:10:27 -0500 Original-Received: from mail-wm1-f48.google.com ([209.85.128.48]:33031) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kqjUc-0007O1-5V for 34765@debbugs.gnu.org; Sat, 19 Dec 2020 16:10:24 -0500 Original-Received: by mail-wm1-f48.google.com with SMTP id n16so8037138wmc.0 for <34765@debbugs.gnu.org>; Sat, 19 Dec 2020 13:10:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tcd-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=4XaYkn4/noaszsvErEt8U+1KdrkvqMu0ohoCcX72iq8=; b=wrQY5ozoV5fzodgPkBFku+3Pd2y3563/3pngr0ZAY4m1BW83+rxcmiT/1aApm9CfKt TZCnrP2zHzFUBqLqFUjlAtAlQ+iFS3e/QVRkLTSu9TVX11ybAnTdgLUsIaib0D0KdVVk KFrewe44m9CWMgd8NrKaGD2GYbRTGoNUhgJywZM2yJl3s9rXErJjgQrvS3o7MT2zB9gS R9oSyAagnyRYHvCjaO0vqdlE6PRdjjyGws4uo915b2he0RvaFHGR9MHy+URpufeorroP TmzjG9L43EYDEYqiaqnV9h5OvLHZKvKGgFHD7n7hCtqJGKI6KLoAlb63BRG+Zis661zn xtXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=4XaYkn4/noaszsvErEt8U+1KdrkvqMu0ohoCcX72iq8=; b=OmLNonrafeVSvfyweTUbwexVUsvszf0HbX5lKQP0F35py6qbvgIy/QHRnJsgMOc+J8 fH/Sgcdm5aoESHoFsRkFf1yqXQQPBWQFULJEIta+pI0QYk8eXefQ0arIGy8RBm2nZdKC gQNsF9/TXqpKOSlbGcWBc8SV+1jiMMIzhS2a4Twx+o90NW958syk+EsfXmjDHh1kk2tz El4vep6OTrsOdq4QZMFBkSTWAU7r8cLhwK2nIB4WWm2yWHd9kdt2D0GJ7yMfc2dUOgtw hW5K69JBdmok5NHk8c9TNC5m72U7oRCNL26DnuBBePmr+P1a/P33n53UmW3qBe0kpUJq 7jqQ== X-Gm-Message-State: AOAM5305UehqGADfufSGNC9eXJDIzCfuuklPdFhs3GvWBwIl33AcePIt dHYFlHkfHs839FuDq/4TCVxwNg== X-Google-Smtp-Source: ABdhPJzc3LBChlRapIKqBkpibG9W1G31p4eygPbZ+jzMcDolvF3yt9IvqcjP1J1c7wQmQvgsQP+f7A== X-Received: by 2002:a1c:f405:: with SMTP id z5mr9344949wma.93.1608412216228; Sat, 19 Dec 2020 13:10:16 -0800 (PST) Original-Received: from localhost ([2a02:8084:20e2:c380:877b:77af:3b46:790d]) by smtp.gmail.com with ESMTPSA id y6sm16448213wmg.39.2020.12.19.13.10.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 19 Dec 2020 13:10:14 -0800 (PST) In-Reply-To: <83mty9u6fn.fsf@gnu.org> (Eli Zaretskii's message of "Sat, 19 Dec 2020 18:06:04 +0200") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:196430 Archived-At: --=-=-= Content-Type: text/plain Eli Zaretskii writes: >> Something like this? >> >> @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 > > Yes. Done. >> >> +Like @code{with-temp-buffer} (@pxref{Definition of with-temp-buffer,, >> > ^^^^^^^^^^ >> > I think this word will look better if not capitalized. >> >> The printed label "see Current Buffer" should be displayed instead of >> this word, which is part of the anchor. Is that okay? > > Sorry, I didn't see that this is an anchor. So I think the anchor > should not start with a capital letter, as it reads more naturally > that way, I think. And then the name should be used without > capitalization in the cross-references. Obviously, this is a minor > nit. I'm hesitant to change the anchor because all 37 such "Definition of..." anchors in the tree are capitalised, as are the printed labels of all their refs. I'm happy to downcase them, but maybe this should be done wholesale in a separate commit? >> >> +static void >> >> +run_buffer_list_update_hook (struct buffer *buf) >> >> +{ >> >> + if (! (NILP (Vrun_hooks) || (buf && buf->inhibit_buffer_hooks))) >> > ^^^ >> > Why this test? is it possible for this function to be called with buf >> > a NULL pointer? >> >> Yes, in Fmake_indirect_buffer, which doesn't check inhibit_buffer_hooks. >> >> The alternatives would be for Fmake_indirect_buffer to not call >> run_buffer_list_update_hook, or to not bother adding >> run_buffer_list_update_hook at all. Do you have a preference? > > I think just having a comment there saying that make-indirect-buffer > calls this with NULL argument should be okay. How's the attached? Thanks, -- Basil --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Inhibit-buffer-hooks-in-temporary-buffers.patch >From 5ad1cc0d3f67ba3077d34949412990fb6e4b50a6 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" Date: Sat, 19 Dec 2020 12:39:45 +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). * 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. --- doc/lispref/buffers.texi | 59 +++++++++++++++++------ 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 | 88 +++++++++++++++++++--------------- 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 +++++++++++-- 30 files changed, 221 insertions(+), 129 deletions(-) diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi index 2860343628..33eb23984d 100644 --- a/doc/lispref/buffers.texi +++ b/doc/lispref/buffers.texi @@ -225,13 +225,22 @@ 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. + +@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 return the contents of the temporary buffer by using @@ -345,9 +354,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 +941,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 +964,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 +1001,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 +1113,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 +1125,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 fa3dacbb7a..0adbef33ca 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 4a8e70e6a6..1b4c21cb45 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -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 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. @@ -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'. ++++ +** 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 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..9e44345616 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,33 @@ 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 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. 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 +614,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 +626,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 +901,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 +1545,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 +1619,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 +1643,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 +1720,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 +1982,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 +2022,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 +2059,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 +5352,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 +5401,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 +6304,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 +6324,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 --=-=-=--