mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
move blankLine to TerminalLine
This commit is contained in:
+4
-4
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 { }
|
||||
|
||||
Reference in New Issue
Block a user