You know that thing where you press ⌘← to jump to the start of a line and Ghostty just... prints ^A?
Yeah. Let's fix that.
The Problem
macOS has beautiful text navigation shortcuts:
- ⌥← / ⌥→ → Jump by word
- ⌘← / ⌘→ → Jump to start/end of line
- ⌘⌫ → Delete everything before cursor
These work everywhere—Notes, VS Code, your browser—except Ghostty. Instead, you get garbage like this:
python -m venv .venv && source .venv/activate^E^A^E^A
Not great.
The Fix
Two things need to happen:
1. Tell Ghostty to treat Option as Alt
Create or edit your Ghostty config:
mkdir -p ~/.config/ghostty
nano ~/.config/ghostty/config
Add this line:
macos-option-as-alt = true
Save and restart Ghostty (it doesn't hot-reload config changes).
2. Put zsh in emacs mode
This is the part that got me. Even with the right Ghostty config, my shell wasn't interpreting the escape codes.
Run this:
bindkey -e
If it works, make it permanent:
echo "bindkey -e" >> ~/.zshrc
That's it. You're done.
Why This Happens
Those ^A and ^E characters are actually the correct escape codes for "beginning of line" and "end of line"—your shell just wasn't listening.
| Shortcut | What it sends | Action |
|---|---|---|
| ⌘← | Ctrl+A |
Beginning of line |
| ⌘→ | Ctrl+E |
End of line |
| ⌥← | \x1bb |
Back one word |
| ⌥→ | \x1bf |
Forward one word |
The bindkey -e command puts zsh into emacs mode, which is what makes it understand these codes. Some shell configs (especially if you're using oh-my-zsh or other frameworks) might override this, which is why it's worth adding explicitly.
Coming from Warp?
If you switched from Warp to Ghostty, this is probably the first thing that felt broken. Warp handles this natively because it's built differently. Ghostty is a traditional terminal emulator, so it needs a little help.
Now you've got the best of both worlds—Ghostty's speed and simplicity with the keybindings your fingers expect.
Tested on Ghostty + zsh on macOS.
Top comments (0)