Add redisplay-can-quit to keep redisplay atomic by default

* src/xdisp.c (redisplay_internal): Bind inhibit-quit when
redisplay-can-quit is nil to ensure atomic redisplay updates.
(syms_of_xdisp): New variable redisplay-can-quit.
* etc/NEWS: Document the new variable.
This commit is contained in:
Daniel Colascione 2025-06-10 11:28:47 -07:00
parent 8e9adb80d1
commit f3c188ceb0
2 changed files with 18 additions and 0 deletions

View file

@ -2455,6 +2455,13 @@ Binding 'inhibit-message' to a non-nil value will now suppress both
the display of messages and the clearing of the echo area, such as
caused by calling 'message' with a nil argument.
---
** New variable 'redisplay-can-quit' to allow quit during redisplay.
This variable is normally nil to ensure redisplay completes atomically.
Setting it to t allows C-g to interrupt redisplay, which can be useful
for debugging redisplay hangs but may leave the display in an
inconsistent state.
** Special Events
+++

View file

@ -17160,6 +17160,9 @@ redisplay_internal (void)
/* Record a function that clears redisplaying_p
when we leave this function. */
specpdl_ref count = SPECPDL_INDEX ();
if (!redisplay_can_quit)
specbind (Qinhibit_quit, Qt);
record_unwind_protect_void (unwind_redisplay);
redisplaying_p = true;
block_buffer_flips ();
@ -38753,6 +38756,14 @@ The recommended non-zero value is between 100000 and 1000000,
depending on your patience and the speed of your system. */);
max_redisplay_ticks = 0;
DEFVAR_BOOL ("redisplay-can-quit",
redisplay_can_quit,
doc: /* If true allow quit to interrupt redisplay.
Normally, we inhibit quit in redisplay to ensure each update completes
atomically and leaves the display in a known-good state. You may want to
set this variable to t to help debug redisplay hangs. */);
redisplay_can_quit = false;
/* Called by decode_mode_spec. */
DEFSYM (Qfile_remote_p, "file-remote-p");