From 8a2dae0c48f86f5714e54c4e6f5a620b65fbdd1b Mon Sep 17 00:00:00 2001 From: roboomp Date: Fri, 5 Jun 2026 05:29:12 +0000 Subject: [PATCH] fix(keybindings): added Ctrl+Q as default follow-up shortcut Windows Terminal does not deliver a distinct Ctrl+Enter event to console apps, so the existing `app.message.followUp` default never fired there. Ctrl+Q (the chord GitHub Copilot CLI uses for the same action) is added as the primary default and works in every terminal we ship to; Ctrl+Enter is kept as a secondary chord so users on Kitty/iTerm2/WezTerm/Ghostty (where it does deliver) keep the existing muscle memory. Fixes #1903 --- docs/keybindings.md | 4 ++-- packages/coding-agent/CHANGELOG.md | 4 ++++ packages/coding-agent/src/config/keybindings.ts | 5 ++++- .../test/keybindings-migration.test.ts | 15 +++++++++++++++ 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/docs/keybindings.md b/docs/keybindings.md index 8e8158bbf..b6c39250e 100644 --- a/docs/keybindings.md +++ b/docs/keybindings.md @@ -34,13 +34,13 @@ app.stt.toggle: [] | `app.thinking.toggle` | `Ctrl+T` | Toggle thinking-block visibility | | `app.thinking.cycle` | `Shift+Tab` | Cycle thinking level | | `app.editor.external` | `Ctrl+G` | Edit the draft in `$VISUAL` / `$EDITOR` | -| `app.message.followUp` | `Ctrl+Enter` | Queue a follow-up message | +| `app.message.followUp` | `Ctrl+Q`, `Ctrl+Enter` | Queue a follow-up message | | `app.message.dequeue` | `Alt+Up` | Dequeue a queued message back into the editor | | `app.clipboard.copyLine` | `Alt+Shift+L` | Copy the current line | | `app.clipboard.copyPrompt` | `Alt+Shift+C` | Copy the whole prompt | | `app.clipboard.pasteImage` | `Ctrl+V` (`Alt+V` fallback on Windows) | Paste an image from the clipboard | | `app.stt.toggle` | `Alt+H` | Toggle speech-to-text recording | -On Windows Terminal, `Ctrl+V` may be handled by the terminal paste command before `omp` sees it; use the `Alt+V` fallback when clipboard image paste appears to do nothing. +On Windows Terminal, `Ctrl+V` may be handled by the terminal paste command before `omp` sees it; use the `Alt+V` fallback when clipboard image paste appears to do nothing. Windows Terminal also swallows `Ctrl+Enter`, so the follow-up shortcut also binds `Ctrl+Q` — the same chord GitHub Copilot CLI uses. Older unqualified action names are migrated when `keybindings.yml` is loaded, but new docs and new configs should use the namespaced action IDs above. Existing `keybindings.json` files are still accepted and migrated to `keybindings.yml`; `keybindings.yaml` is also accepted. diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 8846e99e6..e03539347 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Changed + +- Changed the default `app.message.followUp` binding from `Ctrl+Enter` alone to `[Ctrl+Q, Ctrl+Enter]` so the follow-up shortcut works in Windows Terminal, which does not deliver a distinct `Ctrl+Enter` event to console apps. `Ctrl+Q` mirrors the GitHub Copilot CLI default for the same action; existing remaps in `~/.omp/agent/keybindings.yml` are untouched ([#1903](https://github.com/can1357/oh-my-pi/issues/1903)). + ## [15.9.1] - 2026-06-04 ### Added diff --git a/packages/coding-agent/src/config/keybindings.ts b/packages/coding-agent/src/config/keybindings.ts index ace7f7860..c78b878b2 100644 --- a/packages/coding-agent/src/config/keybindings.ts +++ b/packages/coding-agent/src/config/keybindings.ts @@ -119,7 +119,10 @@ export const KEYBINDINGS = { description: "Open external editor", }, "app.message.followUp": { - defaultKeys: "ctrl+enter", + // Ctrl+Enter is preserved for terminals that deliver it (Kitty/iTerm2/WezTerm/Ghostty), + // but Windows Terminal does not emit a distinct event for Ctrl+Enter — Ctrl+Q is listed + // first so the default binding works there without remapping (#1903). + defaultKeys: ["ctrl+q", "ctrl+enter"], description: "Send follow-up message", }, "app.message.dequeue": { diff --git a/packages/coding-agent/test/keybindings-migration.test.ts b/packages/coding-agent/test/keybindings-migration.test.ts index 2dc8e0614..13d177466 100644 --- a/packages/coding-agent/test/keybindings-migration.test.ts +++ b/packages/coding-agent/test/keybindings-migration.test.ts @@ -106,4 +106,19 @@ describe("KeybindingsManager.create", () => { await fs.rm(agentDir, { recursive: true, force: true }); } }); + + it("defaults the follow-up shortcut to both Ctrl+Q and Ctrl+Enter (#1903)", async () => { + const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "pi-keybindings-")); + + try { + const manager = KeybindingsManager.create(agentDir); + + // Both chords must be registered so Windows Terminal users (which swallow + // Ctrl+Enter at the terminal layer) get a working follow-up binding out + // of the box, without breaking users on Kitty/iTerm2/WezTerm/Ghostty. + expect(manager.getKeys("app.message.followUp")).toEqual(["ctrl+q", "ctrl+enter"]); + } finally { + await fs.rm(agentDir, { recursive: true, force: true }); + } + }); });