Mastering fzf's basic navigation and keybindings: moving through the item list with vim-style keys and jump mode, editing the query with readline shortcuts, and selecting and exiting correctly, including multi-select.

After episode 4 had you design fzf's appearance — height, layout, border, prompt, and colors — now it is time to learn how to move quickly inside it. This episode covers basic navigation & keybindings: how to browse the item list, how to edit the query you're typing, and how to select and exit correctly — including multi-select mode.
One principle ties it all together: fzf adopts two languages you already know. To move through the list, fzf uses the Vim language (j/k). To edit the query, fzf uses the readline language (Ctrl+A, Ctrl+E, and so on) — the same language as your shell. If you are already comfortable with either one, half the work is done.
fzf's interface has two areas that respond differently to keys: the item list and the query. When focus is on the list, j/k move the pointer; when you are typing, the same keys go into the query as letters. This is why fzf feels "smart": you don't need to press a mode key to switch between typing and navigating — you just type to search, and press arrow keys when you want to move through results.
printf "episode-0\nepisode-1\nepisode-2\nepisode-3\nepisode-4\nepisode-5\n" | fzf --height=40% --borderUse the dataset above to try every keybinding in this episode. Type episode to narrow the list, then move the pointer — you are now practicing in both areas at once.
The following keybindings move the pointer through the item list:
| Key | Function |
|---|---|
j / Ctrl+J | Move to the next item (down) |
k / Ctrl+K | Move to the previous item (up) |
PageUp | Jump up one page |
PageDown | Jump down one page |
Home | Go straight to the first item |
End | Go straight to the last item |
Ctrl+Space | Enter jump mode |
Note that Ctrl+J and Ctrl+K are counterparts of j and k — useful in terminals that translate Ctrl+J into a newline. When only a few items remain, j/k feel most comfortable; when the list is long, PageDown and End are far more efficient than pressing j twenty times.
There is one feature that is often overlooked despite being very powerful: jump mode, activated with Ctrl+Space. Once activated, fzf displays letter labels in front of each visible item — similar to easy-motion in Vim:
| Input | Function |
|---|---|
Ctrl+Space | Enter jump mode; show letter labels in front of items |
a-z | Jump directly to the item labeled with that letter |
Once jump mode is active, type the letter shown in front of your target item — the pointer jumps there immediately without pressing arrows repeatedly. For a long list already filtered down to a few items, jump mode turns twenty keypresses into one. Custom keybindings for the jump-accept variant (jump and accept at once) will be covered in the episode about custom keybindings.
To feel the difference, try it on the practice dataset above: without jump mode, press End then k four times to reach the second item; with jump mode, press Ctrl+Space then a single letter. Once you feel it, jump mode becomes a reflex.
The fzf query behaves like a mini command line — and this is where the readline language comes in:
| Key | Function |
|---|---|
Ctrl+A | Move the cursor to the start of the query |
Ctrl+E | Move the cursor to the end of the query |
Ctrl+F | Move forward one character |
Ctrl+B | Move backward one character |
Ctrl+U | Delete from the cursor to the start of the query |
Ctrl+W | Delete one word behind the cursor |
Ctrl+Y | Paste back (yank) what was deleted |
printf "build\nbuild-images\nbuild-cache\nbuildx\n" | fzf --height=40% --borderTry typing build-cache, then press Ctrl+A (cursor to start), Ctrl+W (delete the first word, build-), then Ctrl+Y to paste it back. Ctrl+U deletes the whole query at once — the fastest way to start from scratch — and Ctrl+Y brings it back if you change your mind. These combinations feel like typing in a normal shell, because that is exactly the same language.
Once the item you want is active, it's time to select and exit. These are the four most important keys in all of fzf:
| Key | Function |
|---|---|
Enter | Accept the active item; print it to stdout; exit with code 0 |
Esc | Cancel without selecting; exit with code 1 |
Ctrl+C | Interrupt; exit with code 130 |
Tab | Toggle-select the active item (requires multi-select mode) |
Shift+Tab | Toggle-deselect the active item |
Remember the exit code language from episode 2? This is where it comes into action: Enter means 0 (something selected), Esc means 1 (nothing selected), and Ctrl+C means 130 (canceled). Scripts using fzf || exit 1 rely on these differences to make decisions.
To select more than one item, fzf must be run with the --multi option:
printf "a\nb\nc\nd\n" | fzf --multi --height=40% --borderNow Tab marks the active item as selected (marked with the marker symbol we configured in episode 4), and Shift+Tab undoes the mark. After pressing Enter, fzf prints all selected items — one per line — to stdout, ready to be passed to the next command, for example fzf --multi | xargs rm. Be careful with that last command: once you press Enter, there is no undo button.
Tip
A frequently used multi-select workflow: type a pattern to filter, press Tab on the items you want, press Enter to collect them all. If you mark the wrong one, Shift+Tab undoes it — and Ctrl+U on the query won't save selections that are already marked, because the selection is separate from the query.
In this episode 5, you mastered fzf's basic navigation and keybindings: two focus areas (list and query), navigation with j/k, PageUp/PageDown, Home/End, and jump mode via Ctrl+Space, query editing with readline shortcuts (Ctrl+A/E, Ctrl+U/W, Ctrl+F/B, Ctrl+Y), and how to select and exit with Enter, Esc, Ctrl+C, Tab, and Shift+Tab.
The key takeaways:
j/k or Ctrl+J/Ctrl+K for fine steps, PageUp/PageDown for jumps, Ctrl+Space for jump mode.Ctrl+A/E to the ends, Ctrl+U/W to delete, Ctrl+Y to paste back — the readline language.Enter (code 0), Esc (code 1), Ctrl+C (code 130).Tab marks, Shift+Tab unmarks, requires the --multi option.In the next episode, episode 6, we will cover multi-select transformations & ANSI — how to make use of multiple selected items with output transformations and how to handle colored (ANSI) text inside the list. See you in episode 6!