@xterm/xterm 5.6.0-beta.4 → 5.6.0-beta.41

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.
@@ -2972,14 +2972,18 @@ export class InputHandler extends Disposable implements IInputHandler {
2972
2972
  * feedback. Use `OSC 8 ; ; BEL` to finish the current hyperlink.
2973
2973
  */
2974
2974
  public setHyperlink(data: string): boolean {
2975
- const args = data.split(';');
2976
- if (args.length < 2) {
2977
- return false;
2975
+ // Arg parsing is special cases to support unencoded semi-colons in the URIs (#4944)
2976
+ const idx = data.indexOf(';');
2977
+ if (idx === -1) {
2978
+ // malformed sequence, just return as handled
2979
+ return true;
2978
2980
  }
2979
- if (args[1]) {
2980
- return this._createHyperlink(args[0], args[1]);
2981
+ const id = data.slice(0, idx).trim();
2982
+ const uri = data.slice(idx + 1);
2983
+ if (uri) {
2984
+ return this._createHyperlink(id, uri);
2981
2985
  }
2982
- if (args[0].trim()) {
2986
+ if (id.trim()) {
2983
2987
  return false;
2984
2988
  }
2985
2989
  return this._finishHyperlink();
@@ -3452,6 +3456,6 @@ class DirtyRowTracker implements IDirtyRowTracker {
3452
3456
  }
3453
3457
  }
3454
3458
 
3455
- function isValidColorIndex(value: number): value is ColorIndex {
3459
+ export function isValidColorIndex(value: number): value is ColorIndex {
3456
3460
  return 0 <= value && value < 256;
3457
3461
  }
@@ -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. This
11
- * list is based on binary search and as such locating a key will take O(log n) amortized, this
12
- * includes the by key iterator.
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 readonly _array: T[] = [];
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
- if (this._array.length === 0) {
28
- this._array.push(value);
29
- return;
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._array.splice(i, 1);
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
  }
@@ -425,8 +425,8 @@ type Enumerate<N extends number, Acc extends number[] = []> = Acc['length'] exte
425
425
  : Enumerate<N, [...Acc, Acc['length']]>;
426
426
  type IntRange<F extends number, T extends number> = Exclude<Enumerate<T>, Enumerate<F>>;
427
427
 
428
- type ColorIndex = IntRange<0, 256>; // number from 0 to 255
429
- type AllColorIndex = ColorIndex | SpecialColorIndex;
428
+ export type ColorIndex = IntRange<0, 256>; // number from 0 to 255
429
+ export type AllColorIndex = ColorIndex | SpecialColorIndex;
430
430
  export const enum SpecialColorIndex {
431
431
  FOREGROUND = 256,
432
432
  BACKGROUND = 257,
@@ -611,8 +611,8 @@ export class Buffer implements IBuffer {
611
611
  this._isClearing = true;
612
612
  for (let i = 0; i < this.markers.length; i++) {
613
613
  this.markers[i].dispose();
614
- this.markers.splice(i--, 1);
615
614
  }
615
+ this.markers.length = 0;
616
616
  this._isClearing = false;
617
617
  }
618
618
 
@@ -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);
@@ -47,11 +47,13 @@ declare module '@xterm/xterm' {
47
47
 
48
48
  /**
49
49
  * When enabled the cursor will be set to the beginning of the next line
50
- * with every new line. This is equivalent to sending '\r\n' for each '\n'.
51
- * Normally the termios settings of the underlying PTY deals with the
52
- * translation of '\n' to '\r\n' and this setting should not be used. If you
50
+ * with every new line. This is equivalent to sending `\r\n` for each `\n`.
51
+ * Normally the settings of the underlying PTY (`termios`) deal with the
52
+ * translation of `\n` to `\r\n` and this setting should not be used. If you
53
53
  * deal with data from a non-PTY related source, this settings might be
54
54
  * useful.
55
+ *
56
+ * @see https://pubs.opengroup.org/onlinepubs/007904975/basedefs/termios.h.html
55
57
  */
56
58
  convertEol?: boolean;
57
59
 
File without changes
File without changes
File without changes