Vim registers are how Vim stores text that you yank, delete, or put.

Let’s see this in action. Open Vim, then type:

ihello world<Esc>

Now, yank that line by pressing yy. If you immediately press "p, you’ll paste "hello world". That’s the default register, register 0. Vim automatically stores the most recent yank in register 0.

Now, delete the line by pressing dd. If you press "p again, you’ll paste "hello world". That’s because dd (like yy) also uses a register. By default, deletions and yanks use the unnamed register, which is register 1. So, the last yank went into 0 and the last delete went into 1.

Vim has a bunch of registers. The most common ones are:

  • Unnamed Register ("): This is where the most recent yank, delete, or change goes by default. If you just y or d, it goes here.
  • Numbered Registers (1 to 9): These store recent deletions. Register 1 holds the most recent deletion, 2 the one before that, and so on, up to 9.
  • Lowercase Named Registers (a to z): You can explicitly choose to yank or delete into these. For example, "aywill yank into registera. Then, "apwill put the contents of registera`. This is super useful for storing multiple pieces of text.
  • Uppercase Named Registers (A to Z): These append to the corresponding lowercase named register. So, "Ay will yank text and append it to whatever is already in register a.
  • Clipboard Registers (+ and *): These interact with your system’s clipboard. "+y yanks to the system clipboard, and "+p pastes from it. On X11 systems, * often refers to the primary selection (what you highlight with the mouse), while + is the actual clipboard.
  • Special Registers:
    • %: The name of the current file.
    • #: The name of the alternate file.
    • .: The last text that was inserted.
    • :: The last Ex command executed.
    • /: The last search pattern.
    • ?: The last search pattern (backward).

Let’s try named registers. Imagine you have some text you want to keep aside.

iThis is important text.<Esc>
"ayiw  " <- yank "important" into register 'a'

Now, if you were to delete something else, say dd, it would go into the unnamed register. But to get "important" back, you’d type "ap.

The uppercase registers are for accumulation. Let’s say you want to collect several lines into one register.

iLine 1<Esc>
"ay   " <- yank Line 1 into register 'a'
iLine 2<Esc>
"Ay   " <- append Line 2 to register 'a'
iLine 3<Esc>
"Ay   " <- append Line 3 to register 'a'

Now, if you type "ap, you’ll paste:

Line 1
Line 2
Line 3

The power of registers becomes apparent when you combine them with macros. You can yank multiple snippets into different registers, then use "ap, "bp, etc., to reconstruct complex text structures. Or, you can use a register to store a command you want to repeat. For example, to store the last search pattern into register q: qq:let @q = expand("<cfile>")<CR>. Then, you can use :@"q" to execute that command.

You can view the contents of registers in Vim by typing :reg. This will show you a list of all registers and their contents, which is invaluable for debugging what’s where.

The most surprising thing about Vim registers is how they are used implicitly by many commands, leading users to believe there’s only one or two "active" registers when in reality, there are many, and their contents are overwritten or appended to based on the command’s nature and any explicit register specified. This implicit behavior is efficient but can be a source of confusion until you understand which register each operation targets by default.

Once you’ve mastered registers, you’ll start thinking about how to use them to build sophisticated text manipulation workflows, often involving macros and external tools.

Want structured learning?

Take the full Vim course →