4

Based on the documentation, I am trying the following:

(let ((inhibit-quit t))
    (my-fun)
    (y-or-n-p "Prompt")
    (cancel-effects-of-my-fun))

Here, my-fun performs changes to configuration and cancel-effects-of-my-fun restores the configuration to its original state. I need to make sure that (cancel-effects-of-my-fun) is evaluated even if the user presses C-g during the evaluation of (y-or-n-p "Prompt"). The code above does not do the job. In fact, even setting inhibit-quit globally does not have any effect. I tried (setq quit-flag nil), but that did not make a difference either. What am I missing? Is there a more idiomatic way to achieve what I am trying to achieve?

AlwaysLearning
  • 749
  • 4
  • 14
  • 3
    The doc-string for `unwind-protect` looks interesting and I see it a lot in the built-in code, but I haven't played with it myself. – lawlist Aug 31 '17 at 18:57
  • `unwind-protect` did exactly what I needed! – AlwaysLearning Aug 31 '17 at 19:10
  • 1
    Due to magic, `y-or-n-p` signals a `quit` error in case the user presses `C-g`, rather then setting `quit-flag` like the ordinary `C-g` at top-level. That's why inhibiting it has no effect, it is not set anyway. – politza Sep 01 '17 at 21:15

1 Answers1

6

Based upon the comment of the original poster underneath the question, the function unwind-protect achieves the desired behavior. The doc-string and printout of the *Help* buffer for describe-function is as follows:

unwind-protect is a special form in `eval.c'.

(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.
lawlist
  • 18,826
  • 5
  • 37
  • 118