Claude Code Terminal Setup: Shift+Enter, Bells, Themes

Support varies by terminal. Ghostty, Kitty, iTerm2, WezTerm, Warp, Apple Terminal and Windows Terminal work with no setup. VS Code, Cursor, Devin Desktop, Alacritty and Zed need the /terminal-setup command run once. gnome-terminal and JetBrains IDEs do not support it — use Ctrl+J or a backslash followed by Enter, which work everywhere.
By default Claude Code sends a desktop notification only in Ghostty, Kitty and iTerm2, and iTerm2 needs alerts and escape-sequence-generated alerts enabled in its own settings. In any other terminal, set preferredNotifChannel to terminal_bell, or configure a Notification hook for a custom sound or command.
Three lines in ~/.tmux.conf: allow-passthrough on, extended-keys on, and the extkeys terminal feature. The passthrough line lets notifications and progress updates reach the outer terminal instead of being swallowed by tmux, and the extended-keys lines let tmux distinguish Shift+Enter from plain Enter.
Your terminal is sending the control code that Claude Code reads as the word-delete key. Set CLAUDE_CODE_BS_AS_CTRL_BACKSPACE to 0 and both Backspace and Ctrl+H erase one character each. If you have the opposite problem on macOS or Linux, set the same variable to 1 instead.
Save a JSON file in ~/.claude/themes/ with an optional name, a base preset such as dark or dark-daltonized, and an overrides map of colour tokens. The filename without .json is the slug. Unknown tokens and invalid values are ignored, so a typo cannot break rendering, and the folder is watched so edits apply without a restart.

Key Takeaway
Claude Code works in any terminal without configuration. The settings on this page exist for specific symptoms: Shift+Enter submitting instead of inserting a newline, Option-key shortcuts doing nothing on macOS, no alert when Claude finishes, and Backspace deleting a whole word on Windows. Each has a one-line fix.
I spent a week pressing Ctrl+J for newlines because Shift+Enter submitted my half-written prompt the first time I tried it, and I filed that away as how the tool works. It is not. My terminal was one of the handful that needs a single command run once, and the command had been sitting there the whole time.
Terminal configuration for Claude Code is not a tutorial you work through, it is an index you consult when something specific misbehaves. This post is organised that way: the newline problem and which terminals have it, the macOS modifier that silently disables a set of shortcuts, notifications and why most terminals get none by default, the three tmux lines, custom themes, and what happens to a large paste you recall from history weeks later.
Enter submits. Two ways of inserting a line break work everywhere with no setup at all, and it is worth learning one of them rather than fighting the third — but the third is what everybody reaches for, so here is where it stands.
# Enter submits. For a line break WITHOUT submitting:
# Ctrl+J works in every terminal, no setup
# \ then Enter same
# Shift+Enter depends on the terminal
/terminal-setup # writes the Shift+Enter binding into the
# terminal's own config file
# Run it in the HOST terminal, not inside tmux or screen — it
# needs to write to the host terminal's configuration.
#
# In VS Code, Cursor and Devin Desktop it also sets
# terminal.integrated.gpuAcceleration to "off", which prevents
# garbled text in the integrated terminal, and adjusts the
# mouse wheel sensitivity for fullscreen mode.
#
# To swap the behaviour entirely — Enter inserts a newline and
# Shift+Enter submits — map chat:newline and chat:submit in
# your keybindings file instead.Shift+Enter support by terminal:
| Terminal | Shift+Enter for a newline |
|---|---|
| Ghostty, Kitty, iTerm2, WezTerm, Warp, Apple Terminal, Windows Terminal | Works with no setup |
| VS Code, Cursor, Devin Desktop, Alacritty, Zed | Run the terminal-setup command once |
| gnome-terminal, JetBrains IDEs such as PyCharm | Not available — use Ctrl+J or backslash then Enter |
Several Claude Code shortcuts use the Option key — a newline, the model picker, the fast-mode toggle. On macOS most terminals do not send Option as a modifier by default, so all of them silently do nothing. The setting is usually labelled use Option as Meta key, meta being the historical Unix name for the key now labelled Option or Alt.
Apple Terminal has it under keyboard settings, iTerm2 wants both Option keys set to the escape-plus mode, and VS Code has an editor setting for it. If you accepted Claude Code's first-run terminal prompt on Apple Terminal, this is already done — that prompt runs the setup command for you.
That first-run setup on Apple Terminal also turns off the audible bell, which is usually what you want and is exactly wrong if you use a screen reader. Claude Code now leaves the bell alone in screen reader mode, but a run from before v2.1.211 turned it off regardless. If your bell went quiet and you never chose that, it is in the terminal's advanced profile settings, not in anything Claude Code can change back.
When Claude finishes or pauses for a permission prompt and you appear to be away, it fires a notification event. What happens to that event depends entirely on your terminal:
Two things break under tmux by default, and both are fixed by the same short block. It is worth adding even if you only occasionally use tmux, because the failure modes look like Claude Code bugs rather than multiplexer configuration.
# ~/.tmux.conf — two things break by default under tmux:
# Shift+Enter submits instead of inserting a newline, and
# desktop notifications never reach the outer terminal.
set -g allow-passthrough on
set -s extended-keys on
set -as terminal-features 'xterm*:extkeys'
# Then apply to the running server without restarting it:
# tmux source-file ~/.tmux.conf
# allow-passthrough lets notifications and progress updates
# through instead of being swallowed by tmux.
# The extended-keys lines let tmux tell Shift+Enter apart from
# plain Enter, which is the whole reason the newline shortcut
# does not work under tmux otherwise.Beyond the built-in presets, any JSON file in the themes folder becomes a theme. It takes a base preset and a map of colour token overrides, and tokens you do not list fall through to the base. The interactive editor in the theme command shows the same tokens with a live preview, which is a faster way to find the one you want than reading the reference.
// ~/.claude/themes/midnight.json
// The filename without .json is the slug; selecting it stores
// custom:<slug> as your theme preference.
{
"name": "Midnight",
"base": "dark",
"overrides": {
"claude": "#a78bfa",
"planMode": "#38bdf8",
"diffAdded": "#14532d",
"diffRemoved": "#7f1d1d",
"userMessageBackground": "#1e1b4b"
}
}
// base: dark | light | dark-daltonized | light-daltonized
// dark-ansi | light-ansi
// Colours: #rrggbb, #rgb, rgb(r,g,b), ansi256(n), or
// ansi:<name> for the 16 standard names.
//
// Unknown tokens and invalid values are IGNORED, so a typo
// cannot break rendering. Claude Code watches the folder and
// reloads on change — but restart once if the folder did not
// exist when the session started.Two of the presets are colourblind-friendly — a daltonized dark and a daltonized light — and they are available as bases for your own theme, not just as finished presets. There are also eight named subagent colours you can override, which is how you make parallel agents distinguishable in a palette that otherwise runs them together.
Paste more than 800 characters or more than two lines and Claude Code collapses the input to a placeholder so the box stays usable. The full content is still sent when you submit, and it is kept in a paste cache so recalling that prompt from history — even in a later session — sends the full content again rather than the placeholder text.
The cache is swept on the same retention schedule as everything else in the config directory, so a recalled prompt can reference pasted text that no longer exists. Claude Code never sends the literal placeholder string: in a plain prompt with other text it drops the placeholder and sends the rest, and in a shell-mode or slash command, where dropping it would change what runs, it cancels the submission and leaves your text in the input for you to fix.
The VS Code integrated terminal can drop characters from very large pastes before they ever reach Claude Code, which produces a truncated prompt that looks like a Claude Code problem and is not. For entire files or long logs, write the content to a file and ask Claude to read it — that keeps the transcript readable and lets Claude reference the path in later turns instead of re-reading a wall of pasted text.
These come up often enough to be worth stating outright:
None of this is required and all of it is a lookup, which is exactly why it is worth reading once rather than when you are annoyed. The two changes I would make on any new machine are the terminal-setup command, because it fixes several things at once, and the notification channel, because working with an agent is much better when you can walk away and be called back. Everything else can wait until it bothers you.
Sources & further reading