fix(cli): support Shift+Enter for newline insertion across terminals#87
Open
BingqingLyu wants to merge 11 commits into
Open
fix(cli): support Shift+Enter for newline insertion across terminals#87BingqingLyu wants to merge 11 commits into
BingqingLyu wants to merge 11 commits into
Conversation
Shift+Enter now inserts a newline instead of submitting the message.
This is achieved through three complementary mechanisms:
1. Native modifier detection for Apple Terminal (macOS):
- New `@qwen-code/modifiers-napi` native addon calls
CGEventSourceFlagsState to synchronously detect if Shift is held
- KeypressContext checks native Shift state when Enter arrives
in Apple Terminal (which can't distinguish Shift+Enter from Enter)
2. Expanded /terminal-setup command:
- Alacritty: writes [[keyboard.bindings]] to alacritty.toml
- Zed: writes shift-enter binding to keymap.json
- Apple Terminal: enables "Use Option as Meta Key" via PlistBuddy
- VSCode Remote SSH: detects remote sessions and provides manual
instructions instead of modifying remote filesystem
- VSCode sequence changed from backslash+CRLF to ESC+CR for
more reliable parsing (old sequence still works via backslash
detection for existing users)
3. Improved user experience:
- Keyboard shortcuts help now shows "shift+enter" instead of
"ctrl+j" as the primary newline shortcut
- Unsupported terminal message lists all available alternatives
Closes QwenLM#241
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Fix incomplete string escaping in PlistBuddy profile name (CodeQL): escape backslashes before single quotes, reject control characters - Add console.warn when native modifier module fails to load on macOS, so developers can diagnose missing builds instead of silent no-op Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
The "os": ["darwin"] field in package.json causes npm ci to fail with EBADPLATFORM on Linux. Cross-platform safety is already handled by scripts/install.js (exits 0 on non-darwin) and index.js (returns no-op functions on non-darwin). Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
The previous commit removed "os": ["darwin"] from modifiers-napi's package.json, but the lock file still had the old constraint cached, causing npm ci to fail on Linux CI with EBADPLATFORM. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
40 test cases covering: - Key binding matching (Shift/Ctrl/Meta/Paste+Enter, Ctrl+J) - VSCode ESC+CR sequence byte correctness and JSON serialization - Terminal detection for 13 environment combinations - VSCode Remote SSH detection (5 cases) - PlistBuddy profile name escaping (quotes, backslashes, control chars, unicode) - Modifiers wrapper graceful degradation - Apple Terminal native shift detection simulation - Backslash+Enter backward compatibility Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Creates scripts/e2e-verify-shift-enter.mjs that: - Spawns the real CLI via node-pty (no LLM API key required) - Uses @xterm/headless for ANSI-aware screen state capture - Tests 5 key sequences: plain Enter, Ctrl+J, VSCode ESC+CR, Kitty CSI-u (with protocol handshake simulation), backslash+Enter - Outputs structured Markdown report via --markdown flag - All 5 tests pass on darwin arm64 Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- terminalSetup: fix dead code in VSCode configureVSCode() — check our
own bindings first (idempotency), then check for conflicts; previously
the any-binding guard blocked the already-configured path entirely
- terminalSetup: fix Alacritty and Zed idempotency — distinguish our
own added binding from a conflicting third-party binding so /terminal-setup
can be run multiple times safely
- terminalSetup: fix Zed invalid-JSON handling — return error instead of
silently overwriting user's keymap with an empty array
- terminalSetup: replace shell exec('ps ... $PPID') with execFileAsync
to eliminate potential shell expansion and align with security practices
used elsewhere in the file
- modifiers: cache native module reference in getNativeModule() to avoid
redundant require() calls on every Enter keypress in Apple Terminal
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
… errors - eslint.config.js: add './scripts/**/*.mjs' to the scripts file pattern so Node.js globals (setTimeout, console, process) are available - e2e-verify-shift-enter.mjs: add eslint-disable-next-line comments for intentional no-control-regex usages in the reporting formatter - e2e-verify-shift-enter.mjs: add named catch variable to satisfy no-empty Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
… code
- terminalSetup: replace hand-rolled stripJsonComments regex with the
existing strip-json-comments library — the regex only handled full-line
comments but VS Code keybindings.json is JSONC (inline comments, block
comments, trailing commas)
- i18n/zh.js: add ~35 missing Chinese translations for /terminal-setup
command output (Remote SSH instructions, Alacritty/Zed/Apple Terminal
messages, supported terminals list)
- i18n/en.js: add 3 missing locale keys from idempotency fix
(Alacritty/Zed already-configured, Zed invalid-JSON)
- KeyboardShortcuts: simplify getExternalEditorKey — both ternary
branches returned the same value ('ctrl+x')
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Modern terminals (VSCode, Cursor, iTerm2, Ghostty, Kitty, WezTerm, Warp) already support Shift+Enter natively via the Kitty keyboard protocol. The /terminal-setup command and native macOS modifier detection were over-engineered solutions that either didn't work reliably or were unnecessary for the target use cases. Remove: - packages/modifiers-napi: native C++ addon for Apple Terminal modifier detection — unreliable due to race condition between Shift key release and Node.js event processing - terminalSetup.ts + terminalSetupCommand.ts: the /terminal-setup command and all terminal-specific configuration (VSCode keybindings, Alacritty TOML, Zed keymap, Apple Terminal PlistBuddy) - All related i18n keys, tests, and build config references Keep (the only code actually needed): - Kitty protocol CSI-u sequence parsing (handles most modern terminals) - ESC+CR (meta=true) detection for terminals sending \x1b\r - Backslash+Enter fallback for any terminal - Ctrl+J universal newline (already in keyMatchers, no change needed) Rename shift-enter-newline.test.ts → newline-insertion.test.ts, keeping only the key binding matching and backslash+Enter tests. E2E: 5/5 scenarios pass (plain Enter, Ctrl+J, ESC+CR, Kitty CSI-u, backslash+Enter). Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Node's readline already parses ESC+CR (\x1b\r) as {name:'return',meta:true}.
The explicit override was only needed for the VSCode /terminal-setup
keybinding config, which has been removed.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This was referenced Apr 28, 2026
Owner
Author
Conflict Group 1This PR shares modified functions with 6 other PR(s): #107, #37, #86, #9, #94, #96. These PRs should be reviewed as a batch — merging one may affect the others.
graph LR
PR87["PR #87"]
FKeypressProvider_396["KeypressProvider<br>KeypressContext.tsx"]
PR87 -->|modifies| FKeypressProvider_396
PR37["PR #37"]
PR37 -->|modifies| FKeypressProvider_396
PR94["PR #94"]
PR94 -->|modifies| FKeypressProvider_396
FloadCommands_7884["loadCommands<br>BuiltinCommandLoader.ts"]
PR87 -->|modifies| FloadCommands_7884
PR107["PR #107"]
PR107 -->|modifies| FloadCommands_7884
PR86["PR #86"]
PR86 -->|modifies| FloadCommands_7884
PR9["PR #9"]
PR9 -->|modifies| FloadCommands_7884
PR96["PR #96"]
PR96 -->|modifies| FloadCommands_7884
Posted by codegraph-ai conflict detection. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes QwenLM#241 — Shift+Enter now inserts a newline instead of submitting the message.
Most terminals don't send a distinct escape sequence for Shift+Enter (they send the same
\ras plain Enter). This PR adds three complementary mechanisms to make Shift+Enter work across all major terminals:1. Native modifier detection for Apple Terminal (macOS)
@qwen-code/modifiers-napinative addon calls macOSCGEventSourceFlagsStateAPI to synchronously detect if Shift is physically held down when Enter arrivesKeypressContextchecks native Shift state for Apple Terminal, which cannot distinguish Shift+Enter from Enter through escape sequences2. Expanded
/terminal-setupcommand[[keyboard.bindings]]toalacritty.tomlshift-enterbinding tokeymap.jsonPlistBuddy(with plist backup, no shell injection)\\\r\nto\u001b\r(ESC+CR) for more reliable parsing; old sequence still works for existing users via backslash detection3. Improved user experience
shift+enterinstead ofctrl+jas the primary newline shortcutTerminal support matrix
/terminal-setup)/terminal-setup/terminal-setup/terminal-setup\+ Enter, Ctrl+Enter, Ctrl+JTest plan
🤖 Generated with Claude Code