move blankLine to TerminalLine

This commit is contained in:
Jörg Breitbart
2018-08-26 14:27:38 +02:00
parent a99cac45f7
commit cd8477a942
7 changed files with 43 additions and 41 deletions
+4 -4
View File
@@ -5,7 +5,7 @@
import { assert } from 'chai';
import { ITerminal } from './Types';
import { Buffer } from './Buffer';
import { Buffer, DEFAULT_ATTR } from './Buffer';
import { CircularList } from './common/CircularList';
import { MockTerminal } from './utils/TestUtils.test';
import { TerminalLine } from './TerminalLine';
@@ -37,7 +37,7 @@ describe('Buffer', () => {
describe('fillViewportRows', () => {
it('should fill the buffer with blank lines based on the size of the viewport', () => {
const blankLineChar = terminal.blankLine().get(0);
const blankLineChar = TerminalLine.blankLine(terminal.cols, DEFAULT_ATTR).get(0);
buffer.fillViewportRows();
assert.equal(buffer.lines.length, INIT_ROWS);
for (let y = 0; y < INIT_ROWS; y++) {
@@ -180,7 +180,7 @@ describe('Buffer', () => {
buffer.fillViewportRows();
// Create 10 extra blank lines
for (let i = 0; i < 10; i++) {
buffer.lines.push(terminal.blankLine());
buffer.lines.push(TerminalLine.blankLine(terminal.cols, DEFAULT_ATTR));
}
// Set cursor to the bottom of the buffer
buffer.y = INIT_ROWS - 1;
@@ -200,7 +200,7 @@ describe('Buffer', () => {
buffer.fillViewportRows();
// Create 10 extra blank lines
for (let i = 0; i < 10; i++) {
buffer.lines.push(terminal.blankLine());
buffer.lines.push(TerminalLine.blankLine(terminal.cols, DEFAULT_ATTR));
}
// Set cursor to the bottom of the buffer
buffer.y = INIT_ROWS - 1;
+2 -2
View File
@@ -85,7 +85,7 @@ export class Buffer implements IBuffer {
if (this.lines.length === 0) {
let i = this._terminal.rows;
while (i--) {
this.lines.push(this._terminal.blankLine());
this.lines.push(TerminalLine.blankLine(this._terminal.cols, DEFAULT_ATTR));
}
}
}
@@ -147,7 +147,7 @@ export class Buffer implements IBuffer {
} 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(undefined, undefined, newCols));
this.lines.push(TerminalLine.blankLine(newCols, DEFAULT_ATTR));
}
}
}
+5 -4
View File
@@ -13,6 +13,7 @@ import { wcwidth } from './CharWidth';
import { EscapeSequenceParser } from './EscapeSequenceParser';
import { ICharset } from './core/Types';
import { Disposable } from './common/Lifecycle';
import { TerminalLine } from './TerminalLine';
/**
* Map collect to glevel. Used in `selectCharset`.
@@ -815,7 +816,7 @@ export class InputHandler extends Disposable implements IInputHandler {
// test: echo -e '\e[44m\e[1L\e[0m'
// blankLine(true) - xterm/linux behavior
buffer.lines.splice(scrollBottomAbsolute - 1, 1);
buffer.lines.splice(row, 0, this._terminal.blankLine(true));
buffer.lines.splice(row, 0, TerminalLine.blankLine(this._terminal.cols, this._terminal.eraseAttr()));
}
// this.maxRange();
@@ -845,7 +846,7 @@ export class InputHandler extends Disposable implements IInputHandler {
// test: echo -e '\e[44m\e[1M\e[0m'
// blankLine(true) - xterm/linux behavior
buffer.lines.splice(row, 1);
buffer.lines.splice(j, 0, this._terminal.blankLine(true));
buffer.lines.splice(j, 0, TerminalLine.blankLine(this._terminal.cols, this._terminal.eraseAttr()));
}
// this.maxRange();
@@ -887,7 +888,7 @@ export class InputHandler extends Disposable implements IInputHandler {
while (param--) {
buffer.lines.splice(buffer.ybase + buffer.scrollTop, 1);
buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 0, this._terminal.blankLine());
buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 0, TerminalLine.blankLine(this._terminal.cols, DEFAULT_ATTR));
}
// this.maxRange();
this._terminal.updateRange(buffer.scrollTop);
@@ -906,7 +907,7 @@ export class InputHandler extends Disposable implements IInputHandler {
while (param--) {
buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 1);
buffer.lines.splice(buffer.ybase + buffer.scrollTop, 0, this._terminal.blankLine());
buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 0, TerminalLine.blankLine(this._terminal.cols, DEFAULT_ATTR));
}
// this.maxRange();
this._terminal.updateRange(buffer.scrollTop);
+5 -4
View File
@@ -6,7 +6,8 @@
import { assert, expect } from 'chai';
import { Terminal } from './Terminal';
import { MockViewport, MockCompositionHelper, MockRenderer } from './utils/TestUtils.test';
import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX } from './Buffer';
import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, DEFAULT_ATTR } from './Buffer';
import { TerminalLine } from './TerminalLine';
const INIT_COLS = 80;
const INIT_ROWS = 24;
@@ -141,7 +142,7 @@ describe('term.js addons', () => {
assert.equal(term.buffer.lines.length, term.rows);
assert.deepEqual(term.buffer.lines.get(0), promptLine);
for (let i = 1; i < term.rows; i++) {
assert.deepEqual(term.buffer.lines.get(i), term.blankLine());
assert.deepEqual(term.buffer.lines.get(i), TerminalLine.blankLine(term.cols, DEFAULT_ATTR));
}
});
it('should clear a buffer larger than rows', () => {
@@ -158,7 +159,7 @@ describe('term.js addons', () => {
assert.equal(term.buffer.lines.length, term.rows);
assert.deepEqual(term.buffer.lines.get(0), promptLine);
for (let i = 1; i < term.rows; i++) {
assert.deepEqual(term.buffer.lines.get(i), term.blankLine());
assert.deepEqual(term.buffer.lines.get(i), TerminalLine.blankLine(term.cols, DEFAULT_ATTR));
}
});
it('should not break the prompt when cleared twice', () => {
@@ -171,7 +172,7 @@ describe('term.js addons', () => {
assert.equal(term.buffer.lines.length, term.rows);
assert.deepEqual(term.buffer.lines.get(0), promptLine);
for (let i = 1; i < term.rows; i++) {
assert.deepEqual(term.buffer.lines.get(i), term.blankLine());
assert.deepEqual(term.buffer.lines.get(i), TerminalLine.blankLine(term.cols, DEFAULT_ATTR));
}
});
});
+5 -20
View File
@@ -1170,7 +1170,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
* @param isWrapped Whether the new line is wrapped from the previous line.
*/
public scroll(isWrapped?: boolean): void {
const newLine = this.blankLine(undefined, isWrapped);
const newLine = TerminalLine.blankLine(this.cols, DEFAULT_ATTR, isWrapped);
const topRow = this.buffer.ybase + this.buffer.scrollTop;
const bottomRow = this.buffer.ybase + this.buffer.scrollBottom;
@@ -1757,7 +1757,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
this.buffer.ybase = 0;
this.buffer.y = 0;
for (let i = 1; i < this.rows; i++) {
this.buffer.lines.push(this.blankLine());
this.buffer.lines.push(TerminalLine.blankLine(this.cols, DEFAULT_ATTR));
}
this.refresh(0, this.rows - 1);
this.emit('scroll', this.buffer.ydisp);
@@ -1778,24 +1778,9 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
* @param cols The number of columns in the terminal, if this is not
* set, the terminal's current column count would be used.
*/
// FIXME: can this be removed after transition to TerminalLine.blankLine?
public blankLine(cur?: boolean, isWrapped?: boolean, cols?: number): TerminalLine {
const attr = cur ? this.eraseAttr() : DEFAULT_ATTR;
const ch: CharData = [attr, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; // width defaults to 1 halfwidth character
const line = new TerminalLine();
// TODO: It is not ideal that this is a property on an array, a buffer line
// class should be added that will hold this data and other useful functions.
if (isWrapped) {
line.isWrapped = isWrapped;
}
cols = cols || this.cols;
for (let i = 0; i < cols; i++) {
line.set(i, ch);
}
return line;
return TerminalLine.blankLine(cols || this.cols, cur ? this.eraseAttr() : DEFAULT_ATTR, isWrapped);
}
/**
@@ -1884,7 +1869,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
// blankLine(true) is xterm/linux behavior
const scrollRegionHeight = this.buffer.scrollBottom - this.buffer.scrollTop;
this.buffer.lines.shiftElements(this.buffer.y + this.buffer.ybase, scrollRegionHeight, 1);
this.buffer.lines.set(this.buffer.y + this.buffer.ybase, this.blankLine(true));
this.buffer.lines.set(this.buffer.y + this.buffer.ybase, TerminalLine.blankLine(this.cols, this.eraseAttr()));
this.updateRange(this.buffer.scrollTop);
this.updateRange(this.buffer.scrollBottom);
} else {
+20
View File
@@ -3,8 +3,26 @@
* @license MIT
*/
import { CharData } from './Types';
import { NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR } from './Buffer';
/**
* Class representing a terminal line.
* Currently the class is a thin proxy to `CharData[]`.
* Once the storages are in place it will proxy access to
* typed array based line data.
* TODO: move typical line actions in `InputHandler` and `Terminal` here:
* - create blank line
* - insert cells
* - remove cells
*/
export class TerminalLine {
static blankLine(cols: number, attr: number, isWrapped?: boolean): TerminalLine {
const ch: CharData = [attr, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE];
const line = new TerminalLine();
if (isWrapped) line.isWrapped = true;
for (let i = 0; i < cols; i++) line.push(ch);
return line;
}
private _data: CharData[];
public isWrapped = false;
length: number;
@@ -15,6 +33,7 @@ export class TerminalLine {
// for debugging purpose:
// throw Error when something tries to do number index access
// TODO: remove when done with transition
/*
for (let i = 0; i < 100; ++i) {
Object.defineProperty(this, i.toString(), {
get: () => {
@@ -25,6 +44,7 @@ export class TerminalLine {
}
});
}
*/
}
get(index: number): CharData {
+2 -7
View File
@@ -5,7 +5,7 @@
import { IColorSet, IRenderer, IRenderDimensions, IColorManager } from '../renderer/Types';
import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, ICircularList, ILinkifier, IMouseHelper, ILinkMatcherOptions, XtermListener, CharacterJoinerHandler } from '../Types';
import { Buffer, NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR } from '../Buffer';
import { Buffer } from '../Buffer';
import * as Browser from '../shared/utils/Browser';
import { ITheme, IDisposable, IMarker } from 'xterm';
import { TerminalLine } from '../TerminalLine';
@@ -147,12 +147,7 @@ export class MockTerminal implements ITerminal {
throw new Error('Method not implemented.');
}
blankLine(cur?: boolean, isWrapped?: boolean, cols?: number): TerminalLine {
const line = new TerminalLine();
cols = cols || this.cols;
for (let i = 0; i < cols; i++) {
line.push([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);
}
return line;
return TerminalLine.blankLine(this.cols, 0);
}
registerCharacterJoiner(handler: CharacterJoinerHandler): number { return 0; }
deregisterCharacterJoiner(joinerId: number): void { }