Move range updating to DirtyRowService
This commit is contained in:
+10
-10
@@ -13,7 +13,7 @@ import { CellData } from 'common/buffer/CellData';
|
||||
import { Attributes } from 'common/buffer/Constants';
|
||||
import { AttributeData } from 'common/buffer/AttributeData';
|
||||
import { Params } from 'common/parser/Params';
|
||||
import { MockCoreService, MockBufferService, MockOptionsService, MockLogService } from 'common/TestUtils.test';
|
||||
import { MockCoreService, MockBufferService, MockDirtyRowService, MockOptionsService, MockLogService } from 'common/TestUtils.test';
|
||||
import { IBufferService } from 'common/services/Services';
|
||||
|
||||
function getCursor(term: TestTerminal): number[] {
|
||||
@@ -31,7 +31,7 @@ describe('InputHandler', () => {
|
||||
bufferService.buffer.x = 1;
|
||||
bufferService.buffer.y = 2;
|
||||
bufferService.buffer.ybase = 0;
|
||||
const inputHandler = new InputHandler(terminal, bufferService, new MockCoreService(), new MockLogService(), new MockOptionsService());
|
||||
const inputHandler = new InputHandler(terminal, bufferService, new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService());
|
||||
// Save cursor position
|
||||
inputHandler.saveCursor();
|
||||
assert.equal(bufferService.buffer.x, 1);
|
||||
@@ -50,7 +50,7 @@ describe('InputHandler', () => {
|
||||
describe('setCursorStyle', () => {
|
||||
it('should call Terminal.setOption with correct params', () => {
|
||||
const terminal = new MockInputHandlingTerminal();
|
||||
const inputHandler = new InputHandler(terminal, new MockBufferService(80, 30), new MockCoreService(), new MockLogService(), new MockOptionsService());
|
||||
const inputHandler = new InputHandler(terminal, new MockBufferService(80, 30), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService());
|
||||
const collect = ' ';
|
||||
|
||||
inputHandler.setCursorStyle(Params.fromArray([0]), collect);
|
||||
@@ -93,7 +93,7 @@ describe('InputHandler', () => {
|
||||
const terminal = new MockInputHandlingTerminal();
|
||||
const collect = '?';
|
||||
terminal.bracketedPasteMode = false;
|
||||
const inputHandler = new InputHandler(terminal, new MockBufferService(80, 30), new MockCoreService(), new MockLogService(), new MockOptionsService());
|
||||
const inputHandler = new InputHandler(terminal, new MockBufferService(80, 30), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService());
|
||||
// Set bracketed paste mode
|
||||
inputHandler.setMode(Params.fromArray([2004]), collect);
|
||||
assert.equal(terminal.bracketedPasteMode, true);
|
||||
@@ -112,7 +112,7 @@ describe('InputHandler', () => {
|
||||
it('insertChars', function(): void {
|
||||
const term = new Terminal();
|
||||
const bufferService = new MockBufferService(80, 30);
|
||||
const inputHandler = new InputHandler(term, bufferService, new MockCoreService(), new MockLogService(), new MockOptionsService());
|
||||
const inputHandler = new InputHandler(term, bufferService, new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService());
|
||||
|
||||
// insert some data in first and second line
|
||||
inputHandler.parse(Array(bufferService.cols - 9).join('a'));
|
||||
@@ -150,7 +150,7 @@ describe('InputHandler', () => {
|
||||
it('deleteChars', function(): void {
|
||||
const term = new Terminal();
|
||||
const bufferService = new MockBufferService(80, 30);
|
||||
const inputHandler = new InputHandler(term, bufferService, new MockCoreService(), new MockLogService(), new MockOptionsService());
|
||||
const inputHandler = new InputHandler(term, bufferService, new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService());
|
||||
|
||||
// insert some data in first and second line
|
||||
inputHandler.parse(Array(bufferService.cols - 9).join('a'));
|
||||
@@ -191,7 +191,7 @@ describe('InputHandler', () => {
|
||||
it('eraseInLine', function(): void {
|
||||
const term = new Terminal();
|
||||
const bufferService = new MockBufferService(80, 30);
|
||||
const inputHandler = new InputHandler(term, bufferService, new MockCoreService(), new MockLogService(), new MockOptionsService());
|
||||
const inputHandler = new InputHandler(term, bufferService, new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService());
|
||||
|
||||
// fill 6 lines to test 3 different states
|
||||
inputHandler.parse(Array(bufferService.cols + 1).join('a'));
|
||||
@@ -220,7 +220,7 @@ describe('InputHandler', () => {
|
||||
it('eraseInDisplay', function(): void {
|
||||
const term = new Terminal({cols: 80, rows: 7});
|
||||
const bufferService = new MockBufferService(80, 7);
|
||||
const inputHandler = new InputHandler(term, bufferService, new MockCoreService(), new MockLogService(), new MockOptionsService());
|
||||
const inputHandler = new InputHandler(term, bufferService, new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService());
|
||||
|
||||
// fill display with a's
|
||||
for (let i = 0; i < bufferService.rows; ++i) inputHandler.parse(Array(bufferService.cols + 1).join('a'));
|
||||
@@ -355,7 +355,7 @@ describe('InputHandler', () => {
|
||||
describe('print', () => {
|
||||
it('should not cause an infinite loop (regression test)', () => {
|
||||
const term = new Terminal();
|
||||
const inputHandler = new InputHandler(term, new MockBufferService(80, 30), new MockCoreService(), new MockLogService(), new MockOptionsService());
|
||||
const inputHandler = new InputHandler(term, new MockBufferService(80, 30), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService());
|
||||
const container = new Uint32Array(10);
|
||||
container[0] = 0x200B;
|
||||
inputHandler.print(container, 0, 1);
|
||||
@@ -370,7 +370,7 @@ describe('InputHandler', () => {
|
||||
beforeEach(() => {
|
||||
term = new Terminal();
|
||||
bufferService = new MockBufferService(80, 30);
|
||||
handler = new InputHandler(term, bufferService, new MockCoreService(), new MockLogService(), new MockOptionsService());
|
||||
handler = new InputHandler(term, bufferService, new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService());
|
||||
});
|
||||
it('should handle DECSET/DECRST 47 (alt screen buffer)', () => {
|
||||
handler.parse('\x1b[?47h\r\n\x1b[31mJUNK\x1b[?47lTEST');
|
||||
|
||||
+33
-53
@@ -19,7 +19,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 } from 'common/services/Services';
|
||||
import { ICoreService, IBufferService, IOptionsService, ILogService, IDirtyRowService } from 'common/services/Services';
|
||||
import { ISelectionService } from 'browser/services/Services';
|
||||
|
||||
/**
|
||||
@@ -128,12 +128,13 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
public get onScroll(): IEvent<number> { return this._onScroll.event; }
|
||||
|
||||
constructor(
|
||||
protected _terminal: IInputHandlingTerminal,
|
||||
private _bufferService: IBufferService,
|
||||
private _coreService: ICoreService,
|
||||
private _logService: ILogService,
|
||||
private _optionsService: IOptionsService,
|
||||
private _parser: IEscapeSequenceParser = new EscapeSequenceParser())
|
||||
protected _terminal: IInputHandlingTerminal,
|
||||
private readonly _bufferService: IBufferService,
|
||||
private readonly _coreService: ICoreService,
|
||||
private readonly _dirtyRowService: IDirtyRowService,
|
||||
private readonly _logService: ILogService,
|
||||
private readonly _optionsService: IOptionsService,
|
||||
private readonly _parser: IEscapeSequenceParser = new EscapeSequenceParser())
|
||||
{
|
||||
super();
|
||||
|
||||
@@ -306,7 +307,6 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
|
||||
public dispose(): void {
|
||||
super.dispose();
|
||||
this._terminal = null;
|
||||
}
|
||||
|
||||
// TODO: When InputHandler moves into common, browser dependencies need to move out
|
||||
@@ -315,11 +315,6 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
}
|
||||
|
||||
public parse(data: string): void {
|
||||
// Ensure the terminal is not disposed
|
||||
if (!this._terminal) {
|
||||
return;
|
||||
}
|
||||
|
||||
let buffer = this._bufferService.buffer;
|
||||
const cursorStartX = buffer.x;
|
||||
const cursorStartY = buffer.y;
|
||||
@@ -338,11 +333,6 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
}
|
||||
|
||||
public parseUtf8(data: Uint8Array): void {
|
||||
// Ensure the terminal is not disposed
|
||||
if (!this._terminal) {
|
||||
return;
|
||||
}
|
||||
|
||||
let buffer = this._bufferService.buffer;
|
||||
const cursorStartX = buffer.x;
|
||||
const cursorStartY = buffer.y;
|
||||
@@ -365,14 +355,14 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
let chWidth: number;
|
||||
const buffer = this._bufferService.buffer;
|
||||
const charset = this._terminal.charset;
|
||||
const screenReaderMode = this._terminal.options.screenReaderMode;
|
||||
const screenReaderMode = this._optionsService.options.screenReaderMode;
|
||||
const cols = this._bufferService.cols;
|
||||
const wraparoundMode = this._terminal.wraparoundMode;
|
||||
const insertMode = this._terminal.insertMode;
|
||||
const curAttr = this._terminal.curAttrData;
|
||||
let bufferRow = buffer.lines.get(buffer.y + buffer.ybase);
|
||||
|
||||
this._terminal.updateRange(buffer.y);
|
||||
this._dirtyRowService.markDirty(buffer.y);
|
||||
for (let pos = start; pos < end; ++pos) {
|
||||
code = data[pos];
|
||||
|
||||
@@ -481,7 +471,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
this._parser.precedingCodepoint = this._workCell.content;
|
||||
}
|
||||
}
|
||||
this._terminal.updateRange(buffer.y);
|
||||
this._dirtyRowService.markDirty(buffer.y);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -514,7 +504,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
// make buffer local for faster access
|
||||
const buffer = this._bufferService.buffer;
|
||||
|
||||
if (this._terminal.options.convertEol) {
|
||||
if (this._optionsService.options.convertEol) {
|
||||
buffer.x = 0;
|
||||
}
|
||||
buffer.y++;
|
||||
@@ -559,7 +549,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
}
|
||||
const originalX = this._bufferService.buffer.x;
|
||||
this._bufferService.buffer.x = this._bufferService.buffer.nextStop();
|
||||
if (this._terminal.options.screenReaderMode) {
|
||||
if (this._optionsService.options.screenReaderMode) {
|
||||
this._terminal.onA11yTabEmitter.fire(this._bufferService.buffer.x - originalX);
|
||||
}
|
||||
}
|
||||
@@ -830,16 +820,16 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
switch (params.params[0]) {
|
||||
case 0:
|
||||
j = this._bufferService.buffer.y;
|
||||
this._terminal.updateRange(j);
|
||||
this._dirtyRowService.markDirty(j);
|
||||
this._eraseInBufferLine(j++, this._bufferService.buffer.x, this._bufferService.cols, this._bufferService.buffer.x === 0);
|
||||
for (; j < this._bufferService.rows; j++) {
|
||||
this._resetBufferLine(j);
|
||||
}
|
||||
this._terminal.updateRange(j);
|
||||
this._dirtyRowService.markDirty(j);
|
||||
break;
|
||||
case 1:
|
||||
j = this._bufferService.buffer.y;
|
||||
this._terminal.updateRange(j);
|
||||
this._dirtyRowService.markDirty(j);
|
||||
// Deleted front part of line and everything before. This line will no longer be wrapped.
|
||||
this._eraseInBufferLine(j, 0, this._bufferService.buffer.x + 1, true);
|
||||
if (this._bufferService.buffer.x + 1 >= this._bufferService.cols) {
|
||||
@@ -849,15 +839,15 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
while (j--) {
|
||||
this._resetBufferLine(j);
|
||||
}
|
||||
this._terminal.updateRange(0);
|
||||
this._dirtyRowService.markDirty(0);
|
||||
break;
|
||||
case 2:
|
||||
j = this._bufferService.rows;
|
||||
this._terminal.updateRange(j - 1);
|
||||
this._dirtyRowService.markDirty(j - 1);
|
||||
while (j--) {
|
||||
this._resetBufferLine(j);
|
||||
}
|
||||
this._terminal.updateRange(0);
|
||||
this._dirtyRowService.markDirty(0);
|
||||
break;
|
||||
case 3:
|
||||
// Clear scrollback (everything not in viewport)
|
||||
@@ -897,7 +887,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
this._eraseInBufferLine(this._bufferService.buffer.y, 0, this._bufferService.cols);
|
||||
break;
|
||||
}
|
||||
this._terminal.updateRange(this._bufferService.buffer.y);
|
||||
this._dirtyRowService.markDirty(this._bufferService.buffer.y);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -926,9 +916,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
buffer.lines.splice(row, 0, buffer.getBlankLine(this._terminal.eraseAttrData()));
|
||||
}
|
||||
|
||||
// this.maxRange();
|
||||
this._terminal.updateRange(buffer.y);
|
||||
this._terminal.updateRange(buffer.scrollBottom);
|
||||
this._dirtyRowService.markRangeDirty(buffer.y, buffer.scrollBottom);
|
||||
buffer.x = 0; // see https://vt100.net/docs/vt220-rm/chapter4.html - vt220 only?
|
||||
}
|
||||
|
||||
@@ -959,9 +947,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
buffer.lines.splice(j, 0, buffer.getBlankLine(this._terminal.eraseAttrData()));
|
||||
}
|
||||
|
||||
// this.maxRange();
|
||||
this._terminal.updateRange(buffer.y);
|
||||
this._terminal.updateRange(buffer.scrollBottom);
|
||||
this._dirtyRowService.markRangeDirty(buffer.y, buffer.scrollBottom);
|
||||
buffer.x = 0; // see https://vt100.net/docs/vt220-rm/chapter4.html - vt220 only?
|
||||
}
|
||||
|
||||
@@ -978,7 +964,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
params.params[0] || 1,
|
||||
this._bufferService.buffer.getNullCell(this._terminal.eraseAttrData())
|
||||
);
|
||||
this._terminal.updateRange(this._bufferService.buffer.y);
|
||||
this._dirtyRowService.markDirty(this._bufferService.buffer.y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -995,7 +981,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
params.params[0] || 1,
|
||||
this._bufferService.buffer.getNullCell(this._terminal.eraseAttrData())
|
||||
);
|
||||
this._terminal.updateRange(this._bufferService.buffer.y);
|
||||
this._dirtyRowService.markDirty(this._bufferService.buffer.y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1012,9 +998,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
buffer.lines.splice(buffer.ybase + buffer.scrollTop, 1);
|
||||
buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 0, buffer.getBlankLine(DEFAULT_ATTR_DATA));
|
||||
}
|
||||
// this.maxRange();
|
||||
this._terminal.updateRange(buffer.scrollTop);
|
||||
this._terminal.updateRange(buffer.scrollBottom);
|
||||
this._dirtyRowService.markRangeDirty(buffer.scrollTop, buffer.scrollBottom);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1031,9 +1015,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 1);
|
||||
buffer.lines.splice(buffer.ybase + buffer.scrollTop, 0, buffer.getBlankLine(DEFAULT_ATTR_DATA));
|
||||
}
|
||||
// this.maxRange();
|
||||
this._terminal.updateRange(buffer.scrollTop);
|
||||
this._terminal.updateRange(buffer.scrollBottom);
|
||||
this._dirtyRowService.markRangeDirty(buffer.scrollTop, buffer.scrollBottom);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1050,7 +1032,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
this._bufferService.buffer.x + (params.params[0] || 1),
|
||||
this._bufferService.buffer.getNullCell(this._terminal.eraseAttrData())
|
||||
);
|
||||
this._terminal.updateRange(this._bufferService.buffer.y);
|
||||
this._dirtyRowService.markDirty(this._bufferService.buffer.y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1893,19 +1875,19 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
switch (param) {
|
||||
case 1:
|
||||
case 2:
|
||||
this._terminal.options.cursorStyle = 'block';
|
||||
this._optionsService.options.cursorStyle = 'block';
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
this._terminal.options.cursorStyle = 'underline';
|
||||
this._optionsService.options.cursorStyle = 'underline';
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
this._terminal.options.cursorStyle = 'bar';
|
||||
this._optionsService.options.cursorStyle = 'bar';
|
||||
break;
|
||||
}
|
||||
const isBlinking = param % 2 === 1;
|
||||
this._terminal.options.cursorBlink = isBlinking;
|
||||
this._optionsService.options.cursorBlink = isBlinking;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2097,8 +2079,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
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()));
|
||||
this._terminal.updateRange(buffer.scrollTop);
|
||||
this._terminal.updateRange(buffer.scrollBottom);
|
||||
this._dirtyRowService.markRangeDirty(buffer.scrollTop, buffer.scrollBottom);
|
||||
} else {
|
||||
buffer.y--;
|
||||
this._restrictCursor(); // quickfix to not run out of bounds
|
||||
@@ -2152,8 +2133,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
buffer.lines.get(row).fill(cell);
|
||||
buffer.lines.get(row).isWrapped = false;
|
||||
}
|
||||
this._terminal.updateRange(0);
|
||||
this._terminal.updateRange(this._bufferService.rows);
|
||||
this._dirtyRowService.markAllDirty();
|
||||
this._setCursor(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
+8
-51
@@ -47,7 +47,7 @@ import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine';
|
||||
import { applyWindowsMode } from './WindowsMode';
|
||||
import { ColorManager } from 'browser/ColorManager';
|
||||
import { RenderService } from 'browser/services/RenderService';
|
||||
import { IOptionsService, IBufferService, ICoreService, ILogService } from 'common/services/Services';
|
||||
import { IOptionsService, IBufferService, ICoreService, ILogService, IDirtyRowService } from 'common/services/Services';
|
||||
import { OptionsService } from 'common/services/OptionsService';
|
||||
import { ICharSizeService, IRenderService, IMouseService, ISelectionService, ISoundService } from 'browser/services/Services';
|
||||
import { CharSizeService } from 'browser/services/CharSizeService';
|
||||
@@ -60,6 +60,7 @@ import { IParams } from 'common/parser/Types';
|
||||
import { CoreService } from 'common/services/CoreService';
|
||||
import { LogService } from 'common/services/LogService';
|
||||
import { ILinkifier, IMouseZoneManager, LinkMatcherHandler, ILinkMatcherOptions, IViewport } from 'browser/Types';
|
||||
import { DirtyRowService } from 'common/services/DirtyRowService';
|
||||
|
||||
// Let it work inside Node.js for automated testing purposes.
|
||||
const document = (typeof window !== 'undefined') ? window.document : null;
|
||||
@@ -111,6 +112,7 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
|
||||
// common services
|
||||
private _bufferService: IBufferService;
|
||||
private _coreService: ICoreService;
|
||||
private _dirtyRowService: IDirtyRowService;
|
||||
private _logService: ILogService;
|
||||
public optionsService: IOptionsService;
|
||||
|
||||
@@ -148,8 +150,6 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
|
||||
public urxvtMouse: boolean;
|
||||
|
||||
// misc
|
||||
private _refreshStart: number;
|
||||
private _refreshEnd: number;
|
||||
public savedCols: number;
|
||||
|
||||
public curAttrData: IAttributeData;
|
||||
@@ -243,6 +243,7 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
|
||||
this._bufferService = new BufferService(this.optionsService);
|
||||
this._coreService = new CoreService(() => this.scrollToBottom(), this._bufferService, this.optionsService);
|
||||
this._coreService.onData(e => this._onData.fire(e));
|
||||
this._dirtyRowService = new DirtyRowService(this._bufferService);
|
||||
this._logService = new LogService(this.optionsService);
|
||||
|
||||
this._setupOptionsListeners();
|
||||
@@ -300,7 +301,7 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
|
||||
this._userScrolling = false;
|
||||
|
||||
// Register input handler and refire/handle events
|
||||
this._inputHandler = new InputHandler(this, this._bufferService, this._coreService, this._logService, this.optionsService);
|
||||
this._inputHandler = new InputHandler(this, this._bufferService, this._coreService, this._dirtyRowService, this._logService, this.optionsService);
|
||||
this._inputHandler.onCursorMove(() => this._onCursorMove.fire());
|
||||
this._inputHandler.onLineFeed(() => this._onLineFeed.fire());
|
||||
this.register(this._inputHandler);
|
||||
@@ -1136,8 +1137,7 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
|
||||
}
|
||||
|
||||
// Flag rows that need updating
|
||||
this.updateRange(this.buffer.scrollTop);
|
||||
this.updateRange(this.buffer.scrollBottom);
|
||||
this._dirtyRowService.markRangeDirty(this.buffer.scrollTop, this.buffer.scrollBottom);
|
||||
|
||||
this._onScroll.fire(this.buffer.ydisp);
|
||||
}
|
||||
@@ -1258,19 +1258,9 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
|
||||
this._xoffSentToCatchUp = false;
|
||||
}
|
||||
|
||||
this._refreshStart = this.buffer.y;
|
||||
this._refreshEnd = this.buffer.y;
|
||||
|
||||
// HACK: Set the parser state based on it's state at the time of return.
|
||||
// This works around the bug #662 which saw the parser state reset in the
|
||||
// middle of parsing escape sequence in two chunks. For some reason the
|
||||
// state of the parser resets to 0 after exiting parser.parse. This change
|
||||
// just sets the state back based on the correct return statement.
|
||||
|
||||
this._inputHandler.parseUtf8(data);
|
||||
|
||||
this.updateRange(this.buffer.y);
|
||||
this.refresh(this._refreshStart, this._refreshEnd);
|
||||
this.refresh(this._dirtyRowService.start, this._dirtyRowService.end);
|
||||
|
||||
if (Date.now() - startTime >= WRITE_TIMEOUT_MS) {
|
||||
break;
|
||||
@@ -1345,19 +1335,9 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
|
||||
this._xoffSentToCatchUp = false;
|
||||
}
|
||||
|
||||
this._refreshStart = this.buffer.y;
|
||||
this._refreshEnd = this.buffer.y;
|
||||
|
||||
// HACK: Set the parser state based on it's state at the time of return.
|
||||
// This works around the bug #662 which saw the parser state reset in the
|
||||
// middle of parsing escape sequence in two chunks. For some reason the
|
||||
// state of the parser resets to 0 after exiting parser.parse. This change
|
||||
// just sets the state back based on the correct return statement.
|
||||
|
||||
this._inputHandler.parse(data);
|
||||
|
||||
this.updateRange(this.buffer.y);
|
||||
this.refresh(this._refreshStart, this._refreshEnd);
|
||||
this.refresh(this._dirtyRowService.start, this._dirtyRowService.end);
|
||||
|
||||
if (Date.now() - startTime >= WRITE_TIMEOUT_MS) {
|
||||
break;
|
||||
@@ -1717,29 +1697,6 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
|
||||
this._onResize.fire({ cols: x, rows: y });
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the range of rows to refresh
|
||||
* @param y The number of rows to refresh next.
|
||||
*/
|
||||
public updateRange(y: number): void {
|
||||
if (y < this._refreshStart) this._refreshStart = y;
|
||||
if (y > this._refreshEnd) this._refreshEnd = y;
|
||||
// if (y > this.refreshEnd) {
|
||||
// this.refreshEnd = y;
|
||||
// if (y > this.rows - 1) {
|
||||
// this.refreshEnd = this.rows - 1;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the range of refreshing to the maximum value
|
||||
*/
|
||||
public maxRange(): void {
|
||||
this._refreshStart = 0;
|
||||
this._refreshEnd = this.rows - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the entire buffer, making the prompt line the new first line.
|
||||
*/
|
||||
|
||||
Vendored
-1
@@ -55,7 +55,6 @@ export interface IInputHandlingTerminal {
|
||||
|
||||
bell(): void;
|
||||
focus(): void;
|
||||
updateRange(y: number): void;
|
||||
scroll(isWrapped?: boolean): void;
|
||||
setgLevel(g: number): void;
|
||||
eraseAttrData(): IAttributeData;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { IBufferService, ICoreService, ILogService, IOptionsService, ITerminalOptions, IPartialTerminalOptions } from 'common/services/Services';
|
||||
import { IBufferService, ICoreService, ILogService, IOptionsService, ITerminalOptions, IPartialTerminalOptions, IDirtyRowService } from 'common/services/Services';
|
||||
import { IEvent, EventEmitter } from 'common/EventEmitter';
|
||||
import { clone } from 'common/Clone';
|
||||
import { DEFAULT_OPTIONS } from 'common/services/OptionsService';
|
||||
@@ -36,6 +36,15 @@ export class MockCoreService implements ICoreService {
|
||||
triggerDataEvent(data: string, wasUserInput?: boolean): void {}
|
||||
}
|
||||
|
||||
export class MockDirtyRowService implements IDirtyRowService {
|
||||
start: number = 0;
|
||||
end: number = 0;
|
||||
clearRange(): void {}
|
||||
markDirty(y: number): void {}
|
||||
markRangeDirty(y1: number, y2: number): void {}
|
||||
markAllDirty(): void {}
|
||||
}
|
||||
|
||||
export class MockLogService implements ILogService {
|
||||
debug(message: any, ...optionalParams: any[]): void {}
|
||||
info(message: any, ...optionalParams: any[]): void {}
|
||||
|
||||
Vendored
+5
@@ -153,3 +153,8 @@ export interface IMarker extends IDisposable {
|
||||
export interface IDecPrivateModes {
|
||||
applicationCursorKeys: boolean;
|
||||
}
|
||||
|
||||
export interface IRowRange {
|
||||
start: number;
|
||||
end: number;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { IBufferService, IDirtyRowService } from 'common/services/Services';
|
||||
|
||||
export class DirtyRowService implements IDirtyRowService {
|
||||
private _start!: number;
|
||||
private _end!: number;
|
||||
|
||||
public get start(): number { return this._start; }
|
||||
public get end(): number { return this._end; }
|
||||
|
||||
constructor(
|
||||
private readonly _bufferService: IBufferService
|
||||
) {
|
||||
this.clearRange();
|
||||
}
|
||||
|
||||
public clearRange(): void {
|
||||
this._start = this._bufferService.buffer.y;
|
||||
this._end = this._bufferService.buffer.y;
|
||||
}
|
||||
|
||||
public markDirty(y: number): void {
|
||||
if (y < this._start) {
|
||||
this._start = y;
|
||||
} else if (y > this._end) {
|
||||
this._end = y;
|
||||
}
|
||||
}
|
||||
|
||||
public markRangeDirty(y1: number, y2: number): void {
|
||||
if (y1 > y2) {
|
||||
const temp = y1;
|
||||
y1 = y2;
|
||||
y2 = temp;
|
||||
}
|
||||
if (y1 < this._start) {
|
||||
this._start = y1;
|
||||
}
|
||||
if (y2 > this._end) {
|
||||
this._end = y2;
|
||||
}
|
||||
}
|
||||
|
||||
public markAllDirty(): void {
|
||||
this.markRangeDirty(0, this._bufferService.rows - 1);
|
||||
}
|
||||
}
|
||||
Vendored
+10
@@ -38,6 +38,16 @@ export interface ICoreService {
|
||||
triggerDataEvent(data: string, wasUserInput?: boolean): void;
|
||||
}
|
||||
|
||||
export interface IDirtyRowService {
|
||||
readonly start: number;
|
||||
readonly end: number;
|
||||
|
||||
clearRange(): void;
|
||||
markDirty(y: number): void;
|
||||
markRangeDirty(y1: number, y2: number): void;
|
||||
markAllDirty(): void;
|
||||
}
|
||||
|
||||
export interface ILogService {
|
||||
debug(message: any, ...optionalParams: any[]): void;
|
||||
info(message: any, ...optionalParams: any[]): void;
|
||||
|
||||
@@ -21,9 +21,6 @@ const SELECTION_CLASS = 'xterm-selection';
|
||||
|
||||
let nextTerminalId = 1;
|
||||
|
||||
// TODO: Pull into an addon when TS composite projects allow easier sharing of code (not just
|
||||
// interfaces) between core and addons
|
||||
|
||||
/**
|
||||
* A fallback renderer for when canvas is slow. This is not meant to be
|
||||
* particularly fast or feature complete, more just stable and usable for when
|
||||
|
||||
Reference in New Issue
Block a user