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

How do I split a complex Vim macro into reusable subroutines?

Answer

Record worker macro in @b, call it from @a with @b

Explanation

Complex macros are hard to debug and maintain when crammed into a single register. By splitting work into a worker macro and a driver macro, you can test each part independently, reuse the worker across different contexts, and modify behavior without re-recording everything from scratch.

How it works

  • Record the core transformation in one register (e.g., @b) — this is the "worker"
  • Record the orchestration logic in a second register (e.g., @a) — this calls @b and handles positioning/looping
  • Inside macro @a, type @b to invoke the worker at the right moment
  • Any register can call any other register with @{register}

Example

Suppose you want to wrap each CSV field on a line in quotes. First record the worker in @b — it quotes one word:

qb f, a"<Esc>F,i"<Esc>q

Then record the driver in @a — it runs @b repeatedly across the line:

qa 0@b 3@b j q

Now @a processes one full line. Run 10@a to process 10 lines.

Tips

  • Test @b alone on a single item before building @a around it
  • Changing @b (via :let @b = ...) affects all callers immediately
  • Worker macros pair well with :normal @b across a range — run the worker on every line matching a pattern: :g/pattern/normal @b
  • You can chain three or more registers: @a calls @b which calls @c
  • Keep worker macros short and single-purpose; put loop control exclusively in the driver

Next

How do I use a Vimscript expression to compute the replacement text in a substitution?