From df7cd9c319f42aaff3b3e79ef45a19ebda0cf719 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 23 Jan 2019 22:40:40 -0800 Subject: [PATCH] Get reflow smaller working for wide chars --- src/Buffer.test.ts | 4 ++-- src/Buffer.ts | 9 ++++++++- src/BufferReflow.test.ts | 13 +++++++++++++ src/BufferReflow.ts | 17 +++++++++-------- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/Buffer.test.ts b/src/Buffer.test.ts index 8e1a2f60..82cdff6b 100644 --- a/src/Buffer.test.ts +++ b/src/Buffer.test.ts @@ -568,8 +568,8 @@ describe('Buffer', () => { buffer.resize(11, 10); assert.equal(buffer.ybase, 0); assert.equal(buffer.lines.length, 10); - assert.equal(buffer.lines.get(0).translateToString(true), '汉语汉语汉', '1'); - assert.equal(buffer.lines.get(1).translateToString(true), '语汉语汉语', '2'); + 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(10, 10); assert.equal(buffer.lines.get(0).translateToString(true), '汉语汉语汉'); diff --git a/src/Buffer.ts b/src/Buffer.ts index 30941324..5d3c1a52 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -429,7 +429,7 @@ export class Buffer implements IBuffer { let destCol = destLineLengths[destLineIndex]; // cellsNeeded % newCols; if (destCol === 0) { destLineIndex--; - destCol = newCols; + destCol = destLineLengths[destLineIndex]; } let srcLineIndex = wrappedLines.length - linesToAdd - 1; let srcCol = lastLineLength; @@ -449,6 +449,13 @@ export class Buffer implements IBuffer { } } + // Null out the end of the line ends if a wide character wrapped to the following line + for (let i = 0; i < wrappedLines.length; i++) { + if (destLineLengths[i] < newCols) { + wrappedLines[i].set(destLineLengths[i], FILL_CHAR_DATA); + } + } + // Adjust viewport as needed let viewportAdjustments = linesToAdd - trimmedLines; while (viewportAdjustments-- > 0) { diff --git a/src/BufferReflow.test.ts b/src/BufferReflow.test.ts index a788fbc8..9c978dc0 100644 --- a/src/BufferReflow.test.ts +++ b/src/BufferReflow.test.ts @@ -5,6 +5,7 @@ import { assert } from 'chai'; import { BufferLine } from './BufferLine'; import { reflowSmallerGetNewLineLengths } from './BufferReflow'; +import { NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE } from './Buffer'; describe('BufferReflow', () => { describe('reflowSmallerGetNewLineLengths', () => { @@ -76,5 +77,17 @@ describe('BufferReflow', () => { assert.deepEqual(reflowSmallerGetNewLineLengths([line1, line2], 6, 3), [3, 3, 3, 3], 'lines: a汉, 语b, a汉, 语b'); assert.deepEqual(reflowSmallerGetNewLineLengths([line1, line2], 6, 2), [1, 2, 2, 2, 2, 2, 1], 'lines: a, 汉, 语, ba, 汉, 语, b'); }); + it('should work on lines ending in null space', () => { + const line = new BufferLine(5); + line.set(0, [null, '汉', 2, '汉'.charCodeAt(0)]); + line.set(1, [null, '', 0, undefined]); + line.set(2, [null, '语', 2, '语'.charCodeAt(0)]); + line.set(3, [null, '', 0, undefined]); + line.set(4, [null, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); + assert.equal(line.translateToString(true), '汉语'); + assert.equal(line.translateToString(false), '汉语 '); + assert.deepEqual(reflowSmallerGetNewLineLengths([line], 4, 3), [2, 2], 'line: 汉, 语'); + assert.deepEqual(reflowSmallerGetNewLineLengths([line], 4, 2), [2, 2], 'line: 汉, 语'); + }); }); }); diff --git a/src/BufferReflow.ts b/src/BufferReflow.ts index f56d48c5..f99acd1c 100644 --- a/src/BufferReflow.ts +++ b/src/BufferReflow.ts @@ -80,21 +80,22 @@ export function reflowSmallerGetNewLineLengths(wrappedLines: BufferLine[], oldCo // Use srcCol and srcLine to find the new wrapping point, use that to get the cellsAvailable and // linesNeeded - let srcCol = -1; + let srcCol = 0; let srcLine = 0; let cellsAvailable = 0; while (cellsAvailable < cellsNeeded) { - srcCol += newCols; - if (srcCol >= oldCols) { - srcCol -= oldCols; - srcLine++; - } - if (srcLine >= wrappedLines.length) { + if (cellsNeeded - cellsAvailable < newCols) { // Add the final line and exit the loop newLineLengths.push(cellsNeeded - cellsAvailable); break; } - const endsWithWide = wrappedLines[srcLine].getWidth(srcCol) === 2; + srcCol += newCols; + const oldTrimmedLength = wrappedLines[srcLine].getTrimmedLength(); + if (srcCol > oldTrimmedLength) { + srcCol -= oldTrimmedLength; + srcLine++; + } + const endsWithWide = wrappedLines[srcLine].getWidth(srcCol - 1) === 2; if (endsWithWide) { srcCol--; }