mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
fix(tui): add editor viewport key aliases (closes #7574)
This commit is contained in:
parent
71f6c25c36
commit
b0d382e25a
7 changed files with 87 additions and 9 deletions
|
|
@ -112,6 +112,7 @@
|
|||
- Updated `undici` to 8.9.0 and the packaged `brace-expansion` to 5.0.9 to address GHSA-8xcm-r25x-g524, GHSA-4cwx-7wf7-3272, GHSA-m8rv-5g2x-5cg5, GHSA-jr45-8vmc-qm54, GHSA-v3r7-h72x-cjcm, and GHSA-rgw5-rvv9-x895.
|
||||
- Fixed GitHub Copilot compaction and branch summaries using the Individual endpoint instead of the credential-resolved Business or Enterprise endpoint ([#6768](https://github.com/earendil-works/pi/issues/6768)).
|
||||
- Fixed extension model calls dropping credential-resolved endpoints when forwarding request authentication, including custom compaction with GitHub Copilot Business and Enterprise accounts ([#7579](https://github.com/earendil-works/pi/issues/7579)).
|
||||
- Fixed fullscreen transcript navigation leaving no editor-accessible `Home`, `End`, `PageUp`, or `PageDown` variants by adding Ctrl-modified editor bindings ([#7574](https://github.com/earendil-works/pi/issues/7574)).
|
||||
|
||||
## [0.83.0] - 2026-07-29
|
||||
|
||||
|
|
|
|||
|
|
@ -32,12 +32,12 @@ Modifier combinations: `ctrl+shift+x`, `alt+ctrl+x`, `ctrl+shift+alt+x`, `ctrl+1
|
|||
| `tui.editor.cursorRight` | `right`, `ctrl+f` | Move cursor right |
|
||||
| `tui.editor.cursorWordLeft` | `alt+left`, `ctrl+left`, `alt+b` | Move cursor word left |
|
||||
| `tui.editor.cursorWordRight` | `alt+right`, `ctrl+right`, `alt+f` | Move cursor word right |
|
||||
| `tui.editor.cursorLineStart` | `home`, `ctrl+a` | Move to line start |
|
||||
| `tui.editor.cursorLineEnd` | `end`, `ctrl+e` | Move to line end |
|
||||
| `tui.editor.cursorLineStart` | `home`, `ctrl+home`, `ctrl+a` | Move to line start |
|
||||
| `tui.editor.cursorLineEnd` | `end`, `ctrl+end`, `ctrl+e` | Move to line end |
|
||||
| `tui.editor.jumpForward` | `ctrl+]` | Jump forward to character |
|
||||
| `tui.editor.jumpBackward` | `ctrl+alt+]` | Jump backward to character |
|
||||
| `tui.editor.pageUp` | `pageUp` | Scroll up by page |
|
||||
| `tui.editor.pageDown` | `pageDown` | Scroll down by page |
|
||||
| `tui.editor.pageUp` | `pageUp`, `ctrl+pageUp` | Scroll up by page |
|
||||
| `tui.editor.pageDown` | `pageDown`, `ctrl+pageDown` | Scroll down by page |
|
||||
|
||||
### TUI Editor Deletion
|
||||
|
||||
|
|
@ -82,6 +82,17 @@ Modifier combinations: `ctrl+shift+x`, `alt+ctrl+x`, `ctrl+shift+alt+x`, `ctrl+1
|
|||
|
||||
These actions apply when interactive mode uses `--ui-mode fullscreen` and target the primary transcript scroll region. Two-finger trackpad and mouse-wheel input scroll the region under the pointer, falling back to the transcript over the fixed editor/status/footer dock. Clicking an OSC 8 hyperlink opens it in the default handler. Dragging with the primary mouse button selects text and copies it to the clipboard; holding at the transcript's top or bottom edge auto-scrolls into off-screen content.
|
||||
|
||||
Fullscreen transcript bindings take precedence over editor bindings. The default unmodified navigation keys therefore control the transcript in fullscreen mode, while their `ctrl` variants continue to control the editor. Outside fullscreen mode, both variants control the editor.
|
||||
|
||||
| Key | Default mode | Fullscreen mode |
|
||||
|-----|--------------|-----------------|
|
||||
| `home`, `end` | Editor | Transcript |
|
||||
| `ctrl+home`, `ctrl+end` | Editor | Editor |
|
||||
| `pageUp`, `pageDown` | Editor | Transcript |
|
||||
| `ctrl+pageUp`, `ctrl+pageDown` | Editor | Editor |
|
||||
|
||||
This routing remains configurable through the ordinary action bindings. For example, `"tui.altScreen.pageUp": "ctrl+pageUp"` makes `pageUp` control the editor and `ctrl+pageUp` control the transcript in fullscreen mode. Setting `"tui.altScreen.pageUp": []` disables that transcript shortcut entirely. User bindings replace the defaults for that action.
|
||||
|
||||
| Keybinding id | Default | Description |
|
||||
|--------|---------|-------------|
|
||||
| `tui.altScreen.pageUp` | `pageUp` | Scroll the transcript up by one page |
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
- Fixed spaces in searchable settings queries changing the selected value instead of filtering multi-word labels.
|
||||
- Fixed alternate-screen Kitty images crossing vertical layout clip boundaries and overlapping sticky regions while scrolling.
|
||||
- Fixed alternate-screen redraws retransmitting Kitty image data when placements move or recently offscreen images return, dropping adjacent row content when reusing placements, rendering fixed-basis scroll content twice per frame, and scanning clipped transcript rows while painting.
|
||||
- Fixed fullscreen transcript navigation leaving no editor-accessible `Home`, `End`, `PageUp`, or `PageDown` variants by adding Ctrl-modified editor bindings ([#7574](https://github.com/earendil-works/pi/issues/7574)).
|
||||
|
||||
### Added
|
||||
|
||||
|
|
|
|||
|
|
@ -78,11 +78,11 @@ export const TUI_KEYBINDINGS = {
|
|||
description: "Move cursor word right",
|
||||
},
|
||||
"tui.editor.cursorLineStart": {
|
||||
defaultKeys: ["home", "ctrl+a"],
|
||||
defaultKeys: ["home", "ctrl+home", "ctrl+a"],
|
||||
description: "Move to line start",
|
||||
},
|
||||
"tui.editor.cursorLineEnd": {
|
||||
defaultKeys: ["end", "ctrl+e"],
|
||||
defaultKeys: ["end", "ctrl+end", "ctrl+e"],
|
||||
description: "Move to line end",
|
||||
},
|
||||
"tui.editor.jumpForward": {
|
||||
|
|
@ -93,8 +93,8 @@ export const TUI_KEYBINDINGS = {
|
|||
defaultKeys: "ctrl+alt+]",
|
||||
description: "Jump backward to character",
|
||||
},
|
||||
"tui.editor.pageUp": { defaultKeys: "pageUp", description: "Page up" },
|
||||
"tui.editor.pageDown": { defaultKeys: "pageDown", description: "Page down" },
|
||||
"tui.editor.pageUp": { defaultKeys: ["pageUp", "ctrl+pageUp"], description: "Page up" },
|
||||
"tui.editor.pageDown": { defaultKeys: ["pageDown", "ctrl+pageDown"], description: "Page down" },
|
||||
"tui.editor.deleteCharBackward": {
|
||||
defaultKeys: "backspace",
|
||||
description: "Delete character backward",
|
||||
|
|
@ -138,6 +138,7 @@ export const TUI_KEYBINDINGS = {
|
|||
defaultKeys: ["escape", "ctrl+c"],
|
||||
description: "Cancel selection",
|
||||
},
|
||||
// These intentionally shadow the unmodified editor bindings in fullscreen mode.
|
||||
"tui.altScreen.pageUp": {
|
||||
defaultKeys: "pageUp",
|
||||
description: "Scroll viewport up one page",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,16 @@ describe("KeybindingsManager", () => {
|
|||
assert.strictEqual(keybindings.matches("\x1b[106;5u", "tui.input.newLine"), true);
|
||||
});
|
||||
|
||||
it("binds terminal viewport shortcuts to alternate-screen navigation", () => {
|
||||
it("binds modified and unmodified editor viewport navigation", () => {
|
||||
const keybindings = new KeybindingsManager(TUI_KEYBINDINGS);
|
||||
|
||||
assert.deepStrictEqual(keybindings.getKeys("tui.editor.cursorLineStart"), ["home", "ctrl+home", "ctrl+a"]);
|
||||
assert.deepStrictEqual(keybindings.getKeys("tui.editor.cursorLineEnd"), ["end", "ctrl+end", "ctrl+e"]);
|
||||
assert.deepStrictEqual(keybindings.getKeys("tui.editor.pageUp"), ["pageUp", "ctrl+pageUp"]);
|
||||
assert.deepStrictEqual(keybindings.getKeys("tui.editor.pageDown"), ["pageDown", "ctrl+pageDown"]);
|
||||
});
|
||||
|
||||
it("binds unmodified terminal viewport shortcuts to alternate-screen navigation", () => {
|
||||
const keybindings = new KeybindingsManager(TUI_KEYBINDINGS);
|
||||
|
||||
assert.deepStrictEqual(keybindings.getKeys("tui.altScreen.pageUp"), ["pageUp"]);
|
||||
|
|
|
|||
|
|
@ -480,6 +480,17 @@ describe("matchesKey", () => {
|
|||
assert.strictEqual(matchesKey("\x1bOF", "end"), true);
|
||||
});
|
||||
|
||||
it("should match xterm Ctrl-modified viewport navigation", () => {
|
||||
assert.strictEqual(matchesKey("\x1b[1;5H", "ctrl+home"), true);
|
||||
assert.strictEqual(matchesKey("\x1b[1;5F", "ctrl+end"), true);
|
||||
assert.strictEqual(matchesKey("\x1b[5;5~", "ctrl+pageUp"), true);
|
||||
assert.strictEqual(matchesKey("\x1b[6;5~", "ctrl+pageDown"), true);
|
||||
assert.strictEqual(parseKey("\x1b[1;5H"), "ctrl+home");
|
||||
assert.strictEqual(parseKey("\x1b[1;5F"), "ctrl+end");
|
||||
assert.strictEqual(parseKey("\x1b[5;5~"), "ctrl+pageUp");
|
||||
assert.strictEqual(parseKey("\x1b[6;5~"), "ctrl+pageDown");
|
||||
});
|
||||
|
||||
it("should match legacy function keys and clear", () => {
|
||||
assert.strictEqual(matchesKey("\x1bOP", "f1"), true);
|
||||
assert.strictEqual(matchesKey("\x1b[24~", "f12"), true);
|
||||
|
|
|
|||
|
|
@ -307,6 +307,50 @@ describe("TuiAltScreen", () => {
|
|||
tui.stop();
|
||||
});
|
||||
|
||||
it("routes Ctrl-modified viewport navigation to the focused component", async () => {
|
||||
const terminal = new VirtualTerminal(20, 6);
|
||||
const tui = new TuiAltScreen(terminal);
|
||||
const transcript = new ScrollView(
|
||||
new Text(Array.from({ length: 12 }, (_, index) => `line ${index + 1}`).join("\n"), 0, 0),
|
||||
{ follow: "end", primary: true },
|
||||
);
|
||||
const editorInputs: string[] = [];
|
||||
const editor = {
|
||||
focused: false,
|
||||
render: () => ["editor"],
|
||||
invalidate: () => {},
|
||||
handleInput: (data: string) => editorInputs.push(data),
|
||||
};
|
||||
tui.setLayoutRoot(
|
||||
new VStack([
|
||||
{ component: transcript, basis: 0, grow: 1, minSize: 1 },
|
||||
{ component: editor, basis: 1, shrink: 0 },
|
||||
]),
|
||||
);
|
||||
tui.setFocus(editor);
|
||||
tui.start();
|
||||
await terminal.waitForRender();
|
||||
|
||||
terminal.sendInput("\x1bOH");
|
||||
await terminal.waitForRender();
|
||||
assert.strictEqual(transcript.scrollTop, 0);
|
||||
assert.deepStrictEqual(editorInputs, []);
|
||||
|
||||
const modifiedInputs = ["\x1b[1;5H", "\x1b[1;5F", "\x1b[5;5~", "\x1b[6;5~", "\x1b[57423;5u"];
|
||||
for (const input of modifiedInputs) terminal.sendInput(input);
|
||||
terminal.sendInput("\x1b[57423;5:3u");
|
||||
await terminal.waitForRender();
|
||||
assert.strictEqual(transcript.scrollTop, 0);
|
||||
assert.deepStrictEqual(editorInputs, modifiedInputs);
|
||||
|
||||
terminal.sendInput("\x1b[6~");
|
||||
await terminal.waitForRender();
|
||||
assert.strictEqual(transcript.scrollTop, 1);
|
||||
assert.deepStrictEqual(editorInputs, modifiedInputs);
|
||||
|
||||
tui.stop();
|
||||
});
|
||||
|
||||
it("jumps between OSC 133 semantic prompt markers", async () => {
|
||||
const terminal = new VirtualTerminal(20, 3);
|
||||
const tui = new TuiAltScreen(terminal);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue