Merge branch 'master' into updated_wcwidth

This commit is contained in:
Jörg Breitbart
2019-12-21 15:28:38 +01:00
24 changed files with 427 additions and 376 deletions
+97 -92
View File
@@ -18,7 +18,7 @@ import { NULL_CELL_CODE, NULL_CELL_WIDTH, Attributes, FgFlags, BgFlags, Content
import { CellData } from 'common/buffer/CellData';
import { AttributeData } from 'common/buffer/AttributeData';
import { IAttributeData, IDisposable } from 'common/Types';
import { ICoreService, IBufferService, IOptionsService, ILogService, IDirtyRowService, ICoreMouseService, IUnicodeService } from 'common/services/Services';
import { ICoreService, IBufferService, IOptionsService, ILogService, IDirtyRowService, ICoreMouseService, ICharsetService, IUnicodeService } from 'common/services/Services';
import { OscHandler } from 'common/parser/OscParser';
import { DcsHandler } from 'common/parser/DcsParser';
@@ -127,6 +127,15 @@ export class InputHandler extends Disposable implements IInputHandler {
private _utf8Decoder: Utf8ToUtf32 = new Utf8ToUtf32();
private _workCell: CellData = new CellData();
private _curAttrData: IAttributeData = DEFAULT_ATTR_DATA.clone();
private _eraseAttrDataInternal: IAttributeData = DEFAULT_ATTR_DATA.clone();
private _onRequestRefreshRows = new EventEmitter<number, number>();
public get onRequestRefreshRows(): IEvent<number, number> { return this._onRequestRefreshRows.event; }
private _onRequestReset = new EventEmitter<void>();
public get onRequestReset(): IEvent<void> { return this._onRequestReset.event; }
private _onRequestBell = new EventEmitter<void>();
public get onRequestBell(): IEvent<void> { return this._onRequestBell.event; }
private _onCursorMove = new EventEmitter<void>();
public get onCursorMove(): IEvent<void> { return this._onCursorMove.event; }
private _onLineFeed = new EventEmitter<void>();
@@ -135,8 +144,9 @@ export class InputHandler extends Disposable implements IInputHandler {
public get onScroll(): IEvent<number> { return this._onScroll.event; }
constructor(
protected _terminal: IInputHandlingTerminal,
private _terminal: IInputHandlingTerminal,
private readonly _bufferService: IBufferService,
private readonly _charsetService: ICharsetService,
private readonly _coreService: ICoreService,
private readonly _dirtyRowService: IDirtyRowService,
private readonly _logService: ILogService,
@@ -295,7 +305,7 @@ export class InputHandler extends Disposable implements IInputHandler {
this._parser.setEscHandler({final: 'M'}, () => this.reverseIndex());
this._parser.setEscHandler({final: '='}, () => this.keypadApplicationMode());
this._parser.setEscHandler({final: '>'}, () => this.keypadNumericMode());
this._parser.setEscHandler({final: 'c'}, () => this.reset());
this._parser.setEscHandler({final: 'c'}, () => this.fullReset());
this._parser.setEscHandler({final: 'n'}, () => this.setgLevel(2));
this._parser.setEscHandler({final: 'o'}, () => this.setgLevel(3));
this._parser.setEscHandler({final: '|'}, () => this.setgLevel(3));
@@ -371,19 +381,19 @@ export class InputHandler extends Disposable implements IInputHandler {
}
// Refresh any dirty rows accumulated as part of parsing
this._terminal.refresh(this._dirtyRowService.start, this._dirtyRowService.end);
this._onRequestRefreshRows.fire(this._dirtyRowService.start, this._dirtyRowService.end);
}
public print(data: Uint32Array, start: number, end: number): void {
let code: number;
let chWidth: number;
const buffer = this._bufferService.buffer;
const charset = this._terminal.charset;
const charset = this._charsetService.charset;
const screenReaderMode = this._optionsService.options.screenReaderMode;
const cols = this._bufferService.cols;
const wraparoundMode = this._terminal.wraparoundMode;
const wraparoundMode = this._coreService.decPrivateModes.wraparound;
const insertMode = this._terminal.insertMode;
const curAttr = this._terminal.curAttrData;
const curAttr = this._curAttrData;
let bufferRow = buffer.lines.get(buffer.y + buffer.ybase);
this._dirtyRowService.markDirty(buffer.y);
@@ -438,7 +448,7 @@ export class InputHandler extends Disposable implements IInputHandler {
buffer.y++;
if (buffer.y === buffer.scrollBottom + 1) {
buffer.y--;
this._terminal.scroll(true);
this._terminal.scroll(this._eraseAttrData(), true);
} else {
if (buffer.y >= this._bufferService.rows) {
buffer.y = this._bufferService.rows - 1;
@@ -534,7 +544,7 @@ export class InputHandler extends Disposable implements IInputHandler {
* Bell (Ctrl-G).
*/
public bell(): void {
this._terminal.bell();
this._onRequestBell.fire();
}
/**
@@ -552,7 +562,7 @@ export class InputHandler extends Disposable implements IInputHandler {
buffer.y++;
if (buffer.y === buffer.scrollBottom + 1) {
buffer.y--;
this._terminal.scroll();
this._terminal.scroll(this._eraseAttrData());
} else if (buffer.y >= this._bufferService.rows) {
buffer.y = this._bufferService.rows - 1;
}
@@ -605,7 +615,7 @@ export class InputHandler extends Disposable implements IInputHandler {
* G1 character set.
*/
public shiftOut(): void {
this._terminal.setgLevel(1);
this._charsetService.setgLevel(1);
}
/**
@@ -614,7 +624,7 @@ export class InputHandler extends Disposable implements IInputHandler {
* character set (the default).
*/
public shiftIn(): void {
this._terminal.setgLevel(0);
this._charsetService.setgLevel(0);
}
/**
@@ -622,7 +632,7 @@ export class InputHandler extends Disposable implements IInputHandler {
*/
private _restrictCursor(): void {
this._bufferService.buffer.x = Math.min(this._bufferService.cols - 1, Math.max(0, this._bufferService.buffer.x));
this._bufferService.buffer.y = this._terminal.originMode
this._bufferService.buffer.y = this._coreService.decPrivateModes.origin
? Math.min(this._bufferService.buffer.scrollBottom, Math.max(this._bufferService.buffer.scrollTop, this._bufferService.buffer.y))
: Math.min(this._bufferService.rows - 1, Math.max(0, this._bufferService.buffer.y));
this._dirtyRowService.markDirty(this._bufferService.buffer.y);
@@ -633,7 +643,7 @@ export class InputHandler extends Disposable implements IInputHandler {
*/
private _setCursor(x: number, y: number): void {
this._dirtyRowService.markDirty(this._bufferService.buffer.y);
if (this._terminal.originMode) {
if (this._coreService.decPrivateModes.origin) {
this._bufferService.buffer.x = x;
this._bufferService.buffer.y = this._bufferService.buffer.scrollTop + y;
} else {
@@ -844,7 +854,7 @@ export class InputHandler extends Disposable implements IInputHandler {
line.replaceCells(
start,
end,
this._bufferService.buffer.getNullCell(this._terminal.eraseAttrData())
this._bufferService.buffer.getNullCell(this._eraseAttrData())
);
if (clearWrap) {
line.isWrapped = false;
@@ -858,7 +868,7 @@ export class InputHandler extends Disposable implements IInputHandler {
*/
private _resetBufferLine(y: number): void {
const line = this._bufferService.buffer.lines.get(this._bufferService.buffer.ybase + y);
line.fill(this._bufferService.buffer.getNullCell(this._terminal.eraseAttrData()));
line.fill(this._bufferService.buffer.getNullCell(this._eraseAttrData()));
line.isWrapped = false;
}
@@ -973,7 +983,7 @@ export class InputHandler extends Disposable implements IInputHandler {
// test: echo -e '\e[44m\e[1L\e[0m'
// blankLine(true) - xterm/linux behavior
buffer.lines.splice(scrollBottomAbsolute - 1, 1);
buffer.lines.splice(row, 0, buffer.getBlankLine(this._terminal.eraseAttrData()));
buffer.lines.splice(row, 0, buffer.getBlankLine(this._eraseAttrData()));
}
this._dirtyRowService.markRangeDirty(buffer.y, buffer.scrollBottom);
@@ -1004,7 +1014,7 @@ export class InputHandler extends Disposable implements IInputHandler {
// test: echo -e '\e[44m\e[1M\e[0m'
// blankLine(true) - xterm/linux behavior
buffer.lines.splice(row, 1);
buffer.lines.splice(j, 0, buffer.getBlankLine(this._terminal.eraseAttrData()));
buffer.lines.splice(j, 0, buffer.getBlankLine(this._eraseAttrData()));
}
this._dirtyRowService.markRangeDirty(buffer.y, buffer.scrollBottom);
@@ -1022,7 +1032,7 @@ export class InputHandler extends Disposable implements IInputHandler {
line.insertCells(
this._bufferService.buffer.x,
params.params[0] || 1,
this._bufferService.buffer.getNullCell(this._terminal.eraseAttrData())
this._bufferService.buffer.getNullCell(this._eraseAttrData())
);
this._dirtyRowService.markDirty(this._bufferService.buffer.y);
}
@@ -1039,7 +1049,7 @@ export class InputHandler extends Disposable implements IInputHandler {
line.deleteCells(
this._bufferService.buffer.x,
params.params[0] || 1,
this._bufferService.buffer.getNullCell(this._terminal.eraseAttrData())
this._bufferService.buffer.getNullCell(this._eraseAttrData())
);
this._dirtyRowService.markDirty(this._bufferService.buffer.y);
}
@@ -1056,7 +1066,7 @@ export class InputHandler extends Disposable implements IInputHandler {
while (param--) {
buffer.lines.splice(buffer.ybase + buffer.scrollTop, 1);
buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 0, buffer.getBlankLine(this._terminal.eraseAttrData()));
buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 0, buffer.getBlankLine(this._eraseAttrData()));
}
this._dirtyRowService.markRangeDirty(buffer.scrollTop, buffer.scrollBottom);
}
@@ -1099,7 +1109,7 @@ export class InputHandler extends Disposable implements IInputHandler {
const param = params.params[0] || 1;
for (let y = buffer.scrollTop; y <= buffer.scrollBottom; ++y) {
const line = buffer.lines.get(buffer.ybase + y);
line.deleteCells(0, param, buffer.getNullCell(this._terminal.eraseAttrData()));
line.deleteCells(0, param, buffer.getNullCell(this._eraseAttrData()));
line.isWrapped = false;
}
this._dirtyRowService.markRangeDirty(buffer.scrollTop, buffer.scrollBottom);
@@ -1127,7 +1137,7 @@ export class InputHandler extends Disposable implements IInputHandler {
const param = params.params[0] || 1;
for (let y = buffer.scrollTop; y <= buffer.scrollBottom; ++y) {
const line = buffer.lines.get(buffer.ybase + y);
line.insertCells(0, param, buffer.getNullCell(this._terminal.eraseAttrData()));
line.insertCells(0, param, buffer.getNullCell(this._eraseAttrData()));
line.isWrapped = false;
}
this._dirtyRowService.markRangeDirty(buffer.scrollTop, buffer.scrollBottom);
@@ -1145,7 +1155,7 @@ export class InputHandler extends Disposable implements IInputHandler {
const param = params.params[0] || 1;
for (let y = buffer.scrollTop; y <= buffer.scrollBottom; ++y) {
const line = this._bufferService.buffer.lines.get(buffer.ybase + y);
line.insertCells(buffer.x, param, buffer.getNullCell(this._terminal.eraseAttrData()));
line.insertCells(buffer.x, param, buffer.getNullCell(this._eraseAttrData()));
line.isWrapped = false;
}
this._dirtyRowService.markRangeDirty(buffer.scrollTop, buffer.scrollBottom);
@@ -1163,7 +1173,7 @@ export class InputHandler extends Disposable implements IInputHandler {
const param = params.params[0] || 1;
for (let y = buffer.scrollTop; y <= buffer.scrollBottom; ++y) {
const line = buffer.lines.get(buffer.ybase + y);
line.deleteCells(buffer.x, param, buffer.getNullCell(this._terminal.eraseAttrData()));
line.deleteCells(buffer.x, param, buffer.getNullCell(this._eraseAttrData()));
line.isWrapped = false;
}
this._dirtyRowService.markRangeDirty(buffer.scrollTop, buffer.scrollBottom);
@@ -1180,7 +1190,7 @@ export class InputHandler extends Disposable implements IInputHandler {
line.replaceCells(
this._bufferService.buffer.x,
this._bufferService.buffer.x + (params.params[0] || 1),
this._bufferService.buffer.getNullCell(this._terminal.eraseAttrData())
this._bufferService.buffer.getNullCell(this._eraseAttrData())
);
this._dirtyRowService.markDirty(this._bufferService.buffer.y);
}
@@ -1393,34 +1403,32 @@ export class InputHandler extends Disposable implements IInputHandler {
this._coreService.decPrivateModes.applicationCursorKeys = true;
break;
case 2:
this._terminal.setgCharset(0, DEFAULT_CHARSET);
this._terminal.setgCharset(1, DEFAULT_CHARSET);
this._terminal.setgCharset(2, DEFAULT_CHARSET);
this._terminal.setgCharset(3, DEFAULT_CHARSET);
this._charsetService.setgCharset(0, DEFAULT_CHARSET);
this._charsetService.setgCharset(1, DEFAULT_CHARSET);
this._charsetService.setgCharset(2, DEFAULT_CHARSET);
this._charsetService.setgCharset(3, DEFAULT_CHARSET);
// set VT100 mode here
break;
case 3: // 132 col mode
// TODO: move DECCOLM into compat addon
this._terminal.savedCols = this._bufferService.cols;
this._terminal.resize(132, this._bufferService.rows);
this._terminal.reset();
this._onRequestReset.fire();
break;
case 6:
this._terminal.originMode = true;
this._coreService.decPrivateModes.origin = true;
this._setCursor(0, 0);
break;
case 7:
this._terminal.wraparoundMode = true;
this._coreService.decPrivateModes.wraparound = true;
break;
case 12:
// this.cursorBlink = true;
break;
case 66:
this._logService.debug('Serial port requested application keypad.');
this._terminal.applicationKeypad = true;
if (this._terminal.viewport) {
this._terminal.viewport.syncScrollArea();
}
this._coreService.decPrivateModes.applicationKeypad = true;
this._terminal.viewport?.syncScrollArea();
break;
case 9: // X10 Mouse
// no release, no motion, no wheel, no modifiers.
@@ -1463,11 +1471,9 @@ export class InputHandler extends Disposable implements IInputHandler {
// FALL-THROUGH
case 47: // alt screen buffer
case 1047: // alt screen buffer
this._bufferService.buffers.activateAltBuffer(this._terminal.eraseAttrData());
this._terminal.refresh(0, this._bufferService.rows - 1);
if (this._terminal.viewport) {
this._terminal.viewport.syncScrollArea();
}
this._bufferService.buffers.activateAltBuffer(this._eraseAttrData());
this._onRequestRefreshRows.fire(0, this._bufferService.rows - 1);
this._terminal.viewport?.syncScrollArea();
this._terminal.showCursor();
break;
case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)
@@ -1586,24 +1592,22 @@ export class InputHandler extends Disposable implements IInputHandler {
this._terminal.resize(this._terminal.savedCols, this._bufferService.rows);
}
delete this._terminal.savedCols;
this._terminal.reset();
this._onRequestReset.fire();
break;
case 6:
this._terminal.originMode = false;
this._coreService.decPrivateModes.origin = false;
this._setCursor(0, 0);
break;
case 7:
this._terminal.wraparoundMode = false;
this._coreService.decPrivateModes.wraparound = false;
break;
case 12:
// this.cursorBlink = false;
break;
case 66:
this._logService.debug('Switching back to normal keypad.');
this._terminal.applicationKeypad = false;
if (this._terminal.viewport) {
this._terminal.viewport.syncScrollArea();
}
this._coreService.decPrivateModes.applicationKeypad = false;
this._terminal.viewport?.syncScrollArea();
break;
case 9: // X10 Mouse
case 1000: // vt200 mouse
@@ -1638,10 +1642,8 @@ export class InputHandler extends Disposable implements IInputHandler {
if (params.params[i] === 1049) {
this.restoreCursor();
}
this._terminal.refresh(0, this._bufferService.rows - 1);
if (this._terminal.viewport) {
this._terminal.viewport.syncScrollArea();
}
this._onRequestRefreshRows.fire(0, this._bufferService.rows - 1);
this._terminal.viewport?.syncScrollArea();
this._terminal.showCursor();
break;
case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)
@@ -1791,14 +1793,14 @@ export class InputHandler extends Disposable implements IInputHandler {
public charAttributes(params: IParams): void {
// Optimize a single SGR0.
if (params.length === 1 && params.params[0] === 0) {
this._terminal.curAttrData.fg = DEFAULT_ATTR_DATA.fg;
this._terminal.curAttrData.bg = DEFAULT_ATTR_DATA.bg;
this._curAttrData.fg = DEFAULT_ATTR_DATA.fg;
this._curAttrData.bg = DEFAULT_ATTR_DATA.bg;
return;
}
const l = params.length;
let p;
const attr = this._terminal.curAttrData;
const attr = this._curAttrData;
for (let i = 0; i < l; i++) {
p = params.params[i];
@@ -1960,20 +1962,13 @@ export class InputHandler extends Disposable implements IInputHandler {
public softReset(params: IParams): void {
this._coreService.isCursorHidden = false;
this._terminal.insertMode = false;
this._terminal.originMode = false;
this._terminal.wraparoundMode = true; // defaults: xterm - true, vt100 - false
this._terminal.applicationKeypad = false; // ?
if (this._terminal.viewport) {
this._terminal.viewport.syncScrollArea();
}
this._coreService.decPrivateModes.applicationCursorKeys = false;
this._terminal.viewport?.syncScrollArea();
this._bufferService.buffer.scrollTop = 0;
this._bufferService.buffer.scrollBottom = this._bufferService.rows - 1;
this._terminal.curAttrData = DEFAULT_ATTR_DATA.clone();
this._curAttrData = DEFAULT_ATTR_DATA.clone();
this._bufferService.buffer.x = this._bufferService.buffer.y = 0; // ?
this._terminal.charset = null;
this._terminal.glevel = 0; // ??
this._terminal.charsets = [null]; // ??
this._coreService.reset();
this._charsetService.reset();
}
/**
@@ -2035,9 +2030,9 @@ export class InputHandler extends Disposable implements IInputHandler {
public saveCursor(params?: IParams): void {
this._bufferService.buffer.savedX = this._bufferService.buffer.x;
this._bufferService.buffer.savedY = this._bufferService.buffer.ybase + this._bufferService.buffer.y;
this._bufferService.buffer.savedCurAttrData.fg = this._terminal.curAttrData.fg;
this._bufferService.buffer.savedCurAttrData.bg = this._terminal.curAttrData.bg;
this._bufferService.buffer.savedCharset = this._terminal.charset;
this._bufferService.buffer.savedCurAttrData.fg = this._curAttrData.fg;
this._bufferService.buffer.savedCurAttrData.bg = this._curAttrData.bg;
this._bufferService.buffer.savedCharset = this._charsetService.charset;
}
@@ -2049,11 +2044,11 @@ export class InputHandler extends Disposable implements IInputHandler {
public restoreCursor(params?: IParams): void {
this._bufferService.buffer.x = this._bufferService.buffer.savedX || 0;
this._bufferService.buffer.y = Math.max(this._bufferService.buffer.savedY - this._bufferService.buffer.ybase, 0);
this._terminal.curAttrData.fg = this._bufferService.buffer.savedCurAttrData.fg;
this._terminal.curAttrData.bg = this._bufferService.buffer.savedCurAttrData.bg;
this._terminal.charset = (this as any)._savedCharset;
this._curAttrData.fg = this._bufferService.buffer.savedCurAttrData.fg;
this._curAttrData.bg = this._bufferService.buffer.savedCurAttrData.bg;
this._charsetService.charset = (this as any)._savedCharset;
if (this._bufferService.buffer.savedCharset) {
this._terminal.charset = this._bufferService.buffer.savedCharset;
this._charsetService.charset = this._bufferService.buffer.savedCharset;
}
this._restrictCursor();
}
@@ -2086,10 +2081,8 @@ export class InputHandler extends Disposable implements IInputHandler {
*/
public keypadApplicationMode(): void {
this._logService.debug('Serial port requested application keypad.');
this._terminal.applicationKeypad = true;
if (this._terminal.viewport) {
this._terminal.viewport.syncScrollArea();
}
this._coreService.decPrivateModes.applicationKeypad = true;
this._terminal.viewport?.syncScrollArea();
}
/**
@@ -2099,10 +2092,8 @@ export class InputHandler extends Disposable implements IInputHandler {
*/
public keypadNumericMode(): void {
this._logService.debug('Switching back to normal keypad.');
this._terminal.applicationKeypad = false;
if (this._terminal.viewport) {
this._terminal.viewport.syncScrollArea();
}
this._coreService.decPrivateModes.applicationKeypad = false;
this._terminal.viewport?.syncScrollArea();
}
/**
@@ -2112,8 +2103,8 @@ export class InputHandler extends Disposable implements IInputHandler {
* therefore ESC % G does the same.
*/
public selectDefaultCharset(): void {
this._terminal.setgLevel(0);
this._terminal.setgCharset(0, DEFAULT_CHARSET); // US (default)
this._charsetService.setgLevel(0);
this._charsetService.setgCharset(0, DEFAULT_CHARSET); // US (default)
}
/**
@@ -2140,7 +2131,7 @@ export class InputHandler extends Disposable implements IInputHandler {
if (collectAndFlag[0] === '/') {
return; // TODO: Is this supported?
}
this._terminal.setgCharset(GLEVEL[collectAndFlag[0]], CHARSETS[collectAndFlag[1]] || DEFAULT_CHARSET);
this._charsetService.setgCharset(GLEVEL[collectAndFlag[0]], CHARSETS[collectAndFlag[1]] || DEFAULT_CHARSET);
return;
}
@@ -2156,7 +2147,7 @@ export class InputHandler extends Disposable implements IInputHandler {
this._bufferService.buffer.y++;
if (buffer.y === buffer.scrollBottom + 1) {
buffer.y--;
this._terminal.scroll();
this._terminal.scroll(this._eraseAttrData());
} else if (buffer.y >= this._bufferService.rows) {
buffer.y = this._bufferService.rows - 1;
}
@@ -2190,7 +2181,7 @@ export class InputHandler extends Disposable implements IInputHandler {
// blankLine(true) is xterm/linux behavior
const scrollRegionHeight = buffer.scrollBottom - buffer.scrollTop;
buffer.lines.shiftElements(buffer.y + buffer.ybase, scrollRegionHeight, 1);
buffer.lines.set(buffer.y + buffer.ybase, buffer.getBlankLine(this._terminal.eraseAttrData()));
buffer.lines.set(buffer.y + buffer.ybase, buffer.getBlankLine(this._eraseAttrData()));
this._dirtyRowService.markRangeDirty(buffer.scrollTop, buffer.scrollBottom);
} else {
buffer.y--;
@@ -2203,9 +2194,23 @@ export class InputHandler extends Disposable implements IInputHandler {
* DEC mnemonic: RIS (https://vt100.net/docs/vt510-rm/RIS.html)
* Reset to initial state.
*/
public reset(): void {
public fullReset(): void {
this._parser.reset();
this._terminal.reset(); // TODO: save to move from terminal?
this._onRequestReset.fire();
}
public reset(): void {
this._curAttrData = DEFAULT_ATTR_DATA.clone();
this._eraseAttrDataInternal = DEFAULT_ATTR_DATA.clone();
}
/**
* back_color_erase feature for xterm.
*/
private _eraseAttrData(): IAttributeData {
this._eraseAttrDataInternal.bg &= ~(Attributes.CM_MASK | 0xFFFFFF);
this._eraseAttrDataInternal.bg |= this._curAttrData.bg & ~0xFC000000;
return this._eraseAttrDataInternal;
}
/**
@@ -2219,7 +2224,7 @@ export class InputHandler extends Disposable implements IInputHandler {
* you use another locking shift. (partly supported)
*/
public setgLevel(level: number): void {
this._terminal.setgLevel(level); // TODO: save to move from terminal?
this._charsetService.setgLevel(level);
}
/**
@@ -2234,8 +2239,8 @@ export class InputHandler extends Disposable implements IInputHandler {
// prepare cell data
const cell = new CellData();
cell.content = 1 << Content.WIDTH_SHIFT | 'E'.charCodeAt(0);
cell.fg = this._terminal.curAttrData.fg;
cell.bg = this._terminal.curAttrData.bg;
cell.fg = this._curAttrData.fg;
cell.bg = this._curAttrData.bg;
const buffer = this._bufferService.buffer;