Skip to main content

Vim Productivity: Registers, Macros, and Shortcuts

·1195 words·6 mins
Linux Learning Lab
Author
Linux Learning Lab
Writing about code, tools, and workflows.
vim-essentials - This article is part of a series.
Part 6: This Article

Registers
#

Registers are Vim’s storage slots. Every yank, delete, and change goes into a register. Understanding them means you never lose text you’ve cut and gives you access to multiple “clipboards.”

Viewing registers
#

:registers
" or shorthand
:reg

Types of registers
#

RegisterNamePurpose
""UnnamedDefault — last delete, change, or yank
"0YankLast yank only (not affected by deletes)
"1"9NumberedHistory of deletes (1 = most recent)
"a"zNamedYour own storage (you explicitly choose these)
"+System clipboardCopy/paste with other applications
"*Selection clipboardX11 primary selection (middle-click paste)
"_Black holeDelete without affecting any register
"/SearchLast search pattern
".Last insertText from last Insert mode session
"%FilenameCurrent file name
":CommandLast command-line command

Using named registers
#

Prefix any yank or delete with "x to target register x:

"ayy      Yank current line into register a
"bdiw     Delete word into register b
"ap       Paste from register a
"bp       Paste from register b

This gives you multiple independent clipboards.

The yank register ("0)
#

The key insight: deletes go into "" and "1, but yanks also go into "0.

So if you yank something, then delete text, your yanked content is safe in "0:

yiw       Yank a word
dw        Delete another word (overwrites unnamed register)
"0p       Paste the original yanked word (still in register 0)

System clipboard
#

"+y       Yank to system clipboard
"+p       Paste from system clipboard

Or with set clipboard=unnamedplus in your .vimrc, regular y and p use the system clipboard.

The black hole register
#

Delete text without saving it anywhere:

"_dd      Delete line, don't touch registers
"_diw     Delete word, don't touch registers

Useful when you want to delete something without overwriting what you previously yanked.

Appending to registers
#

Use an uppercase letter to append instead of overwrite:

"ayy      Yank line into register a
           ...move somewhere else...
"Ayy      Append this line to register a
"ap       Paste both lines

Paste in Insert mode
#

Ctrl-r a       Paste register a while in Insert mode
Ctrl-r "       Paste unnamed register in Insert mode
Ctrl-r +       Paste system clipboard in Insert mode
Ctrl-r /       Paste last search pattern in Insert mode

Macros
#

Macros record a sequence of keystrokes and replay them. They’re the fastest way to automate repetitive edits.

Recording a macro
#

qa        Start recording into register a
           ...perform your edits...
q         Stop recording

Playing a macro
#

@a        Play macro in register a
@@        Replay last played macro
5@a       Play macro a five times

Macro workflow
#

The key to a good macro: make it repeatable. End the macro positioned for the next repetition.

Example — add quotes around the first word on each line:

qa        Start recording into register a
0         Go to beginning of line
wi"       Go to end of word, insert a quote
Esc       Back to Normal mode
bi"       Go to beginning of word, insert a quote
Esc       Back to Normal mode
j         Move to next line
q         Stop recording

5@a       Run on the next 5 lines

Running macros on visual selections
#

Select lines with V, then:

:'<,'>normal @a

This applies macro a to each selected line.

Running macros across all lines matching a pattern
#

:g/pattern/normal @a

Editing a macro
#

Macros are just registers. To edit one:

" Paste register a into the buffer
"ap

" Edit the keystrokes as text

" Yank it back into register a
0"ay$

" Delete the pasted line
dd

Recursive macros
#

A macro can call itself for unlimited repetition:

qa        Start recording
           ...your edits...
j         Move to next line
@a        Call itself
q         Stop recording
@a        Start it (runs until it hits an error or end of file)

The macro stops when any command fails (like j at the last line).

The Dot Command Revisited
#

The . command repeats your last change. It’s simpler than macros for one-off repetition:

ciw replacement Esc     Change a word
n                       Jump to next search match
.                       Repeat the change
n                       Next match
.                       Repeat again

When to use dot vs macros
#

ScenarioUse
Same edit, scattered locations. with manual navigation
Same edit, sequential linesMacro with j at the end
Complex multi-step edit, repeatedMacro
Simple single change, repeated.

Visual Block Mode
#

Ctrl-v enters visual block mode for column-wise selection.

Insert text on multiple lines
#

Ctrl-v    Enter block mode
jjj       Select 4 lines
I         Insert before block
//        Type the text
Esc       Apply to all selected lines

Append text on multiple lines
#

Ctrl-v    Enter block mode
jjj       Select lines
$         Extend to end of each line
A         Append after block
;         Type the text
Esc       Apply to all lines

Delete a column
#

Ctrl-v    Enter block mode
jjj       Select rows
ll        Extend selection right
d         Delete the block

Replace a column
#

Ctrl-v    Enter block mode
jjj       Select rows
lll       Select column width
c         Change block
newtext   Type replacement
Esc       Apply to all rows

Power Commands
#

Shell commands
#

:!ls              " Run a shell command
:r !date          " Insert command output into buffer
:r !curl -s url   " Insert curl output
:w !bash          " Send buffer contents to bash
:%!sort           " Sort the entire file in place
:%!jq .           " Format JSON through jq
:'<,'>!sort       " Sort selected lines

The expression register
#

Ctrl-r =          In Insert mode, evaluate an expression
                  Type: 2+2 Enter → inserts "4"
                  Type: system('date') Enter → inserts current date

Other useful commands
#

CommandAction
JJoin current line with next (adds space)
gJJoin without adding space
~Toggle case of character
g~iwToggle case of word
gUiwUppercase word
guiwLowercase word
Ctrl-aIncrement number under cursor
Ctrl-xDecrement number under cursor
gaShow ASCII value of character
gfOpen file path under cursor
gxOpen URL under cursor

Practical Examples
#

Add a prefix to multiple lines
#

Ctrl-v    Block select
4j        Select 5 lines
I         Insert mode
- [ ]     Type the prefix
Esc       Apply

Record a macro to format CSV as markdown table
#

qa
0                    Go to start of line
:s/,/ | /g Enter    Replace commas with pipes
I| Esc              Add leading pipe
A |Esc              Add trailing pipe
j                   Move to next line
q                   Stop recording
10@a                Apply to next 10 lines

Increment a sequence of numbers
#

# Start with:
item1
item1
item1

# Select lines 2-3 with visual block on the number
Ctrl-v jj
g Ctrl-a           Increment as a sequence → item1, item2, item3

Delete every other line
#

:g/pattern/normal dd

Or with a macro:

qa jdd q       Record: skip a line, delete next
100@a          Run 100 times

Best Practices
#

  • Use the yank register ("0) when you need to paste something after deleting other text
  • Use named registers ("a"z) when juggling multiple pieces of text
  • End macros with a movement to the next target so they chain cleanly
  • Test macros on one line first before running them with a count
  • Prefer the dot command over macros for simple, one-step edits
  • Use visual block mode for column operations instead of writing complex macros
  • Use :g/pattern/normal @a to apply macros selectively instead of blindly across the whole file
vim-essentials - This article is part of a series.
Part 6: This Article