Files
xterm.js/src/TerminalLine.ts
T

104 lines
3.2 KiB
TypeScript

/**
* Copyright (c) 2018 The xterm.js authors. All rights reserved.
* @license MIT
*/
import { CharData } from './Types';
import { NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR } from './Buffer';
/**
* Class representing a terminal line.
* Currently the class is a thin proxy to `CharData[]`.
* Once the storages are in place it will proxy access to
* typed array based line data.
* TODO:
* - move Buffer.translateBufferLineToString here?
* - next steps towards typed array:
* - create ITerminalLine interface w'o length methods
* - resize method
* - replace all external push/pop/splice accesses
* - fixed length
* - remove push/pop/splice
* - implement typed array alternative once string is removed from CharData
*/
export class TerminalLine {
static defaultCell: CharData = [0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE];
static blankLine(cols: number, attr: number, isWrapped?: boolean): TerminalLine {
const ch: CharData = [attr, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE];
return new TerminalLine(cols, ch, isWrapped);
}
private _data: CharData[];
public isWrapped = false;
public length: number;
constructor(cols?: number, ch?: CharData, isWrapped?: boolean) {
this._data = [];
this.length = this._data.length;
if (cols) {
if (!ch) ch = TerminalLine.defaultCell;
for (let i = 0; i < cols; i++) this.push(ch); // Note: the ctor ch is not cloned
}
if (isWrapped) this.isWrapped = true;
}
public get(index: number): CharData {
return this._data[index];
}
public set(index: number, data: CharData): void {
this._data[index] = data;
// TODO: unref old, ref new
}
// to be removed for typed array
public pop(): CharData | undefined {
// TODO: unref here, change CharData to [typeof Attributes, ...]
const data = this._data.pop();
this.length = this._data.length;
return data;
}
// to be removed for typed array
public push(data: CharData): void {
this._data.push(data);
this.length = this._data.length;
// TODO: ref here
}
// to be removed for typed array
public splice(start: number, deleteCount: number, ...items: CharData[]): CharData[] {
const removed = this._data.splice(start, deleteCount, ...items);
this.length = this._data.length;
// TODO: ref new, unref old
return removed;
}
/** to be called when a line gets removed */
public release(): void {
// TODO: unref here
}
public toArray(): CharData[] {
return this._data;
}
/** insert n cells ch at pos, right cells are lost (stable length) */
public insertCells(pos: number, n: number, ch: CharData): void {
while (n--) {
this.splice(pos, 0, ch);
this.pop();
}
}
/** delete n cells at pos, right side is filled with fill (stable length) */
public deleteCells(pos: number, n: number, fill: CharData): void {
while (n--) {
this.splice(pos, 1);
this.push(fill);
}
}
/** replace cells from pos to pos + n - 1 with fill */
public replaceCells(start: number, end: number, fill: CharData): void {
while (start < end && start < this.length) this.set(start++, fill); // Note: fill is not cloned
}
}