OK, I'll try an expanded answer. The thing is, Emacs Lisp is single-threaded. You can spin more processes, but not inside the Emacs Lisp interpreter. However, the keyboard input that you need to read from user to interrupt your function needs to be processed by the same Emacs Lisp interpreter. This means that if your interpreter is stuck interpreting some Lisp code there may not be a way for you to interrupt it from within. Here's a place in the manual that describes this situation:
At the level of C code, quitting cannot happen just anywhere; only at the special places that check quit-flag. The reason for this is that quitting at other places might leave an inconsistency in Emacs’s internal state. Because quitting is delayed until a safe place, quitting cannot make Emacs crash.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Quitting.html
So, how Emacs still has the C-g / canceling functionality?--There are timers and functions which do I/O (wait for events in command loop). Timers can arrange for your computations to be done in chunks, so that you would have points in your computations where you can look around and, if necessary, prevent all further computations. I/O functions can send quit
signal. The macro with-keyboard-quit
waits for this signal and once received will exit gracefully. However, your function needs to know to send this signal. This means that if your function prevents the user from sending keyboard input, then you will not be able to benefit from keyboard interrupts.
Bottom line: try wrapping your function's code into while-no-input
. If this doesn't work, try rewriting your function in a way that it will let Emacs process keyboard events.
while-no-input
macro. It seems to do what you want: i.e. it cancels the execution of its body when new input appears.