Handle alt screen

This commit is contained in:
Mmis1000
2020-09-13 21:33:32 +08:00
parent 56bfdb64d4
commit edee1a1067
2 changed files with 55 additions and 5 deletions
@@ -11,6 +11,11 @@ function constrain(value: number, low: number, high: number): number {
return Math.max(low, Math.min(value, high));
}
interface ISerializeOptions {
withAlternate?: boolean;
}
// TODO: Refine this template class later
abstract class BaseSerializeHandler {
constructor(private _buffer: IBuffer) { }
@@ -167,7 +172,7 @@ export class SerializeAddon implements ITerminalAddon {
this._terminal = terminal;
}
public serialize(rows?: number): string {
public serialize(rows?: number, options: ISerializeOptions = {}): string {
// TODO: Add re-position cursor support
// TODO: Add word wrap mode support
// TODO: Add combinedData support
@@ -175,12 +180,25 @@ export class SerializeAddon implements ITerminalAddon {
throw new Error('Cannot use addon until it has been loaded');
}
const maxRows = this._terminal.buffer.active.length;
const handler = new StringSerializeHandler(this._terminal.buffer.active);
if (this._terminal.buffer.active.type === 'normal' || !(options?.withAlternate ?? false)) {
const maxRows = this._terminal.buffer.active.length;
const handler = new StringSerializeHandler(this._terminal.buffer.active);
rows = (rows === undefined) ? maxRows : constrain(rows, 0, maxRows);
rows = (rows === undefined) ? maxRows : constrain(rows, 0, maxRows);
return handler.serialize(maxRows - rows, maxRows);
return handler.serialize(maxRows - rows, maxRows);
}
const maxNormalRows = this._terminal.buffer.normal.length;
const maxAltRows = this._terminal.buffer.alternate.length;
const normalHandler = new StringSerializeHandler(this._terminal.buffer.normal);
const altHandler = new StringSerializeHandler(this._terminal.buffer.alternate);
const normalRows = (rows === undefined) ? maxNormalRows : constrain(rows, 0, maxNormalRows);
const altRows = (rows === undefined) ? maxAltRows : constrain(rows, 0, maxAltRows);
return normalHandler.serialize(maxNormalRows - normalRows, maxNormalRows)
+ '\u001b[?1049h\u001b[H'
+ altHandler.serialize(maxAltRows - altRows, maxAltRows);
}
public dispose(): void { }
@@ -299,6 +299,38 @@ describe('SerializeAddon', () => {
await writeSync(page, lines.join('\\r\\n'));
assert.equal(await page.evaluate(`serializeAddon.serialize();`), expected.join('\r\n'));
});
it('serialize with alt screen correctly', async () => {
const SMCUP = '\u001b[?1049h';
const CUP = '\u001b[H';
const lines = [
`1${SMCUP}${CUP}2`
];
const expected = [
`1${SMCUP}${CUP}2`
];
await writeSync(page, lines.join('\\r\\n'));
assert.equal(JSON.stringify(await page.evaluate(`window.term.buffer.active.type`)), '"alternate"');
assert.equal(JSON.stringify(await page.evaluate(`serializeAddon.serialize(undefined, { withAlternate: true });`)), JSON.stringify(expected.join('\r\n')));
});
it('serialize without alt screen correctly', async () => {
const SMCUP = '\u001b[?1049h';
const RMCUP = '\u001b[?1049l';
const lines = [
`1${SMCUP}2${RMCUP}`
];
const expected = [
`1`
];
await writeSync(page, lines.join('\\r\\n'));
assert.equal(JSON.stringify(await page.evaluate(`window.term.buffer.active === window.term.buffer.alt`)), 'false');
assert.equal(JSON.stringify(await page.evaluate(`serializeAddon.serialize(undefined, { withAlternate: true });`)), JSON.stringify(expected.join('\r\n')));
});
});
function newArray<T>(initial: T | ((index: number) => T), count: number): T[] {