diff options
| author | Gregory Heytings | 2022-07-31 20:32:15 +0000 |
|---|---|---|
| committer | Gregory Heytings | 2022-07-31 22:42:09 +0200 |
| commit | 5e296283f57b21e962e6e6860e448905f99f281e (patch) | |
| tree | 8f2bdd86d108b821f46d19f926929303313b528d /src/keyboard.c | |
| parent | eef591072ab1cbcf2168d7b30b3e1ca1f50717ad (diff) | |
| download | emacs-5e296283f57b21e962e6e6860e448905f99f281e.tar.gz emacs-5e296283f57b21e962e6e6860e448905f99f281e.zip | |
Add locked narrowing around pre- and post-command-hook
* src/keyboard.c (safe_run_hooks_maybe_narrowed): New function.
(command_loop_1): Use it for 'pre-command-hook' and 'post-command-hook'.
(syms_of_keyboard): Update docstrings of 'pre-command-hook' and
'post-command-hook'.
* src/lisp.h: Prototype of the new function.
Diffstat (limited to 'src/keyboard.c')
| -rw-r--r-- | src/keyboard.c | 57 |
1 files changed, 48 insertions, 9 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index 2863058d633..094119340e1 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -1295,7 +1295,8 @@ command_loop_1 (void) | |||
| 1295 | /* Note that the value cell will never directly contain nil | 1295 | /* Note that the value cell will never directly contain nil |
| 1296 | if the symbol is a local variable. */ | 1296 | if the symbol is a local variable. */ |
| 1297 | if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks)) | 1297 | if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks)) |
| 1298 | safe_run_hooks (Qpost_command_hook); | 1298 | safe_run_hooks_maybe_narrowed (Qpost_command_hook, |
| 1299 | XWINDOW (selected_window)); | ||
| 1299 | 1300 | ||
| 1300 | /* If displaying a message, resize the echo area window to fit | 1301 | /* If displaying a message, resize the echo area window to fit |
| 1301 | that message's size exactly. */ | 1302 | that message's size exactly. */ |
| @@ -1461,7 +1462,9 @@ command_loop_1 (void) | |||
| 1461 | } | 1462 | } |
| 1462 | Vthis_command = cmd; | 1463 | Vthis_command = cmd; |
| 1463 | Vreal_this_command = cmd; | 1464 | Vreal_this_command = cmd; |
| 1464 | safe_run_hooks (Qpre_command_hook); | 1465 | |
| 1466 | safe_run_hooks_maybe_narrowed (Qpre_command_hook, | ||
| 1467 | XWINDOW (selected_window)); | ||
| 1465 | 1468 | ||
| 1466 | already_adjusted = 0; | 1469 | already_adjusted = 0; |
| 1467 | 1470 | ||
| @@ -1513,7 +1516,8 @@ command_loop_1 (void) | |||
| 1513 | } | 1516 | } |
| 1514 | kset_last_prefix_arg (current_kboard, Vcurrent_prefix_arg); | 1517 | kset_last_prefix_arg (current_kboard, Vcurrent_prefix_arg); |
| 1515 | 1518 | ||
| 1516 | safe_run_hooks (Qpost_command_hook); | 1519 | safe_run_hooks_maybe_narrowed (Qpost_command_hook, |
| 1520 | XWINDOW (selected_window)); | ||
| 1517 | 1521 | ||
| 1518 | /* If displaying a message, resize the echo area window to fit | 1522 | /* If displaying a message, resize the echo area window to fit |
| 1519 | that message's size exactly. Do this only if the echo area | 1523 | that message's size exactly. Do this only if the echo area |
| @@ -1895,6 +1899,25 @@ safe_run_hooks (Lisp_Object hook) | |||
| 1895 | unbind_to (count, Qnil); | 1899 | unbind_to (count, Qnil); |
| 1896 | } | 1900 | } |
| 1897 | 1901 | ||
| 1902 | void | ||
| 1903 | safe_run_hooks_maybe_narrowed (Lisp_Object hook, struct window *w) | ||
| 1904 | { | ||
| 1905 | specpdl_ref count = SPECPDL_INDEX (); | ||
| 1906 | |||
| 1907 | specbind (Qinhibit_quit, Qt); | ||
| 1908 | |||
| 1909 | if (current_buffer->long_line_optimizations_p) | ||
| 1910 | { | ||
| 1911 | ptrdiff_t begv = get_narrowed_begv (w, PT); | ||
| 1912 | ptrdiff_t zv = get_narrowed_zv (w, PT); | ||
| 1913 | if (!begv) begv = BEGV; | ||
| 1914 | Fnarrow_to_region (make_fixnum (begv), make_fixnum (zv), Qt); | ||
| 1915 | } | ||
| 1916 | |||
| 1917 | run_hook_with_args (2, ((Lisp_Object []) {hook, hook}), safe_run_hook_funcall); | ||
| 1918 | unbind_to (count, Qnil); | ||
| 1919 | } | ||
| 1920 | |||
| 1898 | 1921 | ||
| 1899 | /* Nonzero means polling for input is temporarily suppressed. */ | 1922 | /* Nonzero means polling for input is temporarily suppressed. */ |
| 1900 | 1923 | ||
| @@ -12622,23 +12645,39 @@ Buffer modification stores t in this variable. */); | |||
| 12622 | 12645 | ||
| 12623 | DEFVAR_LISP ("pre-command-hook", Vpre_command_hook, | 12646 | DEFVAR_LISP ("pre-command-hook", Vpre_command_hook, |
| 12624 | doc: /* Normal hook run before each command is executed. | 12647 | doc: /* Normal hook run before each command is executed. |
| 12625 | If an unhandled error happens in running this hook, | 12648 | |
| 12626 | the function in which the error occurred is unconditionally removed, since | 12649 | If an unhandled error happens in running this hook, the function in |
| 12627 | otherwise the error might happen repeatedly and make Emacs nonfunctional. | 12650 | which the error occurred is unconditionally removed, since otherwise |
| 12651 | the error might happen repeatedly and make Emacs nonfunctional. | ||
| 12652 | |||
| 12653 | Note that, when the current buffer contains one or more lines whose | ||
| 12654 | length is above `long-line-threshold', these hook functions are called | ||
| 12655 | with the buffer narrowed to a small portion around point, and the | ||
| 12656 | narrowing is locked (see `narrow-to-region'), so that these hook | ||
| 12657 | functions cannot use `widen' to gain access to other portions of | ||
| 12658 | buffer text. | ||
| 12628 | 12659 | ||
| 12629 | See also `post-command-hook'. */); | 12660 | See also `post-command-hook'. */); |
| 12630 | Vpre_command_hook = Qnil; | 12661 | Vpre_command_hook = Qnil; |
| 12631 | 12662 | ||
| 12632 | DEFVAR_LISP ("post-command-hook", Vpost_command_hook, | 12663 | DEFVAR_LISP ("post-command-hook", Vpost_command_hook, |
| 12633 | doc: /* Normal hook run after each command is executed. | 12664 | doc: /* Normal hook run after each command is executed. |
| 12634 | If an unhandled error happens in running this hook, | 12665 | |
| 12635 | the function in which the error occurred is unconditionally removed, since | 12666 | If an unhandled error happens in running this hook, the function in |
| 12636 | otherwise the error might happen repeatedly and make Emacs nonfunctional. | 12667 | which the error occurred is unconditionally removed, since otherwise |
| 12668 | the error might happen repeatedly and make Emacs nonfunctional. | ||
| 12637 | 12669 | ||
| 12638 | It is a bad idea to use this hook for expensive processing. If | 12670 | It is a bad idea to use this hook for expensive processing. If |
| 12639 | unavoidable, wrap your code in `(while-no-input (redisplay) CODE)' to | 12671 | unavoidable, wrap your code in `(while-no-input (redisplay) CODE)' to |
| 12640 | avoid making Emacs unresponsive while the user types. | 12672 | avoid making Emacs unresponsive while the user types. |
| 12641 | 12673 | ||
| 12674 | Note that, when the current buffer contains one or more lines whose | ||
| 12675 | length is above `long-line-threshold', these hook functions are called | ||
| 12676 | with the buffer narrowed to a small portion around point, and the | ||
| 12677 | narrowing is locked (see `narrow-to-region'), so that these hook | ||
| 12678 | functions cannot use `widen' to gain access to other portions of | ||
| 12679 | buffer text. | ||
| 12680 | |||
| 12642 | See also `pre-command-hook'. */); | 12681 | See also `pre-command-hook'. */); |
| 12643 | Vpost_command_hook = Qnil; | 12682 | Vpost_command_hook = Qnil; |
| 12644 | 12683 | ||