diff --git a/src/Buffer.test.ts b/src/Buffer.test.ts index 82cdff6b..1ef2e92c 100644 --- a/src/Buffer.test.ts +++ b/src/Buffer.test.ts @@ -579,6 +579,20 @@ describe('Buffer', () => { assert.equal(buffer.lines.get(0).translateToString(true), '汉语汉语'); assert.equal(buffer.lines.get(1).translateToString(true), '汉语汉语'); assert.equal(buffer.lines.get(2).translateToString(true), '汉语汉语'); + buffer.resize(8, 10); + assert.equal(buffer.lines.get(0).translateToString(true), '汉语汉语'); + assert.equal(buffer.lines.get(1).translateToString(true), '汉语汉语'); + assert.equal(buffer.lines.get(2).translateToString(true), '汉语汉语'); + buffer.resize(7, 10); + assert.equal(buffer.lines.get(0).translateToString(true), '汉语汉'); + assert.equal(buffer.lines.get(1).translateToString(true), '语汉语'); + assert.equal(buffer.lines.get(2).translateToString(true), '汉语汉'); + assert.equal(buffer.lines.get(3).translateToString(true), '语汉语'); + buffer.resize(6, 10); + assert.equal(buffer.lines.get(0).translateToString(true), '汉语汉'); + assert.equal(buffer.lines.get(1).translateToString(true), '语汉语'); + assert.equal(buffer.lines.get(2).translateToString(true), '汉语汉'); + assert.equal(buffer.lines.get(3).translateToString(true), '语汉语'); }); describe('reflowLarger cases', () => { diff --git a/src/Buffer.ts b/src/Buffer.ts index 5d3c1a52..f534087d 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -9,7 +9,7 @@ import { EventEmitter } from './common/EventEmitter'; import { IMarker } from 'xterm'; import { BufferLine } from './BufferLine'; import { DEFAULT_COLOR } from './renderer/atlas/Types'; -import { reflowSmallerGetLinesNeeded, reflowSmallerGetNewLineLengths } from './BufferReflow'; +import { reflowSmallerGetNewLineLengths } from './BufferReflow'; export const DEFAULT_ATTR = (0 << 18) | (DEFAULT_COLOR << 9) | (256 << 0); export const CHAR_DATA_ATTR_INDEX = 0; @@ -387,18 +387,9 @@ export class Buffer implements IBuffer { wrappedLines.unshift(nextLine); } - - const lastLineLength = wrappedLines[wrappedLines.length - 1].getTrimmedLength(); - const cellsNeeded = (wrappedLines.length - 1) * this._cols + lastLineLength; - // const linesNeeded = reflowSmallerGetLinesNeeded(wrappedLines, this._cols, newCols); const destLineLengths = reflowSmallerGetNewLineLengths(wrappedLines, this._cols, newCols); - console.log(destLineLengths); - const linesNeeded = destLineLengths.length; - - - - const linesToAdd = linesNeeded - wrappedLines.length; + const linesToAdd = destLineLengths.length - wrappedLines.length; let trimmedLines: number; if (this.ybase === 0 && this.y !== this.lines.length - 1) { // If the top section of the buffer is not yet filled diff --git a/src/BufferReflow.ts b/src/BufferReflow.ts index f99acd1c..5e815c7a 100644 --- a/src/BufferReflow.ts +++ b/src/BufferReflow.ts @@ -5,58 +5,6 @@ import { BufferLine } from './BufferLine'; -/** - * Determine how many lines need to be inserted at the end. This is done by finding what each - * wrapping point will be and counting the lines needed This would be a lot simpler but in the case - * of a line ending with a wide character, the wide character needs to be put on the following line - * or it would be cut in half. - * @param wrappedLines The original wrapped lines. - * @param newCols The new column count. - */ -export function reflowSmallerGetLinesNeeded(wrappedLines: BufferLine[], oldCols: number, newCols: number): number { - const lastLineLength = wrappedLines[wrappedLines.length - 1].getTrimmedLength(); - // const cellsNeeded = (wrappedLines.length - 1) * this._cols + lastLineLength; - - // TODO: Make faster - const cellsNeeded = wrappedLines.map(l => l.getTrimmedLength()).reduce((p, c) => p + c); - - // Lines needed needs to take into account what the ending character of each new line is - let linesNeeded = 0; - let cellsAvailable = 0; - // let currentCol = 0; - - // Use srcCol and srcLine to find the new wrapping point, use that to get the cellsAvailable and - // linesNeeded - let srcCol = -1; - let srcLine = 0; - while (cellsAvailable < cellsNeeded) { - // if (srcLine === wrappedLines.length - 1) { - // cellsAvailable += newCols; - // linesNeeded++; - // break; - // } - - srcCol += newCols; - if (srcCol >= oldCols) { - srcCol -= oldCols; - srcLine++; - } - if (srcLine >= wrappedLines.length) { - linesNeeded++; - break; - } - const endsWithWide = wrappedLines[srcLine].getWidth(srcCol) === 2; - if (endsWithWide) { - srcCol--; - } - cellsAvailable += endsWithWide ? newCols - 1 : newCols; - linesNeeded++; - } - - return linesNeeded; - // return Math.ceil(cellsNeeded / newCols); -} - /** * Gets the new line lengths for a given wrapped line. The purpose of this function it to pre- * compute the wrapping points since wide characters may need to be wrapped onto the following line. @@ -74,8 +22,6 @@ export function reflowSmallerGetLinesNeeded(wrappedLines: BufferLine[], oldCols: export function reflowSmallerGetNewLineLengths(wrappedLines: BufferLine[], oldCols: number, newCols: number): number[] { const newLineLengths: number[] = []; - // TODO: Force cols = 2 to be minimum possible value, this will lock up - const cellsNeeded = wrappedLines.map(l => l.getTrimmedLength()).reduce((p, c) => p + c); // Use srcCol and srcLine to find the new wrapping point, use that to get the cellsAvailable and diff --git a/src/Terminal.ts b/src/Terminal.ts index 4c0cd0f8..8a5d96ba 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -69,6 +69,9 @@ const WRITE_BUFFER_PAUSE_THRESHOLD = 5; */ const WRITE_BATCH_SIZE = 300; +const MINIMUM_COLS = 2; // Less than 2 can mess with wide chars +const MINIMUM_ROWS = 1; + /** * The set of options that only have an effect when set in the Terminal constructor. */ @@ -262,8 +265,8 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II // TODO: WHy not document.body? this._parent = document ? document.body : null; - this.cols = this.options.cols; - this.rows = this.options.rows; + this.cols = Math.max(this.options.cols, MINIMUM_COLS); + this.rows = Math.max(this.options.rows, MINIMUM_ROWS); if (this.options.handler) { this.on('data', this.options.handler); @@ -1691,8 +1694,8 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II return; } - if (x < 1) x = 1; - if (y < 1) y = 1; + if (x < MINIMUM_COLS) x = MINIMUM_COLS; + if (y < MINIMUM_ROWS) y = MINIMUM_ROWS; this.buffers.resize(x, y);