I’m stuck in my ways and stubborn so even though I use macOS as my primary platform, I have, for years, insisted on compiling all my tools from source myself. The Mac platform has just enough idiosyncrasies to sometimes make that a challenge. Of course, there’s the excellent Homebrew to solve these problems but as I said: stubborn.
For a long time, I’ve wanted to try out ag
(The Silver Searcher) but the make process required a bunch of utilities that I didn’t have installed and it just seemed like too much trouble. Then I watched Mike Zamansky’s video on using Emacs for C++ programming in which he mentioned ag
and using it with counsel-ag
(part of Ivy) as a particularly nice way of tracking down where identifiers or other symbols are used in a project. There’s also the excellent refactoring workflow using ag
and ivy-occur
that Samuel Barreto wrote about. That, finally, convinced me to install homebrew so that I could easily install ag
and other hard to build tools.
I’ve been really happy with ag
since I installed it and have woven it into my workflow. If you have Ivy installed, you can use counsel-ag
to call ag
from Emacs and have the results put in the minibuffer. That’s what Zamansky showed in his video. You can also put the results in a separate buffer so that you can visit each occurrence separately and conveniently. Although it’s not clear from the video, Zamansky does this by calling ivy-occur
with Ctrl+c Ctrl+o.
Once you’ve got the results in a separate buffer, you can toggle on wgrep
with Ctrl+x Ctrl+q and then use iedit
, multiple-cursors
, or query-replace
to change all occurrences of some text. It’s a really powerful way of working. Because ag
operates recursively, it’s perfect for working with all the files of a project at the same time.
That got me thinking that you could doubtlessly do the same thing with the results of a swiper search. That is, you can move the results of the search from the minibuffer to a separate buffer. There’s no point, of course, in making that buffer writable and making changes because you could do that in the original buffer more easily but it is nice if you want to visit some or all of the results. Since the buffer is an occur buffer you can simply click (or type Return) to visit any particular instance and then change back to the occur buffer to pick another. That’s often very handy.