Skip to content

Commit

Permalink
Merge branch 'master' into optimisation_wcwidth
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyriar committed Nov 23, 2018
2 parents 65c5df9 + b4faaef commit fe027a2
Show file tree
Hide file tree
Showing 16 changed files with 81 additions and 40 deletions.
3 changes: 2 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ opening an issue, read these pointers.

## Contributing code

- Make sure you have a [GitHub account](https://github.com/join)
You can find issues to work on by looking at the [help wanted](https://github.com/xtermjs/xterm.js/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) or [good first issue](https://github.com/xtermjs/xterm.js/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) issues. It's a good idea to comment on the issue saying that you're taking it, just in case someone else comes along and you duplicate work. Once you have your issue, here are the steps to contribute:

- Fork [xterm.js](https://github.com/sourcelair/xterm.js/)
([how to fork a repo](https://help.github.com/articles/fork-a-repo))
- Get the [xterm.js demo](https://github.com/xtermjs/xterm.js/wiki/Contributing#running-the-demo) running
Expand Down
7 changes: 2 additions & 5 deletions src/BufferLine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,8 @@ export class BufferLine implements IBufferLine {
}
}

public copyFrom(line: IBufferLine): void {
this._data = [];
for (let i = 0; i < line.length; ++i) {
this._push(line.get(i));
}
public copyFrom(line: BufferLine): void {
this._data = line._data.slice(0);
this.length = line.length;
this.isWrapped = line.isWrapped;
}
Expand Down
40 changes: 32 additions & 8 deletions src/Terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
* http://linux.die.net/man/7/urxvt
*/

import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, ILinkifier, ILinkMatcherOptions, CustomKeyEventHandler, LinkMatcherHandler, CharData, CharacterJoinerHandler } from './Types';
import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, ILinkifier, ILinkMatcherOptions, CustomKeyEventHandler, LinkMatcherHandler, CharData, CharacterJoinerHandler, IBufferLine } from './Types';
import { IMouseZoneManager } from './ui/Types';
import { IRenderer } from './renderer/Types';
import { BufferSet } from './BufferSet';
import { Buffer, MAX_BUFFER_SIZE, DEFAULT_ATTR, NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR } from './Buffer';
import { Buffer, MAX_BUFFER_SIZE, DEFAULT_ATTR, NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR, CHAR_DATA_ATTR_INDEX } from './Buffer';
import { CompositionHelper } from './CompositionHelper';
import { EventEmitter } from './common/EventEmitter';
import { Viewport } from './Viewport';
Expand Down Expand Up @@ -208,6 +208,9 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
private _screenDprMonitor: ScreenDprMonitor;
private _theme: ITheme;

// bufferline to clone/copy from for new blank lines
private _blankLine: IBufferLine = null;

public cols: number;
public rows: number;

Expand Down Expand Up @@ -497,6 +500,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
case 'experimentalBufferLineImpl':
this.buffers.normal.setBufferLineFactory(value);
this.buffers.alt.setBufferLineFactory(value);
this._blankLine = null;
break;
}
// Inform renderer of changes
Expand Down Expand Up @@ -1174,20 +1178,40 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
* Scroll the terminal down 1 row, creating a blank line.
* @param isWrapped Whether the new line is wrapped from the previous line.
*/
public scroll(isWrapped?: boolean): void {
const newLine = this.buffer.getBlankLine(this.eraseAttr(), isWrapped);
public scroll(isWrapped: boolean = false): void {
let newLine: IBufferLine;
const useRecycling = this.options.experimentalBufferLineImpl === 'TypedArray';
if (useRecycling) {
newLine = this._blankLine;
if (!newLine || newLine.length !== this.cols || newLine.get(0)[CHAR_DATA_ATTR_INDEX] !== this.eraseAttr()) {
newLine = this.buffer.getBlankLine(this.eraseAttr(), isWrapped);
this._blankLine = newLine;
}
newLine.isWrapped = isWrapped;
} else {
newLine = this.buffer.getBlankLine(this.eraseAttr(), isWrapped);
}

const topRow = this.buffer.ybase + this.buffer.scrollTop;
const bottomRow = this.buffer.ybase + this.buffer.scrollBottom;

if (this.buffer.scrollTop === 0) {
// Determine whether the buffer is going to be trimmed after insertion.
const willBufferBeTrimmed = this.buffer.lines.length === this.buffer.lines.maxLength;
const willBufferBeTrimmed = this.buffer.lines.isFull;

// Insert the line using the fastest method
if (bottomRow === this.buffer.lines.length - 1) {
this.buffer.lines.push(newLine);
if (useRecycling) {
if (willBufferBeTrimmed) {
this.buffer.lines.recycle().copyFrom(newLine);
} else {
this.buffer.lines.push(newLine.clone());
}
} else {
this.buffer.lines.push(newLine);
}
} else {
this.buffer.lines.splice(bottomRow + 1, 0, newLine);
this.buffer.lines.splice(bottomRow + 1, 0, (useRecycling) ? newLine.clone() : newLine);
}

// Only adjust ybase and ydisp when the buffer is not trimmed
Expand All @@ -1209,7 +1233,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
// scrollback, instead we can just shift them in-place.
const scrollRegionHeight = bottomRow - topRow + 1/*as it's zero-based*/;
this.buffer.lines.shiftElements(topRow + 1, scrollRegionHeight - 1, -1);
this.buffer.lines.set(bottomRow, newLine);
this.buffer.lines.set(bottomRow, (useRecycling) ? newLine.clone() : newLine);
}

// Move the viewport to the bottom of the buffer unless the user is
Expand Down
2 changes: 1 addition & 1 deletion src/addons/attach/attach.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @license MIT
*/

import { assert, expect } from 'chai';
import { assert } from 'chai';

import * as attach from './attach';

Expand Down
2 changes: 1 addition & 1 deletion src/addons/fit/fit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @license MIT
*/

import { assert, expect } from 'chai';
import { assert } from 'chai';

import * as fit from './fit';

Expand Down
2 changes: 1 addition & 1 deletion src/addons/fullscreen/fullscreen.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @license MIT
*/

import { assert, expect } from 'chai';
import { assert } from 'chai';

import * as fullscreen from './fullscreen';

Expand Down
11 changes: 6 additions & 5 deletions src/addons/fullscreen/fullscreen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,18 @@ import { Terminal } from 'xterm';
* @param fullscreen Toggle fullscreen on (true) or off (false)
*/
export function toggleFullScreen(term: Terminal, fullscreen: boolean): void {
let fn: string;
let fn: (...tokens: string[]) => void;

if (typeof fullscreen === 'undefined') {
fn = (term.element.classList.contains('fullscreen')) ? 'remove' : 'add';
fn = (term.element.classList.contains('fullscreen')) ?
term.element.classList.remove : term.element.classList.add;
} else if (!fullscreen) {
fn = 'remove';
fn = term.element.classList.remove;
} else {
fn = 'add';
fn = term.element.classList.add;
}

term.element.classList[fn]('fullscreen');
fn('fullscreen');
}

export function apply(terminalConstructor: typeof Terminal): void {
Expand Down
1 change: 1 addition & 0 deletions src/addons/search/search.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Copyright (c) 2018 The xterm.js authors. All rights reserved.
* @license MIT
*/
declare var require: any;

import { assert, expect } from 'chai';
import * as search from './search';
Expand Down
3 changes: 0 additions & 3 deletions src/addons/search/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,5 @@
},
"include": [
"**/*.ts"
],
"exclude": [
"**/*.test.ts"
]
}
2 changes: 1 addition & 1 deletion src/addons/terminado/terminado.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @license MIT
*/

import { assert, expect } from 'chai';
import { assert } from 'chai';

import * as terminado from './terminado';

Expand Down
2 changes: 1 addition & 1 deletion src/addons/webLinks/webLinks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @license MIT
*/

import { assert, expect } from 'chai';
import { assert } from 'chai';

import * as webLinks from './webLinks';

Expand Down
2 changes: 1 addition & 1 deletion src/addons/winptyCompat/winptyCompat.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @license MIT
*/

import { assert, expect } from 'chai';
import { assert } from 'chai';

import * as winptyCompat from './winptyCompat';

Expand Down
2 changes: 1 addition & 1 deletion src/addons/zmodem/zmodem.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @license MIT
*/

import { assert, expect } from 'chai';
import { assert } from 'chai';

import * as zmodem from './zmodem';

Expand Down
4 changes: 2 additions & 2 deletions src/addons/zmodem/zmodem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { Terminal } from 'xterm';
* via `detach()` and a re-`attach()`.)
*/

let zmodem;
let zmodem: any;

export interface IZmodemOptions {
noTerminalWriteOutsideSession?: boolean;
Expand All @@ -44,7 +44,7 @@ function zmodemAttach(ws: WebSocket, opts: IZmodemOptions = {}): void {
const term = this;
const senderFunc = (octets: ArrayLike<number>) => ws.send(new Uint8Array(octets));

let zsentry;
let zsentry: any;

function shouldWrite(): boolean {
return !!zsentry.get_confirmed_session() || !opts.noTerminalWriteOutsideSession;
Expand Down
36 changes: 27 additions & 9 deletions src/common/CircularList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,34 @@ export class CircularList<T> extends EventEmitter implements ICircularList<T> {
public push(value: T): void {
this._array[this._getCyclicIndex(this._length)] = value;
if (this._length === this._maxLength) {
this._startIndex++;
if (this._startIndex === this._maxLength) {
this._startIndex = 0;
}
this._startIndex = ++this._startIndex % this._maxLength;
this.emit('trim', 1);
} else {
this._length++;
}
}

/**
* Advance ringbuffer index and return current element for recycling.
* Note: The buffer must be full for this method to work.
* @throws When the buffer is not full.
*/
public recycle(): T {
if (this._length !== this._maxLength) {
throw new Error('Can only recycle when the buffer is full');
}
this._startIndex = ++this._startIndex % this._maxLength;
this.emit('trim', 1);
return this._array[this._getCyclicIndex(this._length - 1)]!;
}

/**
* Ringbuffer is at max length.
*/
public get isFull(): boolean {
return this._length === this._maxLength;
}

/**
* Removes and returns the last value on the list.
* @return The popped value.
Expand Down Expand Up @@ -136,10 +154,10 @@ export class CircularList<T> extends EventEmitter implements ICircularList<T> {
}

// Adjust length as needed
if (this._length + items.length > this.maxLength) {
const countToTrim = (this._length + items.length) - this.maxLength;
if (this._length + items.length > this._maxLength) {
const countToTrim = (this._length + items.length) - this._maxLength;
this._startIndex += countToTrim;
this._length = this.maxLength;
this._length = this._maxLength;
this.emit('trim', countToTrim);
} else {
this._length += items.length;
Expand Down Expand Up @@ -178,7 +196,7 @@ export class CircularList<T> extends EventEmitter implements ICircularList<T> {
const expandListBy = (start + count + offset) - this._length;
if (expandListBy > 0) {
this._length += expandListBy;
while (this._length > this.maxLength) {
while (this._length > this._maxLength) {
this._length--;
this._startIndex++;
this.emit('trim', 1);
Expand All @@ -198,6 +216,6 @@ export class CircularList<T> extends EventEmitter implements ICircularList<T> {
* @returns The cyclic index.
*/
private _getCyclicIndex(index: number): number {
return (this._startIndex + index) % this.maxLength;
return (this._startIndex + index) % this._maxLength;
}
}
2 changes: 2 additions & 0 deletions src/common/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ export interface IKeyboardEvent {
export interface ICircularList<T> extends IEventEmitter {
length: number;
maxLength: number;
isFull: boolean;

get(index: number): T | undefined;
set(index: number, value: T): void;
push(value: T): void;
recycle(): T | undefined;
pop(): T | undefined;
splice(start: number, deleteCount: number, ...items: T[]): void;
trimStart(count: number): void;
Expand Down

0 comments on commit fe027a2

Please sign in to comment.