Visual Mode and Selection
Visual mode lets you select text first, then apply an operator to the selection. It makes complex edits visible and composable.
Core Idea
While Normal mode applies operators to implicit text objects, Visual mode makes the selection explicit and visual before acting on it.
Three Visual Modes
| Mode | Key | Selects |
|---|---|---|
| Character visual | v | Arbitrary character ranges |
| Line visual | V (Shift+v) | Complete lines |
| Block visual | Ctrl+v | Rectangular column region |
Character Visual Mode (v)
Select characters across any range:
v → start selection at cursor
then move:
w/b/e → extend by word
f{char} → extend to character
{ → extend to paragraph
$ → extend to end of line
G → extend to end of file
Then apply an operator:
d → delete selection
y → yank (copy) selection
c → change (delete + insert)
> → indent
< → un-indent
~ → toggle case
u → lowercase all
U → uppercase all
! → filter through external command
Line Visual Mode (V)
Select complete lines:
V → select current line
5j → extend 5 lines down
jj → extend 2 more lines
Then:
d → delete selected lines
y → yank selected lines
> → indent selected lines
Line visual is perfect for: moving/copying blocks of code, indenting multiple lines, deleting function bodies.
Block Visual Mode (Ctrl+v) — Column Editing
Select rectangular regions across multiple lines — the most power-unique feature:
Ctrl+v → start column selection
{motion} → extend selection
Then:
I → insert before all rows
A → append after all rows
c → change all rows
d → delete column
r{char} → replace column with char
Example: Add Comment Prefix to Multiple Lines
# Before:
const name = "Alice"
const age = 30
const city = "NYC"
# Steps:
# 1. Go to start of "const name"
# 2. Ctrl+v — start block visual
# 3. 2j — extend down 2 lines
# 4. I — insert before block
# 5. // — type the prefix
# 6. Esc — applies to all lines
# After:
// const name = "Alice"
// const age = 30
// const city = "NYC"
Example: Change Values in a Table
Before:
Name | Value | Status
Alice | 100 | active
Bob | 200 | pending
Steps to change the "Status" column:
1. Position cursor at "active"
2. Ctrl+v → select "active"
3. 1j → extend to "pending"
4. c → change
5. Type new value → Esc
Useful Visual Mode Commands
| Command | Action |
|---|---|
o | Toggle the "other end" of selection |
O | Toggle corner (block visual) |
gv | Re-select previous selection |
viw | Select inner word (from Normal mode) |
vis | Select inner sentence |
vip | Select inner paragraph |
viB | Select inner {} block |
vi" | Select inside double quotes |
Selecting and Indenting Code
Vjj> → Select 3 lines, indent once
Vjj>> → Won't work (> is applied once)
Vjj>gv> → Select 3 lines, indent, re-select, indent again
Better for repeated indentation: use . after the first indent by re-selecting with gv:
Vjj> → indent selection
gv> → re-select and indent again
gv> → and again
Sorting a Selection
Select lines (V + motion)
:sort → sort alphabetically
:sort! → sort reverse
:sort n → sort numerically
Filtering Through External Commands
Select lines (V + motion)
!sort -u → filter through `sort -u`
!column -t → format as aligned table
!jq . → format selected JSON
Visual Mode with Substitute
Select a range, then :s applies only to the selection:
V5j → Select 6 lines
:'<,'>s/old/new/g → Replace in selection only
(:'<,'> is auto-inserted when you press : in visual)
Common Visual Mode Patterns
| Goal | Keys |
|---|---|
| Select a function | Vjj...V to the closing brace |
| Indent a block | Vjj> |
| Copy a paragraph | yip (from Normal mode) |
| Comment multiple lines | Ctrl+v, I, // |
| Delete from cursor to end of file | VGd |
| Uppercase a word | viw U |