Zsh keyboard shortcuts

This page lists the default key bindings of the Zsh line editor (ZLE) in its emacs keymap, taken from the Standard Widgets list of the zsh 5.9.2 manual. The vi command and insert keymaps and widgets without a default key are left out. Sequences such as Esc, B mean press Esc, then the key; holding Alt instead works when the terminal sends Alt as an Esc prefix. Zsh starts in the vi keymap when VISUAL or EDITOR contains vi.

69 shortcuts in 7 sections. Checked row by row against Zsh manual 5.9.2 on . Edited by Jay.

Cursor movement 11

Bindings the manual prints with an ESC- prefix are sequences: press Esc, release it, then press the key. Holding Alt instead works when the terminal sends Alt as an Esc prefix; the manual itself names the alt key for the numeric argument.

ActionEmacs keymap
Back one charMoves the cursor one character to the left.Ctrl+B
Cursor leftRuns the same widget as Ctrl + B, bound through the sequence the terminal reports for its left cursor key.Left
Forward one charMoves the cursor one character to the right.Ctrl+F
Cursor rightRuns the same widget as Ctrl + F; the manual shows the VT100 form of this cursor key as ESC-[C.Right
Back one wordLands on the first character of the word before the cursor.EscthenB
Forward one wordJumps to the start of the following word; the WORDCHARS parameter decides which characters count as part of a word.EscthenF
Start of linePressed again at the start, it goes on to the start of the line above in a multi-line buffer.Ctrl+A
End of lineAt the end already, it moves on to the last position of the following line, if one exists.Ctrl+E
Find next characterWaits for one more key, then moves to where that character next appears in the line.Ctrl+XthenCtrl+F
Go to columnTakes the column number from a numeric argument typed beforehand.Escthen|
Match bracketJumps to the partner of the brace, parenthesis or square bracket at the cursor; elsewhere it first looks ahead for one.Ctrl+XthenCtrl+B

Deleting and yanking text 12

Ctrl + ? stands for the Delete character, which the manual writes as ^?. Many terminals send that character, and others Ctrl + H, when Backspace is pressed.

Ctrl + D is normally also the end-of-file character. Zsh exits on end-of-file unless the IGNORE_EOF option is set, and with it set still exits after ten in a row.

ActionEmacs keymap
Delete previous charRemoves the character to the left of the cursor; the second binding is the Delete character, written ^? in the manual.Ctrl+HorCtrl+?
Delete char or list choicesRemoves the character at the cursor; with the cursor after the last character it lists completions for the current word.Ctrl+D
Delete word beforeKills the word to the left of the cursor, so a yank can bring it back.Ctrl+WorEscthenCtrl+HorEscthenCtrl+?
Delete word afterA kill, not a plain delete: the current word goes to the kill buffer.EscthenD
Kill to endKills from the cursor to the line end; already there, it kills the newline character instead.Ctrl+K
Kill whole lineTakes only the current line; Ctrl + X, Ctrl + K is the widget for the entire buffer.Ctrl+U
Kill bufferKills everything in the editing buffer, every line of a multi-line command included.Ctrl+XthenCtrl+K
Yank killed textPuts the most recently killed text back in at the cursor.Ctrl+Y
Yank popRight after a yank, swaps the inserted text for the previous entry of the kill ring; repeat to go further back.EscthenY
Set markDrops the mark where the cursor is; the region between mark and cursor becomes active.Ctrl+@
Exchange point and markSwaps the cursor with the mark and activates the region between the two for highlighting.Ctrl+XthenCtrl+X
Copy regionPlaces the text between cursor and mark in the kill buffer and leaves the line as it is.EscthenW

Editing text 13

ActionEmacs keymap
Transpose charsSwaps the character at the cursor with its left neighbour; at the end of a line it swaps the last two.Ctrl+T
Transpose wordsSwaps the current word with the word in front of it.EscthenT
Capitalize wordApplies to the current word and leaves the cursor after it.EscthenC
Lowercase wordTurns every letter of the current word into lower case, then steps past the word.EscthenL
Uppercase wordTurns the current word into capitals and puts the cursor behind it.EscthenU
Copy previous wordInserts a second copy of the word just before the cursor.EscthenCtrl+_
Join linesMerges the current line of a multi-line buffer with the one below it.Ctrl+XthenCtrl+J
Toggle overwrite modeSwitches typing between overwriting and inserting; a second press switches back.Ctrl+XthenCtrl+O
Quoted insertTakes the next character typed literally, so a control character lands in the buffer; an interrupt character is still not inserted.Ctrl+V
Quote lineWraps the current line in single quotes and escapes the single quotes already inside it.Escthen'
Quote regionWorks on the text between the mark and the cursor instead of the full line.Escthen"
Insert tab or newlinePuts the control character typed after Esc into the buffer; a carriage return (Ctrl + M) is stored as a line feed.EscthenCtrl+IorEscthenCtrl+JorEscthenCtrl+M
Undo last changeWorks step by step: each press takes back one more modification of the text.Ctrl+_orCtrl+XthenUorCtrl+XthenCtrl+U

History 13

Ctrl + S and Ctrl + Q are usually the terminal's stop and start characters. They reach the editor once flow control is switched off there with unsetopt FLOW_CONTROL.

ActionEmacs keymap
Previous commandRecalls the previous history event once the cursor is on the top line of the buffer; before that it moves up a line.Ctrl+P
Line up or previous commandThe up cursor key runs the same widget as Ctrl + P.Up
Next commandMoves down a line inside a multi-line buffer and, from the bottom line, on to the next history event.Ctrl+N
Line down or next commandThe down cursor key runs the same widget as Ctrl + N.Down
Buffer start or oldest historyJumps to the first position of the buffer; pressed there, it loads the oldest entry of the history list.Escthen<
Buffer end or newest historyJumps to the last position of the buffer first, and from there to the newest history event.Escthen>
Search historySearches older entries as you type; lower-case search text ignores case, and a leading ^ anchors the match to the line start.Ctrl+RorCtrl+XthenR
Search history forwardThe same incremental search toward newer entries, with the same editing keys in its mini-buffer.Ctrl+SorCtrl+XthenS
History search backwardLooks through older history for a line that starts with the first word now in the buffer.EscthenP
History search forwardMatches on the first word of the buffer as well, but moves toward newer history lines.EscthenN
Infer next historyFinds a history line identical to the current one and fetches the event that came after it.Ctrl+XthenCtrl+N
Insert last argumentInserts the final word of the previous history event; pressed again, it swaps in the final word of the event before.Escthen.orEscthen_
Run line and fetch nextRuns the current line, then puts the history event that follows it on the buffer stack for the next prompt.Ctrl+O

Completion and expansion 6

ActionEmacs keymap
Expand or completeExpands the current word where the shell can, and otherwise attempts completion.Tab
List choicesShows the possible completions of the current word.EscthenCtrl+D
Expand historyResolves the history references in the edit buffer in place, before the line is run.EscthenSpaceorEscthen!
Expand wordApplies shell expansion to the word at the cursor; unlike Tab it does not go on to completion.Ctrl+Xthen*
List expansionDisplays what the current word would expand to.Ctrl+XthenG
Correct spelling of wordAttempts the correction on the current word only.Escthen$orEscthenS

Running commands 6

ActionEmacs keymap
Accept lineEnds editing and normally runs the buffer as a shell command; Ctrl + M is the character sent by Return.Ctrl+JorCtrl+M
Accept and holdRuns the buffer and also keeps it on the buffer stack, so the same text is loaded at the next prompt.EscthenA
Push lineClears the buffer and saves it on the buffer stack; the next time the editor starts, the saved text is loaded again.Ctrl+QorEscthenQ
Get lineBrings back the most recently pushed line from the buffer stack, inserting it at the cursor.EscthenG
Run helpSaves the buffer, then runs run-help for the command being typed; run-help is normally an alias for man.EscthenH
Which commandSaves the buffer, then runs which-command on the current command; by default that is an alias for whence.Escthen?

Editor control and arguments 8

ActionEmacs keymap
Clear screenClears the terminal and redraws the prompt.Ctrl+LorEscthenCtrl+L
Send breakAborts the running editor function or, outside one, the line itself, which stays available in ZLE_LINE_ABORTED.Ctrl+GorEscthenCtrl+G
Execute named commandPrompts for a widget name in a mini-buffer and runs that widget.EscthenX
Repeat last named commandRuns again the widget most recently called through Esc, X.EscthenZ
Digit argumentStarts a numeric argument or appends a digit to it; most widgets then repeat that many times.Escthen0-9
Negative argumentMakes the numeric argument typed next negative.Escthen-
Enter vi command modeLeaves the emacs keymap and selects vicmd, the keymap of vi command mode.Ctrl+XthenCtrl+V
Show cursor positionPrints the character at the cursor with its code in octal, decimal and hexadecimal, plus the buffer position and column.Ctrl+Xthen=

Notes

You are editing with Emacs bindings

Zsh's line editor (ZLE) starts in Emacs keymap for most setups, which is why these keys look familiar to Bash users: Ctrl + A and Ctrl + E jump to the ends of the line, Esc, F / Esc, B step by words (Esc first, then the letter — or hold Alt where the terminal sends it as an Esc prefix), Ctrl + F / Ctrl + B by characters. The deletion keys are kills, not deletes: Ctrl + U kills the whole line, Ctrl + K to the end, Ctrl + W the word behind, Esc, D the word ahead — and everything killed lands in a ring that Ctrl + Y yanks back. Cut-and-paste on the command line, no mouse involved. Ctrl + _ undoes edits.

History is the other half: Ctrl + R opens incremental search, Ctrl + P / Ctrl + N walk previous and next commands, and Esc, . inserts the last argument of the previous command — press it repeatedly to reach earlier commands' arguments. Tab completes, Ctrl + L clears the screen without losing your input.

The two keys people underuse

Esc, Q (push-line) stashes whatever you are typing, gives you a fresh prompt to run something else — check a path, read a man page — and restores your original line afterwards, untouched. It removes the classic dilemma of abandoning a half-written command. And know Ctrl + D's double life: with text on the line it deletes the character under the cursor (at the very end of the text it lists completions instead); on an empty line it sends end-of-file and exits the shell — the source of many accidentally closed terminals.

Questions

These bindings don't work in my zsh. Why?

You are probably in the Vi keymap — zsh selects it automatically when your VISUAL or EDITOR variable contains vi (vi, vim, nvim). Run bindkey -e to switch to Emacs bindings (add it to ~/.zshrc to make it stick), or embrace bindkey -v and use Vi-style editing instead.

What is the difference between killing and deleting?

Killed text (Ctrl + U, Ctrl + K, Ctrl + W, Esc, D) is saved to the kill ring and can be reinserted with Ctrl + Y — it is cut, not destroyed. Plain character deletion is gone for good (though Ctrl + _ can undo the edit).

Why does the table say Esc where I expected Alt, and why does Alt do nothing on my Mac?

The zsh manual prints these bindings with an Esc prefix: Esc, F is Esc pressed and released, then F. Holding Alt gives the same result only when the terminal sends Alt as that Esc prefix. macOS terminals type accented characters on Option by default; in Terminal.app or iTerm2, enable the profile setting that uses Option as Meta (Esc+), and Option with F, B or . starts working immediately.

When would I actually use Esc, Q?

Mid-command realisations: you are halfway through a long command and need to check a filename or free disk space first. Esc, Q stashes the line, you run the check, and the stashed command reappears at the next prompt ready to finish — no copy-paste, nothing lost.

Ctrl + D just closed my terminal. Can I prevent that?

On an empty line Ctrl + D means end-of-file, which ends the shell. Add setopt IGNORE_EOF to ~/.zshrc and zsh will ignore it (asking you to type exit instead; ten in a row still exit), while keeping the delete-character behaviour when the line has content.

Sources and checks

Every row on this page was matched to a line in the documentation above on . A binding that could not be found there is not listed.

Found a wrong or missing key? Tell us and it gets checked against the source. How we verify describes the process and its limits.