vi is the text editor you can count on: almost every Linux and Unix system has it, including minimal servers and containers with no other editor. Most systems ship Vim ("vi improved"), which runs when you type vi. You don't need to master it. You need enough to open a config file, change it, save and get out. This note covers that core.
Modes#
Vi is a modal editor. The same key does different things depending on the mode. This is the one idea that makes vi make sense.
| Mode | What keys do | How to enter |
|---|---|---|
| Normal (command) | Move, delete, copy, paste | Start here; press Esc from any mode |
| Insert | Type text into the file | i, a, o and others from Normal mode |
| Command-line | Run : commands (save, quit, replace) |
Press : in Normal mode |
If you're unsure which mode you're in, press Esc. That always brings you back to Normal mode.
Open, save and quit#
The first thing most people need is a way out, so start with saving and quitting. vi filename opens a file. If it doesn't exist, vi creates it when you first save. All save and quit commands start with : and end with Enter.
| Command | Effect |
|---|---|
:w |
Save and keep editing |
:w newname |
Write to a new file and keep editing the current one |
:q |
Quit; refuses if there are unsaved changes |
:wq or :x |
Save and quit |
:q! |
Quit and throw away unsaved changes |
Entering Insert mode#
To change the file, you switch from Normal mode to Insert mode. Several keys do that, each at a different spot. Press Esc when you finish typing.
| Key | Starts inserting |
|---|---|
i |
Before the cursor |
a |
After the cursor |
I |
At the start of the line |
A |
At the end of the line |
o |
On a new line below |
O |
On a new line above |
A saves a step: it jumps to the end of the line and enters Insert mode at once.
Moving around#
Back in Normal mode, you move the cursor to the next spot you want to edit. Arrow keys work in Vim, but these Normal-mode keys are faster once learned.
| Key | Moves to |
|---|---|
h j k l |
Left, down, up, right |
w / b |
Next word / previous word |
0 / $ |
Start / end of the line |
gg / G |
First line / last line of the file |
42G or :42 |
Line 42 |
Deleting#
The movement keys matter beyond moving, because Vim reuses them as motions in other commands. Delete commands combine d with a motion, and the motion says how far to delete.
| Command | Deletes |
|---|---|
x |
The character under the cursor |
dw |
From the cursor to the start of the next word |
dd |
The whole current line |
3dd |
Three lines, starting with the current one |
d$ or D |
From the cursor to the end of the line |
d0 |
From the cursor back to the start of the line |
dG |
From the current line to the end of the file |
dgg |
From the current line to the top of the file |
dG and dgg both include the current line. A number before most commands repeats it, so 5x deletes five characters.
Copy, cut and paste#
Copying follows the same pattern as deleting. Vi calls copying yank. Anything you delete or yank goes into a register (a clipboard slot), so d works as cut.
| Command | Effect |
|---|---|
yy |
Yank (copy) the current line |
yw |
Yank from the cursor to the next word |
p |
Paste after the cursor (or below the line, for whole lines) |
P |
Paste before the cursor (or above the line) |
u |
Undo the last change |
Ctrl+r |
Redo |
To move a line, press dd, move the cursor, then press p. To duplicate a line, press yy then p.
Search and replace#
In a long config file, searching is faster than moving line by line. Search from Normal mode, and replace with a :s command.
| Command | Effect |
|---|---|
/word |
Search forward for word |
?word |
Search backward |
n / N |
Next match in the same / opposite direction |
:s/old/new/ |
Replace the first old on the current line |
:%s/old/new/g |
Replace every old in the file |
:%s/old/new/gc |
Same, but ask before each change |
% means "every line". g means "every match on the line", not only the first.
Saving a file that needs root#
One situation catches almost everyone. You open /etc/hosts, make changes, and :w fails with a permission error because you didn't start Vim with sudo. You can save from inside Vim without losing your edits.
:w !sudo tee % > /dev/null
Each part has a job:
:w !cmdsends the buffer to a shell command's stdin, instead of writing the file.sudo teerunsteeas root.teewrites its stdin to the file it is given.%expands to the current file's name.> /dev/nullhidestee's copy of the file on the screen.
Vim then sees that the file changed on disk and asks what to do. Press L to load the saved version, or O to keep the buffer. This works in Vim. Neovim can't show the sudo password prompt this way. Next time, open system files with sudoedit /etc/hosts.
Key takeaways#
- Vi has modes.
Escalways returns to Normal mode. :wsaves,:qquits,:wqdoes both,:q!quits without saving.i,a,Aandoenter Insert mode at different spots.dplus a motion deletes:dda line,dwa word,dGto the end,dggto the top.yycopies,ppastes,uundoes./wordsearches;:%s/old/new/greplaces in the whole file.