[Top][All Lists]

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

Re: Signal `quit' in a `font-lock-fontify-region-function'

From: Stefan Monnier
Subject: Re: Signal `quit' in a `font-lock-fontify-region-function'
Date: Sat, 29 Jun 2019 17:26:02 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

> I'm not sure if this is flexible enough.  I don't like the idea of C-g
> already invoking some code (that e.g. disables font-locking).

In my suggestion, C-g wouldn't invoke any significant code.  All it
would do is setup a timer, and when the timer expires a message would be
emitted in the echo area to inform the user what it is that Emacs is
currently doing.
It definitely wouldn't disable font-locking right away.

The disabling would only be in response to a "large" number of C-g,
which presumably should only be needed in extreme circumstances
(basically when currently the user ends up killing Emacs instead).

> So, I'd like to be able to _handle_ `quit' signal in the function
> itself and stop extending the region and return immediately, so that I
> don't throw away work on a considerable region of text that has been
> done already.

I don't understand why you say "don't throw away work on a considerable
region of text that has been done already": if you're in the middle of
extending the region, presumably no "work" has been done yet.

> However, fontlocking code shouldn't discard the results
> (as otherwise this is pointless).  So, I cannot resignal `quit', I
> have to return normally.  But I also don't want to "eat" this signal
> and hide C-g press from Emacs' monitoring code.  So basically, I want
> font-locking still continue to work for a while, even if C-g has been
> pressed too many times, but if so, abort soon.

Could `while-no-input` be usable in this case?

> I'm not sure if it is the best solution, but I'd propose C-g to be
> counted not when `quit' signal is caught, but when it would be
> emitted, even if `inhibit-quit' is t.  And font-locking code would
> look something like this:
>     (let ((count-C-g-presses t))  ; Instead of "registering" as you
> proposed, I think we just
>                                   ; need to tell C-g handler to count
> presses while inside
>                                   ; certain blocks of code.
>       (condition-case error
>           (let ((fontified-region (funcall actual-handler ...)))
>             ;; Process the fontified region
>             ...)
>         (error ;; This logs any errors inside the handler, including uncaught
>                ;; `quit' signals.  Just as now.
>                ...))
>       (when (too-many-C-g-recently)  ; This would count both C-g that
> resulted in (signal 'quit ...)
>                                      ; and those that resulted in
> `(setq quit-flag t)'.

I think if C-g resulted in (signal 'quit ...), then presumably we exited
this code, so the only really interesting case should be the one where
we just have `quit-flag` set to t.

Maybe we should change the C-g code so it sets `quit-flag` to the
number of C-g that are pending.

>         ;; The below forms are roughly what would be "registered" in your
>         ;; proposal.  I feel leaving it up to the caller gives more
>         ;; flexibility in actually permorming "abort everything" tasks.
>         (setq font-lock-mode nil)
>         (message "Too many C-g, font-locking disabled")))

Maybe when "registering", the code could provide a function to
execute instead of "aborting".


reply via email to

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