mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge branch 'master' into optimisation_wcwidth
This commit is contained in:
+2
-1
@@ -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
|
||||
|
||||
+2
-5
@@ -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;
|
||||
}
|
||||
|
||||
+32
-8
@@ -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';
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
import { assert } from 'chai';
|
||||
|
||||
import * as attach from './attach';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
import { assert } from 'chai';
|
||||
|
||||
import * as fit from './fit';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
import { assert } from 'chai';
|
||||
|
||||
import * as fullscreen from './fullscreen';
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -18,8 +18,5 @@
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"**/*.test.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
import { assert } from 'chai';
|
||||
|
||||
import * as terminado from './terminado';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
import { assert } from 'chai';
|
||||
|
||||
import * as webLinks from './webLinks';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
import { assert } from 'chai';
|
||||
|
||||
import * as winptyCompat from './winptyCompat';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
import { assert } from 'chai';
|
||||
|
||||
import * as zmodem from './zmodem';
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ import { Terminal } from 'xterm';
|
||||
* via `detach()` and a re-`attach()`.)
|
||||
*/
|
||||
|
||||
let zmodem;
|
||||
let zmodem: any;
|
||||
|
||||
export interface IZmodemOptions {
|
||||
noTerminalWriteOutsideSession?: boolean;
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user