Merge branch '842_resize_buffers_bug' into 335_xterm_to_ts

setOption('scrollback', 0) no longer returns false, it just warns.
This commit is contained in:
Daniel Imms
2017-08-05 20:48:42 -07:00
12 changed files with 2739 additions and 125 deletions
+121 -7
View File
@@ -5,19 +5,20 @@ import { assert } from 'chai';
import { ITerminal } from './Interfaces'; import { ITerminal } from './Interfaces';
import { Buffer } from './Buffer'; import { Buffer } from './Buffer';
import { CircularList } from './utils/CircularList'; import { CircularList } from './utils/CircularList';
import { MockTerminal } from './utils/TestUtils';
const INIT_COLS = 80;
const INIT_ROWS = 24;
describe('Buffer', () => { describe('Buffer', () => {
let terminal: ITerminal; let terminal: ITerminal;
let buffer: Buffer; let buffer: Buffer;
beforeEach(() => { beforeEach(() => {
terminal = <any>{ terminal = new MockTerminal();
cols: 80, terminal.cols = INIT_COLS;
rows: 24, terminal.rows = INIT_ROWS;
options: { terminal.options.scrollback = 1000;
scrollback: 1000
}
};
buffer = new Buffer(terminal); buffer = new Buffer(terminal);
}); });
@@ -30,4 +31,117 @@ describe('Buffer', () => {
assert.equal(buffer.scrollBottom, terminal.rows - 1); assert.equal(buffer.scrollBottom, terminal.rows - 1);
}); });
}); });
describe('fillViewportRows', () => {
it('should fill the buffer with blank lines based on the size of the viewport', () => {
const blankLineChar = terminal.blankLine()[0];
buffer.fillViewportRows();
assert.equal(buffer.lines.length, INIT_ROWS);
for (let y = 0; y < INIT_ROWS; y++) {
assert.equal(buffer.lines.get(y).length, INIT_COLS);
for (let x = 0; x < INIT_COLS; x++) {
assert.deepEqual(buffer.lines.get(y)[x], blankLineChar);
}
}
});
});
describe('resize', () => {
describe('column size is reduced', () => {
it('should not trim the data in the buffer', () => {
buffer.fillViewportRows();
buffer.resize(INIT_COLS / 2, INIT_ROWS);
assert.equal(buffer.lines.length, INIT_ROWS);
for (let i = 0; i < INIT_ROWS; i++) {
assert.equal(buffer.lines.get(i).length, INIT_COLS);
}
});
});
describe('column size is increased', () => {
it('should add pad columns', () => {
buffer.fillViewportRows();
buffer.resize(INIT_COLS + 10, INIT_ROWS);
assert.equal(buffer.lines.length, INIT_ROWS);
for (let i = 0; i < INIT_ROWS; i++) {
assert.equal(buffer.lines.get(i).length, INIT_COLS + 10);
}
});
});
describe('row size reduced', () => {
it('should trim blank lines from the end', () => {
buffer.fillViewportRows();
buffer.resize(INIT_COLS, INIT_ROWS - 10);
assert.equal(buffer.lines.length, INIT_ROWS - 10);
});
it('should move the viewport down when it\'s at the end', () => {
buffer.fillViewportRows();
// Set cursor y to have 5 blank lines below it
buffer.y = INIT_ROWS - 5 - 1;
buffer.resize(INIT_COLS, INIT_ROWS - 10);
// Trim 5 rows
assert.equal(buffer.lines.length, INIT_ROWS - 5);
// Shift the viewport down 5 rows
assert.equal(buffer.ydisp, 5);
assert.equal(buffer.ybase, 5);
});
});
describe('row size increased', () => {
describe('empty buffer', () => {
it('should add blank lines to end', () => {
buffer.fillViewportRows();
assert.equal(buffer.ydisp, 0);
buffer.resize(INIT_COLS, INIT_ROWS + 10);
assert.equal(buffer.ydisp, 0);
assert.equal(buffer.lines.length, INIT_ROWS + 10);
});
});
describe('filled buffer', () => {
it('should show more of the buffer above', () => {
buffer.fillViewportRows();
// Create 10 extra blank lines
for (let i = 0; i < 10; i++) {
buffer.lines.push(terminal.blankLine());
}
// Set cursor to the bottom of the buffer
buffer.y = INIT_ROWS - 1;
// Scroll down 10 lines
buffer.ybase = 10;
buffer.ydisp = 10;
assert.equal(buffer.lines.length, INIT_ROWS + 10);
buffer.resize(INIT_COLS, INIT_ROWS + 5);
// Should be should 5 more lines
assert.equal(buffer.ydisp, 5);
assert.equal(buffer.ybase, 5);
// Should not trim the buffer
assert.equal(buffer.lines.length, INIT_ROWS + 10);
});
it('should show more of the buffer below when the viewport is at the top of the buffer', () => {
buffer.fillViewportRows();
// Create 10 extra blank lines
for (let i = 0; i < 10; i++) {
buffer.lines.push(terminal.blankLine());
}
// Set cursor to the bottom of the buffer
buffer.y = INIT_ROWS - 1;
// Scroll down 10 lines
buffer.ybase = 10;
buffer.ydisp = 0;
assert.equal(buffer.lines.length, INIT_ROWS + 10);
buffer.resize(INIT_COLS, INIT_ROWS + 5);
// The viewport should remain at the top
assert.equal(buffer.ydisp, 0);
// The buffer ybase should move up 5 lines
assert.equal(buffer.ybase, 5);
// Should not trim the buffer
assert.equal(buffer.lines.length, INIT_ROWS + 10);
});
});
});
});
}); });
+107 -13
View File
@@ -13,31 +13,125 @@ import { CircularList } from './utils/CircularList';
* - scroll position * - scroll position
*/ */
export class Buffer implements IBuffer { export class Buffer implements IBuffer {
public lines: CircularList<[number, string, number][]>; private _lines: CircularList<[number, string, number][]>;
public ydisp: number;
public ybase: number;
public y: number;
public x: number;
public scrollBottom: number;
public scrollTop: number;
public tabs: any;
public savedY: number; public savedY: number;
public savedX: number; public savedX: number;
/** /**
* Create a new Buffer. * Create a new Buffer.
* @param {Terminal} terminal - The terminal the Buffer will belong to * @param {Terminal} _terminal - The terminal the Buffer will belong to
* @param {number} ydisp - The scroll position of the Buffer in the viewport * @param {number} ydisp - The scroll position of the Buffer in the viewport
* @param {number} ybase - The scroll position of the y cursor (ybase + y = the y position within the Buffer) * @param {number} ybase - The scroll position of the y cursor (ybase + y = the y position within the Buffer)
* @param {number} y - The cursor's y position after ybase * @param {number} y - The cursor's y position after ybase
* @param {number} x - The cursor's x position after ybase * @param {number} x - The cursor's x position after ybase
*/ */
constructor( constructor(
private terminal: ITerminal, private _terminal: ITerminal
public ydisp: number = 0,
public ybase: number = 0,
public y: number = 0,
public x: number = 0,
public scrollBottom: number = 0,
public scrollTop: number = 0,
public tabs: any = {},
) { ) {
// TODO: Don't cast terminal to any this.clear();
this.lines = new CircularList<[number, string, number][]>(this.terminal.options.scrollback); }
this.scrollBottom = this.terminal.rows - 1;
public get lines(): CircularList<[number, string, number][]> {
return this._lines;
}
public fillViewportRows(): void {
if (this._lines.length === 0) {
let i = this._terminal.rows;
while (i--) {
this.lines.push(this._terminal.blankLine());
}
}
}
public clear(): void {
this.ydisp = 0;
this.ybase = 0;
this.y = 0;
this.x = 0;
this.scrollBottom = 0;
this.scrollTop = 0;
this.tabs = {};
this._lines = new CircularList<[number, string, number][]>(this._terminal.options.scrollback);
this.scrollBottom = this._terminal.rows - 1;
}
public resize(newCols: number, newRows: number): void {
// Don't resize the buffer if it's empty and hasn't been used yet.
if (this._lines.length === 0) {
return;
}
// Deal with columns increasing (we don't do anything when columns reduce)
if (this._terminal.cols < newCols) {
const ch: [number, string, number] = [this._terminal.defAttr, ' ', 1]; // does xterm use the default attr?
for (let i = 0; i < this._lines.length; i++) {
if (this._lines.get(i) === undefined) {
this._lines.set(i, this._terminal.blankLine());
}
while (this._lines.get(i).length < newCols) {
this._lines.get(i).push(ch);
}
}
}
// Resize rows in both directions as needed
let addToY = 0;
if (this._terminal.rows < newRows) {
for (let y = this._terminal.rows; y < newRows; y++) {
if (this._lines.length < newRows + this.ybase) {
if (this.ybase > 0 && this._lines.length <= this.ybase + this.y + addToY + 1) {
// There is room above the buffer and there are no empty elements below the line,
// scroll up
this.ybase--;
addToY++;
if (this.ydisp > 0) {
// Viewport is at the top of the buffer, must increase downwards
this.ydisp--;
}
} else {
// Add a blank line if there is no buffer left at the top to scroll to, or if there
// are blank lines after the cursor
this._lines.push(this._terminal.blankLine());
}
}
}
} else { // (this._terminal.rows >= newRows)
for (let y = this._terminal.rows; y > newRows; y--) {
if (this._lines.length > newRows + this.ybase) {
if (this._lines.length > this.ybase + this.y + 1) {
// The line is a blank line below the cursor, remove it
this._lines.pop();
} else {
// The line is the cursor, scroll down
this.ybase++;
this.ydisp++;
}
}
}
}
// Make sure that the cursor stays on screen
if (this.y >= newRows) {
this.y = newRows - 1;
}
if (addToY) {
this.y += addToY;
}
if (this.x >= newCols) {
this.x = newCols - 1;
}
this.scrollTop = 0;
this.scrollBottom = newRows - 1;
} }
} }
+5 -7
View File
@@ -5,19 +5,17 @@ import { assert } from 'chai';
import { ITerminal } from './Interfaces'; import { ITerminal } from './Interfaces';
import { BufferSet } from './BufferSet'; import { BufferSet } from './BufferSet';
import { Buffer } from './Buffer'; import { Buffer } from './Buffer';
import { MockTerminal } from './utils/TestUtils';
describe('BufferSet', () => { describe('BufferSet', () => {
let terminal: ITerminal; let terminal: ITerminal;
let bufferSet: BufferSet; let bufferSet: BufferSet;
beforeEach(() => { beforeEach(() => {
terminal = <any>{ terminal = new MockTerminal();
cols: 80, terminal.cols = 80;
rows: 24, terminal.rows = 24;
options: { terminal.options.scrollback = 1000;
scrollback: 1000
}
};
bufferSet = new BufferSet(terminal); bufferSet = new BufferSet(terminal);
}); });
+15
View File
@@ -22,6 +22,7 @@ export class BufferSet extends EventEmitter implements IBufferSet {
constructor(private _terminal: ITerminal) { constructor(private _terminal: ITerminal) {
super(); super();
this._normal = new Buffer(this._terminal); this._normal = new Buffer(this._terminal);
this._normal.fillViewportRows();
this._alt = new Buffer(this._terminal); this._alt = new Buffer(this._terminal);
this._activeBuffer = this._normal; this._activeBuffer = this._normal;
} }
@@ -54,6 +55,11 @@ export class BufferSet extends EventEmitter implements IBufferSet {
* Sets the normal Buffer of the BufferSet as its currently active Buffer * Sets the normal Buffer of the BufferSet as its currently active Buffer
*/ */
public activateNormalBuffer(): void { public activateNormalBuffer(): void {
// The alt buffer should always be cleared when we switch to the normal
// buffer. This frees up memory since the alt buffer should always be new
// when activated.
this._alt.clear();
this._activeBuffer = this._normal; this._activeBuffer = this._normal;
this.emit('activate', this._normal); this.emit('activate', this._normal);
} }
@@ -62,7 +68,16 @@ export class BufferSet extends EventEmitter implements IBufferSet {
* Sets the alt Buffer of the BufferSet as its currently active Buffer * Sets the alt Buffer of the BufferSet as its currently active Buffer
*/ */
public activateAltBuffer(): void { public activateAltBuffer(): void {
// Since the alt buffer is always cleared when the normal buffer is
// activated, we want to fill it when switching to it.
this._alt.fillViewportRows();
this._activeBuffer = this._alt; this._activeBuffer = this._alt;
this.emit('activate', this._alt); this.emit('activate', this._alt);
} }
public resize(newCols: number, newRows: number): void {
this._normal.resize(newCols, newRows);
this._alt.resize(newCols, newRows);
}
} }
-1
View File
@@ -945,7 +945,6 @@ export class InputHandler implements IInputHandler {
case 47: // alt screen buffer case 47: // alt screen buffer
case 1047: // alt screen buffer case 1047: // alt screen buffer
this._terminal.buffers.activateAltBuffer(); this._terminal.buffers.activateAltBuffer();
this._terminal.reset();
this._terminal.viewport.syncScrollArea(); this._terminal.viewport.syncScrollArea();
this._terminal.showCursor(); this._terminal.showCursor();
break; break;
+1
View File
@@ -46,6 +46,7 @@ export interface ITerminal extends IEventEmitter {
log(text: string): void; log(text: string): void;
reset(): void; reset(): void;
showCursor(): void; showCursor(): void;
blankLine(cur?: boolean, isWrapped?: boolean);
} }
/** /**
+15 -11
View File
@@ -9,6 +9,7 @@ import { CircularList } from './utils/CircularList';
import { SelectionManager } from './SelectionManager'; import { SelectionManager } from './SelectionManager';
import { SelectionModel } from './SelectionModel'; import { SelectionModel } from './SelectionModel';
import { BufferSet } from './BufferSet'; import { BufferSet } from './BufferSet';
import { MockTerminal } from './utils/TestUtils';
class TestSelectionManager extends SelectionManager { class TestSelectionManager extends SelectionManager {
constructor( constructor(
@@ -46,7 +47,9 @@ describe('SelectionManager', () => {
window = dom.window; window = dom.window;
document = window.document; document = window.document;
rowContainer = document.createElement('div'); rowContainer = document.createElement('div');
terminal = <any>{ cols: 80, rows: 2, options: {} }; terminal = new MockTerminal();
terminal.cols = 80;
terminal.rows = 2;
terminal.options.scrollback = 100; terminal.options.scrollback = 100;
terminal.buffers = new BufferSet(terminal); terminal.buffers = new BufferSet(terminal);
terminal.buffer = terminal.buffers.active; terminal.buffer = terminal.buffers.active;
@@ -64,7 +67,7 @@ describe('SelectionManager', () => {
describe('_selectWordAt', () => { describe('_selectWordAt', () => {
it('should expand selection for normal width chars', () => { it('should expand selection for normal width chars', () => {
bufferLines.push(stringToRow('foo bar')); bufferLines.set(0, stringToRow('foo bar'));
selectionManager.selectWordAt([0, 0]); selectionManager.selectWordAt([0, 0]);
assert.equal(selectionManager.selectionText, 'foo'); assert.equal(selectionManager.selectionText, 'foo');
selectionManager.selectWordAt([1, 0]); selectionManager.selectWordAt([1, 0]);
@@ -81,7 +84,7 @@ describe('SelectionManager', () => {
assert.equal(selectionManager.selectionText, 'bar'); assert.equal(selectionManager.selectionText, 'bar');
}); });
it('should expand selection for whitespace', () => { it('should expand selection for whitespace', () => {
bufferLines.push(stringToRow('a b')); bufferLines.set(0, stringToRow('a b'));
selectionManager.selectWordAt([0, 0]); selectionManager.selectWordAt([0, 0]);
assert.equal(selectionManager.selectionText, 'a'); assert.equal(selectionManager.selectionText, 'a');
selectionManager.selectWordAt([1, 0]); selectionManager.selectWordAt([1, 0]);
@@ -95,7 +98,7 @@ describe('SelectionManager', () => {
}); });
it('should expand selection for wide characters', () => { it('should expand selection for wide characters', () => {
// Wide characters use a special format // Wide characters use a special format
bufferLines.push([ bufferLines.set(0, [
[null, '中', 2], [null, '中', 2],
[null, '', 0], [null, '', 0],
[null, '文', 2], [null, '文', 2],
@@ -147,7 +150,7 @@ describe('SelectionManager', () => {
assert.equal(selectionManager.selectionText, 'foo'); assert.equal(selectionManager.selectionText, 'foo');
}); });
it('should select up to non-path characters that are commonly adjacent to paths', () => { it('should select up to non-path characters that are commonly adjacent to paths', () => {
bufferLines.push(stringToRow('(cd)[ef]{gh}\'ij"')); bufferLines.set(0, stringToRow('(cd)[ef]{gh}\'ij"'));
selectionManager.selectWordAt([0, 0]); selectionManager.selectWordAt([0, 0]);
assert.equal(selectionManager.selectionText, '(cd'); assert.equal(selectionManager.selectionText, '(cd');
selectionManager.selectWordAt([1, 0]); selectionManager.selectWordAt([1, 0]);
@@ -185,7 +188,7 @@ describe('SelectionManager', () => {
describe('_selectLineAt', () => { describe('_selectLineAt', () => {
it('should select the entire line', () => { it('should select the entire line', () => {
bufferLines.push(stringToRow('foo bar')); bufferLines.set(0, stringToRow('foo bar'));
selectionManager.selectLineAt(0); selectionManager.selectLineAt(0);
assert.equal(selectionManager.selectionText, 'foo bar', 'The selected text is correct'); assert.equal(selectionManager.selectionText, 'foo bar', 'The selected text is correct');
assert.deepEqual(selectionManager.model.finalSelectionStart, [0, 0]); assert.deepEqual(selectionManager.model.finalSelectionStart, [0, 0]);
@@ -195,11 +198,12 @@ describe('SelectionManager', () => {
describe('selectAll', () => { describe('selectAll', () => {
it('should select the entire buffer, beyond the viewport', () => { it('should select the entire buffer, beyond the viewport', () => {
bufferLines.push(stringToRow('1')); bufferLines.length = 5;
bufferLines.push(stringToRow('2')); bufferLines.set(0, stringToRow('1'));
bufferLines.push(stringToRow('3')); bufferLines.set(1, stringToRow('2'));
bufferLines.push(stringToRow('4')); bufferLines.set(2, stringToRow('3'));
bufferLines.push(stringToRow('5')); bufferLines.set(3, stringToRow('4'));
bufferLines.set(4, stringToRow('5'));
selectionManager.selectAll(); selectionManager.selectAll();
terminal.buffer.ybase = bufferLines.length - terminal.rows; terminal.buffer.ybase = bufferLines.length - terminal.rows;
assert.equal(selectionManager.selectionText, '1\n2\n3\n4\n5'); assert.equal(selectionManager.selectionText, '1\n2\n3\n4\n5');
+4 -1
View File
@@ -5,6 +5,7 @@ import { assert } from 'chai';
import { ITerminal } from './Interfaces'; import { ITerminal } from './Interfaces';
import { SelectionModel } from './SelectionModel'; import { SelectionModel } from './SelectionModel';
import {BufferSet} from './BufferSet'; import {BufferSet} from './BufferSet';
import { MockTerminal } from './utils/TestUtils';
class TestSelectionModel extends SelectionModel { class TestSelectionModel extends SelectionModel {
constructor( constructor(
@@ -22,7 +23,9 @@ describe('SelectionManager', () => {
let model: TestSelectionModel; let model: TestSelectionModel;
beforeEach(() => { beforeEach(() => {
terminal = <any>{ cols: 80, rows: 2, ybase: 0, options: {} }; terminal = new MockTerminal();
terminal.cols = 80;
terminal.rows = 2;
terminal.options.scrollback = 10; terminal.options.scrollback = 10;
terminal.buffers = new BufferSet(terminal); terminal.buffers = new BufferSet(terminal);
terminal.buffer = terminal.buffers.active; terminal.buffer = terminal.buffers.active;
+11 -81
View File
@@ -391,11 +391,6 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
this.buffer = buffer; this.buffer = buffer;
}); });
let i = this.rows;
while (i--) {
this.buffer.lines.push(this.blankLine());
}
// Ensure the selection manager has the correct buffer // Ensure the selection manager has the correct buffer
if (this.selectionManager) { if (this.selectionManager) {
this.selectionManager.setBuffer(this.buffer.lines); this.selectionManager.setBuffer(this.buffer.lines);
@@ -1965,86 +1960,21 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
if (x < 1) x = 1; if (x < 1) x = 1;
if (y < 1) y = 1; if (y < 1) y = 1;
// resize cols this.buffers.resize(x, y);
j = this.cols;
if (j < x) { // Adjust rows in the DOM to accurately reflect the new dimensions
ch = [this.defAttr, ' ', 1]; // does xterm use the default attr? while (this.children.length < y) {
i = this.buffer.lines.length; this.insertRow();
while (i--) { }
if (this.buffer.lines.get(i) === undefined) { while (this.children.length > y) {
this.buffer.lines.set(i, this.blankLine()); el = this.children.shift();
} if (!el) continue;
while (this.buffer.lines.get(i).length < x) { el.parentNode.removeChild(el);
this.buffer.lines.get(i).push(ch);
}
}
} }
this.cols = x; this.cols = x;
this.setupStops(this.cols);
// resize rows
j = this.rows;
addToY = 0;
if (j < y) {
el = this.element;
while (j++ < y) {
// y is rows, not this.buffer.y
if (this.buffer.lines.length < y + this.buffer.ybase) {
if (this.buffer.ybase > 0 && this.buffer.lines.length <= this.buffer.ybase + this.buffer.y + addToY + 1) {
// There is room above the buffer and there are no empty elements below the line,
// scroll up
this.buffer.ybase--;
addToY++;
if (this.buffer.ydisp > 0) {
// Viewport is at the top of the buffer, must increase downwards
this.buffer.ydisp--;
}
} else {
// Add a blank line if there is no buffer left at the top to scroll to, or if there
// are blank lines after the cursor
this.buffer.lines.push(this.blankLine());
}
}
if (this.children.length < y) {
this.insertRow();
}
}
} else { // (j > y)
while (j-- > y) {
if (this.buffer.lines.length > y + this.buffer.ybase) {
if (this.buffer.lines.length > this.buffer.ybase + this.buffer.y + 1) {
// The line is a blank line below the cursor, remove it
this.buffer.lines.pop();
} else {
// The line is the cursor, scroll down
this.buffer.ybase++;
this.buffer.ydisp++;
}
}
if (this.children.length > y) {
el = this.children.shift();
if (!el) continue;
el.parentNode.removeChild(el);
}
}
}
this.rows = y; this.rows = y;
this.setupStops(this.cols);
// Make sure that the cursor stays on screen
if (this.buffer.y >= y) {
this.buffer.y = y - 1;
}
if (addToY) {
this.buffer.y += addToY;
}
if (this.buffer.x >= x) {
this.buffer.x = x - 1;
}
this.buffer.scrollTop = 0;
this.buffer.scrollBottom = y - 1;
this.charMeasure.measure(); this.charMeasure.measure();
+14 -4
View File
@@ -44,6 +44,16 @@ describe('xterm.js', function() {
}); });
describe('setOption', function() { describe('setOption', function() {
let originalWarn;
let warnCallCount;
beforeEach(() => {
originalWarn = console.warn;
warnCallCount = 0;
console.warn = () => warnCallCount++;
});
afterEach(() => {
console.warn = originalWarn;
});
it('should set the option correctly', function() { it('should set the option correctly', function() {
xterm.setOption('cursorBlink', true); xterm.setOption('cursorBlink', true);
assert.equal(xterm.cursorBlink, true); assert.equal(xterm.cursorBlink, true);
@@ -55,10 +65,10 @@ describe('xterm.js', function() {
it('should throw when setting a non-existant option', function() { it('should throw when setting a non-existant option', function() {
assert.throws(xterm.setOption.bind(xterm, 'fake', true)); assert.throws(xterm.setOption.bind(xterm, 'fake', true));
}); });
it('should not allow scrollback less than number of rows', function() { it('should warn and do nothing when scrollback is less than number of rows', function() {
let setOptionCall = xterm.setOption.bind(xterm, 'scrollback', xterm.rows - 1); xterm.setOption('scrollback', xterm.rows - 1);
assert.equal(xterm.getOption('scrollback'), 1000);
assert.equal(setOptionCall(), false); assert.equal(warnCallCount, 1);
}); });
}); });
+57
View File
@@ -0,0 +1,57 @@
import { ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, IListenerType } from '../Interfaces';
export class MockTerminal implements ITerminal {
options: ITerminalOptions = {};
element: HTMLElement;
rowContainer: HTMLElement;
selectionContainer: HTMLElement;
selectionManager: ISelectionManager;
charMeasure: ICharMeasure;
textarea: HTMLTextAreaElement;
rows: number;
cols: number;
browser: IBrowser;
writeBuffer: string[];
children: HTMLElement[];
cursorHidden: boolean;
cursorState: number;
defAttr: number;
scrollback: number;
buffers: IBufferSet;
buffer: IBuffer;
handler(data: string): void {
throw new Error('Method not implemented.');
}
on(event: string, callback: () => void): void {
throw new Error('Method not implemented.');
}
off(type: string, listener: IListenerType): void {
throw new Error('Method not implemented.');
}
scrollDisp(disp: number, suppressScrollEvent: boolean): void {
throw new Error('Method not implemented.');
}
cancel(ev: Event, force?: boolean): void {
throw new Error('Method not implemented.');
}
log(text: string): void {
throw new Error('Method not implemented.');
}
emit(event: string, data: any): void {
throw new Error('Method not implemented.');
}
reset(): void {
throw new Error('Method not implemented.');
}
showCursor(): void {
throw new Error('Method not implemented.');
}
blankLine(cur?: boolean, isWrapped?: boolean): [number, string, number][] {
const line: [number, string, number][] = [];
for (let i = 0; i < this.cols; i++) {
line.push([0, ' ', 1]);
}
return line;
}
}
+2389
View File
File diff suppressed because it is too large Load Diff