Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Automatic" swiper-multi by supporting multi-isearch-next-buffer-function #2473

Open
ThibautVerron opened this issue Mar 2, 2020 · 5 comments

Comments

@ThibautVerron
Copy link
Contributor

Hi,

I'm aware of the existence of swiper-multi, but it seems that it requires manually selecting the buffers to process.

For isearch, it is possible to set the variable multi-isearch-next-buffer-function to an appropriate function and get this behavior automatically. Some modes make use of that, for example reftex-isearch-minor-mode makes isearch perform document-wide searches in multi-file LaTeX projects.

Could swiper support this variable? My impression is that it should be possible to use multi-isearch-next-buffer-function to make a list of buffers and then use it with swiper-multi?

It might not be practical though: on big projects, if the function has to create buffers visiting project files, even a short search would require opening a lot of files (and performing hooks, etc.).

Instead, isearch does it on the fly, and requires pressing C-s or C-r twice to jump to the next buffer. I guess that adapting that behavior to swiper would be a lot more work?

@abo-abo
Copy link
Owner

abo-abo commented Mar 4, 2020

I think adding this to swiper would result in a lot of unneeded complexity.

However, we could add it to swiper-multi. It could:

  • Check if multi-isearch-next-buffer-function is not nil
  • Get a list of all search buffers from multi-isearch-next-buffer-function
  • Start the search without having to select the buffer list

But I've never used multi-isearch-next-buffer-function before. Can you provide some examples where it's used?

@ThibautVerron
Copy link
Contributor Author

ThibautVerron commented Mar 4, 2020

Thanks for your answer! Yes, that's what I would expect too. But the alternative, generating the list of buffers beforehand, would make the function too heavy to be used as a replacement for swiper. Definitely better than nothing though.

It is used in reftex-isearch-minor-mode (built-in and autoloaded). You can look at the code, it's slightly more complicated than needed because it also supports a legacy interface with 4 functions instead of the one.

The variable itself is set to reftex-isearch-switch-to-next-file, which is essentially looking at the ordered list of files for the document, then returning the first, last, next or previous buffer (opening the file if needed) depending on the arguments of the function.

Looking at the code for swiper and ivy, I see why you think it would be hard to implement the exact behavior of isearch: apparently there is no predefined way of setting up different actions when reaching the last or first candidate. It might be possible to do something with update-fn?

In any case, it might be a valuable addition in the future, also for other situations, for example generating a large list of files on the go.

@ThibautVerron
Copy link
Contributor Author

After testing with reftex, this naive code should create an ordered list of buffers:

(let ((first-buffer
       (let ((isearch-forward t))
	 (funcall multi-isearch-next-buffer-function (current-buffer) t)))
      (last-buffer
       (let ((isearch-forward nil))
	 (funcall multi-isearch-next-buffer-function (current-buffer) t))))
  (setq tmp-list (list last-buffer))
  (setq tmp-buffer last-buffer)
  (setq isearch-forward nil)
  (while (not (eq tmp-buffer first-buffer))
    (setq tmp-buffer
	  (funcall multi-isearch-next-buffer-function tmp-buffer))
    (setq tmp-list (cons tmp-buffer tmp-list)))
  tmp-list)

@abo-abo
Copy link
Owner

abo-abo commented Mar 8, 2020

Could you PR with your change to swiper-multi?

@ThibautVerron
Copy link
Contributor Author

Sorry for the delay.

I have written a prototype (https://github.com/ThibautVerron/swiper/tree/Multi-isearch), I will do a bit more testing to make sure it works fine and then make a PR. As expected there is an "opening files" phase at the beginning, but so far it doesn't take exceedingly long. I also want to test it on a slower computer.

swiper-multi doesn't immediately make a full replacement to swiper (for example, the display does not follow the candidate), but I didn't look too far in the customizations for now.

On the other hand, I don't think anymore that it would be so complicated to add the feature of passing a function "generate more candidates" to ivy. It looks like it would just be another switch (in addition to wrapping) in ivy-next-line when going over the last line, no?

Anyway, as far as multi-buffer search is concerned, I agree that it's not really a worthwhile effort given that swiper-multi exists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants