Subject: bug#36312: 27.0.50; (message) in display spec condition causes emacs_abort()

From: Pip Cet <[email-masked]>
Date: Thu, 20 Jun 2019 19:32:43 +0000

On Thu, Jun 20, 2019 at 6:12 PM Eli Zaretskii <[email-masked]> wrote:
> > From: Pip Cet <[email-masked]>
> > Date: Thu, 20 Jun 2019 16:06:25 +0000
> >
> > In emacs -Q, evaluate
> >
> > (let ((o (make-overlay (point) (point))))
> >   (overlay-put o 'after-string (propertize " " 'display
> >                        '(when (message "a")
> >   . "b"))))
> >
> > This causes a SIGABRT in the bidi stack code.
>
> Thanks.
>
> You do realize that calling 'message' in a display-spec form causes us
> to re-enter redisplay in the middle of redisplay?  I didn't even know
> we allowed that, but there's something new about our display code to
> learn every day.

I did learn that today, and it's very puzzling. For starters, why do
we allow '(when ...), but not '(eval ...)? And is it really a good
idea to call code from redisplay?

The reason I'm looking at this is that I wanted to define an image
that changes color based on the face properties at point. It turns out
you can do that by abusing a (when ...) spec (which I use to call real
code in a (run-with-timer 0 nil ...), to avoid the issue of recursive
redisplays etc.).

It's very ugly, and I'm not sure what the best way to handle things
would be; luckily, I'm not dependent on running on older or official
Emacs versions, so I'm free to experiment.

So far, what I'm thinking about is a hook that's run _after_ redisplay
to let an overlay know that redisplay just happened and the face used
for the text around the overlay changed. It's soon enough to change
things and trigger another redisplay then, as far as I'm concerned.
(There's some flickering, but for my application that's okay).

But I'd appreciate any suggestions (the immediate application is to
define character-like image-based glyphs that "look like text", but
there might be others).