aboutsummaryrefslogtreecommitdiffstats
path: root/src/keyboard.c
diff options
context:
space:
mode:
authorGregory Heytings2022-07-31 20:32:15 +0000
committerGregory Heytings2022-07-31 22:42:09 +0200
commit5e296283f57b21e962e6e6860e448905f99f281e (patch)
tree8f2bdd86d108b821f46d19f926929303313b528d /src/keyboard.c
parenteef591072ab1cbcf2168d7b30b3e1ca1f50717ad (diff)
downloademacs-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.c57
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
1902void
1903safe_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.
12625If an unhandled error happens in running this hook, 12648
12626the function in which the error occurred is unconditionally removed, since 12649If an unhandled error happens in running this hook, the function in
12627otherwise the error might happen repeatedly and make Emacs nonfunctional. 12650which the error occurred is unconditionally removed, since otherwise
12651the error might happen repeatedly and make Emacs nonfunctional.
12652
12653Note that, when the current buffer contains one or more lines whose
12654length is above `long-line-threshold', these hook functions are called
12655with the buffer narrowed to a small portion around point, and the
12656narrowing is locked (see `narrow-to-region'), so that these hook
12657functions cannot use `widen' to gain access to other portions of
12658buffer text.
12628 12659
12629See also `post-command-hook'. */); 12660See 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.
12634If an unhandled error happens in running this hook, 12665
12635the function in which the error occurred is unconditionally removed, since 12666If an unhandled error happens in running this hook, the function in
12636otherwise the error might happen repeatedly and make Emacs nonfunctional. 12667which the error occurred is unconditionally removed, since otherwise
12668the error might happen repeatedly and make Emacs nonfunctional.
12637 12669
12638It is a bad idea to use this hook for expensive processing. If 12670It is a bad idea to use this hook for expensive processing. If
12639unavoidable, wrap your code in `(while-no-input (redisplay) CODE)' to 12671unavoidable, wrap your code in `(while-no-input (redisplay) CODE)' to
12640avoid making Emacs unresponsive while the user types. 12672avoid making Emacs unresponsive while the user types.
12641 12673
12674Note that, when the current buffer contains one or more lines whose
12675length is above `long-line-threshold', these hook functions are called
12676with the buffer narrowed to a small portion around point, and the
12677narrowing is locked (see `narrow-to-region'), so that these hook
12678functions cannot use `widen' to gain access to other portions of
12679buffer text.
12680
12642See also `pre-command-hook'. */); 12681See also `pre-command-hook'. */);
12643 Vpost_command_hook = Qnil; 12682 Vpost_command_hook = Qnil;
12644 12683