diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index fe5c7f79f9..509bb2acf5 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -1293,6 +1293,7 @@ export class Terminal extends CoreTerminal implements ITerminal { // Don't clear if it's already clear return; } + this.buffer.clearMarkers(); this.buffer.lines.set(0, this.buffer.lines.get(this.buffer.ybase + this.buffer.y)!); this.buffer.lines.length = 1; this.buffer.ydisp = 0; diff --git a/src/browser/TestUtils.test.ts b/src/browser/TestUtils.test.ts index 8fdf458e6d..ee266e9c6b 100644 --- a/src/browser/TestUtils.test.ts +++ b/src/browser/TestUtils.test.ts @@ -254,6 +254,9 @@ export class MockBuffer implements IBuffer { public getWhitespaceCell(attr?: IAttributeData): ICellData { throw new Error('Method not implemented.'); } + public clearMarkers(): void { + throw new Error('Method not implemented.'); + } } export class MockRenderer implements IRenderer { diff --git a/src/common/buffer/Buffer.ts b/src/common/buffer/Buffer.ts index 02ce7c8168..8addf45ada 100644 --- a/src/common/buffer/Buffer.ts +++ b/src/common/buffer/Buffer.ts @@ -43,6 +43,7 @@ export class Buffer implements IBuffer { private _whitespaceCell: ICellData = CellData.fromCharData([0, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_WIDTH, WHITESPACE_CELL_CODE]); private _cols: number; private _rows: number; + private _isClearing: boolean = false; constructor( private _hasScrollback: boolean, @@ -584,6 +585,15 @@ export class Buffer implements IBuffer { return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x; } + public clearMarkers(): void { + this._isClearing = true; + for (const marker of this.markers) { + marker.dispose(); + } + this.markers = []; + this._isClearing = false; + } + public addMarker(y: number): Marker { const marker = new Marker(y); this.markers.push(marker); @@ -615,7 +625,9 @@ export class Buffer implements IBuffer { } private _removeMarker(marker: Marker): void { - this.markers.splice(this.markers.indexOf(marker), 1); + if (!this._isClearing) { + this.markers.splice(this.markers.indexOf(marker), 1); + } } public iterator(trimRight: boolean, startIndex?: number, endIndex?: number, startOverscan?: number, endOverscan?: number): IBufferStringIterator { diff --git a/src/common/buffer/Types.d.ts b/src/common/buffer/Types.d.ts index cbf40a03d3..9259d46d4a 100644 --- a/src/common/buffer/Types.d.ts +++ b/src/common/buffer/Types.d.ts @@ -45,6 +45,7 @@ export interface IBuffer { getNullCell(attr?: IAttributeData): ICellData; getWhitespaceCell(attr?: IAttributeData): ICellData; addMarker(y: number): IMarker; + clearMarkers(): void; } export interface IBufferSet extends IDisposable { diff --git a/test/api/Terminal.api.ts b/test/api/Terminal.api.ts index 2b0c00d470..1fe7545680 100644 --- a/test/api/Terminal.api.ts +++ b/test/api/Terminal.api.ts @@ -559,6 +559,29 @@ describe('API Integration Tests', function(): void { assert.equal(await page.evaluate(`window.term.buffer.active.getLine(0).getCell(2).getChars()`), ''); assert.equal(await page.evaluate(`window.term.buffer.active.getLine(0).getCell(2).getWidth()`), 0); }); + + it('clearMarkers', async () => { + await openTerminal(page, { cols: 5 }); + await page.evaluate(` + window.disposeStack = []; + `); + await writeSync(page, '\\n\\n\\n\\n'); + await writeSync(page, '\\n\\n\\n\\n'); + await writeSync(page, '\\n\\n\\n\\n'); + await writeSync(page, '\\n\\n\\n\\n'); + await page.evaluate(`window.term.addMarker(1)`); + await page.evaluate(`window.term.addMarker(2)`); + await page.evaluate(`window.term.scrollLines(10)`); + await page.evaluate(`window.term.addMarker(3)`); + await page.evaluate(`window.term.addMarker(4)`); + await page.evaluate(` + for (let i = 0; i < window.term.markers.length; ++i) { + const marker = window.term.markers[i]; + marker.onDispose(() => window.disposeStack.push(marker)); + }`); + await page.evaluate(`window.term.clear()`); + assert.equal(await page.evaluate(`window.disposeStack.length`), 4); + }); }); it('active, normal, alternate', async () => {