---
title: "Vim"
description: "Vim is a highly configurable text editor built to make creating and changing any kind of text very efficient. It is included as \"vi\" with most UNIX systems."
author: "Mohammad Abu Mattar"
canonical: https://mkabumattar.com/cheatsheets/vim
---

# Vim

Vim is a highly configurable text editor built to make creating and changing any kind of text very efficient. It is included as "vi" with most UNIX systems.

Browse the sections below to explore Vim commands, shortcuts, and examples.

## Getting Started

Fundamental Vim concepts including modes, exiting, and opening files.

### Modes

Vim operates in several modes. Understanding modes is key to using Vim effectively.

**Keywords:** mode, normal, insert, visual, command, escape

#### Entering Insert mode

```vim
i    " Insert before cursor
a    " Insert after cursor
o    " Open new line below and enter Insert mode
O    " Open new line above and enter Insert mode
I    " Insert at beginning of line
A    " Insert at end of line
```

These keys transition from Normal mode to Insert mode at various cursor positions.

- Press Esc at any time to return to Normal mode.
- i and a are the most commonly used: i inserts before cursor, a inserts after.

#### Entering Visual mode

```vim
v      " Character-wise Visual mode
V      " Line-wise Visual mode
Ctrl-V " Block-wise Visual mode
```

Visual mode lets you select text for operations like copy, delete, or indent.

- Use V to select entire lines quickly.
- Ctrl-V is powerful for column editing.

#### Entering Command-line mode

```vim
:    " Enter Command-line mode
/    " Enter search forward
?    " Enter search backward
```

Command-line mode allows you to execute Ex commands, search, and filter text.

- Press Esc or Ctrl-C to cancel and return to Normal mode.
- Use Tab for command completion in Command-line mode.

**Best practices:**

- Always return to Normal mode (Esc) before executing motion or operator commands.
- Learn to think in terms of mode transitions rather than just key presses.
- Use the mode indicator at the bottom of the screen to confirm your current mode.

**Common errors:**

- **Typing text in Normal mode instead of Insert mode**: Press i to enter Insert mode before typing text.
- **Forgetting to leave Insert mode before issuing commands**: Press Esc to return to Normal mode, then issue the command.

**Advanced notes:**

- **Replace Mode:** Press R to enter Replace mode, which overwrites characters as you type.
- **Select Mode:** Press gh to enter Select mode, similar to selection in other editors.

### Exiting

How to save files and exit Vim.

**Keywords:** quit, save, exit, write, close

#### Save and quit

```vim
:w     " Save (write) the file
:q     " Quit (fails if unsaved changes)
:wq    " Save and quit
:x     " Save and quit (only writes if changes exist)
ZZ     " Save and quit (Normal mode shortcut)
```

These commands write the buffer to disk and/or close Vim.

- :x and ZZ only write if the buffer has been modified, preserving file timestamps.
- :wq always writes, even if no changes were made.

#### Quit without saving

```vim
:q!    " Quit without saving (force quit)
ZQ     " Quit without saving (Normal mode shortcut)
:qa!   " Quit all windows without saving
```

Force-quit commands discard unsaved changes. Use with caution.

- The ! modifier forces the operation, bypassing safety checks.
- :qa! is useful when you have multiple buffers/windows open.

#### Save all and quit

```vim
:wa    " Save all modified buffers
:wqa   " Save all buffers and quit
:xa    " Save all modified buffers and quit
```

Multi-buffer save and quit commands for working with several files at once.

- :wa saves all buffers but keeps Vim open.
- :wqa and :xa close Vim after saving everything.

**Best practices:**

- Use :x or ZZ instead of :wq to avoid unnecessary writes.
- Save frequently with :w to avoid losing work.
- Use :wa before running external build commands.

**Common errors:**

- **E37: No write since last change**: Use :w to save first, or :q! to discard changes.
- **E45: 'readonly' option is set**: Use :w! to force write, or :w newfilename to save elsewhere.

### Opening Files

Different ways to open files in Vim from the command line.

**Keywords:** open, file, edit, split, tab, command line

#### Basic file opening

```vim
vim file.txt          " Open a file
vim +42 file.txt      " Open file at line 42
vim +/pattern file.txt " Open file at first match of pattern
```

Open files directly from the shell with optional line or pattern positioning.

- The + flag accepts any Ex command to run after opening.
- Use vim + file.txt to open at the last line.

#### Opening multiple files

```vim
vim file1.txt file2.txt   " Open in buffers (:bn to switch)
vim -O file1.txt file2.txt " Open in vertical splits
vim -o file1.txt file2.txt " Open in horizontal splits
vim -p file1.txt file2.txt " Open in tabs
```

Open multiple files in different layouts directly from the command line.

- Use -O for side-by-side editing of related files.
- Use -p for tab-based workflow.

#### Opening files from within Vim

```vim
:e file.txt     " Edit a file in current window
:sp file.txt    " Open in horizontal split
:vsp file.txt   " Open in vertical split
:tabe file.txt  " Open in new tab
```

Open additional files without leaving Vim using Ex commands.

- :e replaces the current buffer; use :bn to go back.
- Tab-complete file paths with Tab in command mode.

**Best practices:**

- Use tab completion when opening files from within Vim.
- Use splits for comparing or referencing related files.
- Use :e with wildcards for quick file switching.

**Common errors:**

- **E325: ATTENTION - Found a swap file**: Choose (R)ecover to recover, or (D)elete to discard the swap file.
- **Opening a directory instead of a file**: Vim opens the netrw file explorer for directories. Use :e filename to open a specific file.

## Navigation

Moving efficiently through files and text in Vim.

### Basic Movement

Fundamental cursor movement commands in Normal mode.

**Keywords:** move, cursor, navigation, hjkl, word, line

#### Character and line movement

```vim
h  " Move left
j  " Move down
k  " Move up
l  " Move right
0  " Jump to beginning of line
^  " Jump to first non-blank character
$  " Jump to end of line
```

The h/j/k/l keys replace arrow keys for efficient navigation without leaving the home row.

- Use 0 for absolute start, ^ for first non-whitespace character.
- Prefix with a number for repeated movement (e.g., 5j moves down 5 lines).

#### Word movement

```vim
w   " Move forward to start of next word
b   " Move backward to start of previous word
e   " Move forward to end of current/next word
ge  " Move backward to end of previous word
W   " Move forward to start of next WORD (space-delimited)
B   " Move backward to start of previous WORD
E   " Move forward to end of next WORD
```

Word motions navigate by word boundaries. Lowercase variants treat punctuation as word boundaries; uppercase variants only use whitespace.

- Use w/b for precise navigation around punctuation.
- Use W/B for faster navigation across mixed text.

**Best practices:**

- Use hjkl instead of arrow keys to keep hands on the home row.
- Combine number prefixes with motions for faster movement (e.g., 10j).
- Prefer word motions (w, b, e) over repeated h/l for horizontal movement.

**Common errors:**

- **Using arrow keys instead of hjkl**: Practice with hjkl; consider disabling arrow keys in your vimrc to build the habit.
- **Pressing j/k repeatedly instead of using counts**: Use a count prefix like 8j to jump 8 lines at once. Enable :set relativenumber to see line offsets.

### Document Movement

Commands for navigating through the entire document quickly.

**Keywords:** scroll, page, jump, top, bottom, document

#### Jumping to document positions

```vim
gg     " Go to first line of document
G      " Go to last line of document
:42    " Go to line 42
42G    " Go to line 42 (Normal mode)
H      " Move to top of screen (High)
M      " Move to middle of screen (Middle)
L      " Move to bottom of screen (Low)
```

Jump directly to specific lines or screen positions.

- gg and G are essential for quick top/bottom navigation.
- H/M/L position the cursor on the visible screen area.

#### Scrolling

```vim
Ctrl-D " Scroll down half a page
Ctrl-U " Scroll up half a page
Ctrl-F " Scroll down a full page (Forward)
Ctrl-B " Scroll up a full page (Backward)
Ctrl-E " Scroll down one line
Ctrl-Y " Scroll up one line
```

Scroll the viewport while maintaining or moving the cursor.

- Ctrl-D and Ctrl-U are the most commonly used scroll commands.
- Ctrl-E and Ctrl-Y scroll without moving the cursor line.

**Best practices:**

- Use gg and G to quickly move to file boundaries.
- Prefer Ctrl-D/Ctrl-U over Ctrl-F/Ctrl-B for more controlled scrolling.
- Combine :n with navigation to jump to specific line numbers.

**Common errors:**

- **Losing track of cursor position after large jumps**: Use Ctrl-O to jump back to the previous position. Enable :set cursorline for visibility.
- **Scrolling past the target**: Use Ctrl-D/Ctrl-U (half-page) for finer control than Ctrl-F/Ctrl-B (full page).

### Search Movement

Finding text and navigating by search patterns and character jumps.

**Keywords:** search, find, pattern, next, previous, character

#### Pattern searching

```vim
/pattern   " Search forward for pattern
?pattern   " Search backward for pattern
n          " Repeat search in same direction
N          " Repeat search in opposite direction
*          " Search forward for word under cursor
#          " Search backward for word under cursor
```

Search for text patterns in the file. Vim supports regular expressions in search.

- Use :set hlsearch to highlight all matches.
- Press :noh to clear search highlighting.

#### Character-level jumps

```vim
f{char}  " Jump forward to next occurrence of {char}
F{char}  " Jump backward to previous occurrence of {char}
t{char}  " Jump forward to just before {char}
T{char}  " Jump backward to just after {char}
;        " Repeat last f/F/t/T in same direction
,        " Repeat last f/F/t/T in opposite direction
```

Jump to specific characters on the current line. Extremely useful for precise horizontal navigation.

- f and t are among the most efficient ways to move within a line.
- Combine with operators like d or c (e.g., dt) to delete/change up to a character).

**Best practices:**

- Use * and
- Use f/t for precise in-line jumps rather than repeated w or l.
- Enable incremental search with :set incsearch.

**Common errors:**

- **Search wraps around unexpectedly**: Use :set nowrapscan to prevent search from wrapping around the file.
- **Regex characters interfering with search**: Escape special regex chars with backslash, or use \V for very-nomagic (literal) search.

### Marks and Jumps

Setting bookmarks and navigating the jump list.

**Keywords:** mark, bookmark, jump, position, navigate

#### Setting and jumping to marks

```vim
ma       " Set mark 'a' at current position
'a       " Jump to line of mark 'a'
`a       " Jump to exact position of mark 'a'
:marks   " List all marks
''       " Jump to position before last jump (line)
``       " Jump to position before last jump (exact)
```

Marks let you bookmark positions in a file and jump back to them.

- Lowercase marks (a-z) are local to a buffer; uppercase marks (A-Z) are global across files.
- Use ` (backtick) for exact column position, ' (single quote) for line start.

#### Jump list navigation

```vim
Ctrl-O   " Jump to older position in jump list
Ctrl-I   " Jump to newer position in jump list
:jumps   " Show the jump list
```

The jump list tracks your movement history. Use Ctrl-O/Ctrl-I to go back and forth.

- Searches, marks, and line jumps are all recorded in the jump list.
- Ctrl-O is one of the most useful navigation shortcuts in Vim.

**Best practices:**

- Use uppercase marks (mA) for frequently visited locations across files.
- Use Ctrl-O liberally to retrace your steps after jumping around.
- Combine marks with operators (e.g., d'a deletes from cursor to mark a).

**Common errors:**

- **Mark not set or overwritten**: Use :marks to check existing marks before setting new ones. Choose consistent mark naming conventions.
- **Confusing backtick and single quote jumpsc**: Backtick (`) jumps to the exact position; quote (') jumps to the start of the marked line.

## Editing

Commands for inserting, copying, pasting, and transforming text.

### Inserting Text

Various ways to enter Insert mode and begin typing.

**Keywords:** insert, append, open, substitute, change, replace

#### Basic insert commands

```vim
i  " Insert before cursor
I  " Insert at beginning of line
a  " Append after cursor
A  " Append at end of line
o  " Open new line below
O  " Open new line above
```

Each command enters Insert mode at a different position relative to the cursor or line.

- A is especially useful for adding content to the end of a line.
- o and O are preferred over pressing Enter manually.

#### Substitute and replace

```vim
s  " Delete character under cursor and enter Insert mode
S  " Delete entire line and enter Insert mode
C  " Delete from cursor to end of line and enter Insert mode
r  " Replace single character (stays in Normal mode)
R  " Enter Replace mode (overwrite characters)
```

These commands combine deletion with entering Insert or Replace mode.

- s is equivalent to cl (change one character).
- R is useful for fixed-width editing or overwriting text in place.

**Best practices:**

- Use A to append at line end instead of $a.
- Use S to replace an entire line rather than dd followed by O.
- Use r for single character fixes to stay in Normal mode.

**Common errors:**

- **Accidentally entering Replace mode with R**: Press Esc immediately to return to Normal mode. Use u to undo any overwrites.
- **Using s when meaning to save**: s substitutes characters. Use :w to save the file.

### Clipboard Operations

Deleting, yanking (copying), and putting (pasting) text.

**Keywords:** yank, copy, paste, put, delete, cut, clipboard, register

#### Delete and yank commands

```vim
x     " Delete character under cursor
X     " Delete character before cursor
dd    " Delete (cut) entire line
D     " Delete from cursor to end of line
yy    " Yank (copy) entire line
Y     " Yank entire line (same as yy)
d{motion} " Delete text covered by motion (e.g., dw, d$)
y{motion} " Yank text covered by motion (e.g., yw, y$)
```

Delete commands cut text into a register. Yank commands copy without deleting.

- Deleted text is stored in the unnamed register and can be pasted with p.
- Use d$ or D to delete from cursor to end of line.

#### Put (paste) and system clipboard

```vim
p     " Put (paste) after cursor
P     " Put (paste) before cursor
"+y   " Yank to system clipboard
"+p   " Paste from system clipboard
"*y   " Yank to primary selection (X11)
"*p   " Paste from primary selection (X11)
```

Put commands paste text from registers. The + and * registers access the system clipboard.

- Vim must be compiled with +clipboard for system clipboard support.
- On macOS, + and * registers behave the same.

**Best practices:**

- Use dd and p together for moving lines.
- Use the named registers ("ay, "ap) for storing multiple clipboard items.
- Use "+y to copy text for use outside of Vim.

**Common errors:**

- **Pasted text goes to wrong position**: Use p to paste after cursor, P to paste before. For lines, p pastes below, P above.
- **System clipboard not working**: Check if Vim has clipboard support with :version and look for +clipboard. Install vim-gtk or gvim if needed.

### Undo and Redo

Undoing and redoing changes in Vim.

**Keywords:** undo, redo, history, revert

#### Basic undo and redo

```vim
u       " Undo last change
Ctrl-R  " Redo last undone change
U       " Undo all changes on current line
5u      " Undo last 5 changes
```

Vim maintains an undo tree that allows undoing and redoing changes.

- Vim has unlimited undo by default (limited only by memory).
- U (uppercase) undoes all changes on the current line since last entering it.

#### Undo branches and persistence

```vim
:undolist       " Show undo branches
g-              " Go to older text state
g+              " Go to newer text state
:earlier 10m    " Go to state 10 minutes ago
:later 5m       " Go to state 5 minutes from undo point
:set undofile   " Enable persistent undo across sessions
```

Vim tracks undo as a tree, not just a linear stack. Use time-based undo to revert by duration.

- :earlier and :later accept time units like s, m, h.
- Enable undofile in your vimrc for persistent undo history.

**Best practices:**

- Enable persistent undo with set undofile in your vimrc.
- Use :earlier and :later for time-based undo when you need to go back further.
- Remember that U counts as a change itself and can be undone with u.

**Common errors:**

- **Cannot redo after branching undo**: Use g- and g+ to navigate the undo tree branches, or :earlier/:later for time-based navigation.
- **Undo history lost after closing file**: Add set undofile and set undodir=~/.vim/undodir to your vimrc. Create the directory first.

### Find and Replace

Search and replace text using substitute commands.

**Keywords:** find, replace, substitute, regex, search, global

#### Basic substitution

```vim
:s/old/new/          " Replace first 'old' on current line
:s/old/new/g         " Replace all 'old' on current line
:%s/old/new/g        " Replace all 'old' in entire file
:%s/old/new/gc       " Replace all with confirmation
```

The substitute command is one of the most powerful editing tools in Vim.

- The g flag means global (all occurrences on a line).
- The c flag prompts for confirmation at each match.

#### Advanced substitution

```vim
:5,20s/old/new/g     " Replace in lines 5 through 20
:'<,'>s/old/new/g    " Replace in visual selection
:%s/old/new/gi       " Case-insensitive replace
:%s/\<word\>/new/g   " Replace whole word only
:%s/pattern//gn      " Count matches without replacing
```

Advanced substitution with ranges, flags, and regex word boundaries.

- Use \< and \> for word boundaries in Vim regex.
- The n flag counts matches without performing replacement.

**Best practices:**

- Always use the c flag (:%s/old/new/gc) when making large replacements to verify each change.
- Use visual selection to limit substitution scope.
- Test the search pattern with / first before running substitution.

**Common errors:**

- **Unintended replacements across the file**: Use line ranges (:5,10s/...) or visual selection to limit scope. Add the c flag for confirmation.
- **Regex special characters causing errors**: Escape special regex characters (.*[]^$) with backslash, or use \V for literal matching.

## Operators and Text Objects

Combining operators with motions and text objects for powerful editing.

### Operators

Operators perform actions on text defined by a motion or text object.

**Keywords:** operator, delete, change, yank, indent, case, filter

#### Common operators with motions

```vim
dw    " Delete from cursor to next word
d$    " Delete from cursor to end of line
cw    " Change word (delete and enter Insert mode)
c$    " Change from cursor to end of line
yip   " Yank inner paragraph
>>    " Indent current line right
<<    " Indent current line left
==    " Auto-indent current line
```

The operator + motion pattern is the foundation of Vim editing: {operator}{motion}.

- Double an operator to apply it to the whole line (dd, yy, cc, >>).
- Operators can be prefixed with a count: 3dd deletes 3 lines.

#### Case and filter operators

```vim
gUw   " Uppercase from cursor to end of word
guw   " Lowercase from cursor to end of word
g~~   " Toggle case of entire line
g~w   " Toggle case of word
gUU   " Uppercase entire line
guu   " Lowercase entire line
!}sort " Filter paragraph through external sort command
```

Case operators change letter casing. The filter operator (!) pipes text through external commands.

- g~ toggles case, gU uppercases, gu lowercases.
- The ! operator is powerful for integrating external tools.

**Best practices:**

- Learn the operator + motion pattern: it makes all motions and text objects available to every operator.
- Use . to repeat operator commands for efficient editing.
- Combine operators with counts for batch operations (e.g., 3>> indents 3 lines).

**Common errors:**

- **Operator affects more text than intended**: Use more precise motions or text objects. Undo with u and retry with the correct motion.
- **Forgetting that operators wait for a motion**: After pressing an operator key (d, c, y), you must provide a motion or text object. Press Esc to cancel.

### Text Objects

Text objects define regions of text for operators to act upon.

**Keywords:** text object, inner, around, word, sentence, paragraph, quote, bracket, tag

#### Word, sentence, and paragraph objects

```vim
ciw   " Change inner word
caw   " Change a word (including surrounding space)
dis   " Delete inner sentence
dap   " Delete a paragraph (including trailing blank line)
yip   " Yank inner paragraph
```

i = inner (just the content), a = around (content plus surrounding whitespace/delimiters).

- ciw is one of the most commonly used text objects for replacing a word.
- dap is useful for removing entire paragraphs cleanly.

#### Delimiter-based text objects

```vim
ci"   " Change inside double quotes
ca"   " Change around double quotes (including quotes)
di(   " Delete inside parentheses
da(   " Delete around parentheses (including parens)
ci{   " Change inside curly braces
dit   " Delete inside HTML/XML tags
cat   " Change around tags (including the tags)
ci[   " Change inside square brackets
```

Delimiter text objects work with quotes, brackets, parentheses, and HTML/XML tags.

- These work regardless of cursor position within the delimiters.
- Equivalent pairs: ci( = ci), ci{ = ci}, ci[ = ci].

**Best practices:**

- Prefer text objects over motions for structural editing (ciw instead of bcw).
- Use "inner" (i) when you want to preserve delimiters, "around" (a) to include them.
- Combine text objects with . to repeat changes on similar structures.

**Common errors:**

- **Text object not selecting expected range**: Ensure the cursor is inside the target structure. Text objects work from cursor position to the nearest enclosing pair.
- **Using ci( when cursor is outside the parentheses**: Position cursor inside the parentheses first, or use a search motion to jump there.

### Repeating

Repeating commands and building efficient editing workflows.

**Keywords:** repeat, dot, macro, count, semicolon

#### Dot command and repetition

```vim
.     " Repeat last change
;     " Repeat last f/F/t/T search
,     " Repeat last f/F/t/T in reverse
3dd   " Delete 3 lines
5j    " Move down 5 lines
2yy   " Yank 2 lines
4>>   " Indent 4 lines
```

The dot command (.) is one of the most powerful features in Vim, repeating the last change.

- Design your edits to be repeatable with dot (e.g., use ciw over individual character edits).
- Number prefixes work with almost all commands.

#### Effective dot command usage

```vim
/word      " Search for 'word'
ciwreplace " Change word to 'replace'
n          " Jump to next occurrence
.          " Repeat the change
n          " Jump to next
.          " Repeat again
```

Combine search (n) with dot (.) for a powerful manual find-and-replace workflow.

- This pattern gives you control over each replacement, unlike :%s.
- Use n to skip an occurrence, . to replace it.

**Best practices:**

- Structure edits to maximize the usefulness of the dot command.
- Use text objects (ciw, dap) for dot-repeatable changes.
- Combine count prefix with motions and operators for batch operations.

**Common errors:**

- **Dot command repeats unexpected action**: The dot command repeats the last change, not the last motion. Check what your last change was.
- **Count not working with a command**: Not all commands support counts. Check the documentation for the specific command.

## Visual Mode

Selecting and operating on text visually.

### Visual Selection

Entering Visual mode and selecting text.

**Keywords:** visual, select, character, line, block, reselect

#### Visual mode types

```vim
v      " Enter character-wise Visual mode
V      " Enter line-wise Visual mode
Ctrl-V " Enter block-wise Visual mode
gv     " Reselect last visual selection
o      " Move to other end of selection
O      " Move to other corner of block selection
```

Visual mode provides a way to select text before applying an operator.

- Use o to adjust the other end of the selection without starting over.
- gv is extremely useful after an operation to reselect the same area.

#### Extending selections

```vim
viw    " Select inner word
vip    " Select inner paragraph
vi"    " Select inside quotes
vi(    " Select inside parentheses
vit    " Select inside tags
V5j    " Select current line and 5 lines below
```

Combine entering Visual mode with text objects or motions to select specific regions.

- In Visual mode, any motion extends the selection.
- Text objects in Visual mode select the entire object.

**Best practices:**

- Use Visual mode for operations where you want to verify the selection before acting.
- Prefer operator + text object (ciw) over visual select then operate (viwd) for repeated tasks.
- Use gv to quickly reselect and modify a previous selection.

**Common errors:**

- **Visual selection includes unexpected text**: Use o to toggle the active end of the selection and adjust boundaries.
- **Exiting Visual mode accidentally**: Press gv to restore the previous selection.

### Visual Operations

Operations you can perform on visually selected text.

**Keywords:** delete, yank, change, indent, case, join, command

#### Common visual operations

```vim
d    " Delete selection
x    " Delete selection (same as d)
y    " Yank (copy) selection
c    " Change selection (delete and enter Insert)
>    " Indent selection right
<    " Indent selection left
=    " Auto-indent selection
J    " Join selected lines
```

After making a visual selection, apply an operator to act on the selected text.

- These operations exit Visual mode after execution.
- Use gv to reselect if you need to apply another operation.

#### Case and formatting operations

```vim
~    " Toggle case of selection
U    " Uppercase selection
u    " Lowercase selection
gq   " Format/rewrap selected text
:    " Enter command mode for selection (adds '<,'>)
```

Visual mode allows case changes, formatting, and running Ex commands on selected lines.

- Pressing : in Visual mode automatically adds the range '<,'>.
- gq reformats text to the textwidth setting.

**Best practices:**

- Use Visual mode for one-off operations; use operators with motions for repeatable ones.
- Use gq to reflow paragraphs after editing text.
- Use visual + > repeatedly (with gv and .) for incremental indentation.

**Common errors:**

- **Accidentally deleting instead of yanking**: Use u immediately to undo if you pressed d instead of y.
- **Indent not applying to all selected lines**: Ensure you used V (line-wise) Visual mode for indentation operations.

### Visual Block

Block-wise visual selection for column editing.

**Keywords:** block, column, vertical, multi-line, insert, append

#### Block selection and editing

```vim
Ctrl-V       " Enter block visual mode
I{text}Esc   " Insert text before block on all lines
A{text}Esc   " Append text after block on all lines
r{char}      " Replace all characters in block with {char}
c{text}Esc   " Change block content on all lines
d            " Delete the block
```

Block Visual mode enables column-oriented editing across multiple lines simultaneously.

- After pressing I or A, text appears on the first line only; it applies to all lines after pressing Esc.
- Block mode is invaluable for editing tabular data or adding prefixes.

#### Practical block editing example

```vim
" Add comment prefix to lines 5-15:
5G          " Go to line 5
Ctrl-V      " Enter block visual
10j         " Extend selection 10 lines down
I# Esc      " Insert '# ' at start of each line

" Remove first 2 characters from lines:
Ctrl-V      " Enter block visual
10j         " Select 10 lines
ll          " Extend 2 columns right
d           " Delete the block
```

Practical examples of using block visual mode for commenting and uncommenting code.

- This technique works well for adding/removing comment characters.
- Use $ in block selection to extend to end of each line regardless of length.

**Best practices:**

- Use Ctrl-V + I for adding prefixes (like comment characters) to multiple lines.
- Use Ctrl-V + A for appending suffixes to multiple lines.
- Select with $ to include varying-length lines to their end.

**Common errors:**

- **Block insert only appears on the first line**: You must press Esc to apply the change to all lines. Do not use Ctrl-C as it cancels.
- **Block selection misaligned due to tabs**: Use :set expandtab or :retab to convert tabs to spaces for consistent column alignment.

## Windows and Tabs

Managing multiple views, windows, tabs, and buffers.

### Split Windows

Splitting the Vim window for side-by-side editing.

**Keywords:** split, window, horizontal, vertical, resize, navigate

#### Creating and navigating splits

```vim
:sp          " Horizontal split (same file)
:sp file     " Horizontal split with file
:vsp         " Vertical split (same file)
:vsp file    " Vertical split with file
Ctrl-W s     " Horizontal split (same as :sp)
Ctrl-W v     " Vertical split (same as :vsp)
Ctrl-W w     " Cycle through windows
Ctrl-W h     " Move to window left
Ctrl-W j     " Move to window below
Ctrl-W k     " Move to window above
Ctrl-W l     " Move to window right
```

Splits let you view and edit multiple files or different parts of the same file.

- Ctrl-W is the window command prefix for all window operations.
- Use Ctrl-W w to cycle quickly between two windows.

#### Resizing and closing windows

```vim
Ctrl-W =     " Equalize window sizes
Ctrl-W _     " Maximize current window height
Ctrl-W |     " Maximize current window width
Ctrl-W +     " Increase height by 1 line
Ctrl-W -     " Decrease height by 1 line
Ctrl-W >     " Increase width by 1 column
Ctrl-W <     " Decrease width by 1 column
Ctrl-W q     " Close current window
:only        " Close all windows except current
```

Resize and manage window layout. Prefix resize commands with a count for larger adjustments.

- Use 10 Ctrl-W + to increase height by 10 lines.
- Ctrl-W = is useful after creating/closing splits to rebalance.

**Best practices:**

- Map Ctrl-h/j/k/l to Ctrl-W h/j/k/l in your vimrc for faster window navigation.
- Use :vsp for comparing two files side by side.
- Use Ctrl-W = after resizing to quickly equalize window dimensions.

**Common errors:**

- **Window commands not recognized**: Ensure you are in Normal mode before pressing Ctrl-W. The Ctrl-W prefix only works in Normal mode.
- **Accidentally closing the wrong window**: Use Ctrl-W q carefully. Check which window is active by looking at the cursor position.

### Tab Pages

Using tab pages for organizing multiple files.

**Keywords:** tab, tabpage, tabnew, tabclose, navigate

#### Creating and managing tabs

```vim
:tabnew        " Open a new empty tab
:tabe file     " Open file in a new tab
:tabclose      " Close current tab
:tabonly       " Close all other tabs
:tabs          " List all tabs
```

Tabs in Vim are layouts that can each contain multiple windows/splits.

- Vim tabs are different from tabs in other editors. Each tab can contain multiple windows.
- Use :tabe with a file path to quickly open files in new tabs.

#### Navigating between tabs

```vim
gt           " Go to next tab
gT           " Go to previous tab
3gt          " Go to tab 3
:tabfirst    " Go to first tab
:tablast     " Go to last tab
:tabmove 0   " Move current tab to first position
:tabmove     " Move current tab to last position
```

Navigate between tabs using Normal mode shortcuts or Ex commands.

- gt and gT are the fastest way to switch tabs.
- Tab numbers are 1-indexed in Vim.

**Best practices:**

- Use tabs for different tasks or contexts (e.g., one tab per feature).
- Use buffers and splits within tabs for related files.
- Map tab navigation to convenient keys in your vimrc (e.g., leader+n/p).

**Common errors:**

- **Too many tabs open causing confusion**: Use :tabs to list all tabs. Consider using buffers (:ls, :bn) instead for many files.
- **New tab opens empty instead of with a file**: Use :tabe filename instead of :tabnew to open a file directly in a new tab.

### Buffers

Managing buffers for efficient multi-file editing.

**Keywords:** buffer, list, switch, delete, hidden

#### Listing and switching buffers

```vim
:ls          " List all buffers
:buffers     " List all buffers (same as :ls)
:bn          " Go to next buffer
:bp          " Go to previous buffer
:b name      " Switch to buffer by partial name
:b 3         " Switch to buffer number 3
:b#          " Switch to alternate (last used) buffer
```

Buffers represent open files in memory. You can switch between them without closing any.

- :b with partial name matching allows quick buffer switching.
- Ctrl-^ or :b# toggles between the current and last buffer.

#### Buffer management

```vim
:bd          " Delete (close) current buffer
:bd 3        " Delete buffer number 3
:bd file.txt " Delete buffer by name
:set hidden  " Allow switching buffers without saving
:%bd         " Delete all buffers
:bufdo cmd   " Execute command in all buffers
```

Manage buffer lifecycle and apply commands across multiple buffers.

- set hidden in your vimrc allows switching buffers with unsaved changes.
- :bufdo is powerful for batch operations (e.g., :bufdo %s/old/new/ge).

**Best practices:**

- Use :set hidden to enable seamless buffer switching.
- Prefer buffers over tabs for managing many files: :b with partial matching is very fast.
- Use :bd to clean up buffers you no longer need.

**Common errors:**

- **E37: No write since last change when switching buffers**: Either save with :w first, or add set hidden to your vimrc to allow unsaved buffer switching.
- **Cannot find buffer by name**: Use :ls to see exact buffer names, then :b with a unique substring.

## Advanced Features

Advanced Vim features for power users.

### Macros

Recording and replaying sequences of commands.

**Keywords:** macro, record, replay, register, automate

#### Recording and playing macros

```vim
qa       " Start recording macro into register 'a'
q        " Stop recording
@a       " Play macro stored in register 'a'
@@       " Replay the last executed macro
5@a      " Play macro 'a' five times
```

Macros record a sequence of keystrokes and replay them. They are stored in registers (a-z).

- The bottom of the screen shows 'recording @a' while recording.
- Macros can include any Normal mode commands, motions, and operators.

#### Practical macro example

```vim
" Convert a list of words to quoted, comma-separated:
" apple       ->  'apple',
" banana      ->  'banana',
" cherry      ->  'cherry',

qa            " Start recording to register a
I'Esc         " Insert quote at start
A',Esc        " Append quote and comma at end
j0            " Move to start of next line
q             " Stop recording
2@a           " Apply to next 2 lines
```

A practical macro that wraps each line in quotes and adds a trailing comma.

- End macros with j0 to position for the next line, making them repeatable.
- Use a large count (e.g., 999@a) to apply a macro to all remaining lines.

**Best practices:**

- Structure macros to end at the start of the next target for easy repetition.
- Use lowercase register to overwrite, uppercase (qA) to append to an existing macro.
- Test macros on one line before applying to many.

**Common errors:**

- **Macro stops partway through execution**: The macro likely encountered an error (e.g., search not found). Edit the macro register with :let @a='' and re-record.
- **Macro recorded wrong keystrokes**: View the macro content with :reg a, then edit with :let @a = "new content".

### Registers

Named storage areas for text, macros, and special values.

**Keywords:** register, named, clipboard, yank, black hole, system

#### Using named registers

```vim
"ay      " Yank into register 'a'
"ap      " Paste from register 'a'
"Ay      " Append to register 'a' (uppercase)
:reg     " View all register contents
:reg a   " View contents of register 'a'
```

Named registers (a-z) let you store multiple pieces of text independently.

- Uppercase register name (A-Z) appends to the register instead of overwriting.
- Registers are shared between yank, delete, and macro operations.

#### Special registers

```vim
"0p      " Paste last yanked text (not deleted)
"+y      " Yank to system clipboard
"+p      " Paste from system clipboard
"_d      " Delete to black hole register (truly delete)
"/       " Last search pattern register
":       " Last command register
".       " Last inserted text register
"%       " Current filename register
```

Special registers hold system clipboard, last search, last command, and other special values.

- "0 always holds the last yank, even after deleting (which goes to "1-"9).
- "_ is the black hole register: text deleted into it is truly gone.

**Best practices:**

- Use "0p to paste the last yanked text when a delete has overwritten the default register.
- Use "_d to delete without affecting any registers.
- Use :reg to inspect register contents when debugging macros or yanks.

**Common errors:**

- **Pasting wrong content after a delete operation**: Use "0p to paste the last yanked text, or use named registers to store important text.
- **System clipboard register not available**: Verify clipboard support with :echo has("clipboard"). Install a clipboard-enabled Vim build if needed.

### Folds

Folding and unfolding sections of code or text.

**Keywords:** fold, unfold, toggle, open, close, create

#### Managing folds

```vim
zo       " Open fold under cursor
zO       " Open fold under cursor recursively
zc       " Close fold under cursor
zC       " Close fold under cursor recursively
za       " Toggle fold under cursor
zA       " Toggle fold under cursor recursively
zM       " Close all folds in document
zR       " Open all folds in document
```

Folds hide sections of text, making large files easier to navigate.

- za is the most convenient for toggling individual folds.
- zM and zR are useful for getting an overview or seeing all content.

#### Creating folds

```vim
zf{motion}    " Create a fold over motion
zf5j          " Create fold over next 5 lines
:3,10fold     " Create fold from line 3 to 10
zd            " Delete fold under cursor
zE            " Delete all folds in window
:set foldmethod=indent  " Fold by indentation
:set foldmethod=syntax  " Fold by syntax
:set foldmethod=manual  " Manual fold creation
```

Create folds manually or configure automatic folding by indent, syntax, or other methods.

- Manual folds require foldmethod=manual.
- For code, foldmethod=syntax or foldmethod=indent are most useful.

**Best practices:**

- Set foldmethod=indent or foldmethod=syntax in your vimrc for automatic code folding.
- Use zM to collapse everything, then zo to open just the section you need.
- Set foldlevel to control initial fold depth: set foldlevel=1.

**Common errors:**

- **E350: Cannot create fold with current foldmethod**: Manual folds require foldmethod=manual. Use :set foldmethod=manual to enable.
- **Folds not persisting between sessions**: Add set viewoptions+=folds and autocmds for mkview/loadview in your vimrc.

### Spell Checking

Built-in spell checking in Vim.

**Keywords:** spell, spellcheck, dictionary, correct, suggest

#### Spell check commands

```vim
:set spell       " Enable spell checking
:set nospell     " Disable spell checking
:set spelllang=en_us " Set spell language
]s               " Jump to next misspelled word
[s               " Jump to previous misspelled word
z=               " Show spelling suggestions
zg               " Add word to spell file (good word)
zw               " Mark word as incorrect (wrong word)
zug              " Undo zg (remove from spell file)
```

Vim has built-in spell checking that highlights misspelled words and offers corrections.

- Misspelled words are highlighted based on your colorscheme.
- Use ]s and [s to quickly navigate between spelling errors.

#### Spell checking workflow

```vim
:set spell        " Turn on spell check
]s                " Go to first error
z=                " See suggestions, pick number
1z=               " Accept first suggestion directly
]s                " Go to next error
zg                " Add technical term to dictionary
```

A typical workflow for spell-checking a document using Vim.

- 1z= accepts the first suggestion without showing the menu.
- Use zg liberally for technical terms and proper nouns.

**Best practices:**

- Enable spell checking for prose files with autocommands in your vimrc.
- Maintain a personal spell file for technical terminology.
- Use :set spelllang=en_us,en_gb for multiple language support.

**Common errors:**

- **Spell file not found**: Vim will offer to download it. Accept, or manually place spell files in ~/.vim/spell/.
- **Too many false positives in code files**: Vim only checks spelling in comments and strings for syntax-highlighted files. Disable for code with :set nospell.

### Command-Line Tricks

Powerful Ex commands and external command integration.

**Keywords:** command, external, shell, filter, normal, execute

#### External commands and filters

```vim
:!ls              " Run external command
:!python %        " Run current file with Python
:r !date          " Insert output of date command
:r !curl -s URL   " Insert content from URL
:.!tr a-z A-Z     " Filter current line through tr
Ctrl-R Ctrl-W     " Insert word under cursor in command line
```

Vim integrates with the shell, letting you run commands and pipe text through filters.

- % in Ex commands refers to the current filename.
- :r inserts command output below the cursor.

#### Normal and global commands

```vim
:norm A;          " Append semicolon to current line
:%norm A;         " Append semicolon to all lines
:g/pattern/d      " Delete all lines matching pattern
:v/pattern/d      " Delete all lines NOT matching pattern
:g/TODO/norm O    " Add blank line above every TODO
:.                " Repeat last Ex command
```

:norm runs Normal mode commands on lines. :g (global) runs commands on matching lines.

- :g/pattern/command is incredibly powerful for batch line operations.
- :v is the inverse of :g, matching lines that do NOT contain the pattern.

**Best practices:**

- Use :g/pattern/d to quickly clean up files (remove debug lines, empty lines, etc.).
- Use :%norm for batch edits that are hard to express with substitution.
- Combine :r with shell commands for inserting dynamic content.

**Common errors:**

- **External command not found**: Ensure the command is in your PATH. Use full paths if needed (e.g., :!/usr/bin/python %).
- **:norm command not doing what expected**: Remember that :norm executes from the start of the line. Use :norm! to ignore user mappings.

### Options and Settings

Common Vim options for customizing your editing environment.

**Keywords:** set, option, setting, number, search, tab, indent

#### Display and search settings

```vim
:set number          " Show line numbers
:set relativenumber  " Show relative line numbers
:set cursorline      " Highlight current line
:set hlsearch        " Highlight search matches
:set incsearch       " Show matches while typing
:set ignorecase      " Case-insensitive search
:set smartcase       " Case-sensitive if uppercase present
:set nowrap          " Disable line wrapping
```

Configure how Vim displays content and handles searching.

- Combine ignorecase with smartcase for intelligent case matching.
- Toggle any boolean option with :set option! (e.g., :set number!).

#### Indentation and tab settings

```vim
:set expandtab       " Use spaces instead of tabs
:set tabstop=4       " Display width of tab character
:set shiftwidth=4    " Number of spaces for auto-indent
:set softtabstop=4   " Spaces per Tab keypress
:set autoindent      " Copy indent from current line
:set smartindent     " Smart auto-indenting for C-like code
:set list            " Show invisible characters
:set listchars=tab:>-,trail:. " Define how to show invisibles
```

Configure how Vim handles indentation, tabs, and whitespace display.

- Always set all four tab-related options together for consistency.
- Use :retab to convert existing tabs to spaces (or vice versa).

**Best practices:**

- Put your preferred settings in ~/.vimrc for persistence.
- Use both number and relativenumber together for hybrid line numbers.
- Set expandtab with consistent tabstop/shiftwidth for portable indentation.

**Common errors:**

- **Settings reset after restarting Vim**: Add settings to your ~/.vimrc file for persistence. Use :mkvimrc to generate one from current settings.
- **Mixed tabs and spaces in file**: Set expandtab and run :retab to convert all tabs to spaces uniformly.

### Redirection and Pipes

Piping text to and from external commands.

**Keywords:** pipe, redirect, filter, sort, shell, write, read

#### Filtering and piping

```vim
:w !cmd          " Pipe buffer content to external command
:r !cmd          " Read command output into buffer
:%!sort          " Sort all lines in the file
:%!sort -u       " Sort and remove duplicates
:'<,'>!sort      " Sort selected lines
:%!python -m json.tool " Format JSON
```

Vim can pipe buffer content to shell commands and read results back.

- :w !cmd writes to stdin of cmd, not to a file named !cmd.
- :%!cmd replaces the entire buffer with the command output.

#### Clipboard and advanced piping

```vim
:w !pbcopy          " Copy buffer to macOS clipboard
:r !pbpaste         " Paste from macOS clipboard
:w !xclip -sel clip " Copy to clipboard on Linux
:w !wl-copy         " Copy to clipboard on Wayland
:%!column -t        " Align text into columns
:%!awk '{print $2}' " Extract second field of every line
```

Use external tools for clipboard operations and advanced text processing.

- Choose the clipboard command based on your operating system.
- Combine with visual selection for operating on specific regions.

**Best practices:**

- Use :%!sort for quick sorting without leaving Vim.
- Leverage Unix tools through pipes for complex text transformations.
- Test filter commands on a small selection before applying to the whole file.

**Common errors:**

- **Buffer replaced with error output from command**: Use u to undo immediately. Test the command with :!cmd first before piping with :%!cmd.
- **:w !cmd confused with :w!cmd**: :w !cmd pipes to a command. :w!cmd force-writes to a file named cmd. The space matters.
