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

Swiper from isearch #89

Closed
kaushalmodi opened this Issue May 8, 2015 · 10 comments

Comments

Projects
None yet
4 participants
@kaushalmodi
Copy link
Contributor

kaushalmodi commented May 8, 2015

Hi,

I'd like to share this snippet borrowed from helm-swoop which I find very useful.

Sometimes I am searching for something using the regular isearch and I change my mind and want to use swiper for that instead.

This snippet helps.. I bind it to M-i in isearch-mode-map:

    (defun swiper--from-isearch ()
      "Invoke `swiper' from isearch.

https://github.com/ShingoFukuyama/helm-swoop/blob/f67fa8a4fe3b968b7105f8264a96da61c948a6fd/helm-swoop.el#L657-668
"
      (interactive)
      (let (($query (if isearch-regexp
                        isearch-string
                      (regexp-quote isearch-string))))
        (isearch-exit)
        (swiper $query)))
@abo-abo

This comment has been minimized.

Copy link
Owner

abo-abo commented May 8, 2015

Great, shame I no longer use isearch:).

Could you create a new page on the wiki with your code?

@joedicastro

This comment has been minimized.

Copy link
Contributor

joedicastro commented May 8, 2015

Actually, what could be an excellent idea would be to made an isearch-forward (in my case it would be better an evil-search-forward) after match the swiper query to be able to navigate between the candidates without need to call swiper againl.

@abo-abo is there any variable where that match keeps stored? then I think that I could make that happen in my config.

@abo-abo

This comment has been minimized.

Copy link
Owner

abo-abo commented May 8, 2015

@joedicastro see ivy-text and ivy--current.

@joedicastro

This comment has been minimized.

Copy link
Contributor

joedicastro commented May 8, 2015

Well, as I told, I made my function to achieve that as following:

(defun joe-swiper ()
       (interactive)
       (swiper)
       (add-to-list 'regexp-search-ring ivy-text))

Works fine, you make a swiper and after that you can move through the isearch results without the need to do a swiper again. So, you get the best of both worlds, you can use swiper as regularly and as a substitute of isearch. To me is precious, because move between the results in evil is as simple as use n and N

@abo-abo

This comment has been minimized.

Copy link
Owner

abo-abo commented May 8, 2015

If there are spaces in ivy-text, you should use (ivy--regex ivy-text) instead to build a proper regex.

@joedicastro

This comment has been minimized.

Copy link
Contributor

joedicastro commented May 8, 2015

Oh, thanks! I made the change. 😄

@abo-abo abo-abo closed this May 11, 2015

@lionel-

This comment has been minimized.

Copy link

lionel- commented Feb 9, 2016

@abo-abo Any chance of integrating @joedicastro's change? This is really useful for Evil users.

abo-abo added a commit that referenced this issue Feb 9, 2016

@lionel-

This comment has been minimized.

Copy link

lionel- commented Feb 13, 2016

to Evil users:

I also find the following makes Swiper much more natural to use:

  (defun my-swiper-update-search-ring (&rest args)
    (add-to-list 'regexp-search-ring (ivy--regex ivy-text)))

  (advice-add 'ivy-next-line :after #'my-swiper-update-search-ring)
  (advice-add 'ivy-previous-line :after #'my-swiper-update-search-ring)

This updates the search ring when you hit C-n or C-p. For some reason I often C-g from a search to get back to where I was, and then after a while I use Evil search motions to quickly cycle through the matches of the previous search. Without these advices it doesn't work.

@abo-abo

This comment has been minimized.

Copy link
Owner

abo-abo commented Feb 13, 2016

@lionel- If you press C-g, swiper--cleanup will be called anyway. Might want to advise that instead, to modify the regex ring a bit less.

Also, cycling matches after a search - ivy-occur can do that too. I recently added wgrep functionality to that as well, if you want to edit the matches.

@lionel-

This comment has been minimized.

Copy link

lionel- commented Feb 13, 2016

Hmm I'd rather not update the ring when I just cancel a search without moving through it.

By the way, this is not (add-to-list) that should be used in all these commands, but (add-to-history). The former doesn't push old elements in front of the ring so it won't work with repeated searches. The latter pushes in front and makes sure the ring size doesn't increase indefinitely. It also checks for duplicates at the front of the list.

In addition C-n and C-p should update the direction of the search, so here are updated advices for this use case:

  (defun my-swiper-update-search-ring-forward (&rest args)
    (add-to-history 'regexp-search-ring (ivy--regex ivy-text))
    (setq isearch-forward t))

  (defun my-swiper-update-search-ring-backward (&rest args)
    (add-to-history 'regexp-search-ring (ivy--regex ivy-text))
    (setq isearch-forward nil))

  (advice-add 'ivy-next-line :after #'my-swiper-update-search-ring-forward)
  (advice-add 'ivy-previous-line :after #'my-swiper-update-search-ring-backward)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment