Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions packages/cli/src/__tests__/pi-tui-runner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import { BUSY_SPINNER_FRAMES } from '../tui-attention.js';
import {
assertBottomPickerPlacement,
FakeTerminal,
inputSurfaceRows,
findInputSurfaceRows,
latestPlainLineContaining,
plainTerminalOutput,
WAIT_BUDGET_MS,
Expand Down Expand Up @@ -5476,7 +5476,7 @@ describe('Maka Pi TUI runner', () => {
// Sentinel render: a wrongly-opened picker would be on screen by the time
// the typed char paints.
terminal.input('z');
await waitFor(() => editorInputText(terminal).endsWith('z'));
await waitFor(() => editorInputText(terminal)?.endsWith('z') === true);
assert.equal(plainTerminalOutput(terminal.screenOutput()).includes('回到选定轮次'), false);

exitMaka(terminal);
Expand Down Expand Up @@ -6489,9 +6489,11 @@ function bellCount(terminal: FakeTerminal): number {
return terminal.writes.filter((write) => write === '\x07').length;
}

function editorInputText(terminal: FakeTerminal): string {
function editorInputText(terminal: FakeTerminal): string | undefined {
const lines = plainTerminalOutput(terminal.screenOutput()).split(/\r?\n/);
const [topEditorBorderIndex, bottomEditorBorderIndex] = inputSurfaceRows(lines);
const inputRows = findInputSurfaceRows(lines);
if (!inputRows) return undefined;
const [topEditorBorderIndex, bottomEditorBorderIndex] = inputRows;
return lines
.slice(topEditorBorderIndex + 1, bottomEditorBorderIndex)
.join('\n')
Expand Down
12 changes: 12 additions & 0 deletions packages/cli/src/__tests__/tui-terminal-mock.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import assert from 'node:assert/strict';
import { test } from 'node:test';
import { findInputSurfaceRows, inputSurfaceRows } from './tui-terminal-mock.js';

test('input surface lookup distinguishes an intermediate frame from a settled frame', () => {
const intermediate = ['────────────────'];
const settled = ['────────────────', 'draft', '────────────────'];

assert.equal(findInputSurfaceRows(intermediate), undefined);
assert.deepEqual(findInputSurfaceRows(settled), [0, 2]);
assert.throws(() => inputSurfaceRows(intermediate));
});
18 changes: 11 additions & 7 deletions packages/cli/src/__tests__/tui-terminal-mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,23 @@ export function plainTerminalOutput(output: string): string {
.replace(/\x1b\[[0-9;?]*[ -/]*[@-~]/g, '');
}

export function inputSurfaceRows(lines: readonly string[]): [number, number] {
export function findInputSurfaceRows(lines: readonly string[]): [number, number] | undefined {
const editorBorderIndexes = lines
.map((line, index) => (/^─+$/.test(line) ? index : -1))
.filter((index) => index >= 0);
assert.ok(editorBorderIndexes.length >= 2);
if (editorBorderIndexes.length < 2) return undefined;
return [
editorBorderIndexes[editorBorderIndexes.length - 2]!,
editorBorderIndexes[editorBorderIndexes.length - 1]!,
];
}

export function inputSurfaceRows(lines: readonly string[]): [number, number] {
const rows = findInputSurfaceRows(lines);
assert.ok(rows, 'expected a settled input surface with top and bottom editor borders');
return rows;
}

/**
* The slash-autocomplete suggestion rows on the input surface: the contiguous
* `/command` lines sitting immediately above the editor's top border. The
Expand All @@ -89,11 +95,9 @@ export function inputSurfaceRows(lines: readonly string[]): [number, number] {
*/
export function autocompleteSuggestionLines(lines: readonly string[]): readonly string[] {
if (!lines.some((line) => line.includes('→'))) return [];
const editorBorders = lines
.map((line, index) => (/^─+$/.test(line) ? index : -1))
.filter((index) => index >= 0);
if (editorBorders.length < 2) return [];
const editorTopBorder = editorBorders[editorBorders.length - 2]!;
const inputRows = findInputSurfaceRows(lines);
if (!inputRows) return [];
const [editorTopBorder] = inputRows;
let start = editorTopBorder;
while (start > 0 && /\/\w/.test(lines[start - 1]!)) start -= 1;
return lines.slice(start, editorTopBorder);
Expand Down
Loading