9 Editing in the terminal: Vim#
What this notebook is about#
Part II was all about reading: pulling things out of read-only data. Part III is where you start writing: scripts, configs, submission files of your own. And writing needs an editor.
The editor is Vim. Two reasons it is worth the climb, said plainly. First, it
is everywhere: every Linux box and every cluster has it, often as the only
editor installed. Second, you will be dropped into it whether you ask or not
(git opens it for commit messages, crontab -e opens it, countless tools default
to it), so “I’ll just avoid Vim” is not actually on the menu. Better to learn it
properly once.
As always: the files you edit here are scripts and configs, just text. No physics required.
How to practise this notebook#
Here is the one unusual thing about this notebook. Vim is interactive (it takes over your whole terminal and responds to keystrokes), so it cannot run in the grey cells on this page. There is no live keyboard here.
So the workspace for this notebook is the live terminal, not the page:
Practise this notebook in your terminal
▶ Open the live terminal and keep it beside this page. Every “try it” below is something you do there. The cells on this page show the before and after of an edit (produced with scripted Vim so they are reproducible), but the editing itself is yours to do live.
A. The modal model#
The single idea that unlocks Vim (and the single thing that traps every beginner who skips it) is that Vim is modal. The keys do different things depending on which mode you are in. There are four worth knowing:
Normal: where you start. Letters are commands, not text (
ddeletes,istarts inserting). This is home base.Insert: where you actually type text, like a normal editor.
Visual: where you select a region, then act on it.
Command-line: where you type
:commands like:w(save) and:q(quit).
Esc always takes you back to Normal. When in doubt, press Esc and you are home.
┌──────────────────────────────────────────────┐
│ NORMAL mode │
│ you start here — letters are commands │
└────┬─────────────────┬────────────────┬──────┘
press i a o press v V Ctrl-v press :
│ │ │
▼ ▼ ▼
INSERT VISUAL COMMAND-LINE
(type text) (select a region) ( :w :q :wq :%s/… )
│ │ │
└─────── Esc ─────┴──── Esc ───────┘ ──▶ back to NORMAL
vim is the program you launch; here is its card. Everything inside Vim (the
modes, motions, and : commands) lives in the reference tables below, not in the
card.
| <file> | open (or create) a file for editing |
| +N <file> | open with the cursor already on line N |
| -R <file> | open read-only (the view command does the same) so you cannot change it by accident |
:help inside Vim (quit help with :q); man vimi to type, Esc to go back. If you are ever stuck, :q! always bails out without savingB. Survival first#
Before anything else, the four things that stop you ever being trapped. The most common question about Vim is “how do I get out of it”, so here is the answer, up front.
Esc first if unsure where you are.
| vim file | open (or create) the file |
| i | enter Insert mode and start typing |
| Esc | leave Insert, back to Normal |
| :w | write (save) |
| :q | quit |
| :wq or ZZ | save and quit |
| :q! | quit and throw away unsaved changes: the escape hatch |
That last one, :q!, is your panic button: it always gets you out, no matter what
mess you have made, without saving it. Commit it to memory now.
Try it (in your terminal)
vim scratch-hello.txt, press i, type a line, press Esc, type :wq, Enter.
You just created and saved a file in Vim. Now vim scratch-hello.txt again to
reopen it, and :q to leave.
C. Moving around#
In Normal mode you move the cursor without arrow keys (your hands never leave the
home row). Motions also combine with counts: a number before a motion repeats
it, so 5j moves down five lines.
| h j k l | left, down, up, right (one character/line) |
| w b e | forward a word, back a word, to word-end |
| 0 ^ $ | start of line, first non-blank, end of line |
| gg G | top of file, bottom of file |
| :N | jump to line number N |
| 5j 3w | counts: repeat a motion (down 5 lines; forward 3 words) |
D. Editing — verbs and motions#
The part that makes Vim worth learning rhymes with something you already know. In Part II you saw the Unix idea: small tools composed with pipes. Vim has the same idea for editing: small verbs composed with motions.
A verb is an operator: d delete, c change, y yank (copy). A motion says
how far. Snap them together and you get a precise edit:
dw: delete a word;d$: delete to end of line;3dw: delete three words.cw: change a word (delete it and drop straight into Insert mode).y$: yank to end of line;p: paste it back.
Once you see the grammar, you do not memorise hundreds of commands; you combine a handful of verbs with the motions from the table above.
| x | delete the character under the cursor |
| dd yy | delete / yank (copy) the whole line |
| dw cw | delete / change a word (verb + motion) |
| p P | paste after / before the cursor |
| o O | open a new line below / above and start typing |
| u Ctrl-r | undo / redo |
| . | repeat the last change (astonishingly useful) |
E. Visual mode — select first, then operate#
Verbs-and-motions act forward from the cursor. Visual mode is the other way round: select a region first, watch it highlight, then apply one verb to all of it. There are three flavours, and the third is a Vim signature.
vis charwise: select character by character.Vis linewise: select whole lines.Ctrl-vis blockwise: select a rectangular column. This is the one nothing else does as cleanly, and the one you will reach for constantly on structured text: scripts, config files, aligned columns in an input deck.
Once a region is selected, operate on it: d delete, y yank, c change, > /
< indent, ~ toggle case.
The block-mode power moves#
Blockwise visual mode earns its own paragraph because of what it does to columns.
Mark a rectangle with Ctrl-v, then:
I: insert text at the start of every selected line. Type it once, pressEsc, and it appears on all of them.A: the same, but append (use$first to catch ragged line-ends).ddeletes the column, c changes it,rreplaces it.
The everyday payoff is block-commenting: put # in front of a run of lines in
one move: Ctrl-v, select down with j, I, type # , Esc. Here is that
edit’s before and after, produced on a scratch file with scripted Vim so you can
see the result (in your terminal you would do it with the keystrokes just
described):
cat scratch/deck.txt
set cutoff 300
set maxiter 50
set window 4
vim -es -c '%s/^/# /' -c 'wq' scratch/deck.txt
cat scratch/deck.txt
# set cutoff 300
# set maxiter 50
# set window 4
Every line now carries a leading # : three lines commented in one gesture. The
reverse (deleting a leading column with Ctrl-v then d) is just as quick.
Esc applies block edits to every line.
| v V | charwise / linewise selection |
| Ctrl-v | blockwise (rectangular column) selection |
| d y c | delete / yank / change the selection |
| > < ~ | indent right / left; toggle case |
| Ctrl-v … I | block: insert on every selected line (then Esc) |
| Ctrl-v … A | block: append on every line ($ first for ragged ends) |
F. Search#
Finding things is the same / you already met in less and man (they page
through less, remember). In Normal mode:
/patternthen Enter searches forward;?patternsearches backward.njumps to the next match;Nto the previous one.*searches for the word currently under the cursor (no typing needed).
G. Search and replace — the power tool#
This is the move that justifies the whole notebook, and it carries a gift from
Part II: the regular expressions you learned for grep and sed are the same
regexes Vim searches and replaces with. The command lives in command-line mode:
:s/old/new/: replace the firstoldon the current line.:s/old/new/g: replace globally on the current line (every match).:%s/old/new/g:%means “all lines”, so this replaces every occurrence in the file. This is the one you will use most.:10,20s/old/new/g: only within a line range.:%s/old/new/gc: addcto confirm each change (y/n) before it happens.
Here it is on a scratch parameter file. Before:
cat scratch/params.txt
cutoff = 300
maxsteps = 300
window = 300
In your terminal you would open the file and type :%s/300/500/g. Run
non-interactively for the page, that is:
vim -es -c '%s/300/500/g' -c 'wq' scratch/params.txt
cat scratch/params.txt
cutoff = 500
maxsteps = 500
window = 500
Every 300 became 500, across all three lines, in one command. That is the
edit you will run a thousand times: change a parameter everywhere, rename a
variable throughout a script, retarget a path across a config.
H. A word on nano (and why Vim anyway)#
If Vim’s modes are genuinely not for you today, there is a gentler editor: nano.
It is modeless (you just type, like a text box) and it shows its key shortcuts
along the bottom of the screen (^O to save, ^X to exit, where ^ means Ctrl).
It is a perfectly fine fallback, and on your own machine you may prefer it.
| ^O | write the file out (save) — the ^ means the Ctrl key |
| ^X | exit (it offers to save first) |
| ^W | search ("where is") |
man nano^X shown on screen means Ctrl-X, not a literal caret followed by XBut the reason this notebook leads with Vim and not nano is simple: when you
ssh into a cluster at 2 a.m. to fix a submission script, Vim is what is there,
and the tool that drops you in unannounced is Vim, not nano. Learning it is an
investment that pays off on every machine you will ever touch.
Optional: a friendlier Vim
Vim is endlessly configurable through a ~/.vimrc file. A few beginner-friendly
lines make it much more pleasant: set number (show line numbers), syntax on
(colour), set incsearch (search as you type). You do not need this
to start; just know the knob exists for when you are ready.
Exercises#
These are different from the earlier notebooks’: the editing happens in your
terminal, live, so
open it now
if it is not already beside you. Each exercise tells you what to do in Vim; the
graded ✓ checks the file you end up with. (On this page the answer is produced with scripted Vim so
the build stays green, but the real practice is yours to do in the terminal.) As
always, we work on fresh scratch/ copies, never on data/.
Warm-up — Survival drill#
In your terminal: vim scratch/hello.txt, press i, type Hello, Vim, press
Esc, save and quit with :wq. Reopen it to confirm it stuck.
Hello, Vim
✓ the file holds the line you inserted
Applied 1 — Fix a broken file#
This scratch script has a typo: eccho should be echo. Open it in Vim, fix the
typo (with cw, or x, or :s, your choice), save, and the script will run.
It is just text; you do not need to know what it computes.
binding energy: 42 meV
✓ the typo is fixed and the script now runs
Applied 2 — Search and replace (the centrepiece)#
This config sets the value 300 on every line. Open it in Vim and change every
300 to 500 in one command with :%s/300/500/g. None should be missed.
cutoff = 500
maxsteps = 500
window = 500
seed = 500
✓ every 300 became 500 — all four, none missed
Applied 3 — Block edit a column (visual block)#
The real payoff of block mode. This scratch file has a run of lines. (a)
Block-comment all of them: Ctrl-v, select down with j, I, type # , Esc.
(b) On the second file, delete the leading | column: Ctrl-v, select the
two-character column down, d.
# echo alpha
# echo beta
# echo gamma
1.0 | x |
2.0 | y |
3.0 | z |
✓ every line was commented, and the leading column was removed
Optional stretch (terminal-only) — Efficiency challenge#
No ✓: do this one for speed, in your terminal. Take any of the scratch files above
and redo an edit using counts, verbs, and motions rather than retyping: delete
three words with 3dw, change a word with cw, copy a line with yy and paste it
with p, then undo it all with u. Then do a one-line :%s/.../.../ that would
have taken many manual edits. Feeling where the leverage is (a few keystrokes
standing in for a lot of typing) is the whole point of learning Vim.
Outlook#
You can now create and change text in the terminal: the missing piece before you write anything of your own. Next (Notebook 10): quoting and expansion, the rules that decide how the shell reads what you type. They are quietly responsible for most of the subtle bugs people hit once they start writing real commands and scripts, so they are worth getting straight before you write much more.
See the full Compendium Scriptorum for every command met so far, and where to find it again.