zsh Cheatsheet

5.9

Get more from your shell

Essential zsh shortcuts, tricks, and keybindings for your terminal

Official docs →
Line editingHistory tricksGlobbing & aliases

Last updated: 2026-03-29

zsh is the default shell on macOS and gaining serious ground on Linux, and for good reason — it takes everything bash does and adds smarter completion, better globbing, and a plugin ecosystem that can turn your terminal into something genuinely enjoyable to use. If you've been using zsh without knowing it (thanks, macOS Catalina), you've been driving a sports car in first gear.

The real power of zsh lives in its line editor. Those Ctrl and Alt key combos aren't random — they come from Emacs-style editing, which is the default mode. Every time you hit Ctrl-a to jump to the start of a line, you're using the same binding that Emacs users have been using since the 1970s. You can also switch to vi mode if that's your thing, but start with the defaults. They're surprisingly good once you internalize them.

This cheatsheet focuses on what'll make you faster right away: line navigation so you stop reaching for the arrow keys, history tricks that save you from retyping commands, globbing patterns that let zsh find files for you, and enough oh-my-zsh knowledge to set up a productive environment without drowning in options. We're skipping the 400-page manual and keeping the stuff that pays off daily.

Line Navigation

These work in the default Emacs mode (which is what you're using unless you've explicitly switched to vi). Burn these into muscle memory and your hands never leave the home row.

Line Navigation
Ctrl-a
Jump to the beginning of the line
Ctrl-e
Jump to the end of the line
Alt-f
Move forward one word
Alt-b
Move backward one word
Ctrl-f
Move forward one character
Ctrl-b
Move backward one character
Ctrl-w
Delete the word before the cursor
Alt-d
Delete the word after the cursor
Ctrl-k
Kill (cut) from cursor to end of line
Ctrl-u
Kill (cut) from cursor to beginning of line
Ctrl-y
Yank (paste) the last killed text
Ctrl-t
Swap the two characters before the cursor
Ctrl-l
Clear the screen (keeps current line)
Ctrl-_
Undo the last edit

History

Your shell history is a goldmine. zsh keeps thousands of commands by default, and these shortcuts help you mine them efficiently instead of mashing the up arrow 47 times.

History
Ctrl-r
Reverse search through history (type to filter)
Ctrl-s
Forward search through history
Ctrl-p
Previous command (same as Up arrow)
Ctrl-n
Next command (same as Down arrow)
!!
Repeat the entire last command
sudo !!
Re-run the last command with sudo (lifesaver)
!$
Insert the last argument of the previous command
!^
Insert the first argument of the previous command
!*
Insert all arguments of the previous command
!<string>
Run the most recent command starting with <string>
!<n>
Run command number <n> from history
history
Show recent command history
history -10
Show the last 10 commands
fc
Open the last command in your $EDITOR for editing

Globbing

This is where zsh leaves bash in the dust. zsh's globbing is so powerful it can replace find for most day-to-day file searches. No pipes, no subshells, just patterns.

Globbing
*
Match any string in the current directory
**/*
Match files recursively in all subdirectories
?
Match any single character
[abc]
Match any one of the listed characters
[a-z]
Match any character in the range
[^abc]
Match any character NOT in the list
*.{js,ts}
Match files ending in .js or .ts (brace expansion)
**/*.py
Find all Python files recursively
*(.)
Match only regular files (not directories)
*(/)
Match only directories
*(@)
Match only symlinks
*(m-7)
Files modified in the last 7 days
*(Lk+100)
Files larger than 100 KB
*(om[1,5])
The 5 most recently modified files

Aliases

Aliases are how you make zsh feel like your own. Here are the patterns worth knowing — the specific aliases are up to you, but these forms unlock the most productivity.

Aliases
alias ll="ls -lah"
Simple command alias
alias -g G="| grep"
Global alias — works anywhere in a command (ls G foo)
alias -g L="| less"
Global alias for piping to less
alias -g NE="2>/dev/null"
Global alias to suppress errors
alias -s py=nvim
Suffix alias — typing file.py opens it in nvim
alias -s json=jq .
Suffix alias — typing data.json pretty-prints it
alias -s md=glow
Suffix alias — render markdown files in the terminal
unalias <name>
Remove an alias
alias
List all active aliases
which <command>
Show what a command or alias resolves to

Key Bindings

zsh's line editor (zle) is fully customizable. You can rebind any key to any action, and there are hundreds of built-in widgets to choose from.

Key Bindings
bindkey
List all current key bindings
bindkey -e
Use Emacs key bindings (the default)
bindkey -v
Switch to vi key bindings
bindkey "^X^E" edit-command-line
Bind Ctrl-x Ctrl-e to edit current line in $EDITOR
bindkey "^[[A" history-search-backward
Up arrow searches history matching current input
bindkey "^[[B" history-search-forward
Down arrow searches history matching current input
bindkey "\e." insert-last-word
Alt-. inserts the last word of the previous command
bindkey -l
List available keymaps
zle -la
List all available zle widgets

Vi Mode

If you're a vim/nvim user, vi mode makes zsh feel like home. You get normal mode, insert mode, and most of the motions you already know.

Vi Mode
bindkey -v
Enable vi mode
Esc
Switch to normal mode
i
Enter insert mode
a
Enter insert mode after cursor
0
Jump to beginning of line (normal mode)
$
Jump to end of line (normal mode)
w / b
Move forward / backward by word (normal mode)
dd
Delete the entire line
dw
Delete from cursor to end of word
ci"
Change inside quotes (and other text objects)
v
Enter visual mode for selecting text
/
Search command history (normal mode)

oh-my-zsh Essentials

oh-my-zsh is the most popular zsh framework, and it earns it. But with 300+ plugins, it's easy to bloat your config. Here are the plugins and patterns that are actually worth loading.

oh-my-zsh Setup
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
Install oh-my-zsh
plugins=(git z fzf)
Enable plugins in ~/.zshrc (space-separated list)
ZSH_THEME="robbyrussell"
Set your theme in ~/.zshrc
omz update
Update oh-my-zsh to the latest version
omz plugin list
Show all available plugins
omz theme list
Show all available themes
source ~/.zshrc
Reload your config after changes
Recommended Plugins
git
Adds 100+ git aliases (gst, gco, gp, gl, etc.)
z
Jump to frequently visited directories by partial name
fzf
Fuzzy-find files, history, and more with Ctrl-r / Ctrl-t
zsh-autosuggestions
Fish-style suggestions based on your history (ghost text)
zsh-syntax-highlighting
Colors your commands as you type — red means typo
sudo
Press Esc twice to prepend sudo to the current or last command
copypath
Copy the current directory path to the clipboard
web-search
Search Google/GitHub/Stack Overflow right from the terminal

Tips

Add setopt AUTO_CD to your ~/.zshrc and you can navigate directories by just typing the path — no cd required. Type .. to go up a directory, ~/projects to jump home. Once you get used to this, typing cd feels like wasted keystrokes.

The zsh-autosuggestions plugin is arguably the single biggest productivity boost you can add. It shows ghost text predictions as you type based on your history. Press the right arrow key to accept the whole suggestion, or Alt-f to accept just the next word. Install it and wonder how you ever lived without it.

Use Ctrl-x Ctrl-e (after binding it with autoload -z edit-command-line && zle -N edit-command-line && bindkey '^X^E' edit-command-line) to open the current command line in your $EDITOR. Long commands with pipes and loops are way easier to compose in nvim than on a single terminal line.

Configure your history properly. Add these to ~/.zshrc and you'll never lose a command again: HISTSIZE=50000, SAVEHIST=50000, setopt SHARE_HISTORY (sync across sessions), setopt HIST_IGNORE_DUPS (skip consecutive duplicates), setopt HIST_IGNORE_SPACE (prefix with space to keep it out of history — handy for commands with secrets).

zsh's recursive globbing (**/*) is powerful enough to replace basic find usage. Want all TypeScript files? ls **/*.ts. Want to delete all .DS_Store files? rm -f **/.DS_Store. It's faster to type and easier to remember than find . -name "*.ts".

If Alt key combos don't work in your terminal (common on macOS), go to your terminal's preferences and enable "Use Option as Meta key." In iTerm2 it's under Profiles > Keys. In Terminal.app, it's under Settings > Profiles > Keyboard. Without this, Alt-f, Alt-b, and Alt-d are dead on arrival.

Suffix aliases are an underrated zsh feature. Add alias -s py=python3 to your ~/.zshrc and you can run a Python script by just typing its filename: script.py instead of python3 script.py. Works for any extension — map .json to jq ., .md to your markdown viewer, .log to less.

Related Tools