fix(tui): bind ctrl+j as newline by default

This commit is contained in:
Armin Ronacher
2026-06-22 13:57:02 +02:00
parent 71ca9b2b92
commit 3b56134694
6 changed files with 16 additions and 9 deletions
+1
View File
@@ -4,6 +4,7 @@
### Changed ### Changed
- Added `Ctrl+J` as a default newline keybinding alongside `Shift+Enter`.
- Renamed the displayed `zai` provider label to ZAI Coding Plan (Global) for clarity ([#5965](https://github.com/earendil-works/pi/issues/5965)). - Renamed the displayed `zai` provider label to ZAI Coding Plan (Global) for clarity ([#5965](https://github.com/earendil-works/pi/issues/5965)).
## [0.79.10] - 2026-06-22 ## [0.79.10] - 2026-06-22
+1 -1
View File
@@ -54,7 +54,7 @@ Modifier combinations: `ctrl+shift+x`, `alt+ctrl+x`, `ctrl+shift+alt+x`, `ctrl+1
| Keybinding id | Default | Description | | Keybinding id | Default | Description |
|--------|---------|-------------| |--------|---------|-------------|
| `tui.input.newLine` | `shift+enter` | Insert new line | | `tui.input.newLine` | `shift+enter`, `ctrl+j` | Insert new line |
| `tui.input.submit` | `enter` | Submit input | | `tui.input.submit` | `enter` | Submit input |
| `tui.input.tab` | `tab` | Tab / autocomplete | | `tui.input.tab` | `tab` | Tab / autocomplete |
+1 -7
View File
@@ -30,13 +30,7 @@ That mapping sends a raw linefeed byte. Inside pi, that is indistinguishable fro
If Claude Code 2.x or newer is the only reason you added that mapping, you can remove it, unless you want to use Claude Code in tmux, where it still requires that Ghostty mapping. If Claude Code 2.x or newer is the only reason you added that mapping, you can remove it, unless you want to use Claude Code in tmux, where it still requires that Ghostty mapping.
If you want `Shift+Enter` to keep working in tmux via that remap, add `ctrl+j` to your pi `newLine` keybinding in `~/.pi/agent/keybindings.json`: Pi binds `Ctrl+J` as a default newline alias, so `Shift+Enter` keeps working in tmux via that remap without extra pi configuration.
```json
{
"newLine": ["shift+enter", "ctrl+j"]
}
```
## WezTerm ## WezTerm
+4
View File
@@ -2,6 +2,10 @@
## [Unreleased] ## [Unreleased]
### Changed
- Added `Ctrl+J` as a default newline keybinding alongside `Shift+Enter`.
## [0.79.10] - 2026-06-22 ## [0.79.10] - 2026-06-22
## [0.79.9] - 2026-06-20 ## [0.79.9] - 2026-06-20
+1 -1
View File
@@ -115,7 +115,7 @@ export const TUI_KEYBINDINGS = {
"tui.editor.yank": { defaultKeys: "ctrl+y", description: "Yank" }, "tui.editor.yank": { defaultKeys: "ctrl+y", description: "Yank" },
"tui.editor.yankPop": { defaultKeys: "alt+y", description: "Yank pop" }, "tui.editor.yankPop": { defaultKeys: "alt+y", description: "Yank pop" },
"tui.editor.undo": { defaultKeys: "ctrl+-", description: "Undo" }, "tui.editor.undo": { defaultKeys: "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.submit": { defaultKeys: "enter", description: "Submit input" },
"tui.input.tab": { defaultKeys: "tab", description: "Tab / autocomplete" }, "tui.input.tab": { defaultKeys: "tab", description: "Tab / autocomplete" },
"tui.input.copy": { defaultKeys: "ctrl+c", description: "Copy selection" }, "tui.input.copy": { defaultKeys: "ctrl+c", description: "Copy selection" },
+8
View File
@@ -3,6 +3,14 @@ import { describe, it } from "node:test";
import { KeybindingsManager, TUI_KEYBINDINGS } from "../src/keybindings.ts"; import { KeybindingsManager, TUI_KEYBINDINGS } from "../src/keybindings.ts";
describe("KeybindingsManager", () => { describe("KeybindingsManager", () => {
it("binds Ctrl+J as a default newline alias", () => {
const keybindings = new KeybindingsManager(TUI_KEYBINDINGS);
assert.deepStrictEqual(keybindings.getKeys("tui.input.newLine"), ["shift+enter", "ctrl+j"]);
assert.strictEqual(keybindings.matches("\n", "tui.input.newLine"), true);
assert.strictEqual(keybindings.matches("\x1b[106;5u", "tui.input.newLine"), true);
});
it("does not evict selector confirm when input submit is rebound", () => { it("does not evict selector confirm when input submit is rebound", () => {
const keybindings = new KeybindingsManager(TUI_KEYBINDINGS, { const keybindings = new KeybindingsManager(TUI_KEYBINDINGS, {
"tui.input.submit": ["enter", "ctrl+enter"], "tui.input.submit": ["enter", "ctrl+enter"],