diff options
| author | Basil L. Contovounesios | 2020-12-19 12:39:45 +0000 |
|---|---|---|
| committer | Basil L. Contovounesios | 2020-12-20 17:32:24 +0000 |
| commit | 1a0a11f7d2d1dbecb9f754b1e129d50e489058e6 (patch) | |
| tree | ca78c82ccc83b90ae3e382097fdffc928097f881 /src/buffer.c | |
| parent | 409a9dbe9da64b4d75fec1f511e168c94e60e35b (diff) | |
| download | emacs-1a0a11f7d2d1dbecb9f754b1e129d50e489058e6.tar.gz emacs-1a0a11f7d2d1dbecb9f754b1e129d50e489058e6.zip | |
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.
Diffstat (limited to 'src/buffer.c')
| -rw-r--r-- | src/buffer.c | 88 |
1 files changed, 50 insertions, 38 deletions
diff --git a/src/buffer.c b/src/buffer.c index dfc34faf6e6..9e44345616e 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -37,7 +37,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 37 | #include "window.h" | 37 | #include "window.h" |
| 38 | #include "commands.h" | 38 | #include "commands.h" |
| 39 | #include "character.h" | 39 | #include "character.h" |
| 40 | #include "coding.h" | ||
| 41 | #include "buffer.h" | 40 | #include "buffer.h" |
| 42 | #include "region-cache.h" | 41 | #include "region-cache.h" |
| 43 | #include "indent.h" | 42 | #include "indent.h" |
| @@ -514,16 +513,33 @@ get_truename_buffer (register Lisp_Object filename) | |||
| 514 | return Qnil; | 513 | return Qnil; |
| 515 | } | 514 | } |
| 516 | 515 | ||
| 517 | DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 1, 0, | 516 | /* Run buffer-list-update-hook if Vrun_hooks is non-nil, and BUF is NULL |
| 517 | or does not have buffer hooks inhibited. BUF is NULL when called by | ||
| 518 | make-indirect-buffer, since it does not inhibit buffer hooks. */ | ||
| 519 | |||
| 520 | static void | ||
| 521 | run_buffer_list_update_hook (struct buffer *buf) | ||
| 522 | { | ||
| 523 | if (! (NILP (Vrun_hooks) || (buf && buf->inhibit_buffer_hooks))) | ||
| 524 | call1 (Vrun_hooks, Qbuffer_list_update_hook); | ||
| 525 | } | ||
| 526 | |||
| 527 | DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 2, 0, | ||
| 518 | doc: /* Return the buffer specified by BUFFER-OR-NAME, creating a new one if needed. | 528 | doc: /* Return the buffer specified by BUFFER-OR-NAME, creating a new one if needed. |
| 519 | If BUFFER-OR-NAME is a string and a live buffer with that name exists, | 529 | If BUFFER-OR-NAME is a string and a live buffer with that name exists, |
| 520 | return that buffer. If no such buffer exists, create a new buffer with | 530 | return that buffer. If no such buffer exists, create a new buffer with |
| 521 | that name and return it. If BUFFER-OR-NAME starts with a space, the new | 531 | that name and return it. |
| 522 | buffer does not keep undo information. | 532 | |
| 533 | If BUFFER-OR-NAME starts with a space, the new buffer does not keep undo | ||
| 534 | information. If optional argument INHIBIT-BUFFER-HOOKS is non-nil, the | ||
| 535 | new buffer does not run the hooks `kill-buffer-hook', | ||
| 536 | `kill-buffer-query-functions', and `buffer-list-update-hook'. This | ||
| 537 | avoids slowing down internal or temporary buffers that are never | ||
| 538 | presented to users or passed on to other applications. | ||
| 523 | 539 | ||
| 524 | If BUFFER-OR-NAME is a buffer instead of a string, return it as given, | 540 | If BUFFER-OR-NAME is a buffer instead of a string, return it as given, |
| 525 | even if it is dead. The return value is never nil. */) | 541 | even if it is dead. The return value is never nil. */) |
| 526 | (register Lisp_Object buffer_or_name) | 542 | (register Lisp_Object buffer_or_name, Lisp_Object inhibit_buffer_hooks) |
| 527 | { | 543 | { |
| 528 | register Lisp_Object buffer, name; | 544 | register Lisp_Object buffer, name; |
| 529 | register struct buffer *b; | 545 | register struct buffer *b; |
| @@ -598,11 +614,7 @@ even if it is dead. The return value is never nil. */) | |||
| 598 | set_string_intervals (name, NULL); | 614 | set_string_intervals (name, NULL); |
| 599 | bset_name (b, name); | 615 | bset_name (b, name); |
| 600 | 616 | ||
| 601 | b->inhibit_buffer_hooks | 617 | b->inhibit_buffer_hooks = !NILP (inhibit_buffer_hooks); |
| 602 | = (STRINGP (Vcode_conversion_workbuf_name) | ||
| 603 | && strncmp (SSDATA (name), SSDATA (Vcode_conversion_workbuf_name), | ||
| 604 | SBYTES (Vcode_conversion_workbuf_name)) == 0); | ||
| 605 | |||
| 606 | bset_undo_list (b, SREF (name, 0) != ' ' ? Qnil : Qt); | 618 | bset_undo_list (b, SREF (name, 0) != ' ' ? Qnil : Qt); |
| 607 | 619 | ||
| 608 | reset_buffer (b); | 620 | reset_buffer (b); |
| @@ -614,9 +626,8 @@ even if it is dead. The return value is never nil. */) | |||
| 614 | /* Put this in the alist of all live buffers. */ | 626 | /* Put this in the alist of all live buffers. */ |
| 615 | XSETBUFFER (buffer, b); | 627 | XSETBUFFER (buffer, b); |
| 616 | Vbuffer_alist = nconc2 (Vbuffer_alist, list1 (Fcons (name, buffer))); | 628 | Vbuffer_alist = nconc2 (Vbuffer_alist, list1 (Fcons (name, buffer))); |
| 617 | /* And run buffer-list-update-hook. */ | 629 | |
| 618 | if (!NILP (Vrun_hooks) && !b->inhibit_buffer_hooks) | 630 | run_buffer_list_update_hook (b); |
| 619 | call1 (Vrun_hooks, Qbuffer_list_update_hook); | ||
| 620 | 631 | ||
| 621 | return buffer; | 632 | return buffer; |
| 622 | } | 633 | } |
| @@ -890,9 +901,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */) | |||
| 890 | set_buffer_internal_1 (old_b); | 901 | set_buffer_internal_1 (old_b); |
| 891 | } | 902 | } |
| 892 | 903 | ||
| 893 | /* Run buffer-list-update-hook. */ | 904 | run_buffer_list_update_hook (NULL); |
| 894 | if (!NILP (Vrun_hooks)) | ||
| 895 | call1 (Vrun_hooks, Qbuffer_list_update_hook); | ||
| 896 | 905 | ||
| 897 | return buf; | 906 | return buf; |
| 898 | } | 907 | } |
| @@ -1536,9 +1545,7 @@ This does not change the name of the visited file (if any). */) | |||
| 1536 | && !NILP (BVAR (current_buffer, auto_save_file_name))) | 1545 | && !NILP (BVAR (current_buffer, auto_save_file_name))) |
| 1537 | call0 (intern ("rename-auto-save-file")); | 1546 | call0 (intern ("rename-auto-save-file")); |
| 1538 | 1547 | ||
| 1539 | /* Run buffer-list-update-hook. */ | 1548 | run_buffer_list_update_hook (current_buffer); |
| 1540 | if (!NILP (Vrun_hooks) && !current_buffer->inhibit_buffer_hooks) | ||
| 1541 | call1 (Vrun_hooks, Qbuffer_list_update_hook); | ||
| 1542 | 1549 | ||
| 1543 | /* Refetch since that last call may have done GC. */ | 1550 | /* Refetch since that last call may have done GC. */ |
| 1544 | return BVAR (current_buffer, name); | 1551 | return BVAR (current_buffer, name); |
| @@ -1612,7 +1619,7 @@ exists, return the buffer `*scratch*' (creating it if necessary). */) | |||
| 1612 | buf = Fget_buffer (scratch); | 1619 | buf = Fget_buffer (scratch); |
| 1613 | if (NILP (buf)) | 1620 | if (NILP (buf)) |
| 1614 | { | 1621 | { |
| 1615 | buf = Fget_buffer_create (scratch); | 1622 | buf = Fget_buffer_create (scratch, Qnil); |
| 1616 | Fset_buffer_major_mode (buf); | 1623 | Fset_buffer_major_mode (buf); |
| 1617 | } | 1624 | } |
| 1618 | return buf; | 1625 | return buf; |
| @@ -1636,7 +1643,7 @@ other_buffer_safely (Lisp_Object buffer) | |||
| 1636 | buf = Fget_buffer (scratch); | 1643 | buf = Fget_buffer (scratch); |
| 1637 | if (NILP (buf)) | 1644 | if (NILP (buf)) |
| 1638 | { | 1645 | { |
| 1639 | buf = Fget_buffer_create (scratch); | 1646 | buf = Fget_buffer_create (scratch, Qnil); |
| 1640 | Fset_buffer_major_mode (buf); | 1647 | Fset_buffer_major_mode (buf); |
| 1641 | } | 1648 | } |
| 1642 | 1649 | ||
| @@ -1713,7 +1720,9 @@ buffer to be killed as the current buffer. If any of them returns nil, | |||
| 1713 | the buffer is not killed. The hook `kill-buffer-hook' is run before the | 1720 | the buffer is not killed. The hook `kill-buffer-hook' is run before the |
| 1714 | buffer is actually killed. The buffer being killed will be current | 1721 | buffer is actually killed. The buffer being killed will be current |
| 1715 | while the hook is running. Functions called by any of these hooks are | 1722 | while the hook is running. Functions called by any of these hooks are |
| 1716 | supposed to not change the current buffer. | 1723 | supposed to not change the current buffer. Neither hook is run for |
| 1724 | internal or temporary buffers created by `get-buffer-create' or | ||
| 1725 | `generate-new-buffer' with argument INHIBIT-BUFFER-HOOKS non-nil. | ||
| 1717 | 1726 | ||
| 1718 | Any processes that have this buffer as the `process-buffer' are killed | 1727 | Any processes that have this buffer as the `process-buffer' are killed |
| 1719 | with SIGHUP. This function calls `replace-buffer-in-windows' for | 1728 | with SIGHUP. This function calls `replace-buffer-in-windows' for |
| @@ -1973,9 +1982,7 @@ cleaning up all windows currently displaying the buffer to be killed. */) | |||
| 1973 | bset_width_table (b, Qnil); | 1982 | bset_width_table (b, Qnil); |
| 1974 | unblock_input (); | 1983 | unblock_input (); |
| 1975 | 1984 | ||
| 1976 | /* Run buffer-list-update-hook. */ | 1985 | run_buffer_list_update_hook (b); |
| 1977 | if (!NILP (Vrun_hooks) && !b->inhibit_buffer_hooks) | ||
| 1978 | call1 (Vrun_hooks, Qbuffer_list_update_hook); | ||
| 1979 | 1986 | ||
| 1980 | return Qt; | 1987 | return Qt; |
| 1981 | } | 1988 | } |
| @@ -2015,9 +2022,7 @@ record_buffer (Lisp_Object buffer) | |||
| 2015 | fset_buffer_list (f, Fcons (buffer, Fdelq (buffer, f->buffer_list))); | 2022 | fset_buffer_list (f, Fcons (buffer, Fdelq (buffer, f->buffer_list))); |
| 2016 | fset_buried_buffer_list (f, Fdelq (buffer, f->buried_buffer_list)); | 2023 | fset_buried_buffer_list (f, Fdelq (buffer, f->buried_buffer_list)); |
| 2017 | 2024 | ||
| 2018 | /* Run buffer-list-update-hook. */ | 2025 | run_buffer_list_update_hook (XBUFFER (buffer)); |
| 2019 | if (!NILP (Vrun_hooks) && !XBUFFER (buffer)->inhibit_buffer_hooks) | ||
| 2020 | call1 (Vrun_hooks, Qbuffer_list_update_hook); | ||
| 2021 | } | 2026 | } |
| 2022 | 2027 | ||
| 2023 | 2028 | ||
| @@ -2054,9 +2059,7 @@ DEFUN ("bury-buffer-internal", Fbury_buffer_internal, Sbury_buffer_internal, | |||
| 2054 | fset_buried_buffer_list | 2059 | fset_buried_buffer_list |
| 2055 | (f, Fcons (buffer, Fdelq (buffer, f->buried_buffer_list))); | 2060 | (f, Fcons (buffer, Fdelq (buffer, f->buried_buffer_list))); |
| 2056 | 2061 | ||
| 2057 | /* Run buffer-list-update-hook. */ | 2062 | run_buffer_list_update_hook (XBUFFER (buffer)); |
| 2058 | if (!NILP (Vrun_hooks) && !XBUFFER (buffer)->inhibit_buffer_hooks) | ||
| 2059 | call1 (Vrun_hooks, Qbuffer_list_update_hook); | ||
| 2060 | 2063 | ||
| 2061 | return Qnil; | 2064 | return Qnil; |
| 2062 | } | 2065 | } |
| @@ -5349,10 +5352,11 @@ init_buffer_once (void) | |||
| 5349 | Fput (Qkill_buffer_hook, Qpermanent_local, Qt); | 5352 | Fput (Qkill_buffer_hook, Qpermanent_local, Qt); |
| 5350 | 5353 | ||
| 5351 | /* Super-magic invisible buffer. */ | 5354 | /* Super-magic invisible buffer. */ |
| 5352 | Vprin1_to_string_buffer = Fget_buffer_create (build_pure_c_string (" prin1")); | 5355 | Vprin1_to_string_buffer = |
| 5356 | Fget_buffer_create (build_pure_c_string (" prin1"), Qt); | ||
| 5353 | Vbuffer_alist = Qnil; | 5357 | Vbuffer_alist = Qnil; |
| 5354 | 5358 | ||
| 5355 | Fset_buffer (Fget_buffer_create (build_pure_c_string ("*scratch*"))); | 5359 | Fset_buffer (Fget_buffer_create (build_pure_c_string ("*scratch*"), Qnil)); |
| 5356 | 5360 | ||
| 5357 | inhibit_modification_hooks = 0; | 5361 | inhibit_modification_hooks = 0; |
| 5358 | } | 5362 | } |
| @@ -5397,7 +5401,7 @@ init_buffer (void) | |||
| 5397 | #endif /* USE_MMAP_FOR_BUFFERS */ | 5401 | #endif /* USE_MMAP_FOR_BUFFERS */ |
| 5398 | 5402 | ||
| 5399 | AUTO_STRING (scratch, "*scratch*"); | 5403 | AUTO_STRING (scratch, "*scratch*"); |
| 5400 | Fset_buffer (Fget_buffer_create (scratch)); | 5404 | Fset_buffer (Fget_buffer_create (scratch, Qnil)); |
| 5401 | if (NILP (BVAR (&buffer_defaults, enable_multibyte_characters))) | 5405 | if (NILP (BVAR (&buffer_defaults, enable_multibyte_characters))) |
| 5402 | Fset_buffer_multibyte (Qnil); | 5406 | Fset_buffer_multibyte (Qnil); |
| 5403 | 5407 | ||
| @@ -6300,9 +6304,14 @@ Use Custom to set this variable and update the display. */); | |||
| 6300 | DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions, | 6304 | DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions, |
| 6301 | doc: /* List of functions called with no args to query before killing a buffer. | 6305 | doc: /* List of functions called with no args to query before killing a buffer. |
| 6302 | The buffer being killed will be current while the functions are running. | 6306 | The buffer being killed will be current while the functions are running. |
| 6307 | See `kill-buffer'. | ||
| 6303 | 6308 | ||
| 6304 | If any of them returns nil, the buffer is not killed. Functions run by | 6309 | If any of them returns nil, the buffer is not killed. Functions run by |
| 6305 | this hook are supposed to not change the current buffer. */); | 6310 | this hook are supposed to not change the current buffer. |
| 6311 | |||
| 6312 | This hook is not run for internal or temporary buffers created by | ||
| 6313 | `get-buffer-create' or `generate-new-buffer' with argument | ||
| 6314 | INHIBIT-BUFFER-HOOKS non-nil. */); | ||
| 6306 | Vkill_buffer_query_functions = Qnil; | 6315 | Vkill_buffer_query_functions = Qnil; |
| 6307 | 6316 | ||
| 6308 | DEFVAR_LISP ("change-major-mode-hook", Vchange_major_mode_hook, | 6317 | DEFVAR_LISP ("change-major-mode-hook", Vchange_major_mode_hook, |
| @@ -6315,9 +6324,12 @@ The function `kill-all-local-variables' runs this before doing anything else. * | |||
| 6315 | doc: /* Hook run when the buffer list changes. | 6324 | doc: /* Hook run when the buffer list changes. |
| 6316 | Functions (implicitly) running this hook are `get-buffer-create', | 6325 | Functions (implicitly) running this hook are `get-buffer-create', |
| 6317 | `make-indirect-buffer', `rename-buffer', `kill-buffer', `bury-buffer' | 6326 | `make-indirect-buffer', `rename-buffer', `kill-buffer', `bury-buffer' |
| 6318 | and `select-window'. Functions run by this hook should avoid calling | 6327 | and `select-window'. This hook is not run for internal or temporary |
| 6319 | `select-window' with a nil NORECORD argument or `with-temp-buffer' | 6328 | buffers created by `get-buffer-create' or `generate-new-buffer' with |
| 6320 | since either may lead to infinite recursion. */); | 6329 | argument INHIBIT-BUFFER-HOOKS non-nil. |
| 6330 | |||
| 6331 | Functions run by this hook should avoid calling `select-window' with a | ||
| 6332 | nil NORECORD argument since it may lead to infinite recursion. */); | ||
| 6321 | Vbuffer_list_update_hook = Qnil; | 6333 | Vbuffer_list_update_hook = Qnil; |
| 6322 | DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook"); | 6334 | DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook"); |
| 6323 | 6335 | ||