Skip to main content

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

ModeKeySelects
Character visualvArbitrary character ranges
Line visualV (Shift+v)Complete lines
Block visualCtrl+vRectangular 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

CommandAction
oToggle the "other end" of selection
OToggle corner (block visual)
gvRe-select previous selection
viwSelect inner word (from Normal mode)
visSelect inner sentence
vipSelect inner paragraph
viBSelect 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

GoalKeys
Select a functionVjj...V to the closing brace
Indent a blockVjj>
Copy a paragraphyip (from Normal mode)
Comment multiple linesCtrl+v, I, //
Delete from cursor to end of fileVGd
Uppercase a wordviw U

What's Next