Subject: Re: bug#56682: locked narrowing

From: Gregory Heytings <[email-masked]>
Date: Wed, 30 Nov 2022 22:09:59 +0000

>
> It could (although that would be an unusual thing to do), but that's 
> immaterial: the display engine will never look outside of the 
> restriction, and so searching beyond that is not useful.  Moreover, safe 
> code in Emacs cannot look beyond BEGV..ZV without calling 'widen', 
> because various primitives and subroutines don't expect that and will 
> barf sooner or later; that's why I made that change in the loop.
>

I had to refresh my memory about this, and I think there is a 
misunderstanding here: we check whether a buffer contains long lines only 
when it is about to be redisplayed and its contents have changed enough 
since the last time it was displayed.  What happened between these two 
redisplays can be anything, e.g. it could be a buffer that has not been on 
display during an hour and that has been filled by a process in the 
meantime.  Using BEGV/ZV is wrong, again because we don't know what 
happened between these two redisplays, it could have been filled by a 
process and narrowed, and if after switching to that buffer the user 
widens it, Emacs would become unresponsive.  Or it could be a buffer that 
has been emptied in the background by a command, filled with the contents 
of a file, and narrowed to some portion of that file (e.g. a single hunk 
of a diff file); again if the user widens it to look at the whole file, 
Emacs will hang.  The only safe way to be certain that a buffer does not 
contain long lines is to check the whole buffer.

>
> If we are going to narrow the buffer to PT ± N characters, then 
> searching inside slightly more than this region (say, twice more or 5 
> times more) should be enough, I think.  It might fail in some borderline 
> cases, but most files with very long lines have almost all of their 
> lines long, so I see no problem here.
>

The intention when this detection mechanism was designed was explicitly to 
also support non-file visiting buffers, e.g. a shell buffer in which a 
user cat's a file with long lines.

>
> OTOH, "punishing" large buffers that have no long lines at all doesn't 
> strike me as a good balance.  Your proposed patch will solve a 
> particular use case, but it cannot solve all of them.
>

Indeed, by definition no heuristic can solve all problems.

>
> When modiff becomes large enough, we will search again, and the 
> threshold of 8 is not so large to prevent it from happening frequently 
> enough to be an annoyance.
>

Please, let's not throw away something that was designed with care and 
about which literally no one complained since it was introduced, for the 
sole reason that an artificial benchmark shows a slowdown of ~80 
milliseconds in a 30 MB buffer.  And note that it's not "modiff becomes 
large enough", it is "modiff changed enough between two redisplays".

>
> That annoyance will be for no good reason in buffers that have no long 
> lines.
>

It's not "for no good reason", it's for an excellent reason: it's the 
price to pay to ensure that Emacs remains responsive in as many cases as 
possible.  And it's not an annoyance, for all basic editing commands the 
detection loop will not run.

>
> If you are still unhappy with such a simple heuristics, we could go with 
> something slightly more complex, like change the threshold of modiff 
> dynamically based on the buffer size and perhaps the number of times we 
> already searched without finding long lines -- the larger these two are, 
> the higher we could bump the threshold.
>

I don't see how such a heuristic could catch a case such as a user cat'ing 
a file with long lines in a shell buffer.