← back to latest

Insert the same text at the start of many lines at once

V-BLOCK<C-v>jjIInsert the same text at the start of many lines at once

anatomy

<C-v>
Enter blockwise visual mode. The selection becomes a rectangle of columns instead of a run of characters.
jj
Extend the block down two lines. Any motion works here: 5j, }, G, or a search.
I
Insert at the left edge of the block. You type on the top line only.
<Esc>
Leave insert mode. Vim now replays what you typed on every other line in the block.

In the buffer

Before, with the cursor on the i of if:

def main():
    if len(sys.argv) < 2:
    ^
        print("Usage: script.py <directory>")
        sys.exit(1)
    processor = FileProcessor(sys.argv[1])

After typing <C-v>jj, then I, then # , then <Esc>:

def main():
    # if len(sys.argv) < 2:
    ^
    #     print("Usage: script.py <directory>")
    #     sys.exit(1)
    processor = FileProcessor(sys.argv[1])

Three lines commented out, two characters typed. The cursor lands back on the first character you inserted.

When you would reach for it

You need the same prefix on a run of lines. Comment markers on a block of code you are bisecting, a > in front of quoted mail, a leading dash to turn plain lines into a list, an indent that >> cannot give you because the file uses tabs and you want spaces. The usual answer is a substitute with a line range, which means composing a pattern and counting line numbers. Blockwise insert skips all of that: you select the shape you want, type once, and let vim replay the keystrokes down the column.

Gotchas

  • Nothing appears on the other lines until you press <Esc>. This is the single most common reason people decide block insert is broken. You type # , see it land on one line, and bail out. Finish the insert and the rest fills in.
  • Pressing <Enter> during the insert cancels the replay. Vim splits the first line and leaves every other line untouched. Block insert wants a single line of text, so if you need a newline, do it in a second pass.
  • Lines shorter than the block’s left edge are skipped entirely. Select a column at character 7 across a line that is only two characters long and that line gets nothing. Vim does not pad it with spaces.
  • I here is not normal mode’s I. Normal mode’s I goes to the first non-blank character; block mode’s I goes to the left edge of the block, wherever you put it. Start the block on the first non-blank of the top line and the insert follows the existing indentation, which is usually what you want for code.

Variants

Append past ragged line ends ($A): Plain A appends at the block’s right edge, which cuts through longer lines. Adding $ before A extends the block to the end of every line, however long each one is.

Before:              After <C-v>2j$A; and <Esc>:
alpha                alpha;
beta gamma           beta gamma;
delta                delta;

Useful for adding trailing semicolons or commas to a set of lines with no common length.

Change a column instead of inserting (c): Select a rectangle and press c to delete it on every line and type the replacement once.

Before:              After <C-v>2j3lcAPP_ and <Esc>:
user_alpha = 1       APP__alpha = 1
user_beta = 2        APP__beta = 2
user_gamma = 3       APP__gamma = 3

3l widens the block to cover user, and every line gets the new prefix.

Repeat the block elsewhere (.): After a block insert, . replays it over a block of the same height starting at the cursor. Move to the top of the next run of lines and press one key. This is the same dot command from entry 008, and it remembers the shape of the block, not only the text you typed.

lineage

Original vi had no visual mode. Column work meant describing a range to an ex command and hoping the pattern matched. Vim added Visual mode in version 4.0 (1996), and blockwise selection with CTRL-V came with it. That is why none of this works in POSIX vi.

-- INSERT --vim-hacks.com017-017-insert-on-many-lines-at-once.html
utf-81,1All