Continuing my Prelude modernization effort (see the previous post for context), another long-standing third-party dependency I was happy to drop was anzu.

The Problem

When you’re searching with C-s in Emacs, you can see the current match highlighted, but you have no idea how many total matches exist in the buffer or which one you’re currently on. Are there 3 matches or 300? You just don’t know.

The Old Way

For years, I used the anzu package (an Emacs port of anzu.vim) to display match counts in the mode-line. It worked well, but it was yet another third-party dependency to maintain – and one that eventually ended up in the Emacs orphanage, which is never a great sign for long-term maintenance.

The New Way

Emacs 27 introduced isearch-lazy-count:

(setopt isearch-lazy-count t)

With this enabled, your search prompt shows something like (3/47) – meaning you’re on the 3rd match out of 47 total. Simple, built-in, and requires no external packages.

Unlike anzu, which showed counts in the mode-line, isearch-lazy-count displays them right in the minibuffer alongside the search string, which is arguably a better location since your eyes are already there while searching.

Customizing the Format

Two variables control how the count is displayed:

;; Prefix format (default: "%s/%s ")
;; Shows before the search string in the minibuffer
(setopt lazy-count-prefix-format "(%s/%s) ")

;; Suffix format (default: nil)
;; Shows after the search string
(setopt lazy-count-suffix-format nil)

If you prefer the count at the end of the prompt (closer to how anzu felt), you can swap them:

(setopt lazy-count-prefix-format nil)
(setopt lazy-count-suffix-format " [%s/%s]")

Good to Know

The count works with all isearch variants – regular search, regex search (C-M-s), and word search. It also shows counts during query-replace (M-%) and query-replace-regexp (C-M-%), which is very handy for knowing how many replacements you’re about to make.

The counting is “lazy” in the sense that it piggybacks on the lazy highlighting mechanism (lazy-highlight-mode), so it doesn’t add significant overhead. In very large buffers, you might notice a brief delay before the count appears, controlled by lazy-highlight-initial-delay. One thing to keep in mind – if you’ve disabled lazy highlighting for performance reasons, you’ll need to re-enable it, as the count depends on it.

If you haven’t read it already, check out my earlier article You Have No Idea How Powerful Isearch Is for a deep dive into what isearch can do. isearch-lazy-count pairs nicely with all the features covered there.

Between use-short-answers and isearch-lazy-count, that’s two third-party packages I was able to drop from Prelude just by using built-in functionality. Keep hacking!