From: Paul Pogonyshev <pogonyshev@gmail.com>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: Emacs developers <emacs-devel@gnu.org>
Subject: Re: Signal `quit' in a `font-lock-fontify-region-function'
Date: Sun, 30 Jun 2019 01:49:46 +0200 [thread overview]
Message-ID: <CAG7Bpaq3_LkrDQ3qrd19pKtJcWT0GOa0YJTjnGopYrJc8K-hwQ@mail.gmail.com> (raw)
In-Reply-To: <jwv36jsm72h.fsf-monnier+emacs@gnu.org>
On Sat, 29 Jun 2019 at 23:26, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
>
> > 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).
>
> [...] 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, basically, as I understand, C-g handler in your proposal would
look like (I know it is in C code, but...), simplified:
(defun handle-C-g (...)
(when registered-many-C-g-callback ; variable set by e.g.
font-locking code
(setq num-C-g-presses (1+ num-C-g-presses))
(when (> num-C-g-presses 3)
(funcall registered-many-C-g-callback))))
and font-locking code would be roughly
(let ((registered-many-C-g-callback (lambda () (setq font-lock-mode nil))))
; call fontification function, process its result etc.
)
That's what I meant: here `handle-C-g' already invokes some callback
that higher level (in this case font-locking) registers.
I propose that instead font-locking code simply says "I will process
multiple C-g presses somehow, please count them" by let-binding
`count-C-g-presses' to t. The idea is to not invoke the "abort"
callback immediately when the 3rd C-g is pressed, but instead let the
iteration finish gracefully and _then_ let the higher-level code
(font-locking) abort or not based on all the information it has by
now. Usually this information would be just result of
`(too-many-C-g-recently)', but could be anything in the future, so we
are more flexible.
> > 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.
For example, my function decides to fontify 1000 lines of text and by
the time C-g is pressed (triggering the signal) it has already
fontified 500 of them (this is already more than what font-locking
code wanted, because I extended the requested region). I'd like to be
able to notify font-locking code about the work that has been done,
even if I planned to do even more. If I raise `quit' signal or let
C-g raise it by default, all this work is thrown away.
> Could `while-no-input` be usable in this case?
This macro uses `with-local-quit', which, as I understand will rethrow
signal `quit' after the body. As a result, font-locking code will
still see my function terminate non-locally, deem the whole invocation
failed and set property `fontified' to nil. So no, to achive what I
want I need to let my function return normally somehow.
>
> > 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: [...]
>
> 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.
Yes, but the point is in that I want to avoid C-g resulting in the
signal by binding `inhibit-quit' inside my fontification function.
But still have C-g handler note that C-g is pressed and let
fontification code find if it is being pressed too often.
> Maybe we should change the C-g code so it sets `quit-flag` to the
> number of C-g that are pending.
This generally sounds like a good idea: I'm always in favour of having
more information. However, in my case it is not enough.
I guess it is easier to explain by pseudocode of my fontification
function:
(defun my--fontify-region (region-start region-end _loudly)
;; Very fast, so always work on large regions to avoid setup overhead.
(setq region-end (+ region-start 50000))
;; Here comes some internal setup.
...
(let ((fontified-up-to region-start)
(inhibit-quit t))
;; While `quit' is inhibitted, the below loop will still be
aborted on C-g.
(while (and (< fontified-up-to region-end) (null quit-flag))
... ; do some work on the next small chunk of text; this is
very fast,
; but as the region is quite big, the loop is iterated many times
)
;; Always exit normally. Font-locking code will find out if
we suppressed
;; a C-g through other means, i.e. using (too-many-C-g-recently).
(setq quit-flag nil)
`(jit-lock-bounds ,region-start . ,fontified-up-to)))
Note that the function doesn't suppress any other signals/errors.
Paul
next prev parent reply other threads:[~2019-06-29 23:49 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-29 17:50 Signal `quit' in a `font-lock-fontify-region-function' Paul Pogonyshev
2019-06-29 21:26 ` Stefan Monnier
2019-06-29 23:49 ` Paul Pogonyshev [this message]
2019-06-30 0:18 ` Stefan Monnier
2019-06-30 10:51 ` Paul Pogonyshev
-- strict thread matches above, loose matches on Subject: below --
2019-05-28 16:24 Paul Pogonyshev
2019-05-28 17:50 ` Stefan Monnier
2019-05-28 18:14 ` Paul Pogonyshev
2019-05-28 18:24 ` Stefan Monnier
2019-05-16 22:20 Paul Pogonyshev
2019-05-16 23:20 ` Stefan Monnier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAG7Bpaq3_LkrDQ3qrd19pKtJcWT0GOa0YJTjnGopYrJc8K-hwQ@mail.gmail.com \
--to=pogonyshev@gmail.com \
--cc=emacs-devel@gnu.org \
--cc=monnier@iro.umontreal.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.