emacs-devel
[Top][All Lists]
Advanced

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

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


From: Paul Pogonyshev
Subject: Re: Signal `quit' in a `font-lock-fontify-region-function'
Date: Sat, 29 Jun 2019 19:50:13 +0200

Found this answer to my question in the list archives. I'm not
subscribed, please CC to me.

> Right, here's how I could imagine a "desirable" behavior:
>
> - everytime some operation may block Emacs, it should "register"
>   somewhere (probably some let-binding of a global var is all it takes).
> - After hitting C-g, a timer is started.
> - If this timer is reached before the C-g has had to chance to be
>   processed, emit a message in the echo area explaining what Emacs is
>   currently doing (based on the "registered" information above).
> - when we reach the Nth C-g in a row within the same "registered"
>   operation, we abort the operation (e.g. by calling an ad-hoc
>   function provided while "registering").

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).  Please
read on to see a usecase that I feel would be impossible to support
with your proposal.

My fontification function often extends the fontification region
considerably and then returns `(jit-lock-bounds START . END)', as
required in the documentation.  In my case this makes fontification
much faster, because the function itself is very fast and most of the
time is spent in various setups (both in fontlocking code and the
function itself), not in traversing through the region to be
fontified.

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.  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.

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)'.
        ;; 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")))

I think I could try to implement this myself, but on the other hand
I'm certainly not familiar with Emacs internals.  So I would gladly
give up this task to someone else who would like to do it.

Paul



reply via email to

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