Learn Practice Daily golf Reference
Foundations·Lesson 3 of 6·9 min·0/11 exercises

Jump by words

w b e hop between words. Their uppercase cousins W B E leap over punctuation.

Scene

Day one, 2 p.m. Back from lunch, menu.ts is open again. The menu changes every morning, so you'll be darting around this file all day, and its lines are long.

You could hold l and watch the cursor crawl like a rider stuck in lunch traffic. Or you could move the way you read: a word at a time.

From memory

Warm-up from earlier chapters

One from an earlier chapter, from memory, before the new idea. Two wrong tries show the answer.

One line down.
press the keys…
1 of 1
One line down.

Words are lily pads

Picture the cursor as a frog and every word as a lily pad. Press w and the frog hops to the start of the next pad. It's the single most useful motion you'll learn today, and frogs have known about it for millions of years.

w
const order = await placeOrder(cart, user);
10 hops
Each underline is a lily pad; each arc is one press of w.
1const order = await placeOrder(cart, user);
NORMALLoading the editor…1:7
Try it

Hop forward

Reach each green square with w. Five pads, one line.

1 of 5Move the cursor onto the
1export async function placeOrder(cart: Cart, user: User) {
NORMALLoading the editor…1/50.0s1:1

This exercise needs a keyboard. Read on, and play it at your computer.

Going back

Overshot? b hops back to the start of a word. From the middle of a pad, that's the start of the pad you're on; from its first letter, the start of the one before. The frog can reverse; it just prefers not to talk about it.

1const order = await placeOrder(cart, user);
NORMALLoading the editor…1:42
Check yourself

Back to which pad?

1const order = await placeOrder(cart, user);
NORMAL
Keys pressed: b

The cursor is on the d in the middle of placeOrder. You press b. Where does it land?

Pick an answer (or press its number), then watch the engine prove it.
Try it

Back and forth

Targets now appear on both sides of the cursor. Use w and b.

1 of 6Move the cursor onto the
1 const total = cart.items.reduce((sum, i) => sum + i.price, 0);
2 const discount = user.isStudent ? total * 0.1 : 0;
NORMALLoading the editor…1/60.0s2:52

This exercise needs a keyboard. Read on, and play it at your computer.

Land on the end

e lands on the end of a word: the frog on tiptoes at the far edge of the pad. Already on the edge? Then e hops on to the far edge of the next pad. Handy when you want to add something right after a word: a plural s, a closing quote.

w
const best = reviews.filter(isFiveStar);
9 hops
e
const best = reviews.filter(isFiveStar);
9 hops
Same words, two ways to land: w on the first letter, e on the last.
1const best = reviews.filter(isFiveStar);
NORMALLoading the editor…1:1
Try it

All three

Mix w, b and e. Some targets sit at the end of a word.

1 of 6Move the cursor onto the
1function averageRating(reviews: Review[]) {
1 if (reviews.length === 0) return 0;
2 const sum = reviews.reduce((acc, r) => acc + r.stars, 0);
3 const avg = sum / reviews.length;
NORMALLoading the editor…1/60.0s1:1

This exercise needs a keyboard. Read on, and play it at your computer.

What counts as a word?

To Vim, user.name is three words: user, . and name. Letters, digits and underscores make one kind of word; punctuation makes another. Dots are tiny lily pads, and w stops on every single one.

w
const city = user.profile.address.city;
10 hops
Green underlines are letter-words, amber ones are punctuation. w lands on every one.
Check yourself

Predict the landing

1user.profile.name
NORMAL
Keys pressed: www

You press w three times. Where does the cursor end up?

Pick an answer (or press its number), then watch the engine prove it.

Counts work here too

Counts aren't just for 5j. 3w is three hops in one breath, and the same trick works with b, e and nearly everything else you'll learn.

1if (!item) throw new Error("not on the menu: " + id);
NORMALLoading the editor…1:1
Try it

Count your hops

The targets are further away now. Count the words and jump in one go: 2w, 3b, 4e.

1 of 5Move the cursor onto the
1export function findItem(id: string) {
1 const item = menu.find((m) => m.id === id);
2 if (!item) throw new Error("not on the menu: " + id);
3 return item;
NORMALLoading the editor…1/50.0s1:1

This exercise needs a keyboard. Read on, and play it at your computer.

WORDs skip the punctuation

Hold Shift and the frog becomes a kangaroo. W, B and E treat anything between spaces as one big WORD, so user.profile.name is a single jump. Reach for them when a line is thick with dots and brackets.

w
const nearest = riders.sort((a, b) => a.distance - b.distance)[0];
0 hops
W
const nearest = riders.sort((a, b) => a.distance - b.distance)[0];
0 hops
Frog vs kangaroo, same line. Blue underlines are WORDs: anything between spaces.
1const nearest = riders.sort((a, b) => a.distance - b.distance)[0];
NORMALLoading the editor…1:1
Try it

Leap

Punctuation everywhere. W, B and E get you there in fewer keys.

1 of 6Move the cursor onto the
1const MAX_DISTANCE_KM = 8;
1const riders = await loadRiders({ online: true });
2const nearest = riders.sort((a, b) => a.distance - b.distance)[0];
3if (!nearest || nearest.distance > MAX_DISTANCE_KM) {
4 return refund(order, "No rider nearby, sorry!");
5}
6assign(order, nearest);
7log("assigned", order.id, nearest.name);
NORMALLoading the editor…1/60.0s1:1

This exercise needs a keyboard. Read on, and play it at your computer.

The whole family, in one picture

Six keys, two sizes. Each row below is one press from the same cursor, so you can compare them pair by pair. Take a good look: the next block asks you to recall them without the picture.

if (order.status === "late") notify(user.phone, msg);wWbBeE
Same line, same cursor, one press each. Lowercase stops at punctuation; uppercase only stops at spaces.
From memory

Quick recall

No scrolling up. Read the situation, press the keys.

Hop to the start of the next word.
scroll here, then press the keys
1 of 5
Hop to the start of the next word.
Challenge

Code review sprint

Code review: twelve comments scattered across menu.ts, and the reviewer wants answers before the five o'clock merge. Read them first: visit each spot with any word motion you like.

1 of 12Move the cursor onto the
1export const menu = [
1 { id: "al-pastor", name: "Al astor", price: 9.5, spicy: rue },
2 { id: "veggie", name: "GGarden Veggiee", price: 8.25, spicy: false },
3 { id: "carnitas", name: "Carnitass", price: 10, spicy: falsee },
4];
5
6export function indItem(id: string) {
7 const item = menu.find((m) => m.id === idd);
8 if (!item) throw new Error("not on the enu: " + id);
9 return itemm;
10}
NORMALLoading the editor…1/120.0s1:1

This exercise needs a keyboard. Read on, and play it at your computer.

Boss round

Answer the review

Every comment says the same thing: typo. Ten of them, each marked in the file. Hop to each one with word motions, then fix it the way you learned this morning: x for a letter too many, i for a missing one, Esc when you're done.

Stuck? Show a hintHop with w, e, b (counts help), then x or i… <Esc>
1 of 10Type P where it's shown in green
1export const menu = [
1 { id: "al-pastor", name: "Al astor", price: 9.5, spicy: rue },
2 { id: "veggie", name: "GGarden Veggiee", price: 8.25, spicy: false },
3 { id: "carnitas", name: "Carnitass", price: 10, spicy: falsee },
4];
5
6export function indItem(id: string) {
7 const item = menu.find((m) => m.id === idd);
8 if (!item) throw new Error("not on the enu: " + id);
9 return itemm;
10}
NORMALLoading the editor…1/100.0s1:1

This exercise needs a keyboard. Read on, and play it at your computer.

ApprovedFinish the exercise above to see it.

Extra practice optional

The chapter is done. These rounds keep going as long as you like: stop whenever it stops being useful.

Endless

Keep hopping

Endless mode. New code every ten targets, longer jumps every five. The frog never gets tired, but you can stop whenever you like.

Level 1Move the cursor onto the
1function averageRating(reviews: Review[]) {
1 if (reviews.length === 0) return 0;
2 const sum = reviews.reduce((acc, r) => acc + r.stars, 0);
3 const avg = sum / reviews.length;
4 return Math.round(avg * 10) / 10;
5}
6
7const best = reviews.filter((r) => r.stars === 5);
8console.log("five-star reviews:", best.length);
NORMALLoading the editor…lv 1 · 0 done0.0s1:1

This exercise needs a keyboard. Read on, and play it at your computer.