From ef366cc8717e02e3848ef20501297db1fbbbfd3a Mon Sep 17 00:00:00 2001 From: metaphorics <152830360+metaphorics@users.noreply.github.com> Date: Sun, 14 Jun 2026 05:52:46 +0900 Subject: [PATCH] feat(tui): support ctrl+j as an additional newline key (#2473) --- packages/tui/CHANGELOG.md | 4 ++++ packages/tui/src/keybindings.ts | 2 +- packages/tui/test/keybindings.test.ts | 8 ++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/tui/CHANGELOG.md b/packages/tui/CHANGELOG.md index 4e7c142cb..d5e269dcd 100644 --- a/packages/tui/CHANGELOG.md +++ b/packages/tui/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Added + +- Added `ctrl+j` as a second default binding for the `tui.input.newLine` action alongside `shift+enter`, so terminals that cannot emit `shift+enter` still have a newline key. On terminals with Kitty-protocol / `modifyOtherKeys` disambiguation `ctrl+j` inserts a newline while `Enter` still submits; on legacy terminals where `ctrl+j` and `Enter` are both byte-identical `LF` it submits (documented limitation). User keybinding overrides still take precedence ([#2473](https://github.com/can1357/oh-my-pi/issues/2473)) + ## [15.12.5] - 2026-06-13 ### Added diff --git a/packages/tui/src/keybindings.ts b/packages/tui/src/keybindings.ts index b1ec9d1fd..86bb32617 100644 --- a/packages/tui/src/keybindings.ts +++ b/packages/tui/src/keybindings.ts @@ -118,7 +118,7 @@ export const TUI_KEYBINDINGS = { "tui.editor.yank": { defaultKeys: "ctrl+y", description: "Yank" }, "tui.editor.yankPop": { defaultKeys: "alt+y", description: "Yank pop" }, "tui.editor.undo": { defaultKeys: ["ctrl+-", "ctrl+_"], description: "Undo" }, - "tui.input.newLine": { defaultKeys: "shift+enter", description: "Insert newline" }, + "tui.input.newLine": { defaultKeys: ["shift+enter", "ctrl+j"], description: "Insert newline" }, "tui.input.submit": { defaultKeys: "enter", description: "Submit input" }, "tui.input.tab": { defaultKeys: "tab", description: "Tab / autocomplete" }, "tui.input.copy": { defaultKeys: "ctrl+c", description: "Copy selection" }, diff --git a/packages/tui/test/keybindings.test.ts b/packages/tui/test/keybindings.test.ts index 06fe33685..f0ba5e161 100644 --- a/packages/tui/test/keybindings.test.ts +++ b/packages/tui/test/keybindings.test.ts @@ -44,6 +44,14 @@ describe("KeybindingsManager", () => { expect(keybindings.getKeys("tui.editor.cursorLeft")).toEqual(["left", "ctrl+b"]); }); + it("ships ctrl+j alongside shift+enter as default newline keys", () => { + const keybindings = new KeybindingsManager(TUI_KEYBINDINGS); + + const newLineKeys = keybindings.getKeys("tui.input.newLine"); + expect(newLineKeys).toContain("ctrl+j"); + expect(newLineKeys).toContain("shift+enter"); + }); + it("exports the canonical alias helpers used by matching", () => { const aliases = new Set(); for (const key of ["esc", "return", "?", "shift+a"] as const) {