2

What is the preferred method of reverting a partially applied set of operations within a function? For example in a function that kills some text, performs some intervening operations, and then yanks the earlier killed text-- if one of those intervening operations throws an error the originally killed text should be restored by the function.

Are there are any generalized solutions like SQL transactions for this? I know Emacs has a powerful undo system, but I have not used it programmatically.

  • 1
    killing for immediate yanking in the same function sounds like you're doing it wrong. Killing is meant for interactive use, see second paragraph in (info "(elisp) The Kill Ring"). – YoungFrog Nov 1 '15 at 6:42
1

Sounds like you are looking for unwind-protect or condition-case.

The former is for doing cleanup unconditionally. The latter is for handling errors - in general or of specific types.


unwind-protect:

unwind-protect is a special form in `C source code'.

(unwind-protect BODYFORM UNWINDFORMS...)

Do BODYFORM, protecting with UNWINDFORMS.
If BODYFORM completes normally, its value is returned
after executing the UNWINDFORMS.
If BODYFORM exits nonlocally, the UNWINDFORMS are executed anyway.

See the Elisp manual, node Cleanups.


condition-case:

condition-case is a special form in `C source code'.

  (condition-case VAR BODYFORM &rest HANDLERS)

Regain control when an error is signaled.
Executes BODYFORM and returns its value if no error happens.
Each element of HANDLERS looks like (CONDITION-NAME BODY...)
where the BODY is made of Lisp expressions.

A handler is applicable to an error
if CONDITION-NAME is one of the error's condition names.
If an error happens, the first applicable handler is run.

The car of a handler may be a list of condition names instead of a
single condition name; then it handles all of them.  If the special
condition name `debug' is present in this list, it allows another
condition in the list to run the debugger if `debug-on-error' and the
other usual mechanisms says it should (otherwise, `condition-case'
suppresses the debugger).

When a handler handles an error, control returns to the `condition-case'
and it executes the handler's BODY...
with VAR bound to (ERROR-SYMBOL . SIGNAL-DATA) from the error.
(If VAR is nil, the handler can't access that information.)
Then the value of the last BODY form is returned from the `condition-case'
expression.

See also the function `signal' for more info.

See the Elisp manual, node Handling Errors.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.