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

How do I use a counter variable inside a Vim macro?

Answer

:let i=1 then use <C-r>=i<CR> in macro

Explanation

By combining a Vimscript variable with the expression register inside a macro, you can create a counter that increments on each replay. This is the standard technique for generating numbered lists, IDs, or sequential data.

How it works

  1. Initialize the counter: :let i=1
  2. Record a macro that uses and increments it:
:let i=1
qq I<C-r>=i<CR>. <Esc>:let i+=1<CR>jq
  1. Replay on multiple lines: 10@q

Step-by-step breakdown

:let i=1              " Set counter to 1
qq                    " Start recording into q
I                     " Insert at beginning of line
<C-r>=i<CR>           " Insert value of i (expression register)
. <Esc>               " Type ". " and return to normal mode
:let i+=1<CR>         " Increment counter
j                     " Move to next line
q                     " Stop recording

Example

Before (5 lines, cursor on first):

Apple
Banana
Cherry
Date
Elderberry

After :let i=1 then qq I<C-r>=i<CR>. <Esc>:let i+=1<CR>jq then 4@q:

1. Apple
2. Banana
3. Cherry
4. Date
5. Elderberry

Variations

" Start from a different number
:let i=100

" Use padding (001, 002, ...)
<C-r>=printf('%03d', i)<CR>

" Step by custom increment
:let i+=5    " Instead of i+=1

" Use letters instead of numbers
:let i=65 | <C-r>=nr2char(i)<CR>

Tips

  • Always initialize the variable before replaying the macro
  • <C-r>=i<CR> must be typed while recording in insert mode
  • The :let i+=1<CR> command inside the macro is an Ex command — it won't appear in the buffer
  • For simple sequential numbering, g<C-a> in visual mode is easier (see sequential-increment-visual)

Next

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