MacOS TerminalアプリのClaude Codeに Shift + Enter で改行できるように設定してみた(おまけ:Enterキーの歴史問題)

MacOS TerminalアプリのClaude Codeに Shift + Enter で改行できるように設定してみた(おまけ:Enterキーの歴史問題)

2026.04.15

はじめに

自分は普段MacOSのTerminalアプリでClaude Codeを使っていますが、ずっと気になっていたことがありました。VSCodeやCursorなどのエディタではShift + Enterで改行できるのに、TerminalアプリだとShift + Enterは普通のEnterと同じ扱いになってしまい、メッセージがそのまま送信されてしまいます。

改行するにはOption + Enterを使わないといけないのですが、エディタの癖で毎回Shift + Enterを押してしまい、意図せずメッセージが送られてしまうことがよくありました。

ターミナルの仕様上、EnterShift + Enterは同じ信号(0x0d)として扱われるため、Terminalアプリの設定だけではShift + Enterを改行に変えることができません(詳しくは記事末尾の「Enterキーの歴史問題」で解説)。そこで、OS側でキー入力を変換できるKarabiner-Elementsを使って、Terminalアプリ上でのみShift + Enterをリマップすることで解決できました。

最初は単純にShift + EnterOption + Enterにマッピングすればいいかと思ったのですが、調べていくうちにCtrl + J(LF:Line Feed)の方がターミナル環境全般で改行として広く通用するキーバインドだとわかったので、最終的にCtrl + Jへのマッピングを採用しました。この記事ではその手順を紹介します。

記事の最後に、なぜTerminalアプリでShift + Enterが効かないのか、Enterキーの歴史的な背景も解説します。

検証環境

  • MacOS (Sequoia) Terminalアプリ
  • Claude Code (v2.1.89)
  • Homebrew (v5.1.6)

手順

1. Karabiner-Elementsのインストール

brew install --cask karabiner-elements

インストールできたら、アプリを開いて初期設定をします(キーボードタイプの選択、権限設定など)。

2. 権限の付与

初回起動時に、以下の権限許可を求められるので許可してください。

  1. System Settings → Privacy & Security → Input MonitoringKarabiner-Core-Serviceを有効にする

0

  1. System Settings → General → Login Items & Extensions → Driver Extensions.Karabiner-VirtualHIDDevice-Managerを有効にする

1

2

3

3. karabiner.jsonの編集

~/.config/karabiner/karabiner.jsonを編集します。

profilesの部分はアプリの初期設定で自動生成されるので、complex_modificationsrules部分を追加してください。なお、自分のキーボードはUS配列なので、keyboard_type_v2"ansi"となってます。日本語キーボードの方は初期設定か、もしくはKarabiner-ElementsアプリのVirtual Keyboard → Keyboard Type設定に、JISを選んでいただければ、"jis"になるはずです。

jis

以下はShift + EnterCtrl + Jにマッピングする設定です。

{
    "profiles": [
        {
            "complex_modifications": {
                "rules": [
                    {
                        "description": "Shift+Enter to Ctrl+J in Terminal.app",
                        "manipulators": [
                            {
                                "type": "basic",
                                "from": {
                                    "key_code": "return_or_enter",
                                    "modifiers": {
                                        "mandatory": ["shift"]
                                    }
                                },
                                "to": [
                                    {
                                        "key_code": "j",
                                        "modifiers": ["control"]
                                    }
                                ],
                                "conditions": [
                                    {
                                        "type": "frontmost_application_if",
                                        "bundle_identifiers": [
                                            "^com\\.apple\\.Terminal$"
                                        ]
                                    }
                                ]
                            }
                        ]
                    }
                ]
            },
            "name": "Default profile",
            "selected": true,
            "virtual_hid_keyboard": { "keyboard_type_v2": "ansi" }
        }
    ]
}

Option + Enterにマッピングしたい場合は、"to"の中身を以下のように書き換えてください。

{
    "key_code": "return_or_enter",
    "modifiers": ["option"]
}

設定を保存すれば、Terminalアプリ上でShift + Enterが改行として動作するようになります。

おまけ:Enterキーの歴史問題

なぜTerminalアプリではShift + Enterが効かないのか? その背景には、ターミナルエミュレータの歴史的な仕様があります。

ターミナルのキー入力の仕組み

MacOSはUNIXベースで作られていて、Terminalアプリのキー入力は、古いターミナル規格の仕様に基づいています。

4

Enterキーは、元々テンキー(もしくはそれ以上のキーがあった古いキーボード)時代のSS3(1978年、VT100)規格に由来します。一方、現在のフルサイズキーボードの多くのキーは、その後のCSI(1979年以降、VT220〜)規格に準拠しています。

参考:VT100 User Guide — Chapter 3(Table 3-8 ANSI Mode Auxiliary Keypad Codes)

SS3規格の制約

5

SS3規格では、キーコードは以下のフォーマットで表現されます。

ESC O <1バイト>

ESC Oの後ろに1バイトのみが入る構造なので、修飾キー(Shiftなど)との組み合わせ情報を含める余地がありません。

キーパッドEnter = ESC O M = 0x1b 0x4f 0x4d

Other keys such as CTRL and SHIFT do not transmit codes when typed, but modify the codes transmitted by other keys.

VT100キーボードではShiftキーも存在していましたが、独立した信号として送信されるのではなく、キーボード内部で完結するモード切り替えとして使われていました。例えば、Aを押すとaが送られ、Shift + AAが送られる。1を押すと1Shift + 1!が送られる、といった具合です。

現在のTerminalアプリでの動作

つまり、SS3由来のEnterキーは修飾キーとの組み合わせが定義されておらず、TerminalアプリではEnterShift + Enterも同じ0x0d(CR:キャリッジリターン)として処理されます。

以下のPythonスクリプトをTerminalアプリで実行すると、キー入力のバイトコードを確認できます(Ctrl + Cで終了)。

python3 -c "
import sys, tty, termios

fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
tty.setraw(fd)

try:
    while True:
        b = sys.stdin.buffer.read(1)
        if b == b'\x03': break
        sys.stdout.buffer.write(('0x{:02x}\r\n'.format(b[0])).encode())
        sys.stdout.buffer.flush()
finally:
    termios.tcsetattr(fd, termios.TCSADRAIN, old)
"

Karabiner-Elementsでマッピングする前に試すと、EnterShift + Enterも同じ結果になります。

0x0d

Shift + EnterCtrl + Jにマッピングした後は、以下のように変わります。

0x0a

0x0dはCR(Carriage Return)、0x0aはLF(Line Feed=改行)です。これにより、Terminalアプリ上のClaude CodeでもShift + Enterで改行できるようになります。

おわりに

TerminalアプリでShift + Enterが効かない原因は、VT100時代のSS3規格に由来する歴史的な制約でした。Karabiner-Elementsを使えば、Terminalアプリ上でのみキーをリマップできるので、他のアプリの挙動に影響を与えずに対応できます。

同じ悩みを持っている方の参考になれば幸いです。

この記事をシェアする

関連記事