Clean up serialize addon
This commit is contained in:
@@ -13,7 +13,10 @@ function constrain(value: number, low: number, high: number): number {
|
||||
|
||||
// TODO: Refine this template class later
|
||||
abstract class BaseSerializeHandler {
|
||||
constructor(private _buffer: IBuffer) { }
|
||||
constructor(
|
||||
protected readonly _buffer: IBuffer
|
||||
) {
|
||||
}
|
||||
|
||||
public serialize(startRow: number, endRow: number): string {
|
||||
// we need two of them to flip between old and new cell
|
||||
@@ -71,8 +74,6 @@ function equalFlags(cell1: IBufferCell, cell2: IBufferCell): boolean {
|
||||
&& cell1.isDim() === cell2.isDim();
|
||||
}
|
||||
|
||||
|
||||
|
||||
class StringSerializeHandler extends BaseSerializeHandler {
|
||||
private _rowIndex: number = 0;
|
||||
private _allRows: string[] = new Array<string>();
|
||||
@@ -83,7 +84,7 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
||||
// we can see a full colored cell and a null cell that only have background the same style
|
||||
// but the information isn't preserved by null cell itself
|
||||
// so wee need to record it when required.
|
||||
private _cursorStyle: IBufferCell = this._buffer1.getNullCell();
|
||||
private _cursorStyle: IBufferCell = this._buffer.getNullCell();
|
||||
|
||||
// where exact the cursor styles comes from
|
||||
// because we can't copy the cell directly
|
||||
@@ -92,7 +93,7 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
||||
private _cursorStyleCol: number = 0;
|
||||
|
||||
// this is a null cell for reference for checking whether background is empty or not
|
||||
private _backgroundCell: IBufferCell = this._buffer1.getNullCell();
|
||||
private _backgroundCell: IBufferCell = this._buffer.getNullCell();
|
||||
|
||||
private _firstRow: number = 0;
|
||||
private _lastCursorRow: number = 0;
|
||||
@@ -100,8 +101,11 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
||||
private _lastContentCursorRow: number = 0;
|
||||
private _lastContentCursorCol: number = 0;
|
||||
|
||||
constructor(private _buffer1: IBuffer, private _terminal: Terminal) {
|
||||
super(_buffer1);
|
||||
constructor(
|
||||
buffer: IBuffer,
|
||||
private readonly _terminal: Terminal
|
||||
) {
|
||||
super(buffer);
|
||||
}
|
||||
|
||||
protected _beforeSerialize(rows: number, start: number, end: number): void {
|
||||
@@ -111,14 +115,14 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
||||
this._firstRow = start;
|
||||
}
|
||||
|
||||
private _thisRowLastChar: IBufferCell = this._buffer1.getNullCell();
|
||||
private _thisRowLastSecondChar: IBufferCell = this._buffer1.getNullCell();
|
||||
private _nextRowFirstChar: IBufferCell = this._buffer1.getNullCell();
|
||||
private _thisRowLastChar: IBufferCell = this._buffer.getNullCell();
|
||||
private _thisRowLastSecondChar: IBufferCell = this._buffer.getNullCell();
|
||||
private _nextRowFirstChar: IBufferCell = this._buffer.getNullCell();
|
||||
protected _rowEnd(row: number, isLastRow: boolean): void {
|
||||
// if there is colorful empty cell at line end, whe must pad it back, or the the color block will missing
|
||||
if (this._nullCellCount > 0 && !equalBg(this._cursorStyle, this._backgroundCell)) {
|
||||
// use clear right to set background.
|
||||
this._currentRow += `\x1b[${this._nullCellCount}X`;
|
||||
this._currentRow += `\u001b[${this._nullCellCount}X`;
|
||||
}
|
||||
|
||||
let rowSeparator = '';
|
||||
@@ -127,13 +131,13 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
||||
if (!isLastRow) {
|
||||
// Enable BCE
|
||||
if (row - this._firstRow >= this._terminal.rows) {
|
||||
this._buffer1.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol, this._backgroundCell);
|
||||
this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol, this._backgroundCell);
|
||||
}
|
||||
|
||||
// Fetch current line
|
||||
const currentLine = this._buffer1.getLine(row)!;
|
||||
const currentLine = this._buffer.getLine(row)!;
|
||||
// Fetch next line
|
||||
const nextLine = this._buffer1.getLine(row + 1)!;
|
||||
const nextLine = this._buffer.getLine(row + 1)!;
|
||||
|
||||
if (!nextLine.isWrapped) {
|
||||
// just insert the line break
|
||||
@@ -187,15 +191,15 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
||||
// insert enough character to force the wrap
|
||||
rowSeparator = '-'.repeat(this._nullCellCount + 1);
|
||||
// move back and erase next line head
|
||||
rowSeparator += '\x1b[1D\x1b[1X';
|
||||
rowSeparator += '\u001b[1D\u001b[1X';
|
||||
|
||||
if (this._nullCellCount > 0) {
|
||||
// do these because we filled the last several null slot, which we shouldn't
|
||||
rowSeparator += '\x1b[A';
|
||||
rowSeparator += `\x1b[${currentLine.length - this._nullCellCount}C`;
|
||||
rowSeparator += `\x1b[${this._nullCellCount}X`;
|
||||
rowSeparator += `\x1b[${currentLine.length - this._nullCellCount}D`;
|
||||
rowSeparator += '\x1b[B';
|
||||
rowSeparator += '\u001b[A';
|
||||
rowSeparator += `\u001b[${currentLine.length - this._nullCellCount}C`;
|
||||
rowSeparator += `\u001b[${this._nullCellCount}X`;
|
||||
rowSeparator += `\u001b[${currentLine.length - this._nullCellCount}D`;
|
||||
rowSeparator += '\u001b[B';
|
||||
}
|
||||
|
||||
// This is content and need the be serialized even it is invisible.
|
||||
@@ -285,20 +289,20 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
||||
if (this._nullCellCount > 0) {
|
||||
// use clear right to set background.
|
||||
if (!equalBg(this._cursorStyle, this._backgroundCell)) {
|
||||
this._currentRow += `\x1b[${this._nullCellCount}X`;
|
||||
this._currentRow += `\u001b[${this._nullCellCount}X`;
|
||||
}
|
||||
// use move right to move cursor.
|
||||
this._currentRow += `\x1b[${this._nullCellCount}C`;
|
||||
this._currentRow += `\u001b[${this._nullCellCount}C`;
|
||||
this._nullCellCount = 0;
|
||||
}
|
||||
|
||||
this._lastContentCursorRow = this._lastCursorRow = row;
|
||||
this._lastContentCursorCol = this._lastCursorCol = col;
|
||||
|
||||
this._currentRow += `\x1b[${sgrSeq.join(';')}m`;
|
||||
this._currentRow += `\u001b[${sgrSeq.join(';')}m`;
|
||||
|
||||
// update the last cursor style
|
||||
const line = this._buffer1.getLine(row);
|
||||
const line = this._buffer.getLine(row);
|
||||
if (line !== undefined) {
|
||||
line.getCell(col, this._cursorStyle);
|
||||
this._cursorStyleRow = row;
|
||||
@@ -317,10 +321,10 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
||||
// because style change is handled by previous stage
|
||||
// use move right when background is empty, use clear right when there is background.
|
||||
if (equalBg(this._cursorStyle, this._backgroundCell)) {
|
||||
this._currentRow += `\x1b[${this._nullCellCount}C`;
|
||||
this._currentRow += `\u001b[${this._nullCellCount}C`;
|
||||
} else {
|
||||
this._currentRow += `\x1b[${this._nullCellCount}X`;
|
||||
this._currentRow += `\x1b[${this._nullCellCount}C`;
|
||||
this._currentRow += `\u001b[${this._nullCellCount}X`;
|
||||
this._currentRow += `\u001b[${this._nullCellCount}C`;
|
||||
}
|
||||
this._nullCellCount = 0;
|
||||
}
|
||||
@@ -338,7 +342,7 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
||||
|
||||
// the fixup is only required for data without scrollback
|
||||
// because it will always be placed at last line otherwise
|
||||
if (this._buffer1.length - this._firstRow <= this._terminal.rows) {
|
||||
if (this._buffer.length - this._firstRow <= this._terminal.rows) {
|
||||
rowEnd = this._lastContentCursorRow + 1 - this._firstRow;
|
||||
this._lastCursorCol = this._lastContentCursorCol;
|
||||
this._lastCursorRow = this._lastContentCursorRow;
|
||||
@@ -354,8 +358,8 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
||||
}
|
||||
|
||||
// restore the cursor
|
||||
const realCursorRow = this._buffer1.baseY + this._buffer1.cursorY;
|
||||
const realCursorCol = this._buffer1.cursorX;
|
||||
const realCursorRow = this._buffer.baseY + this._buffer.cursorY;
|
||||
const realCursorCol = this._buffer.cursorX;
|
||||
|
||||
const cursorMoved = (realCursorRow !== this._lastCursorRow || realCursorCol !== this._lastCursorCol);
|
||||
|
||||
@@ -379,7 +383,6 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
||||
moveRight(realCursorCol - this._lastCursorCol);
|
||||
}
|
||||
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
@@ -393,14 +396,11 @@ export class SerializeAddon implements ITerminalAddon {
|
||||
this._terminal = terminal;
|
||||
}
|
||||
|
||||
private _getString(buffer: IBuffer, scrollback?: number): string {
|
||||
private _serializeBuffer(terminal: Terminal, buffer: IBuffer, scrollback?: number): string {
|
||||
const maxRows = buffer.length;
|
||||
const handler = new StringSerializeHandler(buffer, this._terminal!);
|
||||
|
||||
const correctRows = (scrollback === undefined) ? maxRows : constrain(scrollback + this!._terminal!.rows, 0, maxRows);
|
||||
const result = handler.serialize(maxRows - correctRows, maxRows);
|
||||
|
||||
return result;
|
||||
const handler = new StringSerializeHandler(buffer, terminal);
|
||||
const correctRows = (scrollback === undefined) ? maxRows : constrain(scrollback + terminal.rows, 0, maxRows);
|
||||
return handler.serialize(maxRows - correctRows, maxRows);
|
||||
}
|
||||
|
||||
public serialize(scrollback?: number): string {
|
||||
@@ -409,17 +409,16 @@ export class SerializeAddon implements ITerminalAddon {
|
||||
throw new Error('Cannot use addon until it has been loaded');
|
||||
}
|
||||
|
||||
if (this._terminal.buffer.active.type === 'normal') {
|
||||
return this._getString(this._terminal.buffer.active, scrollback);
|
||||
// Normal buffer
|
||||
let content = this._serializeBuffer(this._terminal, this._terminal.buffer.normal, scrollback);
|
||||
|
||||
// Alternate buffer
|
||||
if (this._terminal.buffer.active.type === 'alternate') {
|
||||
const alternativeScreenContent = this._serializeBuffer(this._terminal, this._terminal.buffer.alternate, undefined);
|
||||
content += `\u001b[?1049h\u001b[H${alternativeScreenContent}`;
|
||||
}
|
||||
|
||||
const normalScreenContent = this._getString(this._terminal.buffer.normal, scrollback);
|
||||
// alt screen don't have scrollback
|
||||
const alternativeScreenContent = this._getString(this._terminal.buffer.alternate, undefined);
|
||||
|
||||
return normalScreenContent
|
||||
+ '\u001b[?1049h\u001b[H'
|
||||
+ alternativeScreenContent;
|
||||
return content;
|
||||
}
|
||||
|
||||
public dispose(): void { }
|
||||
|
||||
Reference in New Issue
Block a user