Claude Code 改行——長い指示を書こうとして Enter を押した瞬間に送信されてしまう——この問題は「Shift+Enter を使えば改行できる」という説明で片付けられがちですが、実際には効く端末と効かない端末があります。原因は Claude Code 側ではなく、端末が Shift+Enter に固有のバイト列を割り当てているかどうかにあります。本記事では擬似端末(PTY)越しに7種類のキー入力を実際に送り込み、どのバイト列が改行になり、どれが送信になるかを v2.1.241 で実測しました。

Claude Codeの改行キーの実測結果を示す図。素のEnterのCRは送信、Option+EnterのESC CR・CSI u形式のShift+Enter・バックスラッシュとEnterはいずれも改行になることをバイト列とともに示す。
PTY越しに各キー入力のバイト列を直接送って挙動を確認した結果。判定しているのはキー名ではなくバイト列。

30秒でわかる Claude Code の改行

どこでも確実に効くのはバックスラッシュ+Enter。端末も設定も問わず改行になる(実測)
Shift+Enter がネイティブで効く端末:iTerm2 / WezTerm / Ghostty / Kitty / Warp / Windows Terminal
/terminal-setup が要る端末:Terminal.app(Option+Enter・要再起動)/VSCode・Cursor・Devin Desktop・Zed/Alacritty
tmux・screen の中では /terminal-setup が通らない。いったん抜けて実行してから戻る
IMEの確定Enterによる誤送信は端末設定では直らない。送信Enterと同じ1バイトなので区別できない

Claude Code の設定全般とインストールからの流れは、Claude Code|2026年版・インストールからCLAUDE.md・Hooks・本番運用までの実装手引きにまとめてあります。本記事は入力欄の改行という一点に絞ります。

Claude Code 改行はキーではなくバイト列で決まる

前提を1つ押さえます。Claude Code は「Shift+Enter が押された」という情報を受け取っていません。 端末エミュレータから流れてくるバイト列だけを見ています。

素の Enter は CR(0x0D)1バイトです。多くの端末は Shift を押しながら Enter を打っても同じ CR を送るため、Claude Code からは区別のしようがなく、送信として処理されます。「Shift+Enter で改行できる」という説明が当たったり外れたりするのは、この一点に尽きます。

そこで、代表的な入力が実際にどう解釈されるかを PTY 越しに直接測りました。手順は「AB を入力 → 検証したいバイト列を送信 → CD を入力」で、入力欄が2行になれば改行、応答が始まれば送信という判定です。

キー操作 端末が送るバイト列 v2.1.241 の解釈
Enter CR(0x0D) 送信(対照群)
Option / Alt + Enter ESC CR(0x1B 0x0D) 改行
Shift+Enter(CSI u 形式) ESC [ 1 3 ; 2 u 改行
Shift+Enter(modifyOtherKeys 形式) ESC [ 2 7 ; 2 ; 1 3 ~ 改行
バックスラッシュを打ってから Enter \ + CR 改行(バックスラッシュは残らない)
複数行のペースト ESC [ 2 0 0 ~ … ESC [ 2 0 1 ~ 改行(括弧付きペースト)
日本語の直後に Enter CR 送信(IME確定と区別不可)

対照群として素の Enter が確実に送信になることを毎回確認しているので、「たまたま反応しなかった」ではなく改行として処理されたと言えます。改行になったケースでは、入力欄に ABCD が別々の行として並んだ状態を目視で確認しています。

読み取れるのは次の点です。改行として受け付けられるバイト列は複数あり、そのどれを送るかは端末側の設定で決まる。Claude Code の設定をいくら見ても改行キーの項目が見つからないのは、そこが管轄外だからです。

キー入力からClaude Codeまでの経路を示す図。物理キーを端末エミュレータがバイト列に変換し、Claude Codeはそのバイト列だけを見て改行か送信かを判定するため、改行の可否は端末側の設定で決まることを表す。
Claude Code に届く前に、キーはすでにバイト列へ変換されている。設定すべきレイヤーはその手前にある。

Claude Code 改行の端末別対処——まず自分の端末がどれかを確認する

Claude Code の実行バイナリには、端末ごとの扱いを説明する文字列が埋め込まれています。そこから読み取れる分類は3群です。

1. 何もしなくてよい端末(Shift+Enter ネイティブ対応)

バイナリ内の案内文は次のように明示しています。

Note: iTerm2, WezTerm, Ghostty, Kitty, Warp, and Windows Terminal support Shift+Enter natively.

これらの端末は Shift+Enter に固有のエスケープシーケンス(上表の CSI u 形式など)を割り当てて送信するため、設定なしでそのまま改行できます。iTerm2 については Shift+Enter is natively supported in iTerm2. という個別の文言も持っています。

「Shift+Enter で改行できると書いてあったのにできない」という食い違いは、この6端末以外を使っているときに起きます。まず自分の端末がこのリストに入っているかを確認するのが、切り分けの最短路です。

Claude Codeで改行するための端末別対処を比較した図。iTerm2・WezTerm・Ghostty・Kitty・Warp・Windows Terminalは設定不要、Terminal.app・VSCode系・Alacrittyはterminal-setupが必要で、tmux内では実行できないことを示す。
実行バイナリに埋め込まれた記述から分類。まず自分の端末がどちらの群かを確定させる。

2. /terminal-setup を実行する端末

Claude Code のセッション内で /terminal-setup を打つと、端末側の設定ファイルにキーバインドが書き込まれます。対象と実際の内容は次のとおりです。

対象 設定される内容 備考
macOS Terminal.app Option+Enter で改行 反映に Terminal.app の再起動が必要
VSCode / Cursor / Devin Desktop / Zed shift+enterworkbench.action.terminal.sendSequence で ESC+CR を送る定義を追加 when: terminalFocus の条件付き
Alacritty Shift+Enter のキーバインドを追加 既存の別バインドがある場合は上書きしない

ここで注目したいのは、VSCode 系に書き込まれる中身が ESC+CR である点です。これは上の実測表で「Option+Enter」として測ったバイト列と同一です。つまり VSCode の Shift+Enter は、内部的には Option+Enter と同じものを送っているだけで、Claude Code 側から見れば両者は区別されていません。キー名は3通りあっても、届いているバイト列は同じということです。

既に別の割り当てがある場合は、already has a Shift+Enter terminal binding with different args; leaving it as-is. として上書きせずに残す挙動になっています。自分でキーバインドを育てている人の設定を壊さない作りです。設定が成功したときは Installed Alacritty Shift+Enter key binding のように、どの端末に何を入れたかが個別に報告されます。

# Claude Code のセッション内で実行する(シェルのコマンドではない)
/terminal-setup

3. tmux / screen の中では通らない

多重化ツールの中で /terminal-setup を実行しようとすると、バイナリ内の案内文どおり次の手順を求められます。

1. Exit tmux/screen temporarily
2. Run /terminal-setup directly in one of these terminals:
   • IDE: VSCode, Cursor, Devin Desktop, Zed
   • Other: Alacritty
3. Return to tmux/screen - settings will persist

tmux 越しだと設定対象の端末を判別できないためで、いったん抜けて実行し、戻れば設定は残るという説明になっています。tmux を常用していて「何度実行しても改行できるようにならない」場合は、実行そのものが空振りしている可能性があります。

端末を変えたくない・設定を触りたくない場合

バックスラッシュを打ってから Enter、という方法が常に使えます。実測でも端末やロケールに関係なく改行になり、入力欄にバックスラッシュは残りませんでした。シェルの行継続と同じ発想なので覚えやすく、/terminal-setup を実行できないリモート環境や共用マシンでも確実に動きます。

設定ファイルでキー割り当て自体を変える

端末側ではなく Claude Code 側でキーを変える経路も用意されています。~/.claude/keybindings.json です。

このファイルは実行バイナリが読み込み・検証しており、公式スキーマが SchemaStore に公開されています。スキーマを取得して中身を確認したところ、構造は次のようになっていました。

bindings は配列で、各要素が context(適用範囲)と bindings(キー→アクションの対応表)を持つ
context は列挙型で 19種類Global / Chat / Autocomplete / Confirmation / Transcript / ModelPicker など)
・アクションは組み込みの識別子から選ぶ。入力欄に関わるのは chat:newline(改行)chat:submit(送信)
・値を null にすると既定のショートカットを解除できる
・キーは ctrl+k のような単発のほか、ctrl+k ctrl+s のような和音(chord)も書ける

改行を Ctrl+J に割り当てるなら、次のような形になります。

{
  "bindings": [
    {
      "context": "Chat",
      "bindings": {
        "ctrl+j": "chat:newline"
      }
    }
  ]
}

バイナリ側には「~/.claude/keybindings.json は保存時にホットリロードされるので再起動を案内しないこと」「アクション名はスキーマ由来のものだけを使い、勝手に作らないこと」という趣旨の内部ガイドも埋め込まれており、設定の反映に再起動は不要です。フラットな「キー→コマンド」の対応表ではなく、コンテキストごとのブロックの配列である点に注意してください。形式を間違えると keybindings.json must have a "bindings" array という検証エラーになります。

この節の検証範囲について(未検証部分の明示)

スキーマの内容(chat:newline / chat:submit の存在、19種のコンテキスト、null による解除)は公式スキーマを取得して確認しました。一方、割り当てたキーが実際に発火するかどうかは本記事では未検証です。キーバインドの検証処理は対話TUIの起動時に走り、claude -p の非対話モードでは実行されないため、自動化された手順では確かめられませんでした。導入する場合はご自身の環境で1つ試してから本格運用してください。

flowchart TD A["改行したい"] --> B{"使っている端末は?"} B -->|"iTerm2 / WezTerm / Ghostty
Kitty / Warp / Windows Terminal"| C["Shift+Enter が
そのまま使える"] B -->|"Terminal.app"| D["terminal-setup 実行
Option+Enter・要再起動"] B -->|"VSCode / Cursor / Zed"| E["terminal-setup 実行
shift+enter に ESC+CR"] B -->|"Alacritty"| F["terminal-setup 実行
Shift+Enter バインド追加"] B -->|"tmux / screen の中"| G["いったん抜けて実行
戻れば設定は残る"] B -->|"設定を触れない"| H["バックスラッシュ + Enter
どこでも動く"] C --> I{"IME確定Enterで
誤送信する?"} D --> I E --> I I -->|"する"| J["送信と改行を
別キーに分離する"]

日本語入力で誤送信する問題は、端末設定では直らない

日本語で長文を打つときに固有の問題があります。変換を確定するための Enter が、そのままメッセージ送信になってしまうケースです。

原因を切り分けると、これは改行キーの話とは別の層にあります。IMEの確定 Enter が端末を通り抜けてアプリに届く場合、その中身は送信 Enter と同じ CR 1バイトです。Claude Code 側に区別する材料がありません。

実際に PTY 越しで確認しました。日本語文字列(こんにちは)を送った直後に CR を送ると、ASCII 文字の直後に CR を送ったときと同じく送信が発火します。直前の文字が日本語かどうかで挙動が変わることはありませんでした。

IMEの確定EnterがClaude Codeに届くまでの経路図。日本語の変換確定Enterは端末を通るとCR1バイトになり、送信Enterと区別できないため、端末設定やClaude Codeの言語設定では解けないことを示す。
確定Enterと送信Enterは同じ1バイト。切り分けの答えは「キーを分ける」以外にない。

したがって、対処の方向は1つしかありません。

「Enter を改行にする」ではなく、送信を Enter 以外に逃がすか、改行を Enter 以外に確実に持たせることです。前者は keybindings.jsonchat:submit を別キーへ移す方向、後者は上で説明した端末別の設定になります。

なお、IMEが確定 Enter を端末へ渡すかどうかは端末とIMEの組み合わせによって異なります。 渡さない組み合わせではこの問題自体が起きません。自分の環境で再現するかどうかを先に確認してから設定を変えるのが早道です。

Claude Code を日本語で運用するときの他の論点——UIが英語のままである理由、ロケール設定が応答言語に関与しないこと、日本語がトークンを1.57倍消費することなど——はClaude Codeを日本語で使う完全ガイド|日本語化の設定・文字化けの原因・トークン1.57倍の実測にまとめています。

自分の端末が何を送っているかを1分で確かめる

ここまでの分類はバイナリの記述と実測に基づいていますが、自分の環境で直接確かめるほうが早い場面もあります。端末が Shift+Enter に何を割り当てているかは、Claude Code を起動しなくても確認できます。

シェルで cat -v を実行し、確かめたいキーを押してから Ctrl+C で抜けるだけです。cat -v は制御文字を可視化して表示します。

# 実行後に Enter / Shift+Enter / Option+Enter を順に押し、最後に Ctrl+C
cat -v

表示のされ方で、その端末が何を送っているかが判別できます。

画面に出る表示 実際のバイト列 Claude Code での挙動
^M だけ CR 送信(改行にはならない)
^[^M ESC + CR 改行になる
^[[13;2u CSI u 形式 改行になる
^[[27;2;13~ modifyOtherKeys 形式 改行になる

Shift+Enter を押して ^M しか出ないなら、その端末では何をどう設定しても Claude Code 側で改行にはなりません。 Enter と同じバイト列しか届いていないからです。この場合の選択肢は「端末を変える」「/terminal-setup で別のキーに改行を割り当てる」「バックスラッシュ+Enter を使う」の3つに絞られます。

逆に ^[^M^[[13;2u が出ているのに改行にならない場合は、端末ではなく Claude Code 側の設定(keybindings.jsonchat:newline を潰していないか)を疑う順番になります。切り分けの向きを間違えないための1分です。

なお本記事の実測は、この確認を人手で行う代わりに Python の pty モジュールで擬似端末を作り、上表のバイト列を直接流し込む形で行いました。人間がキーを押す代わりにバイト列を注入しているので、端末ごとのキー割り当ての差を排除して「Claude Code 側の解釈だけ」を測れるという利点があります。

長文を書くなら、そもそも入力欄で書かない選択肢もある

改行の話を突き詰めると、「入力欄で長文を編集すること自体が向いていない」という結論にも行き着きます。Claude Code の入力欄はステータス表示のすぐ上にある1〜数行の領域で、10行を超える指示を推敲する場所としては窮屈です。

実測中に確認できた代替手段が2つあります。

1つ目は外部エディタです。 入力欄の右下には ctrl+g to edit in Vim というヒントが表示されます(実際の PTY 出力で確認しました)。これはキーバインドスキーマの chat:externalEditor に相当する機能で、慣れたエディタで書いてから戻せます。改行キーの設定が一切要らないという意味で、実は最も確実な多行入力の手段です。

2つ目はペーストです。 Claude Code は括弧付きペーストモード(bracketed paste)を有効にして起動しており、起動直後の端末制御シーケンスに該当する指定が含まれることを確認しました。実測でも、括弧付きペーストで囲んだ改行は送信ではなく改行として扱われています。エディタで書いた複数行をそのまま貼り付けても、途中で勝手に送信されることはありません。

Claude Code の入力そのものより手前、つまり「何を書くか」を定型化してしまう方向もあります。プロジェクト規約や繰り返す指示は入力欄ではなく CLAUDE.md に置くのが本筋で、書き方はAI mdファイルとは|CLAUDE.md・AGENTS.md・.cursorrules・GEMINI.mdの違いと書き方に整理してあります。毎回長文を打つ必要があるなら、それは改行キーの問題ではなく規約ファイルの不足かもしれません。

まとめ

Claude Code はキー名ではなくバイト列で判定している。 素の Enter(CR)は送信、ESC+CR / CSI u 形式 / modifyOtherKeys 形式はいずれも改行(すべて実測)
Shift+Enter がそのまま効くのは6端末:iTerm2 / WezTerm / Ghostty / Kitty / Warp / Windows Terminal
/terminal-setup が要るのは Terminal.app(Option+Enter・要再起動)/VSCode・Cursor・Devin Desktop・Zed/Alacritty。tmux・screen の中では実行できない
VSCode に設定される中身は ESC+CR で、Option+Enter と同一のバイト列
どこでも確実なのはバックスラッシュ+Enter。 端末も設定も問わない
~/.claude/keybindings.jsonchat:newline / chat:submit を再割り当てできる(スキーマは確認済み・実発火は未検証)
IMEの確定Enterによる誤送信は送信Enterと同一バイトのため区別不能。 送信と改行をキーごと分けるしかない

「改行できない」は Claude Code の不具合ではなく、端末とアプリの境界で起きている取り違えです。自分の端末がどの群に属するかを先に確定させれば、打つ手は1つに絞れます。

参照ソース