diff --git a/src/Buffer.test.ts b/src/Buffer.test.ts index 6f417f8e..902d54b0 100644 --- a/src/Buffer.test.ts +++ b/src/Buffer.test.ts @@ -273,11 +273,11 @@ describe('Buffer', () => { describe ('translateBufferLineToString', () => { it('should handle selecting a section of ascii text', () => { - const line = new BufferLine(); - line.push([ null, 'a', 1, 'a'.charCodeAt(0)]); - line.push([ null, 'b', 1, 'b'.charCodeAt(0)]); - line.push([ null, 'c', 1, 'c'.charCodeAt(0)]); - line.push([ null, 'd', 1, 'd'.charCodeAt(0)]); + const line = new BufferLine(4); + line.set(0, [ null, 'a', 1, 'a'.charCodeAt(0)]); + line.set(1, [ null, 'b', 1, 'b'.charCodeAt(0)]); + line.set(2, [ null, 'c', 1, 'c'.charCodeAt(0)]); + line.set(3, [ null, 'd', 1, 'd'.charCodeAt(0)]); buffer.lines.set(0, line); const str = buffer.translateBufferLineToString(0, true, 0, 2); @@ -285,10 +285,10 @@ describe('Buffer', () => { }); it('should handle a cut-off double width character by including it', () => { - const line = new BufferLine(); - line.push([ null, '語', 2, 35486 ]); - line.push([ null, '', 0, null]); - line.push([ null, 'a', 1, 'a'.charCodeAt(0)]); + const line = new BufferLine(3); + line.set(0, [ null, '語', 2, 35486 ]); + line.set(1, [ null, '', 0, null]); + line.set(2, [ null, 'a', 1, 'a'.charCodeAt(0)]); buffer.lines.set(0, line); const str1 = buffer.translateBufferLineToString(0, true, 0, 1); @@ -296,10 +296,10 @@ describe('Buffer', () => { }); it('should handle a zero width character in the middle of the string by not including it', () => { - const line = new BufferLine(); - line.push([ null, '語', 2, '語'.charCodeAt(0) ]); - line.push([ null, '', 0, null]); - line.push([ null, 'a', 1, 'a'.charCodeAt(0)]); + const line = new BufferLine(3); + line.set(0, [ null, '語', 2, '語'.charCodeAt(0) ]); + line.set(1, [ null, '', 0, null]); + line.set(2, [ null, 'a', 1, 'a'.charCodeAt(0)]); buffer.lines.set(0, line); const str0 = buffer.translateBufferLineToString(0, true, 0, 1); @@ -313,9 +313,9 @@ describe('Buffer', () => { }); it('should handle single width emojis', () => { - const line = new BufferLine(); - line.push([ null, '😁', 1, '😁'.charCodeAt(0) ]); - line.push([ null, 'a', 1, 'a'.charCodeAt(0)]); + const line = new BufferLine(2); + line.set(0, [ null, '😁', 1, '😁'.charCodeAt(0) ]); + line.set(1, [ null, 'a', 1, 'a'.charCodeAt(0)]); buffer.lines.set(0, line); const str1 = buffer.translateBufferLineToString(0, true, 0, 1); @@ -326,9 +326,9 @@ describe('Buffer', () => { }); it('should handle double width emojis', () => { - const line = new BufferLine(); - line.push([ null, '😁', 2, '😁'.charCodeAt(0) ]); - line.push([ null, '', 0, null]); + const line = new BufferLine(2); + line.set(0, [ null, '😁', 2, '😁'.charCodeAt(0) ]); + line.set(1, [ null, '', 0, null]); buffer.lines.set(0, line); const str1 = buffer.translateBufferLineToString(0, true, 0, 1); @@ -337,10 +337,10 @@ describe('Buffer', () => { const str2 = buffer.translateBufferLineToString(0, true, 0, 2); assert.equal(str2, '😁'); - const line2 = new BufferLine(); - line2.push([ null, '😁', 2, '😁'.charCodeAt(0) ]); - line2.push([ null, '', 0, null]); - line2.push([ null, 'a', 1, 'a'.charCodeAt(0)]); + const line2 = new BufferLine(3); + line2.set(0, [ null, '😁', 2, '😁'.charCodeAt(0) ]); + line2.set(1, [ null, '', 0, null]); + line2.set(2, [ null, 'a', 1, 'a'.charCodeAt(0)]); buffer.lines.set(0, line2); const str3 = buffer.translateBufferLineToString(0, true, 0, 3); diff --git a/src/Buffer.ts b/src/Buffer.ts index 81b8a517..4ae168b4 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -124,9 +124,7 @@ export class Buffer implements IBuffer { if (this._terminal.cols < newCols) { const ch: CharData = [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; // does xterm use the default attr? for (let i = 0; i < this.lines.length; i++) { - while (this.lines.get(i).length < newCols) { - this.lines.get(i).push(ch); - } + this.lines.get(i).resize(newCols, ch); } } diff --git a/src/BufferLine.test.ts b/src/BufferLine.test.ts index 61dfe543..10f4815f 100644 --- a/src/BufferLine.test.ts +++ b/src/BufferLine.test.ts @@ -18,35 +18,20 @@ describe('BufferLine', function(): void { it('ctor', function(): void { let line: IBufferLine = new TestBufferLine(); chai.expect(line.length).equals(0); - chai.expect(line.pop()).equals(undefined); chai.expect(line.isWrapped).equals(false); line = new TestBufferLine(10); chai.expect(line.length).equals(10); - chai.expect(line.pop()).eql([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); + chai.expect(line.get(0)).eql([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); chai.expect(line.isWrapped).equals(false); line = new TestBufferLine(10, null, true); chai.expect(line.length).equals(10); - chai.expect(line.pop()).eql([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); + chai.expect(line.get(0)).eql([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); chai.expect(line.isWrapped).equals(true); line = new TestBufferLine(10, [123, 'a', 456, 789], true); chai.expect(line.length).equals(10); - chai.expect(line.pop()).eql([123, 'a', 456, 789]); + chai.expect(line.get(0)).eql([123, 'a', 456, 789]); chai.expect(line.isWrapped).equals(true); }); - it('splice', function(): void { - const line = new TestBufferLine(); - const data: CharData[] = [ - [1, 'a', 0, 0], - [2, 'b', 0, 0], - [3, 'c', 0, 0] - ]; - for (let i = 0; i < data.length; ++i) line.push(data[i]); - chai.expect(line.length).equals(data.length); - const removed1 = line.splice(1, 1, [4, 'd', 0, 0]); - const removed2 = data.splice(1, 1, [4, 'd', 0, 0]); - chai.expect(removed1).eql(removed2); - chai.expect(line.toArray()).eql(data); - }); it('TerminalLine.blankLine', function(): void { const line = TestBufferLine.blankLine(5, 123); chai.expect(line.length).equals(5); @@ -58,39 +43,30 @@ describe('BufferLine', function(): void { chai.expect(ch[CHAR_DATA_CODE_INDEX]).equals(NULL_CELL_CODE); }); it('insertCells', function(): void { - const line = new TestBufferLine(); - const data: CharData[] = [ - [1, 'a', 0, 0], - [2, 'b', 0, 0], - [3, 'c', 0, 0] - ]; - for (let i = 0; i < data.length; ++i) line.push(data[i]); + const line = new TestBufferLine(3); + line.set(0, [1, 'a', 0, 0]); + line.set(1, [2, 'b', 0, 0]); + line.set(2, [3, 'c', 0, 0]); line.insertCells(1, 3, [4, 'd', 0, 0]); chai.expect(line.toArray()).eql([[1, 'a', 0, 0], [4, 'd', 0, 0], [4, 'd', 0, 0]]); }); it('deleteCells', function(): void { - const line = new TestBufferLine(); - const data: CharData[] = [ - [1, 'a', 0, 0], - [2, 'b', 0, 0], - [3, 'c', 0, 0], - [4, 'd', 0, 0], - [5, 'e', 0, 0] - ]; - for (let i = 0; i < data.length; ++i) line.push(data[i]); + const line = new TestBufferLine(5); + line.set(0, [1, 'a', 0, 0]); + line.set(1, [2, 'b', 0, 0]); + line.set(2, [3, 'c', 0, 0]); + line.set(3, [4, 'd', 0, 0]); + line.set(4, [5, 'e', 0, 0]); line.deleteCells(1, 2, [6, 'f', 0, 0]); chai.expect(line.toArray()).eql([[1, 'a', 0, 0], [4, 'd', 0, 0], [5, 'e', 0, 0], [6, 'f', 0, 0], [6, 'f', 0, 0]]); }); it('replaceCells', function(): void { - const line = new TestBufferLine(); - const data: CharData[] = [ - [1, 'a', 0, 0], - [2, 'b', 0, 0], - [3, 'c', 0, 0], - [4, 'd', 0, 0], - [5, 'e', 0, 0] - ]; - for (let i = 0; i < data.length; ++i) line.push(data[i]); + const line = new TestBufferLine(5); + line.set(0, [1, 'a', 0, 0]); + line.set(1, [2, 'b', 0, 0]); + line.set(2, [3, 'c', 0, 0]); + line.set(3, [4, 'd', 0, 0]); + line.set(4, [5, 'e', 0, 0]); line.replaceCells(2, 4, [6, 'f', 0, 0]); chai.expect(line.toArray()).eql([[1, 'a', 0, 0], [2, 'b', 0, 0], [6, 'f', 0, 0], [6, 'f', 0, 0], [5, 'e', 0, 0]]); }); diff --git a/src/BufferLine.ts b/src/BufferLine.ts index 639049e2..bc54067f 100644 --- a/src/BufferLine.ts +++ b/src/BufferLine.ts @@ -25,7 +25,7 @@ export class BufferLine implements IBufferLine { ch = [0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; } for (let i = 0; i < cols; i++) { - this.push(ch); // Note: the ctor ch is not cloned (resembles old behavior) + this._push(ch); // Note: the ctor ch is not cloned (resembles old behavior) } } if (isWrapped) { @@ -41,18 +41,31 @@ export class BufferLine implements IBufferLine { this._data[index] = data; } - public pop(): CharData | undefined { + /** + * @deprecated + */ + private _pop(): CharData | undefined { const data = this._data.pop(); this.length = this._data.length; return data; } - public push(data: CharData): void { + /** + * @deprecated + * @param data + */ + private _push(data: CharData): void { this._data.push(data); this.length = this._data.length; } - public splice(start: number, deleteCount: number, ...items: CharData[]): CharData[] { + /** + * @deprecated + * @param start + * @param deleteCount + * @param items + */ + private _splice(start: number, deleteCount: number, ...items: CharData[]): CharData[] { const removed = this._data.splice(start, deleteCount, ...items); this.length = this._data.length; return removed; @@ -61,16 +74,16 @@ export class BufferLine implements IBufferLine { /** insert n cells ch at pos, right cells are lost (stable length) */ public insertCells(pos: number, n: number, ch: CharData): void { while (n--) { - this.splice(pos, 0, ch); - this.pop(); + this._splice(pos, 0, ch); + this._pop(); } } /** delete n cells at pos, right side is filled with fill (stable length) */ public deleteCells(pos: number, n: number, fill: CharData): void { while (n--) { - this.splice(pos, 1); - this.push(fill); + this._splice(pos, 1); + this._push(fill); } } @@ -80,4 +93,17 @@ export class BufferLine implements IBufferLine { this.set(start++, fill); // Note: fill is not cloned (resembles old behavior) } } + + /** resize line to cols filling new cells with fill */ + public resize(cols: number, fill: CharData, shrink: boolean = false): void { + if (shrink) { + while (this._data.length > cols) { + this._data.pop(); + } + } + while (this._data.length < cols) { + this._data.push(fill); + } + this.length = cols; + } } diff --git a/src/InputHandler.test.ts b/src/InputHandler.test.ts index 0db6c04f..724f67e9 100644 --- a/src/InputHandler.test.ts +++ b/src/InputHandler.test.ts @@ -97,6 +97,36 @@ class OldInputHandler extends InputHandler { public eraseLine(y: number): void { this.eraseRight(0, y); } + + public insertChars(params: number[]): void { + let param = params[0]; + if (param < 1) param = 1; + + // make buffer local for faster access + const buffer = this._terminal.buffer; + + const row = buffer.y + buffer.ybase; + let j = buffer.x; + while (param-- && j < this._terminal.cols) { + buffer.lines.get(row).insertCells(j++, 1, [this._terminal.eraseAttr(), NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); + } + } + + public deleteChars(params: number[]): void { + let param: number = params[0]; + if (param < 1) { + param = 1; + } + + // make buffer local for faster access + const buffer = this._terminal.buffer; + + const row = buffer.y + buffer.ybase; + while (param--) { + buffer.lines.get(row).deleteCells(buffer.x, 1, [this._terminal.eraseAttr(), NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); + } + this._terminal.updateRange(buffer.y); + } } describe('InputHandler', () => { @@ -177,8 +207,6 @@ describe('InputHandler', () => { }); }); describe('regression tests', function(): void { - type CharData = [number, string, number, number]; - function lineContent(line: IBufferLine): string { let content = ''; for (let i = 0; i < line.length; ++i) content += line.get(i)[CHAR_DATA_CHAR_INDEX]; @@ -194,23 +222,7 @@ describe('InputHandler', () => { it('insertChars', function(): void { const term = new Terminal(); const inputHandler = new InputHandler(term); - - // old variant of the method - function insertChars(params: number[]): void { - let param = params[0]; - if (param < 1) param = 1; - - // make buffer local for faster access - const buffer = term.buffer; - - const row = buffer.y + buffer.ybase; - let j = buffer.x; - const ch: CharData = [term.eraseAttr(), NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; // xterm - while (param-- && j < term.cols) { - buffer.lines.get(row).splice(j++, 0, ch); - buffer.lines.get(row).pop(); - } - } + const oldInputHandler = new OldInputHandler(term); // insert some data in first and second line inputHandler.parse(Array(term.cols - 9).join('a')); @@ -225,7 +237,7 @@ describe('InputHandler', () => { // insert one char from params = [0] term.buffer.y = 0; term.buffer.x = 70; - insertChars([0]); + oldInputHandler.insertChars([0]); expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + ' 123456789'); term.buffer.y = 1; term.buffer.x = 70; @@ -236,7 +248,7 @@ describe('InputHandler', () => { // insert one char from params = [1] term.buffer.y = 0; term.buffer.x = 70; - insertChars([1]); + oldInputHandler.insertChars([1]); expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + ' 12345678'); term.buffer.y = 1; term.buffer.x = 70; @@ -247,7 +259,7 @@ describe('InputHandler', () => { // insert two chars from params = [2] term.buffer.y = 0; term.buffer.x = 70; - insertChars([2]); + oldInputHandler.insertChars([2]); expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + ' 123456'); term.buffer.y = 1; term.buffer.x = 70; @@ -258,7 +270,7 @@ describe('InputHandler', () => { // insert 10 chars from params = [10] term.buffer.y = 0; term.buffer.x = 70; - insertChars([10]); + oldInputHandler.insertChars([10]); expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + ' '); term.buffer.y = 1; term.buffer.x = 70; @@ -269,25 +281,7 @@ describe('InputHandler', () => { it('deleteChars', function(): void { const term = new Terminal(); const inputHandler = new InputHandler(term); - - // old variant of the method - function deleteChars(params: number[]): void { - let param: number = params[0]; - if (param < 1) { - param = 1; - } - - // make buffer local for faster access - const buffer = term.buffer; - - const row = buffer.y + buffer.ybase; - const ch: CharData = [term.eraseAttr(), NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; // xterm - while (param--) { - buffer.lines.get(row).splice(buffer.x, 1); - buffer.lines.get(row).push(ch); - } - term.updateRange(buffer.y); - } + const oldInputHandler = new OldInputHandler(term); // insert some data in first and second line inputHandler.parse(Array(term.cols - 9).join('a')); @@ -302,7 +296,7 @@ describe('InputHandler', () => { // delete one char from params = [0] term.buffer.y = 0; term.buffer.x = 70; - deleteChars([0]); + oldInputHandler.deleteChars([0]); expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + '234567890 '); term.buffer.y = 1; term.buffer.x = 70; @@ -313,7 +307,7 @@ describe('InputHandler', () => { // insert one char from params = [1] term.buffer.y = 0; term.buffer.x = 70; - deleteChars([1]); + oldInputHandler.deleteChars([1]); expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + '34567890 '); term.buffer.y = 1; term.buffer.x = 70; @@ -324,7 +318,7 @@ describe('InputHandler', () => { // insert two chars from params = [2] term.buffer.y = 0; term.buffer.x = 70; - deleteChars([2]); + oldInputHandler.deleteChars([2]); expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + '567890 '); term.buffer.y = 1; term.buffer.x = 70; @@ -335,7 +329,7 @@ describe('InputHandler', () => { // insert 10 chars from params = [10] term.buffer.y = 0; term.buffer.x = 70; - deleteChars([10]); + oldInputHandler.deleteChars([10]); expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + ' '); term.buffer.y = 1; term.buffer.x = 70; diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 3c6aae0f..52ece5df 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -392,10 +392,12 @@ export class InputHandler extends Disposable implements IInputHandler { if (chMinusTwo) { chMinusTwo[CHAR_DATA_CHAR_INDEX] += char; chMinusTwo[CHAR_DATA_CODE_INDEX] = code; + bufferRow.set(buffer.x - 2, chMinusTwo); // must be set explicitly now } } else { chMinusOne[CHAR_DATA_CHAR_INDEX] += char; chMinusOne[CHAR_DATA_CODE_INDEX] = code; + bufferRow.set(buffer.x - 1, chMinusOne); // must be set explicitly now } } continue; @@ -403,6 +405,9 @@ export class InputHandler extends Disposable implements IInputHandler { // goto next line if ch would overflow // TODO: needs a global min terminal width of 2 + // FIXME: additionally ensure chWidth fits into a line + // --> maybe forbid cols= cols) { // autowrap - DECAWM // automatically wraps to the beginning of the next line @@ -430,23 +435,15 @@ export class InputHandler extends Disposable implements IInputHandler { } // insert mode: move characters to right - // To achieve insert, we remove cells from the right - // and insert empty ones at cursor position if (insertMode) { - // do this twice for a fullwidth char - for (let moves = 0; moves < chWidth; ++moves) { - // remove last cell - // if it's width is 0, we have to adjust the second last cell as well - const removed = bufferRow.pop(); - const chMinusTwo = bufferRow.get(buffer.x - 2); - if (removed[CHAR_DATA_WIDTH_INDEX] === 0 - && chMinusTwo - && chMinusTwo[CHAR_DATA_WIDTH_INDEX] === 2) { - bufferRow.set(this._terminal.cols - 2, [curAttr, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); - } - - // insert empty cell at cursor - bufferRow.splice(buffer.x, 0, [curAttr, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); + // right shift cells according to the width + bufferRow.insertCells(buffer.x, chWidth, [curAttr, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); + // test last cell - since the last cell has only room for + // a halfwidth char any fullwidth shifted there is lost + // and will be set to eraseChar + const lastCell = bufferRow.get(cols - 1); + if (lastCell[CHAR_DATA_WIDTH_INDEX] === 2) { + bufferRow.set(cols - 1, [curAttr, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); } } @@ -454,7 +451,9 @@ export class InputHandler extends Disposable implements IInputHandler { bufferRow.set(buffer.x++, [curAttr, char, chWidth, code]); // fullwidth char - also set next cell to placeholder stub and advance cursor - if (chWidth === 2) { + // for graphemes bigger than fullwidth we can simply loop to zero + // we already made sure above, that buffer.x + chWidth will not overflow right + while (--chWidth) { bufferRow.set(buffer.x++, [curAttr, '', 0, undefined]); } } diff --git a/src/Linkifier.test.ts b/src/Linkifier.test.ts index eeaaeedc..5afad3c7 100644 --- a/src/Linkifier.test.ts +++ b/src/Linkifier.test.ts @@ -50,9 +50,9 @@ describe('Linkifier', () => { }); function stringToRow(text: string): IBufferLine { - const result = new BufferLine(); + const result = new BufferLine(text.length); for (let i = 0; i < text.length; i++) { - result.push([0, text.charAt(i), 1, text.charCodeAt(i)]); + result.set(i, [0, text.charAt(i), 1, text.charCodeAt(i)]); } return result; } diff --git a/src/SelectionManager.test.ts b/src/SelectionManager.test.ts index 9359793d..c42735d5 100644 --- a/src/SelectionManager.test.ts +++ b/src/SelectionManager.test.ts @@ -54,16 +54,16 @@ describe('SelectionManager', () => { }); function stringToRow(text: string): IBufferLine { - const result = new BufferLine(); + const result = new BufferLine(text.length); for (let i = 0; i < text.length; i++) { - result.push([0, text.charAt(i), 1, text.charCodeAt(i)]); + result.set(i, [0, text.charAt(i), 1, text.charCodeAt(i)]); } return result; } function stringArrayToRow(chars: string[]): IBufferLine { - const line = new BufferLine(); - chars.map(c => line.push([0, c, 1, c.charCodeAt(0)])); + const line = new BufferLine(chars.length); + chars.map((c, idx) => line.set(idx, [0, c, 1, c.charCodeAt(0)])); return line; } @@ -100,7 +100,6 @@ describe('SelectionManager', () => { }); it('should expand selection for wide characters', () => { // Wide characters use a special format - const line = new BufferLine(); const data: [number, string, number, number][] = [ [null, '中', 2, '中'.charCodeAt(0)], [null, '', 0, null], @@ -118,7 +117,8 @@ describe('SelectionManager', () => { [null, 'o', 1, 'o'.charCodeAt(0)], [null, 'o', 1, 'o'.charCodeAt(0)] ]; - for (let i = 0; i < data.length; ++i) line.push(data[i]); + const line = new BufferLine(data.length); + for (let i = 0; i < data.length; ++i) line.set(i, data[i]); buffer.lines.set(0, line); // Ensure wide characters take up 2 columns selectionManager.selectWordAt([0, 0]); diff --git a/src/Types.ts b/src/Types.ts index 5ea2024a..90e1a531 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -516,10 +516,11 @@ export interface IBufferLine { isWrapped: boolean; get(index: number): CharData; set(index: number, value: CharData): void; - pop(): CharData | undefined; - push(data: CharData): void; - splice(start: number, deleteCount: number, ...items: CharData[]): CharData[]; + // pop(): CharData | undefined; + // push(data: CharData): void; + // splice(start: number, deleteCount: number, ...items: CharData[]): CharData[]; insertCells(pos: number, n: number, ch: CharData): void; deleteCells(pos: number, n: number, fill: CharData): void; replaceCells(start: number, end: number, fill: CharData): void; + resize(cols: number, fill: CharData, shrink?: boolean): void; } diff --git a/src/renderer/CharacterJoinerRegistry.test.ts b/src/renderer/CharacterJoinerRegistry.test.ts index bb7a2c5d..e1981698 100644 --- a/src/renderer/CharacterJoinerRegistry.test.ts +++ b/src/renderer/CharacterJoinerRegistry.test.ts @@ -24,14 +24,18 @@ describe('CharacterJoinerRegistry', () => { lines.set(4, new BufferLine()); lines.set(5, lineData([['a', 0x11111111], [' -> b -> c -> '], ['d', 0x22222222]])); const line6 = lineData([['wi']]); - line6.push([0, '¥', 2, '¥'.charCodeAt(0)]); - line6.push([0, '', 0, null]); + line6.resize(line6.length + 1, [0, '¥', 2, '¥'.charCodeAt(0)]); + line6.resize(line6.length + 1, [0, '', 0, null]); let sub = lineData([['deemo']]); - for (let i = 0; i < sub.length; ++i) line6.push(sub.get(i)); - line6.push([0, '\xf0\x9f\x98\x81', 1, 128513]); - line6.push([0, ' ', 1, ' '.charCodeAt(0)]); + let oldSize = line6.length; + line6.resize(oldSize + sub.length, [0, '', 0, 0]); + for (let i = 0; i < sub.length; ++i) line6.set(i + oldSize, sub.get(i)); + line6.resize(line6.length + 1, [0, '\xf0\x9f\x98\x81', 1, 128513]); + line6.resize(line6.length + 1, [0, ' ', 1, ' '.charCodeAt(0)]); sub = lineData([['jiabc']]); - for (let i = 0; i < sub.length; ++i) line6.push(sub.get(i)); + oldSize = line6.length; + line6.resize(oldSize + sub.length, [0, '', 0, 0]); + for (let i = 0; i < sub.length; ++i) line6.set(i + oldSize, sub.get(i)); lines.set(6, line6); (terminal.buffer).setLines(lines); @@ -264,11 +268,13 @@ describe('CharacterJoinerRegistry', () => { type IPartialLineData = ([string] | [string, number]); function lineData(data: IPartialLineData[]): IBufferLine { - const tline = new BufferLine(); + const tline = new BufferLine(0); for (let i = 0; i < data.length; ++i) { const line = data[i][0]; const attr = (data[i][1] || 0); - line.split('').map(char => tline.push([attr, char, 1, char.charCodeAt(0)])); + const offset = tline.length; + tline.resize(tline.length + line.split('').length, [0, '', 0, 0]); + line.split('').map((char, idx) => tline.set(idx + offset, [attr, char, 1, char.charCodeAt(0)])); } return tline; } diff --git a/src/renderer/dom/DomRendererRowFactory.test.ts b/src/renderer/dom/DomRendererRowFactory.test.ts index 17b1b938..ae180554 100644 --- a/src/renderer/dom/DomRendererRowFactory.test.ts +++ b/src/renderer/dom/DomRendererRowFactory.test.ts @@ -148,9 +148,9 @@ describe('DomRendererRowFactory', () => { } function createEmptyLineData(cols: number): IBufferLine { - const lineData = new BufferLine(); + const lineData = new BufferLine(cols); for (let i = 0; i < cols; i++) { - lineData.push([DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); + lineData.set(i, [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); } return lineData; }