notes from /dev/null

by Charles Choi 최민수


29 Apr 2026

Bulk Search & Replace Commands for Files and Buffers in Emacs

Emacs offers a dizzying number of commands to perform bulk operations on multiple files or buffers. These commands are quite capable and can make trivial the execution of workflows that would be heroic in other editors. Unfortunately these commands are also difficult to discover as a number of them are not featured in easily accessible menus.

This post calls attention to bulk commands related to search and replace in Emacs and how their discoverability can be improved using the Casual and Anju UI packages.

Regular Expressions

Before moving forward, let’s talk about how Emacs handles regular expression syntax in search and/or replace commands. Whenever using an Emacs command involving a regular expression (regexp), you will need to understand what kind of regexp syntax is expected. There are largely two to know:

  • Emacs
  • grep (implementation dependent)

Commands using grep-style regexps do so because they invoke the local install of the grep utility. The grep regex syntax is implementation dependent. If you use GNU grep, you can read its syntax here, which share some character classes with Emacs.

The Casual RE-Builder package is a great way to work with Emacs regexps as it provides a command to escape the regexp properly for interactive input. re-builder alone only provides a regexp that can be used in Elisp code.

Bulk Search & Replace Commands

The table below shows the different search and/or replace workflows and their associated commands.

Workflows Command Regexp Type Notes
Search regexp in files in directory rgrep grep AKA “Find in Files.” Results can be edited using writeable grep (wgrep).
Search regexp in files in project project-find-regexp grep
Search regexp in files in directory and present in Dired find-grep-dired grep
Search regexp in tagged files tags-search Emacs
Search file names matching shell pattern in directory and present in Dired find-name-dired shell
Search file names matching regexp in directory and present in Dired find-lisp-find-dired Emacs Implementation uses Emacs regexp type.
Search file names matching regexp in current directory and present in Dired casual-dired-find-dired-regexp Emacs Wrapper around find-lisp-find-dired using current directory. Available via Casual.
Query replace regexp in project files project-query-replace-regexp Emacs
Incremental search marked files with plain text dired-do-isearch For use in Dired.
Incremental search marked files with regexp dired-do-isearch-regexp Emacs For use in Dired.
Query replace regexp in marked files dired-do-query-replace-regexp Emacs For use in Dired.
Search regexp in marked files dired-do-find-regexp grep For use in Dired.
Search regexp in marked files and display first match dired-do-search Emacs For use in Dired.
Replace regexp in marked files dired-do-find-regexp-and-replace grep For use in Dired.
Incremental search marked buffers with plain text ibuffer-do-isearch For use in IBuffer.
Incremental search marked buffers with plain text with regexp ibuffer-do-isearch-regexp Emacs For use in IBuffer.
View lines which match regexp in marked buffers ibuffer-do-occur Emacs For use in IBuffer.
Query replace plain text in marked buffers ibuffer-do-query-replace For use in IBuffer.
Query replace regexp in marked buffers ibuffer-do-query-replace-regexp Emacs For use in IBuffer.
Run git grep, searching for regexp in directory. vc-git-grep grep
Replace all references to identifier. xref-find-references-and-replace
Interactively replace identifier in current xref buffer. xref-query-replace-in-results
Rename symbol at point for project. eglot-rename Requires Eglot support.

Choice of command depends on the quantity and specificity of files or buffers to work on. Both Dired and IBuffer marking allow for specific selection of files or buffers respectively.

Many of the commands in the table above are discoverable via menu using the Casual and Anju packages. Hierarchical menu categorization aids in the discovery and recognition of these commands, making them more usable.

Command UI Notes
rgrep (C-o) casual-editkit-main-tmenu › (/) Search/Replace › (g) Find in Files… Available via Casual EditKit.
rgrep (Menu-bar) Edit › Search › Search in Files… Available via Anju.
project-find-regexp (Menu-bar) Edit › Search › Search in Project Files…
tags-search (Menu-bar) Edit › Search › Search Tagged Files…
project-query-replace-regexp (Menu-bar) Edit › Replace › Replace in Project Files…
find-name-dired (C-o) casual-editkit-main-tmenu › (/) Search/Replace › (d) Files… Available via Casual EditKit.
find-grep-dired (C-o) casual-editkit-main-tmenu › (/) Search/Replace › (G) Files containing text… Available via Casual EditKit.
casual-dired-find-dired-regexp (C-o) casual-dired-tmenu › (f) Filter by name… Available via Casual Dired.
dired-do-isearch (C-o) casual-dired-tmenu › (/) Search/Replace › (C-s) I-search… Available via Casual Dired.
dired-do-isearch-regexp (C-o) casual-dired-tmenu › (/) Search/Replace › (M-s) I-search regexp… Available via Casual Dired.
dired-do-query-replace-regexp (C-o) casual-dired-tmenu › (/) Search/Replace › (r) Query regexp and replace… Available via Casual Dired.
dired-do-find-regexp (C-o) casual-dired-tmenu › (/) Search/Replace › (g) Find regex… Available via Casual Dired.
dired-do-search (C-o) casual-dired-tmenu › (/) Search/Replace › (s) Search first regexp match… Available via Casual Dired.
dired-do-find-regexp-and-replace (C-o) casual-dired-tmenu › (/) Search/Replace › (G) Find regex and replace… Available via Casual Dired.
ibuffer-do-isearch (C-o) casual-ibuffer-tmenu › (C-s) I-Search… Available via Casual IBuffer.
ibuffer-do-isearch-regexp (C-o) casual-ibuffer-tmenu › (C-M-s) I-Search Regexp… Available via Casual IBuffer.
ibuffer-do-occur (C-o) casual-ibuffer-tmenu › (O) Occur… Available via Casual IBuffer.
ibuffer-do-query-replace (C-o) casual-ibuffer-tmenu › (M-r) Query Replace… Available via Casual IBuffer.
ibuffer-do-query-replace-regexp (C-o) casual-ibuffer-tmenu › (C-M-r) Query Replace Regexp… Available via Casual IBuffer.
vc-git-grep (Menu-bar) Tools › Version Control > Git grep…

Refactoring Guidance

The replace commands can do catastrophic damage if not used with caution. Treat them like power tools.

Some guidance before using replace commands:

  1. Have a backup plan in case you need to recover anything.

  2. Use re-builder to help figure out the right regexp.

  3. Know the scope of what you want to change (directory, files, buffers).

  4. Some commands will only modify the buffer of an affected file. Check if modified buffers are saved. You can use IBuffer to identify and save such buffers. It is left as an exercise to the reader to determine which commands exhibit this behavior.

Closing Thoughts

The inventory of commands above are from what I know of Emacs, which is guaranteed to not be comprehensive. If there are others missing from this list, please let me know at kickingvegas@gmail.com.

While many of these commands have been in Emacs for years (decades even), they were not usable to me until I built a UI for them. I think motivated readers using Casual and Anju for bulk search and/or replace tasks will find a similar sentiment.


Amended 2026-04-30: Added vc-git-grep, eglot-rename, xref-find-references-and-replace, and xref-query-replace-in-results. Thanks to Henry Leach and Gene Pasquet for their input!

emacs

Past Articles

24
APR
2026

Some nice to know keybindings when using the mouse in Emacs

Some keybindings to know whenever you’re working with a mouse in Emacs.

read more
23
APR
2026

Call for Testing: Scrim v1.1.3 TestFlight on pre-release Emacs 31

Looking for folks who want to test a new pre-release build of Scrim v1.1.3 which fixes it for Emacs 31.

read more
8
APR
2026

Computing Days Until with Emacs

Countdown clocks are always useful. Here’s one for computing days until in Emacs.

read more
7
APR
2026

Calming Mouse Interaction in Dired

Single click to open a file in Dired is too twitchy. This post shows how to change it.

read more
30
MAR
2026

Announcing Anju

Announcing Anju, a project to align mouse interactions in Emacs with contemporary (circa 2026) expectations. Now available on MELPA.

read more
3
MAR
2026

Casual now available on NonGNU ELPA

Casual is now available on NonGNU ELPA.

read more
19
FEB
2026

Announcing Casual Org

At long last, announcing Casual support for Org Mode.

read more
10
FEB
2026

Deburring Emacs Imenu GUI Configuration

A bit of tuning to get Imenu GUI configuration working with any derived mode from prog-mode.

read more
7
FEB
2026

Using Casual to work with Emacs Registers, Rectangles, and Windows

Use Casual to effectively use Emacs registers, rectangles, and windows on the regular.

read more

Page 1 / 18   >

 

AboutMastodonBlueskyGitHub

Feeds & Tags
Get Scrim for macOSGet Captee for macOS

Powered by Pelican