diff --git a/src/SelectionManager.test.ts b/src/SelectionManager.test.ts index 8499497a..0b82466d 100644 --- a/src/SelectionManager.test.ts +++ b/src/SelectionManager.test.ts @@ -5,13 +5,12 @@ import { assert } from 'chai'; import { SelectionManager, SelectionMode } from './SelectionManager'; -import { SelectionModel } from './SelectionModel'; -import { BufferSet } from 'common/buffer/BufferSet'; +import { SelectionModel } from 'browser/selection/SelectionModel'; import { ITerminal } from './Types'; import { IBuffer } from 'common/buffer/Types'; import { IBufferLine } from 'common/Types'; import { MockTerminal } from './TestUtils.test'; -import { MockOptionsService, MockBufferService } from 'common/TestUtils.test'; +import { MockBufferService } from 'common/TestUtils.test'; import { BufferLine } from 'common/buffer/BufferLine'; import { IBufferService } from 'common/services/Services'; import { MockCharSizeService, MockMouseService } from 'browser/TestUtils.test'; @@ -52,10 +51,7 @@ describe('SelectionManager', () => { beforeEach(() => { terminal = new TestMockTerminal(); bufferService = new MockBufferService(20, 20); - terminal.buffers = new BufferSet( - new MockOptionsService({ scrollback: 100 }), - bufferService - ); + terminal.buffers = bufferService.buffers; terminal.cols = 20; terminal.rows = 20; terminal.buffer = terminal.buffers.active; @@ -366,14 +362,13 @@ describe('SelectionManager', () => { describe('selectAll', () => { it('should select the entire buffer, beyond the viewport', () => { - buffer.lines.length = 5; + bufferService.resize(20, 5); buffer.lines.set(0, stringToRow('1')); buffer.lines.set(1, stringToRow('2')); buffer.lines.set(2, stringToRow('3')); buffer.lines.set(3, stringToRow('4')); buffer.lines.set(4, stringToRow('5')); selectionManager.selectAll(); - terminal.buffer.ybase = buffer.lines.length - bufferService.rows; assert.equal(selectionManager.selectionText, '1\n2\n3\n4\n5'); }); }); diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index aa388d8a..0b77d183 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -7,7 +7,7 @@ import { ITerminal, ISelectionManager, ISelectionRedrawRequestEvent } from './Ty import { IBuffer } from 'common/buffer/Types'; import { IBufferLine } from 'common/Types'; import * as Browser from 'common/Platform'; -import { SelectionModel } from './SelectionModel'; +import { SelectionModel } from 'browser/selection/SelectionModel'; import { AltClickHandler } from './handlers/AltClickHandler'; import { CellData } from 'common/buffer/CellData'; import { IDisposable } from 'xterm'; @@ -126,7 +126,7 @@ export class SelectionManager implements ISelectionManager { this._initListeners(); this.enable(); - this._model = new SelectionModel(_terminal, bufferService); + this._model = new SelectionModel(bufferService); this._activeSelectionMode = SelectionMode.NORMAL; } diff --git a/src/SelectionModel.test.ts b/src/browser/selection/SelectionModel.test.ts similarity index 79% rename from src/SelectionModel.test.ts rename to src/browser/selection/SelectionModel.test.ts index 605ba9e8..c15cdd29 100644 --- a/src/SelectionModel.test.ts +++ b/src/browser/selection/SelectionModel.test.ts @@ -4,36 +4,15 @@ */ import { assert } from 'chai'; -import { ITerminal } from './Types'; import { SelectionModel } from './SelectionModel'; -import { BufferSet } from 'common/buffer/BufferSet'; -import { MockTerminal } from './TestUtils.test'; -import { MockOptionsService, MockBufferService } from 'common/TestUtils.test'; -import { IBufferService } from 'common/services/Services'; +import { MockBufferService } from 'common/TestUtils.test'; -class TestSelectionModel extends SelectionModel { - constructor( - terminal: ITerminal, - bufferService: IBufferService - ) { - super(terminal, bufferService); - } -} - -describe('SelectionManager', () => { - let terminal: ITerminal; - let model: TestSelectionModel; +describe('SelectionModel', () => { + let model: SelectionModel; beforeEach(() => { - terminal = new MockTerminal(); const bufferService = new MockBufferService(80, 2); - terminal.buffers = new BufferSet( - new MockOptionsService({ scrollback: 10 }), - bufferService - ); - terminal.buffer = terminal.buffers.active; - - model = new TestSelectionModel(terminal, bufferService); + model = new SelectionModel(bufferService); }); describe('clearSelection', () => { @@ -43,8 +22,8 @@ describe('SelectionManager', () => { assert.deepEqual(model.finalSelectionStart, [0, 0]); assert.deepEqual(model.finalSelectionEnd, [10, 2]); model.clearSelection(); - assert.deepEqual(model.finalSelectionStart, null); - assert.deepEqual(model.finalSelectionEnd, null); + assert.deepEqual(model.finalSelectionStart, undefined); + assert.deepEqual(model.finalSelectionEnd, undefined); }); }); @@ -82,8 +61,8 @@ describe('SelectionManager', () => { model.selectionStart = [0, 0]; model.selectionEnd = [10, 0]; model.onTrim(1); - assert.deepEqual(model.finalSelectionStart, null); - assert.deepEqual(model.finalSelectionEnd, null); + assert.deepEqual(model.finalSelectionStart, undefined); + assert.deepEqual(model.finalSelectionEnd, undefined); }); }); @@ -111,9 +90,9 @@ describe('SelectionManager', () => { assert.deepEqual(model.finalSelectionEnd, [80, 1]); }); it('should return null if there is no selection start', () => { - assert.equal(model.finalSelectionEnd, null); + assert.equal(model.finalSelectionEnd, undefined); model.selectionEnd = [1, 2]; - assert.equal(model.finalSelectionEnd, null); + assert.equal(model.finalSelectionEnd, undefined); }); it('should return selection start + length if there is no selection end', () => { model.selectionStart = [2, 2]; diff --git a/src/SelectionModel.ts b/src/browser/selection/SelectionModel.ts similarity index 86% rename from src/SelectionModel.ts rename to src/browser/selection/SelectionModel.ts index 44cd4cac..1420444e 100644 --- a/src/SelectionModel.ts +++ b/src/browser/selection/SelectionModel.ts @@ -3,7 +3,6 @@ * @license MIT */ -import { ITerminal } from './Types'; import { IBufferService } from 'common/services/Services'; /** @@ -14,38 +13,36 @@ export class SelectionModel { /** * Whether select all is currently active. */ - public isSelectAllActive: boolean; - - /** - * The [x, y] position the selection starts at. - */ - public selectionStart: [number, number]; + public isSelectAllActive: boolean = false; /** * The minimal length of the selection from the start position. When double * clicking on a word, the word will be selected which makes the selection * start at the start of the word and makes this variable the length. */ - public selectionStartLength: number; + public selectionStartLength: number = 0; + + /** + * The [x, y] position the selection starts at. + */ + public selectionStart: [number, number] | undefined; /** * The [x, y] position the selection ends at. */ - public selectionEnd: [number, number]; + public selectionEnd: [number, number] | undefined; constructor( - private _terminal: ITerminal, private _bufferService: IBufferService ) { - this.clearSelection(); } /** * Clears the current selection. */ public clearSelection(): void { - this.selectionStart = null; - this.selectionEnd = null; + this.selectionStart = undefined; + this.selectionEnd = undefined; this.isSelectAllActive = false; this.selectionStartLength = 0; } @@ -53,7 +50,7 @@ export class SelectionModel { /** * The final selection start, taking into consideration select all. */ - public get finalSelectionStart(): [number, number] { + public get finalSelectionStart(): [number, number] | undefined { if (this.isSelectAllActive) { return [0, 0]; } @@ -69,13 +66,13 @@ export class SelectionModel { * The final selection end, taking into consideration select all, double click * word selection and triple click line selection. */ - public get finalSelectionEnd(): [number, number] { + public get finalSelectionEnd(): [number, number] | undefined { if (this.isSelectAllActive) { - return [this._bufferService.cols, this._terminal.buffer.ybase + this._bufferService.rows - 1]; + return [this._bufferService.cols, this._bufferService.buffer.ybase + this._bufferService.rows - 1]; } if (!this.selectionStart) { - return null; + return undefined; } // Use the selection start + length if the end doesn't exist or they're reversed diff --git a/src/common/TestUtils.test.ts b/src/common/TestUtils.test.ts index 8e03dcad..c6402fb1 100644 --- a/src/common/TestUtils.test.ts +++ b/src/common/TestUtils.test.ts @@ -8,14 +8,18 @@ import { IEvent, EventEmitter } from 'common/EventEmitter'; import { clone } from 'common/Clone'; import { DEFAULT_OPTIONS } from 'common/services/OptionsService'; import { IBufferSet, IBuffer } from 'common/buffer/Types'; +import { BufferSet } from 'common/buffer/BufferSet'; export class MockBufferService implements IBufferService { - public buffer: IBuffer = {} as any; + public get buffer(): IBuffer { return this.buffers.active; } public buffers: IBufferSet = {} as any; constructor( public cols: number, - public rows: number - ) {} + public rows: number, + optionsService: IOptionsService = new MockOptionsService() + ) { + this.buffers = new BufferSet(optionsService, this); + } resize(cols: number, rows: number): void { this.cols = cols; this.rows = rows; @@ -26,8 +30,10 @@ export class MockBufferService implements IBufferService { export class MockOptionsService implements IOptionsService { options: ITerminalOptions = clone(DEFAULT_OPTIONS); onOptionChange: IEvent = new EventEmitter().event; - constructor(testOptions: IPartialTerminalOptions) { - Object.keys(testOptions).forEach(key => this.options[key] = (testOptions)[key]); + constructor(testOptions?: IPartialTerminalOptions) { + if (testOptions) { + Object.keys(testOptions).forEach(key => this.options[key] = (testOptions)[key]); + } } setOption(key: string, value: T): void { throw new Error('Method not implemented.');