Subject: bug#56393: Actually fix the long lines display bug

From: Gregory Heytings <[email-masked]>
Date: Sat, 09 Jul 2022 08:24:38 +0000

>
> I see that you decided to produce the "restriction" in init_iterator, 
> which would, of course, work, but IMO it has a disadvantage: 
> init_iterator is called a lot, so computing the "restriction" in it 
> should be very fast.  Your current implementation _is_ fast, but AFAIU 
> its result is that we _always_ restrict the display code from seeing the 
> entire buffer, even if there are no long lines in it, which I think is 
> unnecessary.  The original implementation only did that when it detected 
> a long line, and I think we should keep it that way, because the 
> "restriction" will inevitably have some negative effects, however minor, 
> on what we display.
>

I don't think we can detect long lines reliably enough.  The problem of 
the original implementation is what Gerd mentioned: "What happens when 
evaluating an expression in *scratch* that returns a really large result? 
Or maybe in a Shell buffer some large output?" and similar cases, like 
inserting the result of a shell command in the buffer.  Detecting long 
lines in insert-file-contents is not enough to make sure that Emacs will 
always continue to behave normally when a long line is on display.

Note that we the current implementation does not always restrict display 
code from seeing the entire buffer, it does so in a few well-chosen 
places, everywhere else the display code sees the entire buffer.

>
> My proposal is to calculate the "restriction" in start_display.  That 
> function is called by all the commands/functions that use the display 
> code outside of redisplay proper.  (I think one or two such places call 
> init_iterator directly, but we can either handle them specially or 
> change them to use start_display.)  In addition, to prevent even 
> start_display doing more than necessary, redisplay_window should compute 
> the restriction for the window that is about to be redisplayed, and 
> store the values in 'struct window'; then init_iterator, if called 
> inside redisplay, will then simply reuse those values, and start_display 
> will refrain from computing them anew. (To know whether some code is 
> invoked by redisplay, test the value of the global variable 
> redisplaying_p.)  This way, we could make the "restriction" smarter, and 
> only apply it when needed.  Another advantage is that this way the 
> "restriction" will be the same for all the code that is called by 
> redisplay_window, directly or indirectly, which I think is safer than 
> having different "restrictions" computed by different functions.
>

Okay, thanks.  I'll try to do that.