chore(vendor): import pi 1.3.0

Imported as a linear vendor commit so forge rebases do not replay the upstream root tree.

git-subtree-dir: third_party/pi

git-subtree-split: 71023aec1546d6d677a65669c5665c0927ce0dd0
This commit is contained in:
2026-10-15 17:58:48 -04:00
parent 719370c8f7
commit 6081e3e325
1743 changed files with 205460 additions and 131705 deletions

View File

@@ -5,6 +5,7 @@ import { join } from "node:path";
import { describe, it } from "node:test";
import type { Terminal as XtermTerminalType } from "@xterm/headless";
import { Image } from "../src/components/image.ts";
import { Input } from "../src/components/input.ts";
import type { Terminal } from "../src/terminal.ts";
import {
deleteKittyImage,
@@ -13,8 +14,9 @@ import {
setCapabilities,
setCellDimensions,
} from "../src/terminal-image.ts";
import type { Component, TUI } from "../src/tui.ts";
import { type Component, CURSOR_MARKER, renderFakeCursor, type TUI } from "../src/tui.ts";
import { TuiMainScreen } from "../src/tui-main-screen.ts";
import { sliceByColumn } from "../src/utils.ts";
import { VirtualTerminal } from "./virtual-terminal.ts";
class TestComponent implements Component {
@@ -60,6 +62,7 @@ class BoundedWriteTerminal implements Terminal {
clearScreen(): void {}
setTitle(_title: string): void {}
setProgress(_active: boolean): void {}
setProgramStatus(): void {}
}
class LoggingVirtualTerminal extends VirtualTerminal {
@@ -950,3 +953,72 @@ describe("TUI differential rendering", () => {
tui.stop();
});
});
describe("TUI fake cursor", () => {
it("draws the focused fake cursor in reverse video and omits it when the hardware cursor is shown", async () => {
const terminal = new LoggingVirtualTerminal(20, 5);
const tui: TUI = new TuiMainScreen(terminal);
const input = new Input();
input.setValue("abc");
tui.addChild(input);
tui.setFocus(input);
tui.start();
await terminal.waitForRender();
assert.ok(terminal.getWrites().includes("> \x1b[7ma\x1b[27mbc"));
terminal.clearWrites();
tui.setShowHardwareCursor(true);
await terminal.waitForRender();
assert.ok(!terminal.getWrites().includes("\x1b[7m"));
assert.ok(!terminal.getWrites().includes("\x1b_pi:"));
tui.stop();
});
it("keeps the fake cursor of an unfocused input when the hardware cursor is shown", async () => {
const terminal = new LoggingVirtualTerminal(20, 5);
const tui: TUI = new TuiMainScreen(terminal, true);
const input = new Input();
input.setValue("abc");
tui.addChild(input);
tui.start();
await terminal.waitForRender();
assert.ok(terminal.getWrites().includes("> \x1b[7ma\x1b[27mbc"));
tui.stop();
});
it("omits the focused fake cursor when truncation dropped its end marker", async () => {
const terminal = new LoggingVirtualTerminal(20, 5);
const tui: TUI = new TuiMainScreen(terminal, true);
const base = new TestComponent();
base.lines = [sliceByColumn(`ab${CURSOR_MARKER}${renderFakeCursor("c")}def`, 0, 3, true)];
tui.addChild(base);
tui.start();
await terminal.waitForRender();
assert.ok(!terminal.getWrites().includes("\x1b[7m"));
assert.ok(terminal.getWrites().endsWith("\x1b[3G"));
tui.stop();
});
it("keeps the cursor when an overlay ends directly left of it", async () => {
for (const showHardwareCursor of [false, true]) {
const terminal = new LoggingVirtualTerminal(20, 5);
const tui: TUI = new TuiMainScreen(terminal, showHardwareCursor);
const base = new TestComponent();
base.lines = [`abc${CURSOR_MARKER}${renderFakeCursor("d")}ef`];
tui.addChild(base);
const overlay = new TestComponent();
overlay.lines = ["XXX"];
tui.showOverlay(overlay, { row: 0, col: 0, width: 3 });
tui.start();
await terminal.waitForRender();
const writes = terminal.getWrites();
assert.ok(writes.includes("XXX"));
assert.strictEqual(writes.includes("\x1b[7md"), !showHardwareCursor);
// The hardware cursor is positioned at column 4 in both modes
assert.ok(writes.endsWith("\x1b[4G"));
tui.stop();
}
});
});