Shortcuts
Learn six shortcuts first. The rest builds on them.
- Split side by side with D
- Split top and bottom with D
- Move between panes with ← ↓ ↑ →
- Close what's focused with W
- New tab with T
- Open Settings with ,
Pane movement is ⌘⌥ and the direction you want to go. Prefer vim's keys? Four lines in your config move it:
keybind = nav_left=ctrl+h
keybind = nav_down=ctrl+j
keybind = nav_up=ctrl+k
keybind = nav_right=ctrl+l[ and ] step through the panes in order instead, wrapping at both ends. Open drawers are in the ring, so focus never cycles out of one without a way back.
Coming from Ghostty
These are Ghostty's chords. Open ZenTerm after Ghostty and your hands already know where things are.
Two places ZenTerm keeps its own answer. The bracket pair steps tabs here, the way it does in Safari and the rest of the Mac, where Ghostty spends it on panes. That inverts the whole family: tabs take [ and ], panes the shifted pair.
⌃⌘F stays unbound. Ghostty spells fullscreen that way as well as ⏎, but ⌃⌘F is macOS's own native-fullscreen chord and Fill Screen is a maximize, so answering it would promise a space switch it does not make.
Ghostty's ⌃⇥ tab cycling is not bound either, because ]
already is. Add keybind = next_tab=ctrl+tab if you want it back.
Find any command
Press P and type what you want. The command palette lists each action with its shortcut beside it, so it doubles as a reference while you learn. P opens the workspace picker.
A link in the terminal needs a ⌘-click to open. Hold ⌘ and the link underlines and becomes clickable. A plain click does nothing, because a terminal is full of text that only looks like a link.
Read back through a pane
S puts the focused pane in scroll mode. The pane header reads SCROLL and shows how far below the viewport the buffer runs, a band marks the row you are on, and what you type stops at the app.
Scroll mode is a mode because the keys it wants belong to the shell. You use
j, k, ctrl+d and ctrl+u inside your programs, so ZenTerm cannot hold them
as chords. Borrowing them for the length of a read is the trade.
| Keys | What they do |
|---|---|
j k or ↑ ↓ | Move the cursor a row. The buffer scrolls once the cursor hits an edge |
h l or ← → | Move a column |
w b e | Move by word |
W B E | Move by WORD, whitespace-delimited, so foo.bar is one where w sees three |
0 ^ $ | The start of the row, the first thing on it that is not whitespace, the end |
{ } | Move by paragraph, which in a terminal is one command's output |
f F t T | Find a character on the row, forward or back, landing on it or beside it |
; , | Do that find again, or back the other way |
H M L | The top, middle, and last written row on screen |
ctrl+d ctrl+u | Half a screen through the buffer |
ctrl+f ctrl+b or space | A full page |
gg G | Top and bottom of the buffer |
* | Find the word under the cursor in the rest of the buffer |
esc q i | Leave |
Every motion takes a count, so 12j moves twelve rows and 3} skips three blocks
of output. 0 is the start of the row on its own and a digit once a count is
underway, which is vim's own rule: without it 10j would jump to column 0 and
step once.
ctrl+d and ctrl+u carry the cursor with them. The cursor walks
half a screen down the buffer and the view takes as much of that as it can, so the
band parks mid-screen while the text runs past it. Where the view runs out of
buffer the cursor makes the rest of the trip, which is the only way to reach the
last half page by paging.
Your own chords still work inside the mode, so T and pane navigation are never swallowed. The mode ends on its own when focus moves, the pane closes, you change tab, or a tool float or the palette opens.
With a tool float open, S and F read the float's buffer instead of the pane behind it. The card wears the header while they are up, and closing the card ends the mode. Clearing the screen, the prompt jumps and the screen-to-file chords reach a float too.
Select and copy what you read
v starts a selection at the cursor and V takes whole rows. Motions grow it,
y copies it and pulses what it took, and esc hands the selection back without
leaving the mode. With nothing selected, y waits for the second y that names
whole rows, so 3yy copies three.
A selection follows its text. Scrolling grows it by the rows that arrive, and resizing the pane re-finds it where the rewrap put it. It goes when the row you started on leaves the screen, which is as far as the terminal core can read.
Search the scrollback
F opens a find bar along the bottom of the focused pane and searches its whole scrollback, however far back it runs. Matches highlight as you type and the bar counts them. If what you typed sits in history, the pane scrolls to it while you type.
The bar opens on whatever you have selected, so a word you can see costs no
retyping. A mouse selection counts and so does a v selection made in scroll
mode. E searches the selection alone, and does nothing
when there is no selection.
Press Return and the keys go back to the pane, leaving you in scroll mode on the
match, where n and N step through the rest and v, V and y copy what you
found. Stepping is those keys rather than a chord, so search_next and
search_previous ship with no shortcut. Give them one if you want to step from
anywhere.
The count reads in the order you see, so match 1 is the one nearest the top of your scrollback. Stepping does not wrap.
The bar and a live prompt never share the screen, so leaving scroll mode any way at all takes the bar down with it. Close the bar and you land back where you opened it. Typing past the last match does the same, so you are never parked on something that stopped matching.
Move the viewport without the mode
For when you want a look rather than a read.
Home and End go to the ends of the buffer, Page Up and Page Down move a screen at a time, and ↑ and ↓ walk between the prompts your shell marked. All of them repeat while you hold them, and they work on a focused drawer too.
The prompt jumps take Ghostty's shifted spelling and not its bare ⌘↑ and ⌘↓. macOS claims that pair on most Macs, so the keypress never arrives. Bind them if yours are free. Prompt marks come from shell integration, so a shell that sets none leaves the jumps with nothing to find.
Work on the screen itself
- Clear the screen, and the scrollback with it, using K
- Select the whole buffer, ready for ⌘C, using A
- Scroll back to the selection with J
- Paste what you have selected with V
- Write the screen to a file with J
V types your selection back into the pane. Either
kind counts, a mouse selection or a v selection from scroll mode, and ⌘V still
pastes the clipboard.
K leaves a full-screen program alone: vim and its kind draw on a second screen with no scrollback to clear.
The write has two other endings. J copies the path instead and J opens the file. The file is written either way, so the three differ only in where the path goes. Reach for it when a wall of output is easier to grep than to read.
A comes from Edit → Select All. A menu shortcut reaches
a text field and a pane both, which a keybind cannot. Two things follow: any
keybind or tool float key: landing on ⌘A is refused with a notice, and
select_all=none cannot hand the chord back to your program. Bind
select_all to another chord and it works over a pane like anything else.
Clear a notice
ZenTerm posts a card when a background tab needs you or a long command finishes in one. N takes the oldest, so presses walk down the stack, and N takes the lot. A card holding the keyboard also answers Return and Esc directly.
Whether a card waits to be answered or clears itself is attention-toast and
completion-toast in your
config, both sticky by default, and
toast-duration sets how long anything that clears itself stays up.
Change the font size
= and - step the font, and
0 returns to the font-size in your
config. All three apply to every pane in every
tab and window, so your panes stay in step.
Take a shortcut away
Point an action at none and the chord reaches your program instead:
keybind = clear_screen=noneK then goes to whatever runs in the pane. Settings does the same thing: open Shortcuts, select the row, and press Delete. Moving an action to another chord frees the old one the same way.
Each action holds exactly one shortcut, so there is one place to look when you want to change something, and rebinding moves the whole action.
Hide a toolbar button
Settings under Appearance hides any of the footer toolbar's built-in buttons,
and hide-toolbar-buttons does it from the config. The shortcut and the palette
entry stay live either way. A tool float takes toolbar:false for the same
reason: the toolbar button goes and the chord stays.
The full set
The keybind reference has every default shortcut, grouped by category. Remap any of them in Settings under Shortcuts, or in your config.