Subject: bug#29360: 26.0; Add full-buffer choice for `isearch-lazy-highlight'

From: Juri Linkov <[email-masked]>
Date: Sun, 21 Oct 2018 01:12:49 +0300

>> Actually, a full-buffer lazy-highlighting possibility already exists:
>>
>>   (setq lazy-highlight-cleanup nil)
>>   (add-hook 'isearch-mode-end-hook
>>             (lambda ()
>>               (setq window-group-start-function (lambda (_w) (point-min)))
>>               (setq window-group-end-function (lambda (_w _u) (point-max)))))
>
> Thanks for this info. I don't really understand it, though. `C-h
> v window-group-start-function' tells me nothing, for instance - no
> doc, apparently.
>
> (FWIW, I already use `isearch-mode-end-hook' quite a bit. Not that another
> addition would necessarily break the bank. ;-))

Sorry, I meant isearch-mode-hook, not isearch-mode-end-hook.
But this detail is not important for properly implementing
this feature.

>> That patch was installed more than a year ago.
>
> What is that patch? Is this about `window-group-start|end-function' or
> is there some other way to force lazy highlighting to be done throughout
> the buffer? If this is patch is now reflected in isearch.el, where would
> I see it there?

It's here: http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=c5e66afa88d6ff8ad5c42318d85188ed477e7db2

>> Both need special treatment for possible slowdown in a
>> large buffer, so for performance reasons we need to add
>> a new customizable variable like lazy-buffer-max-at-a-time,
>> separate not to conflict with lazy-highlight-max-at-a-time.
>> The latter applies to the matches on the screen, the former
>> to the matches in the full buffer.
>
> I see. Sounds like that would be do-able, but I don't know anything
> about the details. Hope you can/will resolve this sometime soon.

The biggest obstacle is this - currently the traversal order of
visiting matches to lazy-highlight is the following:

1. start from the current match forward to the bottom of the window;

2. wrap from the bottom to the top of the window;

3. start from the top of the window down to the current match.

Visually you can observe how the current algorithm works by setting:

  (setq lazy-highlight-max-at-a-time 1
        lazy-highlight-initial-delay 1
        lazy-highlight-interval 1)

This works well when matches are highlighted only on the screen.

But when boundaries will be extended from the window to the full buffer,
the problem of performance creeps in.  Lazy-highlighting will work
in the following order:

1. start from the current match forward to the end of the buffer;

2. wrap from the end to the beginning of the buffer;

3. start from the beginning of the buffer down to the current match.

The problem is that matches in the upper part of the window might be
highlighted too late - only when all matches in the full buffer
are highlighted, and most of these matches likely will be outside
of the displayed part of the buffer in the window.

IOW, highlighting of the matches above the current match will be delayed
until all other matches in the whole buffer will get a highlighting
overlay.

Do you think we should change the algorithm and adapt it to highlighting
of the buffer?  Maybe we should first highlight matches on the bottom
and the top part of the window before going to highlight matches in
other parts of the buffer that are not visible on the screen?