mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 08:02:28 +00:00
fix(terminal): disable marker row shortcut after reflow
This commit is contained in:
@@ -192,4 +192,28 @@ describe.each([
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
it('keeps wrapped continuation cells when reflow erased the marker row', async () => {
|
||||
const terminal = new HeadlessTerminal({
|
||||
cols: 20,
|
||||
rows: 5,
|
||||
scrollback: 500,
|
||||
allowProposedApi: true,
|
||||
logLevel: 'off'
|
||||
})
|
||||
const retirement = createTerminalOscLinkRetirement(terminal)
|
||||
const liveUri = `${URL}/reflow-erased-marker`
|
||||
try {
|
||||
await write(terminal, `\x1b]8;;${liveUri}\x1b\\abcdefghijklmno${CLOSE}\r\n`)
|
||||
terminal.resize(5, 5)
|
||||
await write(terminal, '\x1b[1;1H\x1b[2K\x1b[5;1H')
|
||||
for (let index = 0; index < 1024; index++) {
|
||||
await write(terminal, `\r\x1b[2K${OPEN}s${CLOSE}`)
|
||||
}
|
||||
retirement()
|
||||
expect(hasUri(terminal, 'normal', liveUri)).toBe(true)
|
||||
} finally {
|
||||
terminal.dispose()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -2,13 +2,15 @@ import type { IBuffer, Terminal } from '@xterm/headless'
|
||||
|
||||
type OscLinkMarker = { dispose(): void; line?: number }
|
||||
type OscLinkEntry = { id: number; lines: OscLinkMarker[] }
|
||||
type TerminalBuffers = Pick<Terminal, 'buffer'>
|
||||
type TerminalBuffers = Pick<Terminal, 'buffer' | 'cols'>
|
||||
|
||||
/** xterm's line markers outlive overwritten hyperlinks, including redraws without scrollback. */
|
||||
export function createTerminalOscLinkRetirement(terminal: TerminalBuffers): () => number {
|
||||
const SWEEP_GROWTH = 1024
|
||||
let nextSweepSize = SWEEP_GROWTH
|
||||
let previousSize = 0
|
||||
let markerRowsEnabled = true
|
||||
let previousColumns = terminal.cols
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === 'object' && value !== null
|
||||
@@ -66,7 +68,7 @@ export function createTerminalOscLinkRetirement(terminal: TerminalBuffers): () =
|
||||
}
|
||||
}
|
||||
|
||||
/** Marker lines identify the only rows that can still contain a registered link. */
|
||||
/** Marker lines identify link rows until a reflow can leave text on unmarked continuation rows. */
|
||||
function collectMarkerRows(entries: Iterable<unknown>): Set<number> | undefined {
|
||||
const rows = new Set<number>()
|
||||
for (const value of entries) {
|
||||
@@ -99,6 +101,10 @@ export function createTerminalOscLinkRetirement(terminal: TerminalBuffers): () =
|
||||
return 0
|
||||
}
|
||||
const entries: Map<unknown, unknown> = service._dataByLinkId
|
||||
if (terminal.cols !== previousColumns) {
|
||||
markerRowsEnabled = false
|
||||
previousColumns = terminal.cols
|
||||
}
|
||||
if (entries.size < previousSize) {
|
||||
nextSweepSize = entries.size + SWEEP_GROWTH
|
||||
}
|
||||
@@ -108,7 +114,7 @@ export function createTerminalOscLinkRetirement(terminal: TerminalBuffers): () =
|
||||
}
|
||||
|
||||
const live = new Set<number>()
|
||||
const markerRows = collectMarkerRows(entries.values())
|
||||
const markerRows = markerRowsEnabled ? collectMarkerRows(entries.values()) : undefined
|
||||
collectBufferLinks(terminal.buffer.normal, live, markerRows)
|
||||
collectBufferLinks(terminal.buffer.alternate, live, markerRows)
|
||||
// An OSC 8 open can finish one write before its linked text arrives in the next.
|
||||
|
||||
Reference in New Issue
Block a user