vimtricks.wiki Concise Vim tricks, one at a time.

How do I make a macro that finds and operates on specific patterns?

Answer

qq /pattern<CR> {commands} q

Explanation

By incorporating a search command inside a macro, you can make it jump to the next occurrence of a pattern before performing its edits. This makes macros far more robust than relying on fixed cursor movements.

How it works

  1. Start recording: qq
  2. Search for the target: /pattern<CR>
  3. Perform the edit at the match
  4. Stop recording: q
  5. Replay: @q or 100@q (stops when search finds no more matches)

Example: Wrap all function calls in try-catch

qq                          " Start recording
/\<fetch(\><CR>             " Search for fetch(
ciwtry { await fetch(<Esc>  " Change and wrap
f)a) } catch(e) {}<Esc>     " Complete the wrapper
q                           " Stop recording
100@q                       " Apply to all remaining matches

Why search-based macros are superior

  • Position-independent: The macro finds its target regardless of where it is
  • Self-terminating: When 100@q hits a search that fails (no more matches), the macro stops automatically
  • Pattern-precise: You operate on exactly what you want, not just whatever happens to be at the cursor

Another example: Add type annotations

qq /\vlet (\w+) =<CR>       " Find 'let x =' declarations
ea: string<Esc>              " Append ': string' after the variable name
q
50@q                         " Apply to next 50 matches

Tips

  • Use n inside a macro instead of /pattern<CR> to repeat the last search
  • The macro auto-aborts when the search fails — this is a feature, not a bug
  • Combine with :g/pattern/normal @q for guaranteed execution on every match
  • Test the search pattern with /pattern first before recording the macro

Next

How do I run the same command across all windows, buffers, or tabs?