[FEATURE] Desktop app: option to make Enter insert a newline and Ctrl+Enter submit in the chat composer
Status Open
Maintainer reply None cached
Workaround ✓ Mentioned in thread ↓
Activity 9 comments · opened Aug 26, 2026
Feature request
Add a way to make Enter insert a newline and Ctrl+Enter (or Cmd+Enter) submit in the Desktop app's chat composer.
Current behavior
- In the Desktop app, Enter always submits the message; the only way to get a newline is Shift+Enter.
~/.claude/keybindings.json(e.g.{"context": "Chat", "bindings": {"enter": "chat:newline", "ctrl+enter": "chat:submit"}}) works in the terminal TUI as documented, but is completely ignored by the Desktop app's composer.- This was reported in #25087, which was closed without a fix landing — the thread ends with an OS-level Karabiner-Elements workaround that only helps macOS users. There is no equivalent workaround on Windows.
Why
When writing longer, structured prompts (multi-line lists, pasted context plus instructions), it's very easy to accidentally send an incomplete message with a reflexive Enter. Enter-for-newline with a modifier-to-send is the standard convention in many chat/messenger apps, so muscle memory works against the current default.
Proposed solutions (either would work)
- Make the Desktop composer respect the
Chatcontext in~/.claude/keybindings.json, or - Add a simple composer setting in the Desktop app: "Enter sends / Enter inserts newline (use Ctrl+Enter to send)".
Environment
- Claude Code Desktop app on Windows 11 (also affects macOS per #25087)
🤖 Generated with Claude Code
9 Comments
+1, though a mechanism for this already exists:
keybindings.jsonwith"enter": "chat:newline"in theChatcontext works in the terminal TUI and the VS Code extension — the Desktop composer just ignores it (#90878). Honoring it there would fix both at once and keep behavior consistent across all three surfaces.Adding a data point from the macOS Desktop app (Claude 1.46388.4), and one failure mode I don't think has been raised yet: Enter-to-send is materially worse for IME users, in a way that care and habit cannot fix.
The IME failure mode
With Enter-to-send, one keystroke carries two meanings: "commit the IME conversion" and "send the message". The dangerous case is not a reflexive Enter — it is a mode mismatch:
The keystroke was correct for the mode I believed I was in, so there is no amount of attention that prevents this. Note that an
isComposingguard does not help, because nothing is composing at that moment. Only decoupling "send" from bare Enter removes the failure. This applies to Japanese, Chinese and Korean input alike.Confirming that keybindings.json is structurally ignored, not merely unimplemented
Worth stating explicitly, because the natural assumption ("the Desktop app is the TUI in a window") sends people down a dead end — I spent an afternoon there. The Desktop app does not render the CLI's TUI at all. It spawns the bundled binary headless:
The composer is an Electron/React component, so
~/.claude/keybindings.jsonandeditorMode: "vim"— both TUI-layer features — cannot reach it by construction. I wrote akeybindings.jsonwith{"enter": "chat:newline", "meta+enter": "chat:submit"}, restarted, and nothing changed.cmd+gjust opens Electron's find bar.Two observations from the app bundle
In the shortcuts modal, send is a literal while other entries are ID-based:
Separately, the bundle already ships an input component taking a
submitOnEnterprop that implements both modes, including a guard tied to a timestamp recorded inonCompositionEnd:To be clear, that component is used for small inline inputs, not the main composer, so this is not "the feature is already built" — but the two-mode behavior and its IME handling do already exist in the codebase.
On the Karabiner workaround from #25087
Restating that it is not a fix, from someone who was in a position to take it. I have Karabiner-Elements installed and already run
frontmost_application_ifrules for other apps, so scopingenter→shift+entertocom.anthropic.claudefordesktopwas a few lines away. I rejected it anyway: I use Claude Code on this Mac and on two Windows machines, and a keybinding that exists on exactly one of them makes the UX less predictable, not more. I would rather keep a bad default that is identical everywhere than hold two different muscle memories. That is the same conclusion as the OP's "no equivalent workaround on Windows", reached from the macOS side.For that reason I lean toward proposal 2 (a composer setting): honoring
keybindings.jsononly helps people who already sync their dotfiles, whereas a setting in the app is reproducible by the same steps on every platform — which is exactly what the Karabiner workaround is not. If it could ride the existing account sync, better still (plugins already do: "This plugin is now enabled for your account... the next time Claude syncs your plugins"), though I have no idea whether composer settings are in scope for that —config.jsoncurrently keeps even theme and locale local, so I would not assume it. Same steps on every platform is the part that matters.Adding a concrete root-cause detail I don't think is in this thread yet, in case it helps route the fix.
The desktop app ships the CLI as a separate binary and renders its own composer from the web front end, which is why
~/.claude/keybindings.jsonhas no effect here (as #25087 reported, and as #74655 assumes).macOS 15.7.4, Claude Desktop 2.110.0, bundled CLI 2.1.271:
app.asaralso contains only a handful ofmetaKey/onKeyDownreferences and points athttps://claude.ai, so the Code tab composer is the web UI in an Electron shell with the bundled CLI running headless behind it. The only prompt-input binding option in the desktop bundle's settings schema iseditorMode(vim/emacs), which is CLI-only.Practical consequence for this request: it can't be satisfied by
keybindings.jsonsupport alone — either the composer's Enter handling changes on the claude.ai side, or the desktop shell reads the same config and intercepts before the web input gets the key. Might be worth confirming which team owns it, since that may be part of why this cluster has stayed open so long.Workaround in the meantime: run
claudein a real terminal (including the desktop app's own Terminal panel), wherekeybindings.jsonis honored:I add "IME reason" too.
He explains the use-case and the issue very well in English. Thank you.
And basically, sometimes I use multiple lines to communicate with Clause.
"Sending" is a little bit special action. Something such like command+return / Shift+return / Cntrl+return seems better.
For example, ChatGPT can do this kind of key assignment. (like this comment, with "return" strokes...)
+1 from macOS: Enter for newline,
Cmd+Enterto send.Small addition to the VS Code point earlier in the thread: the VS Code extension handles this with its own setting,
"claudeCode.useCtrlEnterToSend": trueThat's a precedent for proposal 2: the same kind of simple on/off setting in the Desktop composer would cover it, and it wouldn't depend on keybindings.json, which (as explained above) can't reach the Desktop composer anyway.
Strong +1 for macos claude app. Make a setting, this shouldn't be that hard.
Claude firing on enter is wasting my money -- I have to kill the session when I meant to give additional input.
Having to run a system extension to change this is lame for a product I'm paying $200/month for!
exactly. Shouldn't have to use external tools or compose outside the app and copy-past to make sure entire message isn't prematurely evaluated.
i drafted an overly detailed feature spec over here :)
https://github.com/anthropics/claude-code/issues/74655#issuecomment-5484657361
The inability to assign Cmd+Enter to submit in Claude Desktop is quite annoying, given that ever other desktop agent I use allow this.
I hate whoever started introducing this in chat apps etc. in General. The amount of times I have sent messages by accident, because I didn't quite hit shift hard enough or forgot about it... It is so annoying.