[BUG] keybindings.json ignored in Claude desktop app — Enter/Shift+Enter always submit

Status Fixed / completed
Reported on v2.1.39
Maintainer reply None cached
Activity 17 comments · opened Feb 11, 2026 · closed Aug 18, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

The ~/.claude/keybindings.json configuration file is completely ignored when running Claude Code through the Claude desktop app on macOS.

Both Enter and Shift+Enter submit the message, regardless of the keybindings config. The config sets "enter": null to unbind Enter from submit and "ctrl+enter": "chat:submit" to use Ctrl+Enter instead, but this has no effect.

The file is valid JSON, correct encoding, located at the correct path (~/.claude/keybindings.json), and verified with python3 -c "import json; json.load(open(...))".

keybindings.json contents:

{
  "$schema": "https://www.schemastore.org/claude-code-keybindings.json",
  "$docs": "https://code.claude.com/docs/en/keybindings",
  "bindings": [
    {
      "context": "Chat",
      "bindings": {
        "enter": null,
        "ctrl+enter": "chat:submit"
      }
    }
  ]
}

What Should Happen?

  • Enter should insert a newline (unbound from submit via "enter": null)
  • Ctrl+Enter should submit the message (bound via "ctrl+enter": "chat:submit")
  • Shift+Enter should insert a newline
  • The ~/.claude/keybindings.json config should be respected in the Claude desktop app, just as it is in the CLI

Error Messages/Logs

Steps to Reproduce

  1. Create ~/.claude/keybindings.json with the following content:
{
  "$schema": "https://www.schemastore.org/claude-code-keybindings.json",
  "$docs": "https://code.claude.com/docs/en/keybindings",
  "bindings": [
    {
      "context": "Chat",
      "bindings": {
        "enter": null,
        "ctrl+enter": "chat:submit"
      }
    }
  ]
}
  1. Open Claude Code in the Claude desktop app (not terminal or VS Code)
  2. Type a message in the chat input
  3. Press Enter — it submits the message instead of inserting a newline
  4. Press Shift+Enter — it also submits the message instead of inserting a newline
  5. The keybindings.json config appears to be completely ignored

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.39 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Other

Additional Information

Terminal/Shell note: Running Claude Code inside the Claude desktop app on macOS (not a standalone terminal). The desktop app is not listed in the Terminal/Shell dropdown, so "Other" was selected.

This issue may be that the Claude desktop app simply does not read ~/.claude/keybindings.json at all. Either the desktop app should respect the keybindings config, or there should be a separate keybinding setting within the desktop app itself.

OS: macOS (Darwin 25.3.0)

View original on GitHub ↗

16 Comments

github-actions[bot] · 6 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/25089
  2. https://github.com/anthropics/claude-code/issues/25070
  3. https://github.com/anthropics/claude-code/issues/25054

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

KenInLV · 6 months ago

Of the various duplicates, which will be kept as the active issue? So I can 👍 it.

bananablueprint · 6 months ago

Yes, not working on Windows 11 either.

GregEisenberg · 6 months ago

Feature Request: Default keybinding for newline in chat input

Summary

There is no default keybinding to insert a newline in the chat input. This makes composing multi-line prompts unnecessarily difficult, and multi-line prompts are important for writing clear, structured instructions.

Current behavior

  • enter submits the message (the only default chat input binding)
  • chat:newline has no default keybinding
  • The natural choice shift+enter does not work because most terminal emulators send the same keycode for shift+enter and enter — they are indistinguishable

Workarounds that exist today

  • ctrl+g to open an external editor — works, but can conflict with other apps (e.g., Gemini uses ctrl+g globally on macOS)
  • Backslash \ continuation before pressing enter — works, but not intuitive
  • Pasting multi-line text from clipboard — works, but breaks the flow

Suggestion

Assign a default keybinding to chat:newline that actually works in terminals. alt+enter (or option+enter on macOS) is distinguishable from enter in most terminal emulators and is a common newline convention in other tools (Slack, JetBrains IDEs, etc.).

Why this matters

Good prompts are often multi-line — numbered instructions, code blocks, structured context. Making newline entry frictionless would improve the experience for everyone using Claude Code in the terminal.

Environment

  • macOS (Terminal / iTerm2)
  • Claude Code CLI
MU5K · 5 months ago

Also reproducible on Windows Terminal + CLI

Same issue here — keybindings.json is completely ignored.

Environment

  • OS: Windows 11 (MINGW64_NT-10.0-26200)
  • Terminal: Windows Terminal
  • Shell: Git Bash (MSYS2)
  • Claude Code: v2.1.76
  • Platform: Anthropic API (CLI, not desktop app)

keybindings.json (~/.claude/keybindings.json)

{
  "$schema": "https://www.schemastore.org/claude-code-keybindings.json",
  "$docs": "https://code.claude.com/docs/en/keybindings",
  "bindings": [
    {
      "context": "Chat",
      "bindings": {
        "enter": "chat:newline",
        "ctrl+enter": "chat:submit"
      }
    }
  ]
}

Actual behavior

  • Enter → submits (should be newline per config)
  • Ctrl+Enter → newline (default behavior, ignoring config)
  • Ctrl+Shift+Enter → newline

The config is valid JSON, UTF-8 without BOM, at the correct path. Restarting Claude Code does not help. This confirms the issue is not limited to the desktop app — it also affects the CLI on Windows Terminal.

jhardin-accumula · 5 months ago

FWIW, I'm actually finding that \[ENTER] (backslash then [ENTER]) is _easier_ to type than [SHIFT]+[ENTER]...

MU5K · 5 months ago

@jhardin-accumula Nice tip! I confirmed \[ENTER] works as a newline workaround — but only when the IME (Input Method Editor) is off.

When Japanese IME is active, the backslash key produces ¥ instead of \, so the shortcut doesn't register. This likely affects all CJK IME users (Japanese, Chinese, Korean).

Environment: Windows 11 + Git Bash, Claude Code CLI

MU5K · 5 months ago

Small addition: my IME is Google Japanese Input (Google 日本語入力), not the default Microsoft IME.

philRVT · 4 months ago

+1 for this. In Claude Code GUI, too often I'm not getting my left pinky on the shift key before I hit the enter key -- and thus Claude starts thinking.

I'd rather configure it so the enter key is a simple newline -- and ctrl-enter / command-enter / alt-enter is submit

jayf0x · 3 months ago

+1.
a Claude suggestion:

✅ Workaround: Karabiner-Elements (macOS) — remap Enter app-specifically
You can remap Enter → a newline-only key only when the Claude desktop app is focused:

Install Karabiner-Elements
- Create a complex modification that fires return_or_enter only when the frontmost app is Claude (bundle ID: com.anthropic.claudefordesktop or similar)
- Map it to shift+return (which currently still inserts a newline... though the bug affects that too), or map it to do nothing

The reliable version maps Enter → nothing in Claude's context, forcing you to use the mouse or a different keybind to submit — not ideal but stops accidental submits.
albertdick · 2 months ago

+1

OpenAI Codex already does this.

ramondacal · 2 months ago

+1

It works in the CLI Claude Code, but not in Windows desktop app.

Sire · 2 months ago

This is extremely annoying. Most coding prompts are multi-line, at least during planning.

Here's a workaround for Windows users with AutoHotKey:

;==============================================================================
; Claude desktop app (Windows): Enter = newline (Shift+Enter), Ctrl+Enter = send
;
; Shift+Enter DOES insert a newline in the app when pressed for real, but the
; app is Chromium-based and misses AutoHotkey's default ultra-fast synthetic
; input. So we use Event mode + a key delay + an explicit Shift hold so the
; app reliably sees Shift held while Enter is pressed.
;
; Only active while the Claude window is focused. AutoHotkey v1.1.
; Verify target: right-click tray icon > Window Spy, focus Claude, check ahk_exe.
;
; TUNING: if a newline still doesn't register, raise the SetKeyDelay numbers
; below (try 40, 40), or uncomment the Sleep line inside SendNewline().
;==============================================================================

#SingleInstance Force
#NoEnv
SendMode Event
SetKeyDelay, 20, 20        ; ms between keystrokes / between press and release

#IfWinActive ahk_exe claude.exe

    ; --- Plain Enter -> Shift+Enter (newline) -----------------------------
    Enter::SendNewline()
    NumpadEnter::SendNewline()

    ; --- Ctrl+Enter -> submit (plain, unmodified Enter) -------------------
    ^Enter::Send, {Enter}
    ^NumpadEnter::Send, {Enter}

#IfWinActive

; Ctrl+Alt+Enter toggles the remap off/on (works even while suspended).
^!Enter::
Suspend
ToolTip % A_IsSuspended ? "Claude Enter remap: OFF" : "Claude Enter remap: ON"
SetTimer, RemoveClaudeTip, -1500
return
RemoveClaudeTip:
ToolTip
return

; -----------------------------------------------------------------------------
SendNewline() {
    Send, {Shift down}
    ; Sleep, 30            ; uncomment if Shift needs longer to register
    Send, {Enter}
    Send, {Shift up}
}
glowball-nick · 1 month ago

macOS data point: Same behavior on the macOS Desktop app. ~/.claude/keybindings.json with

{ "context": "Chat", "bindings": { "enter": "chat:newline", "shift+enter": "chat:submit" } }

works as documented in the terminal TUI but is completely ignored in Desktop — Enter always submits.

Use case: answering multi-line prompts with multi-line responses without accidentally sending incomplete messages.

Even if full keybindings.json support in Desktop is a bigger lift, this could be as simple as a checkbox in Preferences or a small toggle beneath the entry field ("Enter inserts newline / Shift+Enter sends"). That would cover the most-requested case here and would also resolve #2054 for Desktop users.

glowball-nick · 1 month ago

macOS data point: Same behavior on the macOS Desktop app. ~/.claude/keybindings.json with

{ "context": "Chat", "bindings": { "enter": "chat:newline", "shift+enter": "chat:submit" } }

works as documented in the terminal TUI but is completely ignored in Desktop — Enter always submits.

Use case: answering multi-line prompts with multi-line responses without accidentally sending an incomplete message. Even if full keybindings.json support in Desktop is a bigger lift, a simple toggle — a checkbox in Preferences, or a small popup/selector beneath the entry field — for "Enter inserts newline / Shift+Enter sends" would cover the most-requested case, and would also resolve #2054 for Desktop users.

shigennn · 28 days ago

We are all after the same thing here — Enter for a newline, a modifier for submit.
At least for Enter, I don't think keybindings.json can get us there on Desktop: the composer handles that key itself, and decides what it does from whether the machine has a touchscreen.

// shared-1-3-6x7RKF.js
function ir(){ return "undefined" != typeof window && window.matchMedia("(pointer: coarse)").matches }

// composer's Enter handler, [c360a9e1c-DrYIyI47.js](http://c360a9e1c-dryiyi47.js/) (verbatim)
if (e.shiftKey || e.altKey) return;
if (e.nativeEvent.isComposing) return;
if (ia() && !e.metaKey && !e.ctrlKey) return;   // coarse pointer -> Enter does NOT submit

Two machines, same account, same version (1.24012.9), both MSIX.
On a ThinkPad with no touchscreen, Enter submits — with several forms of keybindings.json, and also with the file deleted entirely.
On a Surface Pro, Enter inserts a newline with no keybindings.json present at all.
matchMedia('(pointer: coarse)').matches in DevTools tells you which side you are on.
This may also be what is behind #77723 and #79696, where people report the opposite problem.

What I ended up doing: I write in Japanese, so the AutoHotkey remap above does not work for me — with a Japanese IME, Enter is also what commits the kana-to-kanji conversion, so remapping it means the conversion can never be committed.
Instead of touching the key I force the pointer type at launch, which leaves key handling alone:

# Close Claude first — single instance, otherwise the flag is a no-op.
$pkg = Get-AppxPackage | Where-Object PackageFamilyName -eq 'Claude_pzs8sxrjxfjjc'
Start-Process (Join-Path $pkg.InstallLocation 'app\Claude.exe') `
  -ArgumentList '--blink-settings=primaryPointerType=2,availablePointerTypes=2'

Enter = newline, Ctrl+Enter = submit, IME still fine. No admin needed, and resolving the path this way survives app updates.

This is only a workaround on my machine, though. Desktop should honour keybindings.json the same way the terminal does — or at the very least expose this as a setting, instead of deciding it from the hardware.

Showing cached comments. Read the full discussion on GitHub ↗