Merge branch 'master' into master
This commit is contained in:
+3
-4
@@ -508,11 +508,10 @@ describe('Buffer', () => {
|
||||
// the dangling last cell is wrongly added in the string
|
||||
// --> fixable after resolving #1685
|
||||
terminal.writeSync(input);
|
||||
// TODO: reenable after fix
|
||||
// const s = terminal.buffer.contents(true).toArray()[0];
|
||||
// assert.equal(input, s);
|
||||
const s = terminal.buffer.iterator(true).next().content;
|
||||
assert.equal(input, s);
|
||||
for (let i = 10; i < input.length; ++i) {
|
||||
const bufferIndex = terminal.buffer.stringIndexToBufferIndex(0, i + 1); // TODO: remove +1 after fix
|
||||
const bufferIndex = terminal.buffer.stringIndexToBufferIndex(0, i);
|
||||
const j = (i - 0) << 1;
|
||||
assert.deepEqual([(j / terminal.cols) | 0, j % terminal.cols], bufferIndex);
|
||||
}
|
||||
|
||||
+8
-58
@@ -17,9 +17,13 @@ export const CHAR_DATA_WIDTH_INDEX = 2;
|
||||
export const CHAR_DATA_CODE_INDEX = 3;
|
||||
export const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1
|
||||
|
||||
export const NULL_CELL_CHAR = ' ';
|
||||
export const NULL_CELL_CHAR = '';
|
||||
export const NULL_CELL_WIDTH = 1;
|
||||
export const NULL_CELL_CODE = 32;
|
||||
export const NULL_CELL_CODE = 0;
|
||||
|
||||
export const WHITESPACE_CELL_CHAR = ' ';
|
||||
export const WHITESPACE_CELL_WIDTH = 1;
|
||||
export const WHITESPACE_CELL_CODE = 32;
|
||||
|
||||
/**
|
||||
* This class represents a terminal buffer (an internal state of the terminal), where the
|
||||
@@ -272,64 +276,11 @@ export class Buffer implements IBuffer {
|
||||
* @param endCol The column to end at.
|
||||
*/
|
||||
public translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol: number = 0, endCol: number = null): string {
|
||||
// Get full line
|
||||
let lineString = '';
|
||||
const line = this.lines.get(lineIndex);
|
||||
if (!line) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Initialize column and index values. Column values represent the actual
|
||||
// cell column, indexes represent the index in the string. Indexes are
|
||||
// needed here because some chars are 0 characters long (eg. after wide
|
||||
// chars) and some chars are longer than 1 characters long (eg. emojis).
|
||||
let startIndex = startCol;
|
||||
// Only set endCol to the line length when it is null. 0 is a valid column.
|
||||
if (endCol === null) {
|
||||
endCol = line.length;
|
||||
}
|
||||
let endIndex = endCol;
|
||||
|
||||
for (let i = 0; i < line.length; i++) {
|
||||
const char = line.get(i);
|
||||
lineString += char[CHAR_DATA_CHAR_INDEX];
|
||||
// Adjust start and end cols for wide characters if they affect their
|
||||
// column indexes
|
||||
if (char[CHAR_DATA_WIDTH_INDEX] === 0) {
|
||||
if (startCol >= i) {
|
||||
startIndex--;
|
||||
}
|
||||
if (endCol > i) {
|
||||
endIndex--;
|
||||
}
|
||||
} else {
|
||||
// Adjust the columns to take glyphs that are represented by multiple
|
||||
// code points into account.
|
||||
if (char[CHAR_DATA_CHAR_INDEX].length > 1) {
|
||||
if (startCol > i) {
|
||||
startIndex += char[CHAR_DATA_CHAR_INDEX].length - 1;
|
||||
}
|
||||
if (endCol > i) {
|
||||
endIndex += char[CHAR_DATA_CHAR_INDEX].length - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the final end col by trimming whitespace on the right of the
|
||||
// line if needed.
|
||||
if (trimRight) {
|
||||
const rightWhitespaceIndex = lineString.search(/\s+$/);
|
||||
if (rightWhitespaceIndex !== -1) {
|
||||
endIndex = Math.min(endIndex, rightWhitespaceIndex);
|
||||
}
|
||||
// Return the empty string if only trimmed whitespace is selected
|
||||
if (endIndex <= startIndex) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
return lineString.substring(startIndex, endIndex);
|
||||
return line.translateToString(trimRight, startCol, endCol);
|
||||
}
|
||||
|
||||
public getWrappedRangeForLine(y: number): { first: number, last: number } {
|
||||
@@ -488,8 +439,7 @@ export class BufferStringIterator implements IBufferStringIterator {
|
||||
range.last = Math.min(range.last, this._buffer.lines.length);
|
||||
let result = '';
|
||||
for (let i = range.first; i <= range.last; ++i) {
|
||||
// TODO: always apply trimRight after fixing #1685
|
||||
result += this._buffer.translateBufferLineToString(i, (this._trimRight) ? i === range.last : false);
|
||||
result += this._buffer.translateBufferLineToString(i, this._trimRight);
|
||||
}
|
||||
this._current = range.last + 1;
|
||||
return {range: range, content: result};
|
||||
|
||||
+127
-1
@@ -5,7 +5,7 @@
|
||||
import * as chai from 'chai';
|
||||
import { BufferLine } from './BufferLine';
|
||||
import { CharData, IBufferLine } from './Types';
|
||||
import { NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE } from './Buffer';
|
||||
import { NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE, DEFAULT_ATTR } from './Buffer';
|
||||
|
||||
|
||||
class TestBufferLine extends BufferLine {
|
||||
@@ -200,4 +200,130 @@ describe('BufferLine', function(): void {
|
||||
chai.expect(line.toArray()).eql(Array(7).fill([1, 'a', 0, 'a'.charCodeAt(0)]));
|
||||
});
|
||||
});
|
||||
describe('getTrimLength', function(): void {
|
||||
it('empty line', function(): void {
|
||||
const line = new TestBufferLine(10, [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE], false);
|
||||
chai.expect(line.getTrimmedLength()).equal(0);
|
||||
});
|
||||
it('ASCII', function(): void {
|
||||
const line = new TestBufferLine(10, [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE], false);
|
||||
line.set(0, [1, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
line.set(2, [1, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
chai.expect(line.getTrimmedLength()).equal(3);
|
||||
});
|
||||
it('surrogate', function(): void {
|
||||
const line = new TestBufferLine(10, [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE], false);
|
||||
line.set(0, [1, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
line.set(2, [1, '𝄞', 1, '𝄞'.charCodeAt(0)]);
|
||||
chai.expect(line.getTrimmedLength()).equal(3);
|
||||
});
|
||||
it('combining', function(): void {
|
||||
const line = new TestBufferLine(10, [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE], false);
|
||||
line.set(0, [1, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
line.set(2, [1, 'e\u0301', 1, '\u0301'.charCodeAt(0)]);
|
||||
chai.expect(line.getTrimmedLength()).equal(3);
|
||||
});
|
||||
it('fullwidth', function(): void {
|
||||
const line = new TestBufferLine(10, [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE], false);
|
||||
line.set(0, [1, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
line.set(2, [1, '1', 2, '1'.charCodeAt(0)]);
|
||||
line.set(3, [0, '', 0, undefined]);
|
||||
chai.expect(line.getTrimmedLength()).equal(4); // also counts null cell after fullwidth
|
||||
});
|
||||
});
|
||||
describe('translateToString with and w\'o trimming', function(): void {
|
||||
it('empty line', function(): void {
|
||||
const line = new TestBufferLine(10, [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE], false);
|
||||
chai.expect(line.translateToString(false)).equal(' ');
|
||||
chai.expect(line.translateToString(true)).equal('');
|
||||
});
|
||||
it('ASCII', function(): void {
|
||||
const line = new TestBufferLine(10, [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE], false);
|
||||
line.set(0, [1, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
line.set(2, [1, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
line.set(4, [1, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
line.set(5, [1, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
chai.expect(line.translateToString(false)).equal('a a aa ');
|
||||
chai.expect(line.translateToString(true)).equal('a a aa');
|
||||
chai.expect(line.translateToString(false, 0, 5)).equal('a a a');
|
||||
chai.expect(line.translateToString(false, 0, 4)).equal('a a ');
|
||||
chai.expect(line.translateToString(false, 0, 3)).equal('a a');
|
||||
chai.expect(line.translateToString(true, 0, 5)).equal('a a a');
|
||||
chai.expect(line.translateToString(true, 0, 4)).equal('a a ');
|
||||
chai.expect(line.translateToString(true, 0, 3)).equal('a a');
|
||||
|
||||
});
|
||||
it('surrogate', function(): void {
|
||||
const line = new TestBufferLine(10, [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE], false);
|
||||
line.set(0, [1, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
line.set(2, [1, '𝄞', 1, '𝄞'.charCodeAt(0)]);
|
||||
line.set(4, [1, '𝄞', 1, '𝄞'.charCodeAt(0)]);
|
||||
line.set(5, [1, '𝄞', 1, '𝄞'.charCodeAt(0)]);
|
||||
chai.expect(line.translateToString(false)).equal('a 𝄞 𝄞𝄞 ');
|
||||
chai.expect(line.translateToString(true)).equal('a 𝄞 𝄞𝄞');
|
||||
chai.expect(line.translateToString(false, 0, 5)).equal('a 𝄞 𝄞');
|
||||
chai.expect(line.translateToString(false, 0, 4)).equal('a 𝄞 ');
|
||||
chai.expect(line.translateToString(false, 0, 3)).equal('a 𝄞');
|
||||
chai.expect(line.translateToString(true, 0, 5)).equal('a 𝄞 𝄞');
|
||||
chai.expect(line.translateToString(true, 0, 4)).equal('a 𝄞 ');
|
||||
chai.expect(line.translateToString(true, 0, 3)).equal('a 𝄞');
|
||||
});
|
||||
it('combining', function(): void {
|
||||
const line = new TestBufferLine(10, [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE], false);
|
||||
line.set(0, [1, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
line.set(2, [1, 'e\u0301', 1, '\u0301'.charCodeAt(0)]);
|
||||
line.set(4, [1, 'e\u0301', 1, '\u0301'.charCodeAt(0)]);
|
||||
line.set(5, [1, 'e\u0301', 1, '\u0301'.charCodeAt(0)]);
|
||||
chai.expect(line.translateToString(false)).equal('a e\u0301 e\u0301e\u0301 ');
|
||||
chai.expect(line.translateToString(true)).equal('a e\u0301 e\u0301e\u0301');
|
||||
chai.expect(line.translateToString(false, 0, 5)).equal('a e\u0301 e\u0301');
|
||||
chai.expect(line.translateToString(false, 0, 4)).equal('a e\u0301 ');
|
||||
chai.expect(line.translateToString(false, 0, 3)).equal('a e\u0301');
|
||||
chai.expect(line.translateToString(true, 0, 5)).equal('a e\u0301 e\u0301');
|
||||
chai.expect(line.translateToString(true, 0, 4)).equal('a e\u0301 ');
|
||||
chai.expect(line.translateToString(true, 0, 3)).equal('a e\u0301');
|
||||
});
|
||||
it('fullwidth', function(): void {
|
||||
const line = new TestBufferLine(10, [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE], false);
|
||||
line.set(0, [1, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
line.set(2, [1, '1', 2, '1'.charCodeAt(0)]);
|
||||
line.set(3, [0, '', 0, undefined]);
|
||||
line.set(5, [1, '1', 2, '1'.charCodeAt(0)]);
|
||||
line.set(6, [0, '', 0, undefined]);
|
||||
line.set(7, [1, '1', 2, '1'.charCodeAt(0)]);
|
||||
line.set(8, [0, '', 0, undefined]);
|
||||
chai.expect(line.translateToString(false)).equal('a 1 11 ');
|
||||
chai.expect(line.translateToString(true)).equal('a 1 11');
|
||||
chai.expect(line.translateToString(false, 0, 7)).equal('a 1 1');
|
||||
chai.expect(line.translateToString(false, 0, 6)).equal('a 1 1');
|
||||
chai.expect(line.translateToString(false, 0, 5)).equal('a 1 ');
|
||||
chai.expect(line.translateToString(false, 0, 4)).equal('a 1');
|
||||
chai.expect(line.translateToString(false, 0, 3)).equal('a 1');
|
||||
chai.expect(line.translateToString(false, 0, 2)).equal('a ');
|
||||
chai.expect(line.translateToString(true, 0, 7)).equal('a 1 1');
|
||||
chai.expect(line.translateToString(true, 0, 6)).equal('a 1 1');
|
||||
chai.expect(line.translateToString(true, 0, 5)).equal('a 1 ');
|
||||
chai.expect(line.translateToString(true, 0, 4)).equal('a 1');
|
||||
chai.expect(line.translateToString(true, 0, 3)).equal('a 1');
|
||||
chai.expect(line.translateToString(true, 0, 2)).equal('a ');
|
||||
});
|
||||
it('space at end', function(): void {
|
||||
const line = new TestBufferLine(10, [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE], false);
|
||||
line.set(0, [1, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
line.set(2, [1, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
line.set(4, [1, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
line.set(5, [1, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
line.set(6, [1, ' ', 1, ' '.charCodeAt(0)]);
|
||||
chai.expect(line.translateToString(false)).equal('a a aa ');
|
||||
chai.expect(line.translateToString(true)).equal('a a aa ');
|
||||
});
|
||||
it('should always return some sane value', function(): void {
|
||||
// sanity check - broken line with invalid out of bound null width cells
|
||||
// this can atm happen with deleting/inserting chars in inputhandler by "breaking"
|
||||
// fullwidth pairs --> needs to be fixed after settling BufferLine impl
|
||||
const line = new TestBufferLine(10, [DEFAULT_ATTR, NULL_CELL_CHAR, 0, NULL_CELL_CODE], false);
|
||||
chai.expect(line.translateToString(false)).equal(' ');
|
||||
chai.expect(line.translateToString(true)).equal('');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+53
-4
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
import { CharData, IBufferLine } from './Types';
|
||||
import { NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR } from './Buffer';
|
||||
import { NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, WHITESPACE_CELL_CHAR } from './Buffer';
|
||||
|
||||
/**
|
||||
* Class representing a terminal line.
|
||||
@@ -107,6 +107,29 @@ export class BufferLineJSArray implements IBufferLine {
|
||||
newLine.copyFrom(this);
|
||||
return newLine;
|
||||
}
|
||||
|
||||
public getTrimmedLength(): number {
|
||||
for (let i = this.length - 1; i >= 0; --i) {
|
||||
const ch = this.get(i);
|
||||
if (ch[CHAR_DATA_CHAR_INDEX] !== '') {
|
||||
return i + ch[CHAR_DATA_WIDTH_INDEX];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public translateToString(trimRight: boolean = false, startCol: number = 0, endCol: number = null): string {
|
||||
let length = endCol || this.length;
|
||||
if (trimRight) {
|
||||
length = Math.min(length, this.getTrimmedLength());
|
||||
}
|
||||
let result = '';
|
||||
while (startCol < length) {
|
||||
result += this.get(startCol)[CHAR_DATA_CHAR_INDEX] || WHITESPACE_CELL_CHAR;
|
||||
startCol += this.get(startCol)[CHAR_DATA_WIDTH_INDEX] || 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/** typed array slots taken by one cell */
|
||||
@@ -119,6 +142,9 @@ const enum Cell {
|
||||
WIDTH = 2
|
||||
}
|
||||
|
||||
/** single vs. combined char distinction */
|
||||
const IS_COMBINED_BIT_MASK = 0x80000000;
|
||||
|
||||
/**
|
||||
* Typed array based bufferline implementation.
|
||||
*/
|
||||
@@ -144,11 +170,11 @@ export class BufferLine implements IBufferLine {
|
||||
const stringData = this._data[index * CELL_SIZE + Cell.STRING];
|
||||
return [
|
||||
this._data[index * CELL_SIZE + Cell.FLAGS],
|
||||
(stringData & 0x80000000)
|
||||
(stringData & IS_COMBINED_BIT_MASK)
|
||||
? this._combined[index]
|
||||
: (stringData) ? String.fromCharCode(stringData) : '',
|
||||
this._data[index * CELL_SIZE + Cell.WIDTH],
|
||||
(stringData & 0x80000000)
|
||||
(stringData & IS_COMBINED_BIT_MASK)
|
||||
? this._combined[index].charCodeAt(this._combined[index].length - 1)
|
||||
: stringData
|
||||
];
|
||||
@@ -158,7 +184,7 @@ export class BufferLine implements IBufferLine {
|
||||
this._data[index * CELL_SIZE + Cell.FLAGS] = value[0];
|
||||
if (value[1].length > 1) {
|
||||
this._combined[index] = value[1];
|
||||
this._data[index * CELL_SIZE + Cell.STRING] = index | 0x80000000;
|
||||
this._data[index * CELL_SIZE + Cell.STRING] = index | IS_COMBINED_BIT_MASK;
|
||||
} else {
|
||||
this._data[index * CELL_SIZE + Cell.STRING] = value[1].charCodeAt(0);
|
||||
}
|
||||
@@ -269,4 +295,27 @@ export class BufferLine implements IBufferLine {
|
||||
newLine.isWrapped = this.isWrapped;
|
||||
return newLine;
|
||||
}
|
||||
|
||||
public getTrimmedLength(): number {
|
||||
for (let i = this.length - 1; i >= 0; --i) {
|
||||
if (this._data[i * CELL_SIZE + Cell.STRING] !== 0) { // 0 ==> ''.charCodeAt(0) ==> NaN ==> 0
|
||||
return i + this._data[i * CELL_SIZE + Cell.WIDTH];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public translateToString(trimRight: boolean = false, startCol: number = 0, endCol: number = null): string {
|
||||
let length = endCol || this.length;
|
||||
if (trimRight) {
|
||||
length = Math.min(length, this.getTrimmedLength());
|
||||
}
|
||||
let result = '';
|
||||
while (startCol < length) {
|
||||
const stringData = this._data[startCol * CELL_SIZE + Cell.STRING];
|
||||
result += (stringData & IS_COMBINED_BIT_MASK) ? this._combined[startCol] : (stringData) ? String.fromCharCode(stringData) : WHITESPACE_CELL_CHAR;
|
||||
startCol += this._data[startCol * CELL_SIZE + Cell.WIDTH] || 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
+137
-309
@@ -6,130 +6,10 @@
|
||||
import { assert, expect } from 'chai';
|
||||
import { InputHandler } from './InputHandler';
|
||||
import { MockInputHandlingTerminal } from './ui/TestUtils.test';
|
||||
import { NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, CHAR_DATA_CHAR_INDEX, CHAR_DATA_ATTR_INDEX, DEFAULT_ATTR } from './Buffer';
|
||||
import { CHAR_DATA_ATTR_INDEX, DEFAULT_ATTR } from './Buffer';
|
||||
import { Terminal } from './Terminal';
|
||||
import { IBufferLine } from './Types';
|
||||
|
||||
|
||||
// TODO: This and the sections related to this object in associated tests can be
|
||||
// removed safely after InputHandler refactors are finished
|
||||
class OldInputHandler extends InputHandler {
|
||||
public eraseInLine(params: number[]): void {
|
||||
switch (params[0]) {
|
||||
case 0:
|
||||
this.eraseRight(this._terminal.buffer.x, this._terminal.buffer.y);
|
||||
break;
|
||||
case 1:
|
||||
this.eraseLeft(this._terminal.buffer.x, this._terminal.buffer.y);
|
||||
break;
|
||||
case 2:
|
||||
this.eraseLine(this._terminal.buffer.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public eraseInDisplay(params: number[]): void {
|
||||
let j;
|
||||
switch (params[0]) {
|
||||
case 0:
|
||||
this.eraseRight(this._terminal.buffer.x, this._terminal.buffer.y);
|
||||
j = this._terminal.buffer.y + 1;
|
||||
for (; j < this._terminal.rows; j++) {
|
||||
this.eraseLine(j);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
this.eraseLeft(this._terminal.buffer.x, this._terminal.buffer.y);
|
||||
j = this._terminal.buffer.y;
|
||||
while (j--) {
|
||||
this.eraseLine(j);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
j = this._terminal.rows;
|
||||
while (j--) this.eraseLine(j);
|
||||
break;
|
||||
case 3:
|
||||
// Clear scrollback (everything not in viewport)
|
||||
const scrollBackSize = this._terminal.buffer.lines.length - this._terminal.rows;
|
||||
if (scrollBackSize > 0) {
|
||||
this._terminal.buffer.lines.trimStart(scrollBackSize);
|
||||
this._terminal.buffer.ybase = Math.max(this._terminal.buffer.ybase - scrollBackSize, 0);
|
||||
this._terminal.buffer.ydisp = Math.max(this._terminal.buffer.ydisp - scrollBackSize, 0);
|
||||
// Force a scroll event to refresh viewport
|
||||
this._terminal.emit('scroll', 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Erase in the identified line everything from "x" to the end of the line (right).
|
||||
* @param x The column from which to start erasing to the end of the line.
|
||||
* @param y The line in which to operate.
|
||||
*/
|
||||
public eraseRight(x: number, y: number): void {
|
||||
const line = this._terminal.buffer.lines.get(this._terminal.buffer.ybase + y);
|
||||
if (!line) {
|
||||
return;
|
||||
}
|
||||
line.replaceCells(x, this._terminal.cols, [this._terminal.eraseAttr(), NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);
|
||||
this._terminal.updateRange(y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erase in the identified line everything from "x" to the start of the line (left).
|
||||
* @param x The column from which to start erasing to the start of the line.
|
||||
* @param y The line in which to operate.
|
||||
*/
|
||||
public eraseLeft(x: number, y: number): void {
|
||||
const line = this._terminal.buffer.lines.get(this._terminal.buffer.ybase + y);
|
||||
if (!line) {
|
||||
return;
|
||||
}
|
||||
line.replaceCells(0, x + 1, [this._terminal.eraseAttr(), NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);
|
||||
this._terminal.updateRange(y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erase all content in the given line
|
||||
* @param y The line to erase all of its contents.
|
||||
*/
|
||||
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', () => {
|
||||
describe('save and restore cursor', () => {
|
||||
const terminal = new MockInputHandlingTerminal();
|
||||
@@ -208,296 +88,250 @@ describe('InputHandler', () => {
|
||||
});
|
||||
});
|
||||
describe('regression tests', function(): void {
|
||||
function lineContent(line: IBufferLine): string {
|
||||
let content = '';
|
||||
for (let i = 0; i < line.length; ++i) content += line.get(i)[CHAR_DATA_CHAR_INDEX];
|
||||
return content;
|
||||
}
|
||||
|
||||
function termContent(term: Terminal): string[] {
|
||||
function termContent(term: Terminal, trim: boolean): string[] {
|
||||
const result = [];
|
||||
for (let i = 0; i < term.rows; ++i) result.push(lineContent(term.buffer.lines.get(i)));
|
||||
for (let i = 0; i < term.rows; ++i) result.push(term.buffer.lines.get(i).translateToString(trim));
|
||||
return result;
|
||||
}
|
||||
|
||||
it('insertChars', function(): void {
|
||||
const term = new Terminal();
|
||||
const inputHandler = new InputHandler(term);
|
||||
const oldInputHandler = new OldInputHandler(term);
|
||||
|
||||
// insert some data in first and second line
|
||||
inputHandler.parse(Array(term.cols - 9).join('a'));
|
||||
inputHandler.parse('1234567890');
|
||||
inputHandler.parse(Array(term.cols - 9).join('a'));
|
||||
inputHandler.parse('1234567890');
|
||||
const line1: IBufferLine = term.buffer.lines.get(0); // line for old variant
|
||||
const line2: IBufferLine = term.buffer.lines.get(1); // line for new variant
|
||||
expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + '1234567890');
|
||||
expect(lineContent(line2)).equals(Array(term.cols - 9).join('a') + '1234567890');
|
||||
const line1: IBufferLine = term.buffer.lines.get(0);
|
||||
expect(line1.translateToString(false)).equals(Array(term.cols - 9).join('a') + '1234567890');
|
||||
|
||||
// insert one char from params = [0]
|
||||
term.buffer.y = 0;
|
||||
term.buffer.x = 70;
|
||||
oldInputHandler.insertChars([0]);
|
||||
expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + ' 123456789');
|
||||
term.buffer.y = 1;
|
||||
term.buffer.x = 70;
|
||||
inputHandler.insertChars([0]);
|
||||
expect(lineContent(line2)).equals(Array(term.cols - 9).join('a') + ' 123456789');
|
||||
expect(lineContent(line2)).equals(lineContent(line1));
|
||||
expect(line1.translateToString(false)).equals(Array(term.cols - 9).join('a') + ' 123456789');
|
||||
|
||||
// insert one char from params = [1]
|
||||
term.buffer.y = 0;
|
||||
term.buffer.x = 70;
|
||||
oldInputHandler.insertChars([1]);
|
||||
expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + ' 12345678');
|
||||
term.buffer.y = 1;
|
||||
term.buffer.x = 70;
|
||||
inputHandler.insertChars([1]);
|
||||
expect(lineContent(line2)).equals(Array(term.cols - 9).join('a') + ' 12345678');
|
||||
expect(lineContent(line2)).equals(lineContent(line1));
|
||||
expect(line1.translateToString(false)).equals(Array(term.cols - 9).join('a') + ' 12345678');
|
||||
|
||||
// insert two chars from params = [2]
|
||||
term.buffer.y = 0;
|
||||
term.buffer.x = 70;
|
||||
oldInputHandler.insertChars([2]);
|
||||
expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + ' 123456');
|
||||
term.buffer.y = 1;
|
||||
term.buffer.x = 70;
|
||||
inputHandler.insertChars([2]);
|
||||
expect(lineContent(line2)).equals(Array(term.cols - 9).join('a') + ' 123456');
|
||||
expect(lineContent(line2)).equals(lineContent(line1));
|
||||
expect(line1.translateToString(false)).equals(Array(term.cols - 9).join('a') + ' 123456');
|
||||
|
||||
// insert 10 chars from params = [10]
|
||||
term.buffer.y = 0;
|
||||
term.buffer.x = 70;
|
||||
oldInputHandler.insertChars([10]);
|
||||
expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + ' ');
|
||||
term.buffer.y = 1;
|
||||
term.buffer.x = 70;
|
||||
inputHandler.insertChars([10]);
|
||||
expect(lineContent(line2)).equals(Array(term.cols - 9).join('a') + ' ');
|
||||
expect(lineContent(line2)).equals(lineContent(line1));
|
||||
expect(line1.translateToString(false)).equals(Array(term.cols - 9).join('a') + ' ');
|
||||
expect(line1.translateToString(true)).equals(Array(term.cols - 9).join('a'));
|
||||
});
|
||||
it('deleteChars', function(): void {
|
||||
const term = new Terminal();
|
||||
const inputHandler = new InputHandler(term);
|
||||
const oldInputHandler = new OldInputHandler(term);
|
||||
|
||||
// insert some data in first and second line
|
||||
inputHandler.parse(Array(term.cols - 9).join('a'));
|
||||
inputHandler.parse('1234567890');
|
||||
inputHandler.parse(Array(term.cols - 9).join('a'));
|
||||
inputHandler.parse('1234567890');
|
||||
const line1: IBufferLine = term.buffer.lines.get(0); // line for old variant
|
||||
const line2: IBufferLine = term.buffer.lines.get(1); // line for new variant
|
||||
expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + '1234567890');
|
||||
expect(lineContent(line2)).equals(Array(term.cols - 9).join('a') + '1234567890');
|
||||
const line1: IBufferLine = term.buffer.lines.get(0);
|
||||
expect(line1.translateToString(false)).equals(Array(term.cols - 9).join('a') + '1234567890');
|
||||
|
||||
// delete one char from params = [0]
|
||||
term.buffer.y = 0;
|
||||
term.buffer.x = 70;
|
||||
oldInputHandler.deleteChars([0]);
|
||||
expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + '234567890 ');
|
||||
term.buffer.y = 1;
|
||||
term.buffer.x = 70;
|
||||
inputHandler.deleteChars([0]);
|
||||
expect(lineContent(line2)).equals(Array(term.cols - 9).join('a') + '234567890 ');
|
||||
expect(lineContent(line2)).equals(lineContent(line1));
|
||||
expect(line1.translateToString(false)).equals(Array(term.cols - 9).join('a') + '234567890 ');
|
||||
expect(line1.translateToString(true)).equals(Array(term.cols - 9).join('a') + '234567890');
|
||||
|
||||
// insert one char from params = [1]
|
||||
term.buffer.y = 0;
|
||||
term.buffer.x = 70;
|
||||
oldInputHandler.deleteChars([1]);
|
||||
expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + '34567890 ');
|
||||
term.buffer.y = 1;
|
||||
term.buffer.x = 70;
|
||||
inputHandler.deleteChars([1]);
|
||||
expect(lineContent(line2)).equals(Array(term.cols - 9).join('a') + '34567890 ');
|
||||
expect(lineContent(line2)).equals(lineContent(line1));
|
||||
expect(line1.translateToString(false)).equals(Array(term.cols - 9).join('a') + '34567890 ');
|
||||
expect(line1.translateToString(true)).equals(Array(term.cols - 9).join('a') + '34567890');
|
||||
|
||||
// insert two chars from params = [2]
|
||||
term.buffer.y = 0;
|
||||
term.buffer.x = 70;
|
||||
oldInputHandler.deleteChars([2]);
|
||||
expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + '567890 ');
|
||||
term.buffer.y = 1;
|
||||
term.buffer.x = 70;
|
||||
inputHandler.deleteChars([2]);
|
||||
expect(lineContent(line2)).equals(Array(term.cols - 9).join('a') + '567890 ');
|
||||
expect(lineContent(line2)).equals(lineContent(line1));
|
||||
expect(line1.translateToString(false)).equals(Array(term.cols - 9).join('a') + '567890 ');
|
||||
expect(line1.translateToString(true)).equals(Array(term.cols - 9).join('a') + '567890');
|
||||
|
||||
// insert 10 chars from params = [10]
|
||||
term.buffer.y = 0;
|
||||
term.buffer.x = 70;
|
||||
oldInputHandler.deleteChars([10]);
|
||||
expect(lineContent(line1)).equals(Array(term.cols - 9).join('a') + ' ');
|
||||
term.buffer.y = 1;
|
||||
term.buffer.x = 70;
|
||||
inputHandler.deleteChars([10]);
|
||||
expect(lineContent(line2)).equals(Array(term.cols - 9).join('a') + ' ');
|
||||
expect(lineContent(line2)).equals(lineContent(line1));
|
||||
expect(line1.translateToString(false)).equals(Array(term.cols - 9).join('a') + ' ');
|
||||
expect(line1.translateToString(true)).equals(Array(term.cols - 9).join('a'));
|
||||
});
|
||||
it('eraseInLine', function(): void {
|
||||
const term = new Terminal();
|
||||
const inputHandler = new InputHandler(term);
|
||||
const oldInputHandler = new OldInputHandler(term);
|
||||
|
||||
// fill 6 lines to test 3 different states
|
||||
inputHandler.parse(Array(term.cols + 1).join('a'));
|
||||
inputHandler.parse(Array(term.cols + 1).join('a'));
|
||||
inputHandler.parse(Array(term.cols + 1).join('a'));
|
||||
inputHandler.parse(Array(term.cols + 1).join('a'));
|
||||
inputHandler.parse(Array(term.cols + 1).join('a'));
|
||||
inputHandler.parse(Array(term.cols + 1).join('a'));
|
||||
|
||||
// params[0] - right erase
|
||||
term.buffer.y = 0;
|
||||
term.buffer.x = 70;
|
||||
oldInputHandler.eraseInLine([0]);
|
||||
expect(lineContent(term.buffer.lines.get(0))).equals(Array(71).join('a') + ' ');
|
||||
inputHandler.eraseInLine([0]);
|
||||
expect(term.buffer.lines.get(0).translateToString(false)).equals(Array(71).join('a') + ' ');
|
||||
|
||||
// params[1] - left erase
|
||||
term.buffer.y = 1;
|
||||
term.buffer.x = 70;
|
||||
inputHandler.eraseInLine([0]);
|
||||
expect(lineContent(term.buffer.lines.get(1))).equals(Array(71).join('a') + ' ');
|
||||
inputHandler.eraseInLine([1]);
|
||||
expect(term.buffer.lines.get(1).translateToString(false)).equals(Array(71).join(' ') + ' aaaaaaaaa');
|
||||
|
||||
// params[1] - left erase
|
||||
term.buffer.y = 2;
|
||||
term.buffer.x = 70;
|
||||
oldInputHandler.eraseInLine([1]);
|
||||
expect(lineContent(term.buffer.lines.get(2))).equals(Array(71).join(' ') + ' aaaaaaaaa');
|
||||
term.buffer.y = 3;
|
||||
term.buffer.x = 70;
|
||||
inputHandler.eraseInLine([1]);
|
||||
expect(lineContent(term.buffer.lines.get(3))).equals(Array(71).join(' ') + ' aaaaaaaaa');
|
||||
|
||||
// params[1] - left erase
|
||||
term.buffer.y = 4;
|
||||
term.buffer.x = 70;
|
||||
oldInputHandler.eraseInLine([2]);
|
||||
expect(lineContent(term.buffer.lines.get(4))).equals(Array(term.cols + 1).join(' '));
|
||||
term.buffer.y = 5;
|
||||
term.buffer.x = 70;
|
||||
inputHandler.eraseInLine([2]);
|
||||
expect(lineContent(term.buffer.lines.get(5))).equals(Array(term.cols + 1).join(' '));
|
||||
expect(term.buffer.lines.get(2).translateToString(false)).equals(Array(term.cols + 1).join(' '));
|
||||
|
||||
});
|
||||
it('eraseInDisplay', function(): void {
|
||||
const termOld = new Terminal();
|
||||
const inputHandlerOld = new OldInputHandler(termOld);
|
||||
const termNew = new Terminal();
|
||||
const inputHandlerNew = new InputHandler(termNew);
|
||||
const term = new Terminal({cols: 80, rows: 7});
|
||||
const inputHandler = new InputHandler(term);
|
||||
|
||||
// fill display with a's
|
||||
for (let i = 0; i < termOld.rows; ++i) inputHandlerOld.parse(Array(termOld.cols + 1).join('a'));
|
||||
for (let i = 0; i < termNew.rows; ++i) inputHandlerNew.parse(Array(termOld.cols + 1).join('a'));
|
||||
const data = [];
|
||||
for (let i = 0; i < termOld.rows; ++i) data.push(Array(termOld.cols + 1).join('a'));
|
||||
expect(termContent(termOld)).eql(data);
|
||||
expect(termContent(termOld)).eql(termContent(termNew));
|
||||
for (let i = 0; i < term.rows; ++i) inputHandler.parse(Array(term.cols + 1).join('a'));
|
||||
|
||||
// params [0] - right and below erase
|
||||
termOld.buffer.y = 5;
|
||||
termOld.buffer.x = 40;
|
||||
inputHandlerOld.eraseInDisplay([0]);
|
||||
termNew.buffer.y = 5;
|
||||
termNew.buffer.x = 40;
|
||||
inputHandlerNew.eraseInDisplay([0]);
|
||||
expect(termContent(termNew)).eql(termContent(termOld));
|
||||
term.buffer.y = 5;
|
||||
term.buffer.x = 40;
|
||||
inputHandler.eraseInDisplay([0]);
|
||||
expect(termContent(term, false)).eql([
|
||||
Array(term.cols + 1).join('a'),
|
||||
Array(term.cols + 1).join('a'),
|
||||
Array(term.cols + 1).join('a'),
|
||||
Array(term.cols + 1).join('a'),
|
||||
Array(term.cols + 1).join('a'),
|
||||
Array(40 + 1).join('a') + Array(term.cols - 40 + 1).join(' '),
|
||||
Array(term.cols + 1).join(' ')
|
||||
]);
|
||||
expect(termContent(term, true)).eql([
|
||||
Array(term.cols + 1).join('a'),
|
||||
Array(term.cols + 1).join('a'),
|
||||
Array(term.cols + 1).join('a'),
|
||||
Array(term.cols + 1).join('a'),
|
||||
Array(term.cols + 1).join('a'),
|
||||
Array(40 + 1).join('a'),
|
||||
''
|
||||
]);
|
||||
|
||||
// reset
|
||||
termOld.buffer.y = 0;
|
||||
termOld.buffer.x = 0;
|
||||
termNew.buffer.y = 0;
|
||||
termNew.buffer.x = 0;
|
||||
for (let i = 0; i < termOld.rows; ++i) inputHandlerOld.parse(Array(termOld.cols + 1).join('a'));
|
||||
for (let i = 0; i < termNew.rows; ++i) inputHandlerNew.parse(Array(termOld.cols + 1).join('a'));
|
||||
term.buffer.y = 0;
|
||||
term.buffer.x = 0;
|
||||
for (let i = 0; i < term.rows; ++i) inputHandler.parse(Array(term.cols + 1).join('a'));
|
||||
|
||||
// params [1] - left and above
|
||||
termOld.buffer.y = 5;
|
||||
termOld.buffer.x = 40;
|
||||
inputHandlerOld.eraseInDisplay([1]);
|
||||
termNew.buffer.y = 5;
|
||||
termNew.buffer.x = 40;
|
||||
inputHandlerNew.eraseInDisplay([1]);
|
||||
expect(termContent(termNew)).eql(termContent(termOld));
|
||||
term.buffer.y = 5;
|
||||
term.buffer.x = 40;
|
||||
inputHandler.eraseInDisplay([1]);
|
||||
expect(termContent(term, false)).eql([
|
||||
Array(term.cols + 1).join(' '),
|
||||
Array(term.cols + 1).join(' '),
|
||||
Array(term.cols + 1).join(' '),
|
||||
Array(term.cols + 1).join(' '),
|
||||
Array(term.cols + 1).join(' '),
|
||||
Array(41 + 1).join(' ') + Array(term.cols - 41 + 1).join('a'),
|
||||
Array(term.cols + 1).join('a')
|
||||
]);
|
||||
expect(termContent(term, true)).eql([
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
Array(41 + 1).join(' ') + Array(term.cols - 41 + 1).join('a'),
|
||||
Array(term.cols + 1).join('a')
|
||||
]);
|
||||
|
||||
// reset
|
||||
termOld.buffer.y = 0;
|
||||
termOld.buffer.x = 0;
|
||||
termNew.buffer.y = 0;
|
||||
termNew.buffer.x = 0;
|
||||
for (let i = 0; i < termOld.rows; ++i) inputHandlerOld.parse(Array(termOld.cols + 1).join('a'));
|
||||
for (let i = 0; i < termNew.rows; ++i) inputHandlerNew.parse(Array(termOld.cols + 1).join('a'));
|
||||
term.buffer.y = 0;
|
||||
term.buffer.x = 0;
|
||||
for (let i = 0; i < term.rows; ++i) inputHandler.parse(Array(term.cols + 1).join('a'));
|
||||
|
||||
// params [2] - whole screen
|
||||
termOld.buffer.y = 5;
|
||||
termOld.buffer.x = 40;
|
||||
inputHandlerOld.eraseInDisplay([2]);
|
||||
termNew.buffer.y = 5;
|
||||
termNew.buffer.x = 40;
|
||||
inputHandlerNew.eraseInDisplay([2]);
|
||||
expect(termContent(termNew)).eql(termContent(termOld));
|
||||
term.buffer.y = 5;
|
||||
term.buffer.x = 40;
|
||||
inputHandler.eraseInDisplay([2]);
|
||||
expect(termContent(term, false)).eql([
|
||||
Array(term.cols + 1).join(' '),
|
||||
Array(term.cols + 1).join(' '),
|
||||
Array(term.cols + 1).join(' '),
|
||||
Array(term.cols + 1).join(' '),
|
||||
Array(term.cols + 1).join(' '),
|
||||
Array(term.cols + 1).join(' '),
|
||||
Array(term.cols + 1).join(' ')
|
||||
]);
|
||||
expect(termContent(term, true)).eql([
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
''
|
||||
]);
|
||||
|
||||
// reset and add a wrapped line
|
||||
termNew.buffer.y = 0;
|
||||
termNew.buffer.x = 0;
|
||||
inputHandlerNew.parse(Array(termNew.cols + 1).join('a')); // line 0
|
||||
inputHandlerNew.parse(Array(termNew.cols + 10).join('a')); // line 1 and 2
|
||||
for (let i = 3; i < termOld.rows; ++i) inputHandlerNew.parse(Array(termNew.cols + 1).join('a'));
|
||||
term.buffer.y = 0;
|
||||
term.buffer.x = 0;
|
||||
inputHandler.parse(Array(term.cols + 1).join('a')); // line 0
|
||||
inputHandler.parse(Array(term.cols + 10).join('a')); // line 1 and 2
|
||||
for (let i = 3; i < term.rows; ++i) inputHandler.parse(Array(term.cols + 1).join('a'));
|
||||
|
||||
// params[1] left and above with wrap
|
||||
// confirm precondition that line 2 is wrapped
|
||||
expect(termNew.buffer.lines.get(2).isWrapped).true;
|
||||
termNew.buffer.y = 2;
|
||||
termNew.buffer.x = 40;
|
||||
inputHandlerNew.eraseInDisplay([1]);
|
||||
expect(termNew.buffer.lines.get(2).isWrapped).false;
|
||||
expect(term.buffer.lines.get(2).isWrapped).true;
|
||||
term.buffer.y = 2;
|
||||
term.buffer.x = 40;
|
||||
inputHandler.eraseInDisplay([1]);
|
||||
expect(term.buffer.lines.get(2).isWrapped).false;
|
||||
|
||||
// reset and add a wrapped line
|
||||
termNew.buffer.y = 0;
|
||||
termNew.buffer.x = 0;
|
||||
inputHandlerNew.parse(Array(termNew.cols + 1).join('a')); // line 0
|
||||
inputHandlerNew.parse(Array(termNew.cols + 10).join('a')); // line 1 and 2
|
||||
for (let i = 3; i < termOld.rows; ++i) inputHandlerNew.parse(Array(termNew.cols + 1).join('a'));
|
||||
term.buffer.y = 0;
|
||||
term.buffer.x = 0;
|
||||
inputHandler.parse(Array(term.cols + 1).join('a')); // line 0
|
||||
inputHandler.parse(Array(term.cols + 10).join('a')); // line 1 and 2
|
||||
for (let i = 3; i < term.rows; ++i) inputHandler.parse(Array(term.cols + 1).join('a'));
|
||||
|
||||
// params[1] left and above with wrap
|
||||
// confirm precondition that line 2 is wrapped
|
||||
expect(termNew.buffer.lines.get(2).isWrapped).true;
|
||||
termNew.buffer.y = 1;
|
||||
termNew.buffer.x = 90; // Cursor is beyond last column
|
||||
inputHandlerNew.eraseInDisplay([1]);
|
||||
expect(termNew.buffer.lines.get(2).isWrapped).false;
|
||||
expect(term.buffer.lines.get(2).isWrapped).true;
|
||||
term.buffer.y = 1;
|
||||
term.buffer.x = 90; // Cursor is beyond last column
|
||||
inputHandler.eraseInDisplay([1]);
|
||||
expect(term.buffer.lines.get(2).isWrapped).false;
|
||||
});
|
||||
});
|
||||
it('convertEol setting', function(): void {
|
||||
// not converting
|
||||
let s = '';
|
||||
const termNotConverting = new Terminal({cols: 15, rows: 10});
|
||||
(termNotConverting as any)._inputHandler.parse('Hello\nWorld');
|
||||
for (let i = 0; i < termNotConverting.cols; ++i) {
|
||||
s += termNotConverting.buffer.lines.get(0).get(i)[CHAR_DATA_CHAR_INDEX];
|
||||
}
|
||||
expect(s).equals('Hello ');
|
||||
s = '';
|
||||
for (let i = 0; i < termNotConverting.cols; ++i) {
|
||||
s += termNotConverting.buffer.lines.get(1).get(i)[CHAR_DATA_CHAR_INDEX];
|
||||
}
|
||||
expect(s).equals(' World ');
|
||||
expect(termNotConverting.buffer.lines.get(0).translateToString(false)).equals('Hello ');
|
||||
expect(termNotConverting.buffer.lines.get(1).translateToString(false)).equals(' World ');
|
||||
expect(termNotConverting.buffer.lines.get(0).translateToString(true)).equals('Hello');
|
||||
expect(termNotConverting.buffer.lines.get(1).translateToString(true)).equals(' World');
|
||||
|
||||
// converting
|
||||
s = '';
|
||||
const termConverting = new Terminal({cols: 15, rows: 10, convertEol: true});
|
||||
(termConverting as any)._inputHandler.parse('Hello\nWorld');
|
||||
for (let i = 0; i < termConverting.cols; ++i) {
|
||||
s += termConverting.buffer.lines.get(0).get(i)[CHAR_DATA_CHAR_INDEX];
|
||||
}
|
||||
expect(s).equals('Hello ');
|
||||
s = '';
|
||||
for (let i = 0; i < termConverting.cols; ++i) {
|
||||
s += termConverting.buffer.lines.get(1).get(i)[CHAR_DATA_CHAR_INDEX];
|
||||
}
|
||||
expect(s).equals('World ');
|
||||
expect(termConverting.buffer.lines.get(0).translateToString(false)).equals('Hello ');
|
||||
expect(termConverting.buffer.lines.get(1).translateToString(false)).equals('World ');
|
||||
expect(termConverting.buffer.lines.get(0).translateToString(true)).equals('Hello');
|
||||
expect(termConverting.buffer.lines.get(1).translateToString(true)).equals('World');
|
||||
});
|
||||
describe('print', () => {
|
||||
it('should not cause an infinite loop (regression test)', () => {
|
||||
@@ -511,34 +345,28 @@ describe('InputHandler', () => {
|
||||
let term: Terminal;
|
||||
let handler: InputHandler;
|
||||
|
||||
function lineContent(line: IBufferLine): string {
|
||||
let content = '';
|
||||
for (let i = 0; i < line.length; ++i) content += line.get(i)[CHAR_DATA_CHAR_INDEX];
|
||||
return content;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
term = new Terminal();
|
||||
handler = new InputHandler(term);
|
||||
});
|
||||
it('should handle DECSET/DECRST 47 (alt screen buffer)', () => {
|
||||
handler.parse('\x1b[?47h\r\n\x1b[31mJUNK\x1b[?47lTEST');
|
||||
expect(lineContent(term.buffer.lines.get(0))).to.equal(Array(term.cols + 1).join(' '));
|
||||
expect(lineContent(term.buffer.lines.get(1))).to.equal(' TEST' + Array(term.cols - 7).join(' '));
|
||||
expect(term.buffer.translateBufferLineToString(0, true)).to.equal('');
|
||||
expect(term.buffer.translateBufferLineToString(1, true)).to.equal(' TEST');
|
||||
// Text color of 'TEST' should be red
|
||||
expect((term.buffer.lines.get(1).get(4)[CHAR_DATA_ATTR_INDEX] >> 9) & 0x1ff).to.equal(1);
|
||||
});
|
||||
it('should handle DECSET/DECRST 1047 (alt screen buffer)', () => {
|
||||
handler.parse('\x1b[?1047h\r\n\x1b[31mJUNK\x1b[?1047lTEST');
|
||||
expect(lineContent(term.buffer.lines.get(0))).to.equal(Array(term.cols + 1).join(' '));
|
||||
expect(lineContent(term.buffer.lines.get(1))).to.equal(' TEST' + Array(term.cols - 7).join(' '));
|
||||
expect(term.buffer.translateBufferLineToString(0, true)).to.equal('');
|
||||
expect(term.buffer.translateBufferLineToString(1, true)).to.equal(' TEST');
|
||||
// Text color of 'TEST' should be red
|
||||
expect((term.buffer.lines.get(1).get(4)[CHAR_DATA_ATTR_INDEX] >> 9) & 0x1ff).to.equal(1);
|
||||
});
|
||||
it('should handle DECSET/DECRST 1048 (alt screen cursor)', () => {
|
||||
handler.parse('\x1b[?1048h\r\n\x1b[31mJUNK\x1b[?1048lTEST');
|
||||
expect(lineContent(term.buffer.lines.get(0))).to.equal('TEST' + Array(term.cols - 3).join(' '));
|
||||
expect(lineContent(term.buffer.lines.get(1))).to.equal('JUNK' + Array(term.cols - 3).join(' '));
|
||||
expect(term.buffer.translateBufferLineToString(0, true)).to.equal('TEST');
|
||||
expect(term.buffer.translateBufferLineToString(1, true)).to.equal('JUNK');
|
||||
// Text color of 'TEST' should be default
|
||||
expect(term.buffer.lines.get(0).get(0)[CHAR_DATA_ATTR_INDEX]).to.equal(DEFAULT_ATTR);
|
||||
// Text color of 'JUNK' should be red
|
||||
@@ -546,18 +374,18 @@ describe('InputHandler', () => {
|
||||
});
|
||||
it('should handle DECSET/DECRST 1049 (alt screen buffer+cursor)', () => {
|
||||
handler.parse('\x1b[?1049h\r\n\x1b[31mJUNK\x1b[?1049lTEST');
|
||||
expect(lineContent(term.buffer.lines.get(0))).to.equal('TEST' + Array(term.cols - 3).join(' '));
|
||||
expect(lineContent(term.buffer.lines.get(1))).to.equal(Array(term.cols + 1).join(' '));
|
||||
expect(term.buffer.translateBufferLineToString(0, true)).to.equal('TEST');
|
||||
expect(term.buffer.translateBufferLineToString(1, true)).to.equal('');
|
||||
// Text color of 'TEST' should be default
|
||||
expect(term.buffer.lines.get(0).get(0)[CHAR_DATA_ATTR_INDEX]).to.equal(DEFAULT_ATTR);
|
||||
});
|
||||
it('should handle DECSET/DECRST 1049 - maintains saved cursor for alt buffer', () => {
|
||||
handler.parse('\x1b[?1049h\r\n\x1b[31m\x1b[s\x1b[?1049lTEST');
|
||||
expect(lineContent(term.buffer.lines.get(0))).to.equal('TEST' + Array(term.cols - 3).join(' '));
|
||||
expect(term.buffer.translateBufferLineToString(0, true)).to.equal('TEST');
|
||||
// Text color of 'TEST' should be default
|
||||
expect(term.buffer.lines.get(0).get(0)[CHAR_DATA_ATTR_INDEX]).to.equal(DEFAULT_ATTR);
|
||||
handler.parse('\x1b[?1049h\x1b[uTEST');
|
||||
expect(lineContent(term.buffer.lines.get(1))).to.equal('TEST' + Array(term.cols - 3).join(' '));
|
||||
expect(term.buffer.translateBufferLineToString(1, true)).to.equal('TEST');
|
||||
// Text color of 'TEST' should be red
|
||||
expect((term.buffer.lines.get(1).get(0)[CHAR_DATA_ATTR_INDEX] >> 9) & 0x1ff).to.equal(1);
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ import * as path from 'path';
|
||||
import * as pty from 'node-pty';
|
||||
import { assert } from 'chai';
|
||||
import { Terminal } from './Terminal';
|
||||
import { CHAR_DATA_CHAR_INDEX } from './Buffer';
|
||||
import { CHAR_DATA_CHAR_INDEX, WHITESPACE_CELL_CHAR } from './Buffer';
|
||||
import { IViewport } from './Types';
|
||||
|
||||
class TestTerminal extends Terminal {
|
||||
@@ -67,7 +67,7 @@ function terminalToString(term: Terminal): string {
|
||||
for (let line = term.buffer.ybase; line < term.buffer.ybase + term.rows; line++) {
|
||||
lineText = '';
|
||||
for (let cell = 0; cell < term.cols; ++cell) {
|
||||
lineText += term.buffer.lines.get(line).get(cell)[CHAR_DATA_CHAR_INDEX];
|
||||
lineText += term.buffer.lines.get(line).get(cell)[CHAR_DATA_CHAR_INDEX] || WHITESPACE_CELL_CHAR;
|
||||
}
|
||||
// rtrim empty cells as xterm does
|
||||
lineText = lineText.replace(/\s+$/, '');
|
||||
|
||||
+21
-21
@@ -462,7 +462,7 @@ describe('term.js addons', () => {
|
||||
assert.equal(term.buffer.lines.length, INIT_ROWS + 1);
|
||||
assert.equal(term.buffer.lines.get(0).get(0)[CHAR_DATA_CHAR_INDEX], 'a');
|
||||
assert.equal(term.buffer.lines.get(INIT_ROWS - 1).get(0)[CHAR_DATA_CHAR_INDEX], 'b');
|
||||
assert.equal(term.buffer.lines.get(INIT_ROWS).get(0)[CHAR_DATA_CHAR_INDEX], ' ');
|
||||
assert.equal(term.buffer.lines.get(INIT_ROWS).get(0)[CHAR_DATA_CHAR_INDEX], '');
|
||||
});
|
||||
|
||||
it('should properly scroll inside a scroll region (scrollTop set)', () => {
|
||||
@@ -491,7 +491,7 @@ describe('term.js addons', () => {
|
||||
assert.equal(term.buffer.lines.get(1).get(0)[CHAR_DATA_CHAR_INDEX], 'b');
|
||||
assert.equal(term.buffer.lines.get(2).get(0)[CHAR_DATA_CHAR_INDEX], 'c');
|
||||
assert.equal(term.buffer.lines.get(3).get(0)[CHAR_DATA_CHAR_INDEX], 'd');
|
||||
assert.equal(term.buffer.lines.get(4).get(0)[CHAR_DATA_CHAR_INDEX], ' ', 'a blank line should be added at scrollBottom\'s index');
|
||||
assert.equal(term.buffer.lines.get(4).get(0)[CHAR_DATA_CHAR_INDEX], '', 'a blank line should be added at scrollBottom\'s index');
|
||||
assert.equal(term.buffer.lines.get(5).get(0)[CHAR_DATA_CHAR_INDEX], 'e');
|
||||
});
|
||||
|
||||
@@ -509,7 +509,7 @@ describe('term.js addons', () => {
|
||||
assert.equal(term.buffer.lines.get(0).get(0)[CHAR_DATA_CHAR_INDEX], 'a');
|
||||
assert.equal(term.buffer.lines.get(1).get(0)[CHAR_DATA_CHAR_INDEX], 'c', '\'b\' should be removed from the buffer');
|
||||
assert.equal(term.buffer.lines.get(2).get(0)[CHAR_DATA_CHAR_INDEX], 'd');
|
||||
assert.equal(term.buffer.lines.get(3).get(0)[CHAR_DATA_CHAR_INDEX], ' ', 'a blank line should be added at scrollBottom\'s index');
|
||||
assert.equal(term.buffer.lines.get(3).get(0)[CHAR_DATA_CHAR_INDEX], '', 'a blank line should be added at scrollBottom\'s index');
|
||||
assert.equal(term.buffer.lines.get(4).get(0)[CHAR_DATA_CHAR_INDEX], 'e');
|
||||
});
|
||||
});
|
||||
@@ -530,9 +530,9 @@ describe('term.js addons', () => {
|
||||
assert.equal(term.buffer.lines.length, INIT_ROWS);
|
||||
// 'a' gets pushed out of buffer
|
||||
assert.equal(term.buffer.lines.get(0).get(0)[CHAR_DATA_CHAR_INDEX], 'b');
|
||||
assert.equal(term.buffer.lines.get(1).get(0)[CHAR_DATA_CHAR_INDEX], ' ');
|
||||
assert.equal(term.buffer.lines.get(1).get(0)[CHAR_DATA_CHAR_INDEX], '');
|
||||
assert.equal(term.buffer.lines.get(INIT_ROWS - 2).get(0)[CHAR_DATA_CHAR_INDEX], 'c');
|
||||
assert.equal(term.buffer.lines.get(INIT_ROWS - 1).get(0)[CHAR_DATA_CHAR_INDEX], ' ');
|
||||
assert.equal(term.buffer.lines.get(INIT_ROWS - 1).get(0)[CHAR_DATA_CHAR_INDEX], '');
|
||||
});
|
||||
|
||||
it('should properly scroll inside a scroll region (scrollTop set)', () => {
|
||||
@@ -560,7 +560,7 @@ describe('term.js addons', () => {
|
||||
assert.equal(term.buffer.lines.get(0).get(0)[CHAR_DATA_CHAR_INDEX], 'b');
|
||||
assert.equal(term.buffer.lines.get(1).get(0)[CHAR_DATA_CHAR_INDEX], 'c');
|
||||
assert.equal(term.buffer.lines.get(2).get(0)[CHAR_DATA_CHAR_INDEX], 'd');
|
||||
assert.equal(term.buffer.lines.get(3).get(0)[CHAR_DATA_CHAR_INDEX], ' ', 'a blank line should be added at scrollBottom\'s index');
|
||||
assert.equal(term.buffer.lines.get(3).get(0)[CHAR_DATA_CHAR_INDEX], '', 'a blank line should be added at scrollBottom\'s index');
|
||||
assert.equal(term.buffer.lines.get(4).get(0)[CHAR_DATA_CHAR_INDEX], 'e');
|
||||
});
|
||||
|
||||
@@ -578,7 +578,7 @@ describe('term.js addons', () => {
|
||||
assert.equal(term.buffer.lines.get(0).get(0)[CHAR_DATA_CHAR_INDEX], 'a');
|
||||
assert.equal(term.buffer.lines.get(1).get(0)[CHAR_DATA_CHAR_INDEX], 'c', '\'b\' should be removed from the buffer');
|
||||
assert.equal(term.buffer.lines.get(2).get(0)[CHAR_DATA_CHAR_INDEX], 'd');
|
||||
assert.equal(term.buffer.lines.get(3).get(0)[CHAR_DATA_CHAR_INDEX], ' ', 'a blank line should be added at scrollBottom\'s index');
|
||||
assert.equal(term.buffer.lines.get(3).get(0)[CHAR_DATA_CHAR_INDEX], '', 'a blank line should be added at scrollBottom\'s index');
|
||||
assert.equal(term.buffer.lines.get(4).get(0)[CHAR_DATA_CHAR_INDEX], 'e');
|
||||
});
|
||||
});
|
||||
@@ -776,7 +776,7 @@ describe('term.js addons', () => {
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(high + String.fromCharCode(i));
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(2);
|
||||
expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1);
|
||||
expect(term.buffer.lines.get(0).get(1)[CHAR_DATA_CHAR_INDEX]).eql(' ');
|
||||
expect(term.buffer.lines.get(0).get(1)[CHAR_DATA_CHAR_INDEX]).eql('');
|
||||
term.reset();
|
||||
}
|
||||
});
|
||||
@@ -787,7 +787,7 @@ describe('term.js addons', () => {
|
||||
term.write(high + String.fromCharCode(i));
|
||||
expect(term.buffer.lines.get(0).get(term.buffer.x - 1)[CHAR_DATA_CHAR_INDEX]).eql(high + String.fromCharCode(i));
|
||||
expect(term.buffer.lines.get(0).get(term.buffer.x - 1)[CHAR_DATA_CHAR_INDEX].length).eql(2);
|
||||
expect(term.buffer.lines.get(1).get(0)[CHAR_DATA_CHAR_INDEX]).eql(' ');
|
||||
expect(term.buffer.lines.get(1).get(0)[CHAR_DATA_CHAR_INDEX]).eql('');
|
||||
term.reset();
|
||||
}
|
||||
});
|
||||
@@ -800,7 +800,7 @@ describe('term.js addons', () => {
|
||||
expect(term.buffer.lines.get(0).get(term.cols - 1)[CHAR_DATA_CHAR_INDEX]).eql('a');
|
||||
expect(term.buffer.lines.get(1).get(0)[CHAR_DATA_CHAR_INDEX]).eql(high + String.fromCharCode(i));
|
||||
expect(term.buffer.lines.get(1).get(0)[CHAR_DATA_CHAR_INDEX].length).eql(2);
|
||||
expect(term.buffer.lines.get(1).get(1)[CHAR_DATA_CHAR_INDEX]).eql(' ');
|
||||
expect(term.buffer.lines.get(1).get(1)[CHAR_DATA_CHAR_INDEX]).eql('');
|
||||
term.reset();
|
||||
}
|
||||
});
|
||||
@@ -813,7 +813,7 @@ describe('term.js addons', () => {
|
||||
// auto wraparound mode should cut off the rest of the line
|
||||
expect(term.buffer.lines.get(0).get(term.cols - 1)[CHAR_DATA_CHAR_INDEX]).eql('a');
|
||||
expect(term.buffer.lines.get(0).get(term.cols - 1)[CHAR_DATA_CHAR_INDEX].length).eql(1);
|
||||
expect(term.buffer.lines.get(1).get(1)[CHAR_DATA_CHAR_INDEX]).eql(' ');
|
||||
expect(term.buffer.lines.get(1).get(1)[CHAR_DATA_CHAR_INDEX]).eql('');
|
||||
term.reset();
|
||||
}
|
||||
});
|
||||
@@ -826,7 +826,7 @@ describe('term.js addons', () => {
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(high + String.fromCharCode(i));
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(2);
|
||||
expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1);
|
||||
expect(term.buffer.lines.get(0).get(1)[CHAR_DATA_CHAR_INDEX]).eql(' ');
|
||||
expect(term.buffer.lines.get(0).get(1)[CHAR_DATA_CHAR_INDEX]).eql('');
|
||||
term.reset();
|
||||
}
|
||||
});
|
||||
@@ -845,8 +845,8 @@ describe('term.js addons', () => {
|
||||
expect(term.buffer.lines.get(0).get(term.cols - 1)[CHAR_DATA_CHAR_INDEX]).eql('e\u0301');
|
||||
expect(term.buffer.lines.get(0).get(term.cols - 1)[CHAR_DATA_CHAR_INDEX].length).eql(2);
|
||||
expect(term.buffer.lines.get(0).get(term.cols - 1)[CHAR_DATA_WIDTH_INDEX]).eql(1);
|
||||
expect(term.buffer.lines.get(0).get(1)[CHAR_DATA_CHAR_INDEX]).eql(' ');
|
||||
expect(term.buffer.lines.get(0).get(1)[CHAR_DATA_CHAR_INDEX].length).eql(1);
|
||||
expect(term.buffer.lines.get(0).get(1)[CHAR_DATA_CHAR_INDEX]).eql('');
|
||||
expect(term.buffer.lines.get(0).get(1)[CHAR_DATA_CHAR_INDEX].length).eql(0);
|
||||
expect(term.buffer.lines.get(0).get(1)[CHAR_DATA_WIDTH_INDEX]).eql(1);
|
||||
});
|
||||
it('multiple combined é', () => {
|
||||
@@ -928,8 +928,8 @@ describe('term.js addons', () => {
|
||||
}
|
||||
}
|
||||
let tchar = term.buffer.lines.get(0).get(term.cols - 1);
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(' ');
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(1);
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('');
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(0);
|
||||
expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1);
|
||||
tchar = term.buffer.lines.get(1).get(0);
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('¥');
|
||||
@@ -953,8 +953,8 @@ describe('term.js addons', () => {
|
||||
}
|
||||
}
|
||||
let tchar = term.buffer.lines.get(0).get(term.cols - 1);
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(' ');
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(1);
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('');
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(0);
|
||||
expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1);
|
||||
tchar = term.buffer.lines.get(1).get(0);
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('¥\u0301');
|
||||
@@ -998,8 +998,8 @@ describe('term.js addons', () => {
|
||||
}
|
||||
}
|
||||
let tchar = term.buffer.lines.get(0).get(term.cols - 1);
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(' ');
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(1);
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('');
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(0);
|
||||
expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1);
|
||||
tchar = term.buffer.lines.get(1).get(0);
|
||||
expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('\ud843\ude6d\u0301');
|
||||
@@ -1063,7 +1063,7 @@ describe('term.js addons', () => {
|
||||
expect(term.buffer.lines.get(0).length).eql(term.cols);
|
||||
expect(term.buffer.lines.get(0).get(10)[CHAR_DATA_CHAR_INDEX]).eql('a');
|
||||
expect(term.buffer.lines.get(0).get(11)[CHAR_DATA_CHAR_INDEX]).eql('¥');
|
||||
expect(term.buffer.lines.get(0).get(79)[CHAR_DATA_CHAR_INDEX]).eql(' '); // fullwidth char got replaced
|
||||
expect(term.buffer.lines.get(0).get(79)[CHAR_DATA_CHAR_INDEX]).eql(''); // fullwidth char got replaced
|
||||
term.write('b');
|
||||
expect(term.buffer.lines.get(0).length).eql(term.cols);
|
||||
expect(term.buffer.lines.get(0).get(11)[CHAR_DATA_CHAR_INDEX]).eql('b');
|
||||
|
||||
@@ -524,6 +524,8 @@ export interface IBufferLine {
|
||||
fill(fillCharData: CharData): void;
|
||||
copyFrom(line: IBufferLine): void;
|
||||
clone(): IBufferLine;
|
||||
getTrimmedLength(): number;
|
||||
translateToString(trimRight?: boolean, startCol?: number, endCol?: number): string;
|
||||
}
|
||||
|
||||
export interface IBufferLineConstructor {
|
||||
|
||||
@@ -118,8 +118,6 @@ describe('search addon', () => {
|
||||
it('should not select empty lines', () => {
|
||||
search.apply(<any>MockTerminal);
|
||||
const term = new MockTerminal({cols: 20, rows: 3});
|
||||
term.core.write(' ');
|
||||
term.pushWriteData();
|
||||
const line = term.searchHelper.findInLine('^.*$', 0, { regex: true });
|
||||
expect(line).eql(undefined);
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { CHAR_DATA_ATTR_INDEX, CHAR_DATA_CODE_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, NULL_CELL_CODE } from '../Buffer';
|
||||
import { CHAR_DATA_ATTR_INDEX, CHAR_DATA_CODE_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, NULL_CELL_CODE, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE } from '../Buffer';
|
||||
import { FLAGS, IColorSet, IRenderDimensions, ICharacterJoinerRegistry } from './Types';
|
||||
import { CharData, ITerminal } from '../Types';
|
||||
import { INVERTED_DEFAULT_COLOR, DEFAULT_COLOR } from './atlas/Types';
|
||||
@@ -73,11 +73,11 @@ export class TextRenderLayer extends BaseRenderLayer {
|
||||
const joinedRanges = joinerRegistry ? joinerRegistry.getJoinedCharacters(row) : [];
|
||||
for (let x = 0; x < terminal.cols; x++) {
|
||||
const charData = line.get(x);
|
||||
let code: number = <number>charData[CHAR_DATA_CODE_INDEX];
|
||||
let code: number = <number>charData[CHAR_DATA_CODE_INDEX] || WHITESPACE_CELL_CODE;
|
||||
|
||||
// Can either represent character(s) for a single cell or multiple cells
|
||||
// if indicated by a character joiner.
|
||||
let chars: string = charData[CHAR_DATA_CHAR_INDEX];
|
||||
let chars: string = charData[CHAR_DATA_CHAR_INDEX] || WHITESPACE_CELL_CHAR;
|
||||
const attr: number = charData[CHAR_DATA_ATTR_INDEX];
|
||||
let width: number = charData[CHAR_DATA_WIDTH_INDEX];
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_ATTR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CODE_INDEX, NULL_CELL_CODE } from '../../Buffer';
|
||||
import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_ATTR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CODE_INDEX, NULL_CELL_CODE, WHITESPACE_CELL_CHAR } from '../../Buffer';
|
||||
import { FLAGS } from '../Types';
|
||||
import { IBufferLine } from '../../Types';
|
||||
import { DEFAULT_COLOR, INVERTED_DEFAULT_COLOR } from '../atlas/Types';
|
||||
@@ -41,7 +41,7 @@ export class DomRendererRowFactory {
|
||||
|
||||
for (let x = 0; x < lineLength; x++) {
|
||||
const charData = lineData.get(x);
|
||||
const char = charData[CHAR_DATA_CHAR_INDEX];
|
||||
const char = charData[CHAR_DATA_CHAR_INDEX] || WHITESPACE_CELL_CHAR;
|
||||
const attr = charData[CHAR_DATA_ATTR_INDEX];
|
||||
const width = charData[CHAR_DATA_WIDTH_INDEX];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user