emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: timer handlers and ^G


From: Stefan Monnier
Subject: Re: timer handlers and ^G
Date: Thu, 25 Oct 2001 13:05:20 -0400

>        If the timer handler is written so that its author is _positive_ it 
> can 
>        be interrupted, that code can enable quitting.
> Actually I am not sure that this can be done safely.  If the timer
> handler can get run inside of a place where quitting is not allowed,
> and the handler binds inhibit-quit to nil, then the result could be to
> quit from a place in the main program where quitting should not happen.

My understanding is that it's not a problem of crashing Emacs,
but just of the user not expecting to interrupt Emacs in the
middle of something.  When the user does C-g during the normal
execution of a command, he isn't surprised if the end result is that
the command was only partly executed and that the resulting state
is a bit ugly, but when he interrupts a background activity, he
might not even be aware of that activity and could be surprised
to see part of his buffer incompletely fontified because of some
C-g he did a while back when Emacs was stealthily fontifying.

Another problem is that any non-local exit from a post-command-hook
is assumed to be an error and the hook is then cleared to prevent
this error from repeating itself ad-nauseam.  So if you don't
explicitly catch `quit', hitting C-g (with inhibit-quit set to nil)
might inadvertantly clear post-command-hook.  That's the problem
I personally encountered with my `reveal' minor-mode (coming soon
to a repository near you) where I tried to bind `inhibit-quit' to nil
and couldn't figure out why the thing stopped working every once
in a while.

This gets back to your point above.  I think we should create a macro like:

   (defmacro with-enabled-quit (&rest body)
     ;; we assume that inhibit-quit is bound to non-nil before.
     `(condition-case nil
          (let ((inhibit-quit nil))
            ,@body)
        (quit (setq quit-flag t))))

This makes sure that the quit is only locally enabled and won't
end up interrupting the outside code which is runs with `inhibit-quit'
set to t.


        Stefan




reply via email to

[Prev in Thread] Current Thread [Next in Thread]