How to Do a Project-wide Search & Replace in Doom Emacs
This is a guide on how to do a project-wide text search and replace operation using Doom Emacs and all its preinstalled packages and keybindings.
Earlier this week I went looking for “how to search and replace in a whole project” in Emacs. I knew had Doom Emacs set up with evil turned on by default, and I knew to use
SPC s p to launch a project text search. What was next…?
Today, I’m documenting the process so that I won’t forget again. Hopefully it’ll help someone out there too.
- for ivy module users
SPC s p foo C-c C-e :%s/foo/bar/g RET Z Z
- for vertico module users
SPC s p foo C-; E C-c C-p :%s/foo/bar/g RET Z Z
Entering those keys will replace “foo” with “bar” in your whole project. Magic!
Not sure if you’re using ivy or vertico? If you set up Doom Emacs after, you’re probably using vertico. Otherwise, probably ivy. Check your
init.elfile to see which is active1
The Long Explanation
- Make sure you’re in the right project and all your open buffers/files are saved. If you’re making a large change, maybe a
git commitwould give you a little extra insurance.
SPC s pto launch the project search. This is what you would normally use to search strings or regular expressions2 within your project. I’ve set
ivy-more-chars-alistto not return any results until at least 3 characters have been entered3, otherwise counsel can be a little overzealous in returning results.
- Type in a search string or regular expression,
fooin this example, to get some results. This doesn’t have to be exactly what you want to replace; it just needs to be specific enough to get the right results into view.
- This step depends on which completion engine you’ve set up for Doom.
- for ivy users1
C-c C-eto transform the search results into a wgrep or writable grep buffer. This calls
+ivy/woccur, which is equivalent to pressing
C-c C-o C-c C-p(i.e.
ivy-occurfor turning ivy results into a buffer and
wgrep-change-to-wgrep-modeto make it writable).
embark-export, which exports what you’re looking at into a new buffer. Embark is smart enough to know that you’re looking at grep search results, so it will export to a new buffer in
C-c C-pto run
wgrep-change-to-wgrep-modeto make the search results writable.
- for ivy users1
Use your preferred method of search and replace in a single file. Doom relies heavily on evil’s vim emulation, so the smoothest option for me was to type
:%s/foo/bar/gto preview the changes and hitting
You can also edit the buffer manually using any technique you want.
C-M-%to do a regular Emacs query replace? Sure.
C-vto do a rectangle/visual block edit? Go for it.
g z zfor evil-mc multiple cursors? No worries—just be careful of the readonly region of filenames on the left.
At this stage nothing has been written to the files yet, so you can still undo easily. Go through all the lines in the search results to check if the changes are as expected.
You can also
SPC : wgrepor
M-x wgrepto look at the other advanced wgrep actions.
Z Zto write all the changes to their respective files, or
Z Qto abort the search and replace.
This post was originally written back when ivy was still the default completion engine used by Doom Emacs. However, since this commit on , new users of Doom will be using the vertico completion stack. Existing users upgrading to the current version of Doom will keep using Ivy.
How can you tell if you’re using Ivy or vertico? Have a look at your
init.el file in your Doom config to check if
vertico are present and uncommented. Whichever one is uncommented is the one you’re using.
Just a reminder that Emacs has its own idiosyncratic version of regular expressions. It’s weird, I know.
I have this in my
config.el to set the minimum characters to 3 before a search is fired. You can customize the threshold individually for each of the commands.
(after! ivy (setq ivy-more-chars-alist '((counsel-grep . 3) (counsel-rg . 3) (counsel-search . 3) (t . 3))))