@xterm/xterm 5.6.0-beta.4 → 5.6.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
package/src/browser/Viewport.ts
CHANGED
|
@@ -51,6 +51,8 @@ export class Viewport extends Disposable implements IViewport {
|
|
|
51
51
|
target: -1
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
+
private _ensureTimeout: number;
|
|
55
|
+
|
|
54
56
|
private readonly _onRequestScrollLines = this.register(new EventEmitter<{ amount: number, suppressScrollEvent: boolean }>());
|
|
55
57
|
public readonly onRequestScrollLines = this._onRequestScrollLines.event;
|
|
56
58
|
|
|
@@ -83,7 +85,7 @@ export class Viewport extends Disposable implements IViewport {
|
|
|
83
85
|
this.register(this._optionsService.onSpecificOptionChange('scrollback', () => this.syncScrollArea()));
|
|
84
86
|
|
|
85
87
|
// Perform this async to ensure the ICharSizeService is ready.
|
|
86
|
-
setTimeout(() => this.syncScrollArea());
|
|
88
|
+
this._ensureTimeout = window.setTimeout(() => this.syncScrollArea());
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
private _handleThemeChange(colors: ReadonlyColorSet): void {
|
|
@@ -405,4 +407,8 @@ export class Viewport extends Disposable implements IViewport {
|
|
|
405
407
|
this._viewportElement.scrollTop += deltaY;
|
|
406
408
|
return this._bubbleScroll(ev, deltaY);
|
|
407
409
|
}
|
|
410
|
+
|
|
411
|
+
public dispose(): void {
|
|
412
|
+
clearTimeout(this._ensureTimeout);
|
|
413
|
+
}
|
|
408
414
|
}
|
|
@@ -20,6 +20,8 @@ import { IBufferNamespace as IBufferNamespaceApi, IDecoration, IDecorationOption
|
|
|
20
20
|
*/
|
|
21
21
|
const CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows'];
|
|
22
22
|
|
|
23
|
+
let $value = 0;
|
|
24
|
+
|
|
23
25
|
export class Terminal extends Disposable implements ITerminalApi {
|
|
24
26
|
private _core: ITerminal;
|
|
25
27
|
private _addonManager: AddonManager;
|
|
@@ -249,16 +251,16 @@ export class Terminal extends Disposable implements ITerminalApi {
|
|
|
249
251
|
}
|
|
250
252
|
|
|
251
253
|
private _verifyIntegers(...values: number[]): void {
|
|
252
|
-
for (
|
|
253
|
-
if (value === Infinity || isNaN(value) || value % 1 !== 0) {
|
|
254
|
+
for ($value of values) {
|
|
255
|
+
if ($value === Infinity || isNaN($value) || $value % 1 !== 0) {
|
|
254
256
|
throw new Error('This API only accepts integers');
|
|
255
257
|
}
|
|
256
258
|
}
|
|
257
259
|
}
|
|
258
260
|
|
|
259
261
|
private _verifyPositiveIntegers(...values: number[]): void {
|
|
260
|
-
for (
|
|
261
|
-
if (value && (value === Infinity || isNaN(value) || value % 1 !== 0 || value < 0)) {
|
|
262
|
+
for ($value of values) {
|
|
263
|
+
if ($value && ($value === Infinity || isNaN($value) || $value % 1 !== 0 || $value < 0)) {
|
|
262
264
|
throw new Error('This API only accepts positive integers');
|
|
263
265
|
}
|
|
264
266
|
}
|
package/src/common/SortedList.ts
CHANGED
|
@@ -3,16 +3,27 @@
|
|
|
3
3
|
* @license MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { IdleTaskQueue } from 'common/TaskQueue';
|
|
7
|
+
|
|
6
8
|
// Work variables to avoid garbage collection.
|
|
7
9
|
let i = 0;
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
|
-
* A generic list that is maintained in sorted order and allows values with duplicate keys.
|
|
11
|
-
*
|
|
12
|
-
*
|
|
12
|
+
* A generic list that is maintained in sorted order and allows values with duplicate keys. Deferred
|
|
13
|
+
* batch insertion and deletion is used to significantly reduce the time it takes to insert and
|
|
14
|
+
* delete a large amount of items in succession. This list is based on binary search and as such
|
|
15
|
+
* locating a key will take O(log n) amortized, this includes the by key iterator.
|
|
13
16
|
*/
|
|
14
17
|
export class SortedList<T> {
|
|
15
|
-
private
|
|
18
|
+
private _array: T[] = [];
|
|
19
|
+
|
|
20
|
+
private readonly _insertedValues: T[] = [];
|
|
21
|
+
private readonly _flushInsertedTask = new IdleTaskQueue();
|
|
22
|
+
private _isFlushingInserted = false;
|
|
23
|
+
|
|
24
|
+
private readonly _deletedIndices: number[] = [];
|
|
25
|
+
private readonly _flushDeletedTask = new IdleTaskQueue();
|
|
26
|
+
private _isFlushingDeleted = false;
|
|
16
27
|
|
|
17
28
|
constructor(
|
|
18
29
|
private readonly _getKey: (value: T) => number
|
|
@@ -21,18 +32,50 @@ export class SortedList<T> {
|
|
|
21
32
|
|
|
22
33
|
public clear(): void {
|
|
23
34
|
this._array.length = 0;
|
|
35
|
+
this._insertedValues.length = 0;
|
|
36
|
+
this._flushInsertedTask.clear();
|
|
37
|
+
this._isFlushingInserted = false;
|
|
38
|
+
this._deletedIndices.length = 0;
|
|
39
|
+
this._flushDeletedTask.clear();
|
|
40
|
+
this._isFlushingDeleted = false;
|
|
24
41
|
}
|
|
25
42
|
|
|
26
43
|
public insert(value: T): void {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
44
|
+
this._flushCleanupDeleted();
|
|
45
|
+
if (this._insertedValues.length === 0) {
|
|
46
|
+
this._flushInsertedTask.enqueue(() => this._flushInserted());
|
|
47
|
+
}
|
|
48
|
+
this._insertedValues.push(value);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private _flushInserted(): void {
|
|
52
|
+
const sortedAddedValues = this._insertedValues.sort((a, b) => this._getKey(a) - this._getKey(b));
|
|
53
|
+
let sortedAddedValuesIndex = 0;
|
|
54
|
+
let arrayIndex = 0;
|
|
55
|
+
|
|
56
|
+
const newArray = new Array(this._array.length + this._insertedValues.length);
|
|
57
|
+
|
|
58
|
+
for (let newArrayIndex = 0; newArrayIndex < newArray.length; newArrayIndex++) {
|
|
59
|
+
if (arrayIndex >= this._array.length || this._getKey(sortedAddedValues[sortedAddedValuesIndex]) <= this._getKey(this._array[arrayIndex])) {
|
|
60
|
+
newArray[newArrayIndex] = sortedAddedValues[sortedAddedValuesIndex];
|
|
61
|
+
sortedAddedValuesIndex++;
|
|
62
|
+
} else {
|
|
63
|
+
newArray[newArrayIndex] = this._array[arrayIndex++];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
this._array = newArray;
|
|
68
|
+
this._insertedValues.length = 0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private _flushCleanupInserted(): void {
|
|
72
|
+
if (!this._isFlushingInserted && this._insertedValues.length > 0) {
|
|
73
|
+
this._flushInsertedTask.flush();
|
|
30
74
|
}
|
|
31
|
-
i = this._search(this._getKey(value));
|
|
32
|
-
this._array.splice(i, 0, value);
|
|
33
75
|
}
|
|
34
76
|
|
|
35
77
|
public delete(value: T): boolean {
|
|
78
|
+
this._flushCleanupInserted();
|
|
36
79
|
if (this._array.length === 0) {
|
|
37
80
|
return false;
|
|
38
81
|
}
|
|
@@ -49,14 +92,43 @@ export class SortedList<T> {
|
|
|
49
92
|
}
|
|
50
93
|
do {
|
|
51
94
|
if (this._array[i] === value) {
|
|
52
|
-
this.
|
|
95
|
+
if (this._deletedIndices.length === 0) {
|
|
96
|
+
this._flushDeletedTask.enqueue(() => this._flushDeleted());
|
|
97
|
+
}
|
|
98
|
+
this._deletedIndices.push(i);
|
|
53
99
|
return true;
|
|
54
100
|
}
|
|
55
101
|
} while (++i < this._array.length && this._getKey(this._array[i]) === key);
|
|
56
102
|
return false;
|
|
57
103
|
}
|
|
58
104
|
|
|
105
|
+
private _flushDeleted(): void {
|
|
106
|
+
this._isFlushingDeleted = true;
|
|
107
|
+
const sortedDeletedIndices = this._deletedIndices.sort((a, b) => a - b);
|
|
108
|
+
let sortedDeletedIndicesIndex = 0;
|
|
109
|
+
const newArray = new Array(this._array.length - sortedDeletedIndices.length);
|
|
110
|
+
let newArrayIndex = 0;
|
|
111
|
+
for (let i = 0; i < this._array.length; i++) {
|
|
112
|
+
if (sortedDeletedIndices[sortedDeletedIndicesIndex] === i) {
|
|
113
|
+
sortedDeletedIndicesIndex++;
|
|
114
|
+
} else {
|
|
115
|
+
newArray[newArrayIndex++] = this._array[i];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
this._array = newArray;
|
|
119
|
+
this._deletedIndices.length = 0;
|
|
120
|
+
this._isFlushingDeleted = false;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private _flushCleanupDeleted(): void {
|
|
124
|
+
if (!this._isFlushingDeleted && this._deletedIndices.length > 0) {
|
|
125
|
+
this._flushDeletedTask.flush();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
59
129
|
public *getKeyIterator(key: number): IterableIterator<T> {
|
|
130
|
+
this._flushCleanupInserted();
|
|
131
|
+
this._flushCleanupDeleted();
|
|
60
132
|
if (this._array.length === 0) {
|
|
61
133
|
return;
|
|
62
134
|
}
|
|
@@ -73,6 +145,8 @@ export class SortedList<T> {
|
|
|
73
145
|
}
|
|
74
146
|
|
|
75
147
|
public forEachByKey(key: number, callback: (value: T) => void): void {
|
|
148
|
+
this._flushCleanupInserted();
|
|
149
|
+
this._flushCleanupDeleted();
|
|
76
150
|
if (this._array.length === 0) {
|
|
77
151
|
return;
|
|
78
152
|
}
|
|
@@ -89,6 +163,8 @@ export class SortedList<T> {
|
|
|
89
163
|
}
|
|
90
164
|
|
|
91
165
|
public values(): IterableIterator<T> {
|
|
166
|
+
this._flushCleanupInserted();
|
|
167
|
+
this._flushCleanupDeleted();
|
|
92
168
|
// Duplicate the array to avoid issues when _array changes while iterating
|
|
93
169
|
return [...this._array].values();
|
|
94
170
|
}
|
|
@@ -45,7 +45,8 @@ export class DecorationService extends Disposable implements IDecorationService
|
|
|
45
45
|
const decoration = new Decoration(options);
|
|
46
46
|
if (decoration) {
|
|
47
47
|
const markerDispose = decoration.marker.onDispose(() => decoration.dispose());
|
|
48
|
-
decoration.onDispose(() => {
|
|
48
|
+
const listener = decoration.onDispose(() => {
|
|
49
|
+
listener.dispose();
|
|
49
50
|
if (decoration) {
|
|
50
51
|
if (this._decorations.delete(decoration)) {
|
|
51
52
|
this._onDecorationRemoved.fire(decoration);
|