Failing Gracefully
When an error occurs in Emacs, the current computation is aborted and Emacs returns to the top of its main loop, where it waits for keyboard or other input. When an error occurs while executing a limited-save-excursion
subexpression, the whole limited-save-excursion
is aborted before reaching the call to goto-char
, leaving point who knows where. But the real save-excursion
manages to correctly restore point (and the mark and the current buffer) even when an error occurs. How is this possible?
Information about pending function calls is kept in an internal data structure called a stack. Getting back to the top of the main loop after an error involves unwinding the stack, one function call at a time, in reverse order—so if a called b, and b called c, and then an error occurred, c will be unwound, followed by b, then a, until Emacs is back at "top level."
It is possible to write Lisp code that gets executed while the stack is being unwound! This is the key to writing code that fails "gracefully," cleaning up after itself if it doesn't get the chance to finish due to some error (or due to the user interrupting the operation with C-g). The function to use is called unwind-protect
, which takes one expression to evaluate normally, followed by any number of expressions to execute afterward—even if an error interrupted the first expression. It looks like this:
(unwind-protect normal cleanup1 cleanup2 ...)
Clearly, we'd like to restore the value of point in the "cleanup" portion ...
Get Writing GNU Emacs Extensions now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.