diff --git a/src/Buffer.test.ts b/src/Buffer.test.ts index be9afe93..042c42d5 100644 --- a/src/Buffer.test.ts +++ b/src/Buffer.test.ts @@ -4,7 +4,7 @@ */ import { assert, expect } from 'chai'; -import { Buffer } from './Buffer'; +import { Buffer } from './common/buffer/Buffer'; import { CircularList } from 'common/CircularList'; import { TestTerminal, MockOptionsService, MockBufferService } from './TestUtils.test'; import { BufferLine, CellData, DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; diff --git a/src/BufferSet.test.ts b/src/BufferSet.test.ts index e8e978e5..44c23d79 100644 --- a/src/BufferSet.test.ts +++ b/src/BufferSet.test.ts @@ -5,7 +5,7 @@ import { assert } from 'chai'; import { BufferSet } from './BufferSet'; -import { Buffer } from './Buffer'; +import { Buffer } from './common/buffer/Buffer'; import { MockOptionsService, MockBufferService } from './TestUtils.test'; describe('BufferSet', () => { diff --git a/src/BufferSet.ts b/src/BufferSet.ts index 47e9d6fa..fc07b9a7 100644 --- a/src/BufferSet.ts +++ b/src/BufferSet.ts @@ -6,7 +6,7 @@ import { IBufferSet } from './Types'; import { IBuffer } from 'common/buffer/Types'; import { IAttributeData } from 'common/Types'; -import { Buffer } from './Buffer'; +import { Buffer } from './common/buffer/Buffer'; import { EventEmitter2, IEvent } from 'common/EventEmitter2'; import { IOptionsService, IBufferService } from 'common/services/Services'; diff --git a/src/SelectionManager.test.ts b/src/SelectionManager.test.ts index 40a75a5a..57397faa 100644 --- a/src/SelectionManager.test.ts +++ b/src/SelectionManager.test.ts @@ -12,6 +12,7 @@ import { IBuffer } from 'common/buffer/Types'; import { IBufferLine } from 'common/Types'; import { MockTerminal, MockCharSizeService, MockOptionsService, MockBufferService } from './TestUtils.test'; import { BufferLine, CellData } from 'common/buffer/BufferLine'; +import { IBufferService } from 'common/services/Services'; class TestMockTerminal extends MockTerminal { emit(event: string, data: any): void {} @@ -19,9 +20,10 @@ class TestMockTerminal extends MockTerminal { class TestSelectionManager extends SelectionManager { constructor( - terminal: ITerminal + terminal: ITerminal, + bufferService: IBufferService ) { - super(terminal, new MockCharSizeService(10, 10), new MockBufferService(20, 20)); + super(terminal, new MockCharSizeService(10, 10), bufferService); } public get model(): SelectionModel { return this._model; } @@ -41,17 +43,21 @@ class TestSelectionManager extends SelectionManager { describe('SelectionManager', () => { let terminal: ITerminal; let buffer: IBuffer; + let bufferService: IBufferService; let selectionManager: TestSelectionManager; beforeEach(() => { terminal = new TestMockTerminal(); + bufferService = new MockBufferService(20, 20); terminal.buffers = new BufferSet( new MockOptionsService({ scrollback: 100 }), - new MockBufferService(80, 2) + bufferService ); + terminal.cols = 20; + terminal.rows = 20; terminal.buffer = terminal.buffers.active; buffer = terminal.buffer; - selectionManager = new TestSelectionManager(terminal); + selectionManager = new TestSelectionManager(terminal, bufferService); }); function stringToRow(text: string): IBufferLine { @@ -191,36 +197,36 @@ describe('SelectionManager', () => { assert.equal(selectionManager.selectionText, 'ij"'); }); it('should expand upwards or downards for wrapped lines', () => { - buffer.lines.set(0, stringToRow(' foo')); - buffer.lines.set(1, stringToRow('bar ')); + buffer.lines.set(0, stringToRow(' foo')); + buffer.lines.set(1, stringToRow('bar ')); buffer.lines.get(1).isWrapped = true; selectionManager.selectWordAt([1, 1]); assert.equal(selectionManager.selectionText, 'foobar'); selectionManager.model.clearSelection(); - selectionManager.selectWordAt([78, 0]); + selectionManager.selectWordAt([18, 0]); assert.equal(selectionManager.selectionText, 'foobar'); }); it('should expand both upwards and downwards for word wrapped over many lines', () => { - const expectedText = 'fooaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbar'; - buffer.lines.set(0, stringToRow(' foo')); - buffer.lines.set(1, stringToRow('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')); - buffer.lines.set(2, stringToRow('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')); - buffer.lines.set(3, stringToRow('cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc')); - buffer.lines.set(4, stringToRow('bar ')); + const expectedText = 'fooaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbccccccccccccccccccccbar'; + buffer.lines.set(0, stringToRow(' foo')); + buffer.lines.set(1, stringToRow('aaaaaaaaaaaaaaaaaaaa')); + buffer.lines.set(2, stringToRow('bbbbbbbbbbbbbbbbbbbb')); + buffer.lines.set(3, stringToRow('cccccccccccccccccccc')); + buffer.lines.set(4, stringToRow('bar ')); buffer.lines.get(1).isWrapped = true; buffer.lines.get(2).isWrapped = true; buffer.lines.get(3).isWrapped = true; buffer.lines.get(4).isWrapped = true; - selectionManager.selectWordAt([78, 0]); + selectionManager.selectWordAt([18, 0]); assert.equal(selectionManager.selectionText, expectedText); selectionManager.model.clearSelection(); - selectionManager.selectWordAt([40, 1]); + selectionManager.selectWordAt([10, 1]); assert.equal(selectionManager.selectionText, expectedText); selectionManager.model.clearSelection(); - selectionManager.selectWordAt([40, 2]); + selectionManager.selectWordAt([10, 2]); assert.equal(selectionManager.selectionText, expectedText); selectionManager.model.clearSelection(); - selectionManager.selectWordAt([40, 3]); + selectionManager.selectWordAt([10, 3]); assert.equal(selectionManager.selectionText, expectedText); selectionManager.model.clearSelection(); selectionManager.selectWordAt([1, 4]); @@ -341,7 +347,7 @@ describe('SelectionManager', () => { selectionManager.selectLineAt(0); assert.equal(selectionManager.selectionText, 'foo bar', 'The selected text is correct'); assert.deepEqual(selectionManager.model.finalSelectionStart, [0, 0]); - assert.deepEqual(selectionManager.model.finalSelectionEnd, [terminal.cols, 0], 'The actual selection spans the entire column'); + assert.deepEqual(selectionManager.model.finalSelectionEnd, [bufferService.cols, 0], 'The actual selection spans the entire column'); }); it('should select the entire wrapped line', () => { buffer.lines.set(0, stringToRow('foo')); @@ -351,7 +357,7 @@ describe('SelectionManager', () => { selectionManager.selectLineAt(0); assert.equal(selectionManager.selectionText, 'foobar', 'The selected text is correct'); assert.deepEqual(selectionManager.model.finalSelectionStart, [0, 0]); - assert.deepEqual(selectionManager.model.finalSelectionEnd, [terminal.cols, 1], 'The actual selection spans the entire column'); + assert.deepEqual(selectionManager.model.finalSelectionEnd, [bufferService.cols, 1], 'The actual selection spans the entire column'); }); }); @@ -364,7 +370,7 @@ describe('SelectionManager', () => { buffer.lines.set(3, stringToRow('4')); buffer.lines.set(4, stringToRow('5')); selectionManager.selectAll(); - terminal.buffer.ybase = buffer.lines.length - terminal.rows; + terminal.buffer.ybase = buffer.lines.length - bufferService.rows; assert.equal(selectionManager.selectionText, '1\n2\n3\n4\n5'); }); }); @@ -377,7 +383,7 @@ describe('SelectionManager', () => { buffer.lines.set(2, stringToRow('3')); selectionManager.selectLines(1, 1); assert.deepEqual(selectionManager.model.finalSelectionStart, [0, 1]); - assert.deepEqual(selectionManager.model.finalSelectionEnd, [terminal.cols, 1]); + assert.deepEqual(selectionManager.model.finalSelectionEnd, [bufferService.cols, 1]); }); it('should select multiple lines', () => { buffer.lines.length = 5; @@ -388,7 +394,7 @@ describe('SelectionManager', () => { buffer.lines.set(4, stringToRow('5')); selectionManager.selectLines(1, 3); assert.deepEqual(selectionManager.model.finalSelectionStart, [0, 1]); - assert.deepEqual(selectionManager.model.finalSelectionEnd, [terminal.cols, 3]); + assert.deepEqual(selectionManager.model.finalSelectionEnd, [bufferService.cols, 3]); }); it('should select the to the start when requesting a negative row', () => { buffer.lines.length = 2; @@ -396,7 +402,7 @@ describe('SelectionManager', () => { buffer.lines.set(1, stringToRow('2')); selectionManager.selectLines(-1, 0); assert.deepEqual(selectionManager.model.finalSelectionStart, [0, 0]); - assert.deepEqual(selectionManager.model.finalSelectionEnd, [terminal.cols, 0]); + assert.deepEqual(selectionManager.model.finalSelectionEnd, [bufferService.cols, 0]); }); it('should select the to the end when requesting beyond the final row', () => { buffer.lines.length = 2; @@ -404,7 +410,7 @@ describe('SelectionManager', () => { buffer.lines.set(1, stringToRow('2')); selectionManager.selectLines(1, 2); assert.deepEqual(selectionManager.model.finalSelectionStart, [0, 1]); - assert.deepEqual(selectionManager.model.finalSelectionEnd, [terminal.cols, 1]); + assert.deepEqual(selectionManager.model.finalSelectionEnd, [bufferService.cols, 1]); }); }); diff --git a/src/Terminal.ts b/src/Terminal.ts index 47672c38..a15c9229 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -24,7 +24,7 @@ import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, ILinkifier, ILinkMatcherOptions, CustomKeyEventHandler, LinkMatcherHandler, CharacterJoinerHandler, IMouseZoneManager } from './Types'; import { IRenderer } from './renderer/Types'; import { BufferSet } from './BufferSet'; -import { Buffer } from './Buffer'; +import { Buffer } from './common/buffer/Buffer'; import { CompositionHelper } from './CompositionHelper'; import { EventEmitter } from 'common/EventEmitter'; import { Viewport } from './Viewport'; diff --git a/src/TestUtils.test.ts b/src/TestUtils.test.ts index 47dd4089..f9f4f037 100644 --- a/src/TestUtils.test.ts +++ b/src/TestUtils.test.ts @@ -7,7 +7,7 @@ import { IRenderer, IRenderDimensions } from './renderer/Types'; import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminal, IBufferSet, IBrowser, ISelectionManager, ITerminalOptions as IInternalTerminalOptions, ILinkifier, IMouseHelper, ILinkMatcherOptions, CharacterJoinerHandler } from './Types'; import { IBuffer, IBufferStringIterator } from 'common/buffer/Types'; import { IBufferLine, ICellData, IAttributeData, ICircularList, XtermListener } from 'common/Types'; -import { Buffer } from './Buffer'; +import { Buffer } from './common/buffer/Buffer'; import * as Browser from 'common/Platform'; import { IDisposable, IMarker, IEvent, ISelectionPosition } from 'xterm'; import { Terminal } from './Terminal'; @@ -33,8 +33,7 @@ export class MockTerminal implements ITerminal { onTitleChange: IEvent; onScroll: IEvent; onKey: IEvent<{ key: string; domEvent: KeyboardEvent; }>; - onRender: IEvent<{ start: number - ; end: number; }>; + onRender: IEvent<{ start: number; end: number; }>; onResize: IEvent<{ cols: number; rows: number; }>; markers: IMarker[]; optionsService: IOptionsService; diff --git a/src/Buffer.ts b/src/common/buffer/Buffer.ts similarity index 98% rename from src/Buffer.ts rename to src/common/buffer/Buffer.ts index 8d4b3686..4269f79c 100644 --- a/src/Buffer.ts +++ b/src/common/buffer/Buffer.ts @@ -21,16 +21,16 @@ export const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1 * - scroll position */ export class Buffer implements IBuffer { - public lines: CircularList; - public ydisp: number; - public ybase: number; - public y: number; - public x: number; - public scrollBottom: number; - public scrollTop: number; + public lines!: CircularList; + public ydisp: number = 0; + public ybase: number = 0; + public y: number = 0; + public x: number = 0; + public scrollBottom!: number; + public scrollTop!: number; public tabs: any; - public savedY: number; - public savedX: number; + public savedY: number = 0; + public savedX: number = 0; public savedCurAttrData = DEFAULT_ATTR_DATA.clone(); public markers: Marker[] = []; private _nullCell: ICellData = CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); @@ -150,7 +150,7 @@ export class Buffer implements IBuffer { // Deal with columns increasing (reducing needs to happen after reflow) if (this._cols < newCols) { for (let i = 0; i < this.lines.length; i++) { - this.lines.get(i).resize(newCols, nullCell); + this.lines.get(i)!.resize(newCols, nullCell); } } @@ -223,7 +223,7 @@ export class Buffer implements IBuffer { // Trim the end of the line off if cols shrunk if (this._cols > newCols) { for (let i = 0; i < this.lines.length; i++) { - this.lines.get(i).resize(newCols, nullCell); + this.lines.get(i)!.resize(newCols, nullCell); } } } @@ -505,11 +505,11 @@ export class Buffer implements IBuffer { let first = y; let last = y; // Scan upwards for wrapped lines - while (first > 0 && this.lines.get(first).isWrapped) { + while (first > 0 && this.lines.get(first)!.isWrapped) { first--; } // Scan downwards for wrapped lines - while (last + 1 < this.lines.length && this.lines.get(last + 1).isWrapped) { + while (last + 1 < this.lines.length && this.lines.get(last + 1)!.isWrapped) { last++; } return { first, last };