Subject: Re: bug#50906: xref-find-references blocks Emacs: asynchronous operation?

From: Dmitry Gutov <[email-masked]>
Date: Tue, 5 Oct 2021 04:59:29 +0300

On 30.09.2021 01:49, Stefan Kangas wrote:
> Severity: wishlist
> 
> `xref-find-references' blocks Emacs while searching for matches.
> This can take a long time to complete in large repositories.
> 
> It would be nice if it could work asynchronously, like e.g. `M-x rgrep'.

Wishlist indeed!

Daniel's bug report shows a good case for this kind of feature: huge 
projects where the search, even using fast tools (e.g. ripgrep), takes 
multiple seconds. So if results of such searches could be displayed 
incrementally, it would improve the perceive speed and usability.

What can be done here:

- Design an "asynchronous" format for xref-show-xrefs-function to 
consume. FETCHER of a different shape. Not sure how it's going to work 
in the end -- maybe a simple-ish iterator (call a function again for 
more results), but ideally it would look synchronous somehow, and the 
concurrency would be achieved through the use of threads. Not sure if 
that's realistic.

- The new kind of fetcher would need to provide a way to abort the 
search, since 'C-g' would not be available anymore.

- Implement it for the common searches of course.

Downsides:

- No way to quickly 'C-g' out of a search, supposedly one would have to 
switch to the results buffer (maybe it will be selected right away) and 
type 'C-c C-c'. And then kill the buffer, I guess?

- The size threshold of a project where the improvement will be 
significant is pretty big -- for instance, searching across the Emacs 
checkout takes about 100-200ms (just the time the external process 
uses). If the search results in many matches (1000s or 10000s) the 
results will take a while to display, but most of the time is taken up 
by processing of results which is implemented in Lisp. We might have 
Emacs which shows the first results soon, but then remains sluggish 
until all search results are processed. This problem could be worked 
around, however, by limiting the displayed number of results and having 
buttons like the ones at the bottom of vc-print-root-log output buffer.

- Search results come in unsorted, and, in the case of ripgrep, sorted 
randomly every time the search is performed (the files, at least). We 
sort them now at the bottom of xref-matches-in-files, but asynchronous 
search results would make that infeasible.

Given all of the above, I've been putting off this work, but thoughts 
and opinions welcome, and POC patches -- doubly so.