Vim Visual Block Mode: Editing Columns Instead of Lines
Vim's Ctrl-V block mode edits a column across many lines at once. A worked prefix example, how I, A and r differ, and where tabs and wrapped lines break the rectangle.
09 Jun 2026, 00:00 UTC

The problem: one column, many lines
Some edits are vertical. You have a list of hostnames and want to prefix each one with - to make a Markdown list, add a trailing comma to every line of a data file, or replace the first character of twenty lines with #. Done line by line, that is twenty operations. Vim's visual block mode does it in one, and it is built in — no plugin and no macro recording.
The catch is that block mode has its own small vocabulary. I, A, r and c do not behave like their character-wise counterparts, and tabs and wrapped lines can make the highlighted rectangle lie about what is about to change.
What Ctrl-V actually selects
Vim has three visual modes. v selects character-wise (a run of text), V selects line-wise (whole lines), and Ctrl-V selects block-wise: a rectangle defined by two corners in buffer columns and lines.
Press Ctrl-V, then move the cursor with any motion — j/k, w, 3j, $, or a search. The highlighted region is the block. From there d deletes it, c changes it, y yanks it, r replaces every character in it with one character you type, and >/< shift it.
Two notes before the example. On Windows console Vim, Ctrl-V is often bound to paste, so block selection is Ctrl-Q. And gv reselects the previous visual region, including a block, which is handy when you want to repeat the same edit somewhere else.
Worked example: prefixing a column
Start with a file hosts.txt in the current directory:
alpha
bravo
charlie
delta
Run vim hosts.txt in a terminal. No elevated permissions are needed; you are editing a file you own. Then, in normal mode:
gg0— go to line 1, column 1.Ctrl-V— start a block selection.3j— extend the block down four lines. The block is one column wide at column 1.Shift-I(capitalI) — Vim enters insert mode at the left edge of the block.- Type
-. Esc— Vim applies the insertion to every line the block spans.
The buffer becomes:
- alpha
- bravo
- charlie
- delta
The insertion is applied when you leave insert mode, not as you type. If the result is wrong, u undoes the whole block change in a single step.
I, A and r are not interchangeable
| Key | Effect in block mode |
|---|---|
I | Insert at the left edge of the block, on every spanned line. |
A | Append at the right edge of the block. On lines shorter than that column, Vim pads with spaces to reach it. |
r | Replace every character inside the block with a single typed character. A one-column block replaces one character per line. |
c | Delete the block and enter insert mode; the typed text replaces the block on each line. |
The padding behaviour of A is the one to watch: appending to a rectangular block over ragged lines can leave trailing whitespace. If you want to append at the true end of each line instead, make the block ragged first — Ctrl-V, then $, then A — so the right edge follows each line's own end. Try both on a scratch buffer before using them on real data, because the result depends on where the block's right edge lands.
Where block mode breaks down
Wrapped lines. Block selection works in buffer columns, not screen columns. With wrap on, a long line drawn across several screen rows still counts as one buffer line, so the rectangle you see does not match what changes. :set nowrap while you work avoids the confusion.
Tabs. A tab is one buffer column but several screen columns wide. A block that looks aligned over tab-indented text will not be aligned in the buffer. :set list shows tabs as ^I so you can see the real column positions.
Overshooting. 3j when you meant 2j silently includes an extra line, and the change applies there too. u is the fix, but check the block's extent before typing — with showcmd enabled (the default), the status line reports the selection size.
Blockwise paste. Yanking a block with "vy and putting it with "bp inserts it as a column. How it treats destination lines shorter than the block is worth testing on a copy rather than assuming.
Checking it works
Vim ships its own documentation, so no network access is required. In Vim, run :help visual.txt to open the visual-mode documentation, then :help v_b_I, :help v_b_A and :help v_b_r for the individual operators. The blockwise operator tags all start with v_b_.
The behaviour described here is stable across Vim 7.x, 8.x and 9.x, and Neovim implements the same block mode. Very old vi implementations may lack some of these extensions, so if Ctrl-V does nothing useful, check :version before assuming you made a mistake.
To verify on your own build: open a scratch file with lines of differing lengths, select a block with Ctrl-V, and run Shift-I with a short string. If the string lands on every spanned line at the same column, block insert is working as described. Then try A over the same ragged lines and look for added spaces at the end of the short ones.
The practical takeaway: learn Ctrl-V plus Shift-I first. It covers the most common vertical edit — prefixing or commenting a run of lines — and once that is automatic, A, r and c follow naturally.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.