← back to latest

Turn a column of zeros into a numbered list

VISUALV4jg<C-a>Turn a column of zeros into a numbered list

anatomy

V
Start linewise visual mode on the first line you want numbered.
4j
Extend the selection down four more lines, five lines in total. Any motion works: ip, }, G, or a search.
g
Prefix that turns the plain increment into a progressive one. Without it, every line gets the same bump.
<C-a>
Add to the first number on each selected line. With the g prefix, line one gets +1, line two +2, line three +3, and so on down the selection.

In the buffer

Before, cursor on the first 0:

steps:
  0. clone the repo
  0. install dependencies
  0. copy .env.example to .env
  0. run the migrations
  0. start the dev server
  ^

After typing V4jg<C-a>:

steps:
  1. clone the repo
  ^
  2. install dependencies
  3. copy .env.example to .env
  4. run the migrations
  5. start the dev server

Each line gets its position in the selection added to its first number. The cursor returns to the start of the first selected line.

When you would reach for it

You wrote a list of steps, pasted a block of near-identical lines, or duplicated a config entry five times with yy5p, and now every copy carries the same number. Renumbering by hand means visiting each line and doing arithmetic in your head, and inserting a new step in the middle means doing it all again. Type a placeholder 0 on every line, select them, and let g<C-a> count for you.

Gotchas

  • Leading zeros can trigger octal. With nrformats containing octal (the default under vim -u NONE and in old Vim configs), 007 incremented by 1 becomes 010, because 7 + 1 in base 8 is 10. Vim 9’s defaults.vim and Neovim both drop octal, so 007 becomes 008. Run :set nrformats-=octal if you see this.
  • Only the first number on each line changes. On a line like a 1 b 1, linewise selection bumps the first 1. To target a later column, use a blockwise selection (<C-v>) that starts on the number you want, and the increment searches from the left edge of the block.
  • Lines with no number are skipped and do not count. A blank line or a heading inside the selection does not consume a step, so 0, blank, 0, 0 becomes 1, blank, 2, 3.
  • A minus sign counts as part of the number when it is preceded by a space or the start of the line. -1 on every line becomes 0, 1, 2, which is correct arithmetic but surprises you if the dash was meant as a bullet.

Variants

10g<C-a>

A count sets the step size. On three lines of item1, this produces item11, item21, item31: each line gets 10 more than the one above.

gvg<C-a>

gv reselects the last visual area, so you can apply the progression again. Each run adds 1, 2, 3… on top of the current values, turning 1 2 3 into 2 4 6.

g<C-x>

The decrementing twin. Three lines of 5 become 4, 3, 2. Plain <C-a> or <C-x> without the g adds or subtracts the same amount on every selected line.

lineage

Ctrl-a has incremented the number under the cursor since early Vim, but in visual mode it did nothing useful until patch 7.4.754 in June 2015. That patch, contributed by Christian Brabandt, taught Ctrl-a and Ctrl-x to work on every line of a selection and added the g-prefixed progressive form at the same time. Neovim inherited it from the Vim codebase.

-- INSERT --vim-hacks.com025-025-turn-zeros-into-a-numbered-list.html
utf-81,1All