diff --git a/addons/xterm-addon-serialize/src/SerializeAddon.ts b/addons/xterm-addon-serialize/src/SerializeAddon.ts index 3113777e..2363e326 100644 --- a/addons/xterm-addon-serialize/src/SerializeAddon.ts +++ b/addons/xterm-addon-serialize/src/SerializeAddon.ts @@ -320,10 +320,11 @@ export class SerializeAddon implements ITerminalAddon { this._terminal = terminal; } - private _getString(buffer: IBuffer, rows?: number, option?: ISerializeOptions): string { + private _getString(buffer: IBuffer, scrollback?: number, option?: ISerializeOptions): string { const maxRows = buffer.length; const handler = new StringSerializeHandler(buffer, this._terminal!, option); - const correctRows = (rows === undefined) ? maxRows : constrain(rows, 0, maxRows); + + const correctRows = (scrollback === undefined) ? maxRows : constrain(scrollback + this!._terminal!.rows, 0, maxRows); const result = handler.serialize(maxRows - correctRows, maxRows); return result; @@ -366,7 +367,7 @@ export class SerializeAddon implements ITerminalAddon { }; } - public serialize(rows?: number, options: ISerializeOptions = {}): string { + public serialize(scrollback?: number, options: ISerializeOptions = {}): string { // TODO: Add word wrap mode support // TODO: Add combinedData support if (!this._terminal) { @@ -374,11 +375,12 @@ export class SerializeAddon implements ITerminalAddon { } if (this._terminal.buffer.active.type === 'normal' || !(options.withAlternate ?? true)) { - return this._getString(this._terminal.buffer.active, rows, options); + return this._getString(this._terminal.buffer.active, scrollback, options); } - const normalScreenContent = this._getString(this._terminal.buffer.normal, rows, options); - const alternativeScreenContent = this._getString(this._terminal.buffer.alternate, rows, options); + const normalScreenContent = this._getString(this._terminal.buffer.normal, scrollback, options); + // alt screen don't have scrollback + const alternativeScreenContent = this._getString(this._terminal.buffer.alternate, undefined, options); return normalScreenContent + '\u001b[?1049h\u001b[H' diff --git a/addons/xterm-addon-serialize/test/SerializeAddon.api.ts b/addons/xterm-addon-serialize/test/SerializeAddon.api.ts index a63e386b..0401953d 100644 --- a/addons/xterm-addon-serialize/test/SerializeAddon.api.ts +++ b/addons/xterm-addon-serialize/test/SerializeAddon.api.ts @@ -39,7 +39,7 @@ describe('SerializeAddon', () => { assert.equal(await page.evaluate(`serializeAddon.serialize();`), ''); }); - it('trim last empty lines', async function(): Promise { + it('preserve last empty lines', async function(): Promise { const cols = 10; const lines = [ '', @@ -55,7 +55,7 @@ describe('SerializeAddon', () => { '' ]; await writeSync(page, lines.join('\\r\\n')); - assert.equal(await page.evaluate(`serializeAddon.serialize();`), lines.slice(0, 8).join('\r\n')); + assert.equal(await page.evaluate(`serializeAddon.serialize();`), lines.join('\r\n')); }); it('digits content', async function(): Promise { @@ -67,21 +67,22 @@ describe('SerializeAddon', () => { assert.equal(await page.evaluate(`serializeAddon.serialize();`), lines.join('\r\n')); }); - it('serialize half rows of content', async function(): Promise { - const rows = 10; - const halfRows = rows >> 1; + it('serialize with half of scrollback', async function(): Promise { + const rows = 20; + const scrollback = rows - 10; + const halfScrollback = scrollback / 2; const cols = 10; const lines = newArray((index: number) => digitsString(cols, index), rows); await writeSync(page, lines.join('\\r\\n')); - assert.equal(await page.evaluate(`serializeAddon.serialize(${halfRows});`), lines.slice(halfRows, 2 * halfRows).join('\r\n')); + assert.equal(await page.evaluate(`serializeAddon.serialize(${halfScrollback});`), lines.slice(halfScrollback, rows).join('\r\n')); }); - it('serialize 0 rows of content', async function(): Promise { - const rows = 10; + it('serialize 0 rows of scrollback', async function(): Promise { + const rows = 20; const cols = 10; const lines = newArray((index: number) => digitsString(cols, index), rows); await writeSync(page, lines.join('\\r\\n')); - assert.equal(await page.evaluate(`serializeAddon.serialize(0);`), ''); + assert.equal(await page.evaluate(`serializeAddon.serialize(0);`), lines.slice(rows - 10, rows).join('\r\n')); }); it('serialize all rows of content with color16', async function(): Promise {