@xterm/xterm 6.1.0-beta.215 → 6.1.0-beta.216
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/lib/xterm.js +1 -1
- package/lib/xterm.js.map +1 -1
- package/lib/xterm.mjs +8 -8
- package/lib/xterm.mjs.map +3 -3
- package/package.json +2 -2
- package/src/browser/AccessibilityManager.ts +5 -3
- package/src/browser/renderer/dom/DomRenderer.ts +41 -39
- package/src/browser/scrollable/scrollableElement.ts +7 -5
- package/src/browser/services/SelectionService.ts +26 -27
- package/src/common/CoreTerminal.ts +3 -3
- package/src/common/InputHandler.ts +18 -20
- package/src/common/Version.ts +1 -1
- package/src/common/buffer/BufferLine.ts +56 -58
- package/src/common/input/WriteBuffer.ts +30 -30
- package/src/common/parser/Params.ts +14 -8
- package/src/common/services/BufferService.ts +6 -4
- package/src/common/services/ServiceRegistry.ts +9 -7
|
@@ -9,25 +9,26 @@ import { CellData } from 'common/buffer/CellData';
|
|
|
9
9
|
import { Attributes, BgFlags, CHAR_DATA_ATTR_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, Content, NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR } from 'common/buffer/Constants';
|
|
10
10
|
import { stringFromCodePoint } from 'common/input/TextDecoder';
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
|
|
12
|
+
// Buffer memory layout:
|
|
13
|
+
//
|
|
14
|
+
// [0]: content `uint32_t` - wcwidth(2) comb(1) codepoint(21)
|
|
15
|
+
// [1]: fg `uint32_t` - flags(8) r(8) g(8) b(8)
|
|
16
|
+
// [2]: bg `uint32_t` - flags(8) r(8) g(8) b(8)
|
|
17
|
+
|
|
18
|
+
const enum Constants {
|
|
19
|
+
/** The number of 32 bit array indices taken by one cell. */
|
|
20
|
+
CELL_INDICIES = 3,
|
|
21
|
+
/** Factor when to cleanup underlying array buffer after shrinking. */
|
|
22
|
+
CLEANUP_THRESHOLD = 2
|
|
23
|
+
}
|
|
23
24
|
|
|
24
25
|
/**
|
|
25
26
|
* Cell member indices.
|
|
26
27
|
*
|
|
27
28
|
* Direct access:
|
|
28
|
-
* `content = data[column *
|
|
29
|
-
* `fg = data[column *
|
|
30
|
-
* `bg = data[column *
|
|
29
|
+
* `content = data[column * Constants.CELL_INDICIES + Cell.CONTENT];`
|
|
30
|
+
* `fg = data[column * Constants.CELL_INDICIES + Cell.FG];`
|
|
31
|
+
* `bg = data[column * Constants.CELL_INDICIES + Cell.BG];`
|
|
31
32
|
*/
|
|
32
33
|
const enum Cell {
|
|
33
34
|
CONTENT = 0,
|
|
@@ -41,9 +42,6 @@ export const DEFAULT_ATTR_DATA = Object.freeze(new AttributeData());
|
|
|
41
42
|
let $startIndex = 0;
|
|
42
43
|
const $workCell = new CellData();
|
|
43
44
|
|
|
44
|
-
/** Factor when to cleanup underlying array buffer after shrinking. */
|
|
45
|
-
const CLEANUP_THRESHOLD = 2;
|
|
46
|
-
|
|
47
45
|
export interface IBufferLineStringCacheEntry {
|
|
48
46
|
value: string | undefined;
|
|
49
47
|
isTrimmed: boolean;
|
|
@@ -84,7 +82,7 @@ export class BufferLine implements IBufferLine {
|
|
|
84
82
|
fillCellData?: ICellData,
|
|
85
83
|
public isWrapped: boolean = false
|
|
86
84
|
) {
|
|
87
|
-
this._data = new Uint32Array(cols *
|
|
85
|
+
this._data = new Uint32Array(cols * Constants.CELL_INDICIES);
|
|
88
86
|
const cell = fillCellData ?? CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);
|
|
89
87
|
for (let i = 0; i < cols; ++i) {
|
|
90
88
|
this.setCell(i, cell);
|
|
@@ -97,10 +95,10 @@ export class BufferLine implements IBufferLine {
|
|
|
97
95
|
* @deprecated
|
|
98
96
|
*/
|
|
99
97
|
public get(index: number): CharData {
|
|
100
|
-
const content = this._data[index *
|
|
98
|
+
const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];
|
|
101
99
|
const cp = content & Content.CODEPOINT_MASK;
|
|
102
100
|
return [
|
|
103
|
-
this._data[index *
|
|
101
|
+
this._data[index * Constants.CELL_INDICIES + Cell.FG],
|
|
104
102
|
(content & Content.IS_COMBINED_MASK)
|
|
105
103
|
? this._combined[index]
|
|
106
104
|
: (cp) ? stringFromCodePoint(cp) : '',
|
|
@@ -117,12 +115,12 @@ export class BufferLine implements IBufferLine {
|
|
|
117
115
|
*/
|
|
118
116
|
public set(index: number, value: CharData): void {
|
|
119
117
|
this._invalidateStringCache();
|
|
120
|
-
this._data[index *
|
|
118
|
+
this._data[index * Constants.CELL_INDICIES + Cell.FG] = value[CHAR_DATA_ATTR_INDEX];
|
|
121
119
|
if (value[CHAR_DATA_CHAR_INDEX].length > 1) {
|
|
122
120
|
this._combined[index] = value[1];
|
|
123
|
-
this._data[index *
|
|
121
|
+
this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = index | Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
|
|
124
122
|
} else {
|
|
125
|
-
this._data[index *
|
|
123
|
+
this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
|
|
126
124
|
}
|
|
127
125
|
}
|
|
128
126
|
|
|
@@ -131,22 +129,22 @@ export class BufferLine implements IBufferLine {
|
|
|
131
129
|
* use these when only one value is needed, otherwise use `loadCell`
|
|
132
130
|
*/
|
|
133
131
|
public getWidth(index: number): number {
|
|
134
|
-
return this._data[index *
|
|
132
|
+
return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT;
|
|
135
133
|
}
|
|
136
134
|
|
|
137
135
|
/** Test whether content has width. */
|
|
138
136
|
public hasWidth(index: number): number {
|
|
139
|
-
return this._data[index *
|
|
137
|
+
return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.WIDTH_MASK;
|
|
140
138
|
}
|
|
141
139
|
|
|
142
140
|
/** Get FG cell component. */
|
|
143
141
|
public getFg(index: number): number {
|
|
144
|
-
return this._data[index *
|
|
142
|
+
return this._data[index * Constants.CELL_INDICIES + Cell.FG];
|
|
145
143
|
}
|
|
146
144
|
|
|
147
145
|
/** Get BG cell component. */
|
|
148
146
|
public getBg(index: number): number {
|
|
149
|
-
return this._data[index *
|
|
147
|
+
return this._data[index * Constants.CELL_INDICIES + Cell.BG];
|
|
150
148
|
}
|
|
151
149
|
|
|
152
150
|
/**
|
|
@@ -155,7 +153,7 @@ export class BufferLine implements IBufferLine {
|
|
|
155
153
|
* from real empty cells.
|
|
156
154
|
*/
|
|
157
155
|
public hasContent(index: number): number {
|
|
158
|
-
return this._data[index *
|
|
156
|
+
return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK;
|
|
159
157
|
}
|
|
160
158
|
|
|
161
159
|
/**
|
|
@@ -164,7 +162,7 @@ export class BufferLine implements IBufferLine {
|
|
|
164
162
|
* a single UTF32 codepoint or the last codepoint of a combined string.
|
|
165
163
|
*/
|
|
166
164
|
public getCodePoint(index: number): number {
|
|
167
|
-
const content = this._data[index *
|
|
165
|
+
const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];
|
|
168
166
|
if (content & Content.IS_COMBINED_MASK) {
|
|
169
167
|
return this._combined[index].charCodeAt(this._combined[index].length - 1);
|
|
170
168
|
}
|
|
@@ -173,12 +171,12 @@ export class BufferLine implements IBufferLine {
|
|
|
173
171
|
|
|
174
172
|
/** Test whether the cell contains a combined string. */
|
|
175
173
|
public isCombined(index: number): number {
|
|
176
|
-
return this._data[index *
|
|
174
|
+
return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.IS_COMBINED_MASK;
|
|
177
175
|
}
|
|
178
176
|
|
|
179
177
|
/** Returns the string content of the cell. */
|
|
180
178
|
public getString(index: number): string {
|
|
181
|
-
const content = this._data[index *
|
|
179
|
+
const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];
|
|
182
180
|
if (content & Content.IS_COMBINED_MASK) {
|
|
183
181
|
return this._combined[index];
|
|
184
182
|
}
|
|
@@ -191,7 +189,7 @@ export class BufferLine implements IBufferLine {
|
|
|
191
189
|
|
|
192
190
|
/** Get state of protected flag. */
|
|
193
191
|
public isProtected(index: number): number {
|
|
194
|
-
return this._data[index *
|
|
192
|
+
return this._data[index * Constants.CELL_INDICIES + Cell.BG] & BgFlags.PROTECTED;
|
|
195
193
|
}
|
|
196
194
|
|
|
197
195
|
/**
|
|
@@ -199,7 +197,7 @@ export class BufferLine implements IBufferLine {
|
|
|
199
197
|
* to GC as it significantly reduced the amount of new objects/references needed.
|
|
200
198
|
*/
|
|
201
199
|
public loadCell(index: number, cell: ICellData): ICellData {
|
|
202
|
-
$startIndex = index *
|
|
200
|
+
$startIndex = index * Constants.CELL_INDICIES;
|
|
203
201
|
cell.content = this._data[$startIndex + Cell.CONTENT];
|
|
204
202
|
cell.fg = this._data[$startIndex + Cell.FG];
|
|
205
203
|
cell.bg = this._data[$startIndex + Cell.BG];
|
|
@@ -223,9 +221,9 @@ export class BufferLine implements IBufferLine {
|
|
|
223
221
|
if (cell.bg & BgFlags.HAS_EXTENDED) {
|
|
224
222
|
this._extendedAttrs[index] = cell.extended;
|
|
225
223
|
}
|
|
226
|
-
this._data[index *
|
|
227
|
-
this._data[index *
|
|
228
|
-
this._data[index *
|
|
224
|
+
this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = cell.content;
|
|
225
|
+
this._data[index * Constants.CELL_INDICIES + Cell.FG] = cell.fg;
|
|
226
|
+
this._data[index * Constants.CELL_INDICIES + Cell.BG] = cell.bg;
|
|
229
227
|
}
|
|
230
228
|
|
|
231
229
|
/**
|
|
@@ -238,9 +236,9 @@ export class BufferLine implements IBufferLine {
|
|
|
238
236
|
if (attrs.bg & BgFlags.HAS_EXTENDED) {
|
|
239
237
|
this._extendedAttrs[index] = attrs.extended;
|
|
240
238
|
}
|
|
241
|
-
this._data[index *
|
|
242
|
-
this._data[index *
|
|
243
|
-
this._data[index *
|
|
239
|
+
this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = codePoint | (width << Content.WIDTH_SHIFT);
|
|
240
|
+
this._data[index * Constants.CELL_INDICIES + Cell.FG] = attrs.fg;
|
|
241
|
+
this._data[index * Constants.CELL_INDICIES + Cell.BG] = attrs.bg;
|
|
244
242
|
}
|
|
245
243
|
|
|
246
244
|
/**
|
|
@@ -251,7 +249,7 @@ export class BufferLine implements IBufferLine {
|
|
|
251
249
|
*/
|
|
252
250
|
public addCodepointToCell(index: number, codePoint: number, width: number): void {
|
|
253
251
|
this._invalidateStringCache();
|
|
254
|
-
let content = this._data[index *
|
|
252
|
+
let content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];
|
|
255
253
|
if (content & Content.IS_COMBINED_MASK) {
|
|
256
254
|
// we already have a combined string, simply add
|
|
257
255
|
this._combined[index] += stringFromCodePoint(codePoint);
|
|
@@ -273,7 +271,7 @@ export class BufferLine implements IBufferLine {
|
|
|
273
271
|
content &= ~Content.WIDTH_MASK;
|
|
274
272
|
content |= width << Content.WIDTH_SHIFT;
|
|
275
273
|
}
|
|
276
|
-
this._data[index *
|
|
274
|
+
this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = content;
|
|
277
275
|
}
|
|
278
276
|
|
|
279
277
|
public insertCells(pos: number, n: number, fillCellData: ICellData): void {
|
|
@@ -369,14 +367,14 @@ export class BufferLine implements IBufferLine {
|
|
|
369
367
|
* The underlying array buffer will not change if there is still enough space
|
|
370
368
|
* to hold the new buffer line data.
|
|
371
369
|
* Returns a boolean indicating, whether a `cleanupMemory` call would free
|
|
372
|
-
* excess memory (true after shrinking > CLEANUP_THRESHOLD).
|
|
370
|
+
* excess memory (true after shrinking > Constants.CLEANUP_THRESHOLD).
|
|
373
371
|
*/
|
|
374
372
|
public resize(cols: number, fillCellData: ICellData): boolean {
|
|
375
373
|
this._invalidateStringCache();
|
|
376
374
|
if (cols === this.length) {
|
|
377
|
-
return this._data.length * 4 * CLEANUP_THRESHOLD < this._data.buffer.byteLength;
|
|
375
|
+
return this._data.length * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength;
|
|
378
376
|
}
|
|
379
|
-
const uint32Cells = cols *
|
|
377
|
+
const uint32Cells = cols * Constants.CELL_INDICIES;
|
|
380
378
|
if (cols > this.length) {
|
|
381
379
|
if (this._data.buffer.byteLength >= uint32Cells * 4) {
|
|
382
380
|
// optimization: avoid alloc and data copy if buffer has enough room
|
|
@@ -411,17 +409,17 @@ export class BufferLine implements IBufferLine {
|
|
|
411
409
|
}
|
|
412
410
|
}
|
|
413
411
|
this.length = cols;
|
|
414
|
-
return uint32Cells * 4 * CLEANUP_THRESHOLD < this._data.buffer.byteLength;
|
|
412
|
+
return uint32Cells * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength;
|
|
415
413
|
}
|
|
416
414
|
|
|
417
415
|
/**
|
|
418
416
|
* Cleanup underlying array buffer.
|
|
419
417
|
* A cleanup will be triggered if the array buffer exceeds the actual used
|
|
420
|
-
* memory by a factor of CLEANUP_THRESHOLD.
|
|
418
|
+
* memory by a factor of Constants.CLEANUP_THRESHOLD.
|
|
421
419
|
* Returns 0 or 1 indicating whether a cleanup happened.
|
|
422
420
|
*/
|
|
423
421
|
public cleanupMemory(): number {
|
|
424
|
-
if (this._data.length * 4 * CLEANUP_THRESHOLD < this._data.buffer.byteLength) {
|
|
422
|
+
if (this._data.length * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength) {
|
|
425
423
|
const data = new Uint32Array(this._data.length);
|
|
426
424
|
data.set(this._data);
|
|
427
425
|
this._data = data;
|
|
@@ -487,8 +485,8 @@ export class BufferLine implements IBufferLine {
|
|
|
487
485
|
|
|
488
486
|
public getTrimmedLength(): number {
|
|
489
487
|
for (let i = this.length - 1; i >= 0; --i) {
|
|
490
|
-
if ((this._data[i *
|
|
491
|
-
return i + (this._data[i *
|
|
488
|
+
if ((this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK)) {
|
|
489
|
+
return i + (this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT);
|
|
492
490
|
}
|
|
493
491
|
}
|
|
494
492
|
return 0;
|
|
@@ -496,8 +494,8 @@ export class BufferLine implements IBufferLine {
|
|
|
496
494
|
|
|
497
495
|
public getNoBgTrimmedLength(): number {
|
|
498
496
|
for (let i = this.length - 1; i >= 0; --i) {
|
|
499
|
-
if ((this._data[i *
|
|
500
|
-
return i + (this._data[i *
|
|
497
|
+
if ((this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK) || (this._data[i * Constants.CELL_INDICIES + Cell.BG] & Attributes.CM_MASK)) {
|
|
498
|
+
return i + (this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT);
|
|
501
499
|
}
|
|
502
500
|
}
|
|
503
501
|
return 0;
|
|
@@ -508,19 +506,19 @@ export class BufferLine implements IBufferLine {
|
|
|
508
506
|
const srcData = src._data;
|
|
509
507
|
if (applyInReverse) {
|
|
510
508
|
for (let cell = length - 1; cell >= 0; cell--) {
|
|
511
|
-
for (let i = 0; i <
|
|
512
|
-
this._data[(destCol + cell) *
|
|
509
|
+
for (let i = 0; i < Constants.CELL_INDICIES; i++) {
|
|
510
|
+
this._data[(destCol + cell) * Constants.CELL_INDICIES + i] = srcData[(srcCol + cell) * Constants.CELL_INDICIES + i];
|
|
513
511
|
}
|
|
514
|
-
if (srcData[(srcCol + cell) *
|
|
512
|
+
if (srcData[(srcCol + cell) * Constants.CELL_INDICIES + Cell.BG] & BgFlags.HAS_EXTENDED) {
|
|
515
513
|
this._extendedAttrs[destCol + cell] = src._extendedAttrs[srcCol + cell];
|
|
516
514
|
}
|
|
517
515
|
}
|
|
518
516
|
} else {
|
|
519
517
|
for (let cell = 0; cell < length; cell++) {
|
|
520
|
-
for (let i = 0; i <
|
|
521
|
-
this._data[(destCol + cell) *
|
|
518
|
+
for (let i = 0; i < Constants.CELL_INDICIES; i++) {
|
|
519
|
+
this._data[(destCol + cell) * Constants.CELL_INDICIES + i] = srcData[(srcCol + cell) * Constants.CELL_INDICIES + i];
|
|
522
520
|
}
|
|
523
|
-
if (srcData[(srcCol + cell) *
|
|
521
|
+
if (srcData[(srcCol + cell) * Constants.CELL_INDICIES + Cell.BG] & BgFlags.HAS_EXTENDED) {
|
|
524
522
|
this._extendedAttrs[destCol + cell] = src._extendedAttrs[srcCol + cell];
|
|
525
523
|
}
|
|
526
524
|
}
|
|
@@ -574,7 +572,7 @@ export class BufferLine implements IBufferLine {
|
|
|
574
572
|
}
|
|
575
573
|
let result = '';
|
|
576
574
|
while (startCol < endCol) {
|
|
577
|
-
const content = this._data[startCol *
|
|
575
|
+
const content = this._data[startCol * Constants.CELL_INDICIES + Cell.CONTENT];
|
|
578
576
|
const cp = content & Content.CODEPOINT_MASK;
|
|
579
577
|
const chars = (content & Content.IS_COMBINED_MASK) ? this._combined[startCol] : (cp) ? stringFromCodePoint(cp) : WHITESPACE_CELL_CHAR;
|
|
580
578
|
result += chars;
|
|
@@ -9,30 +9,30 @@ import { Emitter } from 'common/Event';
|
|
|
9
9
|
|
|
10
10
|
declare const setTimeout: (handler: () => void, timeout?: number) => void;
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
12
|
+
const enum Constants {
|
|
13
|
+
/**
|
|
14
|
+
* Safety watermark to avoid memory exhaustion and browser engine crash on fast data input.
|
|
15
|
+
* Enable flow control to avoid this limit and make sure that your backend correctly
|
|
16
|
+
* propagates this to the underlying pty. (see docs for further instructions)
|
|
17
|
+
* Since this limit is meant as a safety parachute to prevent browser crashs,
|
|
18
|
+
* it is set to a very high number. Typically xterm.js gets unresponsive with
|
|
19
|
+
* a 100 times lower number (>500 kB).
|
|
20
|
+
*/
|
|
21
|
+
DISCARD_WATERMARK = 50000000, // ~50 MB
|
|
22
|
+
/**
|
|
23
|
+
* The max number of ms to spend on writes before allowing the renderer to
|
|
24
|
+
* catch up with a 0ms setTimeout. A value of < 33 to keep us close to
|
|
25
|
+
* 30fps, and a value of < 16 to try to run at 60fps. Of course, the real FPS
|
|
26
|
+
* depends on the time it takes for the renderer to draw the frame.
|
|
27
|
+
*/
|
|
28
|
+
WRITE_TIMEOUT_MS = 12,
|
|
29
|
+
/**
|
|
30
|
+
* Threshold of max held chunks in the write buffer, that were already processed.
|
|
31
|
+
* This is a tradeoff between extensive write buffer shifts (bad runtime) and high
|
|
32
|
+
* memory consumption by data thats not used anymore.
|
|
33
|
+
*/
|
|
34
|
+
WRITE_BUFFER_LENGTH_THRESHOLD = 50
|
|
35
|
+
}
|
|
36
36
|
|
|
37
37
|
export class WriteBuffer extends Disposable {
|
|
38
38
|
private _writeBuffer: (string | Uint8Array)[] = [];
|
|
@@ -133,7 +133,7 @@ export class WriteBuffer extends Disposable {
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
public write(data: string | Uint8Array, callback?: () => void): void {
|
|
136
|
-
if (this._pendingData > DISCARD_WATERMARK) {
|
|
136
|
+
if (this._pendingData > Constants.DISCARD_WATERMARK) {
|
|
137
137
|
throw new Error('write data discarded, use flow control to avoid losing data');
|
|
138
138
|
}
|
|
139
139
|
|
|
@@ -169,7 +169,7 @@ export class WriteBuffer extends Disposable {
|
|
|
169
169
|
* effectively lowering the redrawing needs, schematically:
|
|
170
170
|
*
|
|
171
171
|
* macroTask _innerWrite:
|
|
172
|
-
* if (performance.now() - (lastTime | 0) < WRITE_TIMEOUT_MS):
|
|
172
|
+
* if (performance.now() - (lastTime | 0) < Constants.WRITE_TIMEOUT_MS):
|
|
173
173
|
* schedule microTask _innerWrite(lastTime)
|
|
174
174
|
* else:
|
|
175
175
|
* schedule macroTask _innerWrite(0)
|
|
@@ -218,7 +218,7 @@ export class WriteBuffer extends Disposable {
|
|
|
218
218
|
* responsibility to slice hard work), but we can at least schedule a screen update as we
|
|
219
219
|
* gain control.
|
|
220
220
|
*/
|
|
221
|
-
const continuation: (r: boolean) => void = (r: boolean) => performance.now() - startTime >= WRITE_TIMEOUT_MS
|
|
221
|
+
const continuation: (r: boolean) => void = (r: boolean) => performance.now() - startTime >= Constants.WRITE_TIMEOUT_MS
|
|
222
222
|
? setTimeout(() => this._innerWrite(0, r))
|
|
223
223
|
: this._innerWrite(startTime, r);
|
|
224
224
|
|
|
@@ -235,7 +235,7 @@ export class WriteBuffer extends Disposable {
|
|
|
235
235
|
* current microtask queue (executed before setTimeout).
|
|
236
236
|
*/
|
|
237
237
|
// const continuation: (r: boolean) => void = performance.now() - startTime >=
|
|
238
|
-
// WRITE_TIMEOUT_MS
|
|
238
|
+
// Constants.WRITE_TIMEOUT_MS
|
|
239
239
|
// ? r => setTimeout(() => this._innerWrite(0, r))
|
|
240
240
|
// : r => this._innerWrite(startTime, r);
|
|
241
241
|
|
|
@@ -255,14 +255,14 @@ export class WriteBuffer extends Disposable {
|
|
|
255
255
|
this._bufferOffset++;
|
|
256
256
|
this._pendingData -= data.length;
|
|
257
257
|
|
|
258
|
-
if (performance.now() - startTime >= WRITE_TIMEOUT_MS) {
|
|
258
|
+
if (performance.now() - startTime >= Constants.WRITE_TIMEOUT_MS) {
|
|
259
259
|
break;
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
if (this._writeBuffer.length > this._bufferOffset) {
|
|
263
263
|
// Allow renderer to catch up before processing the next batch
|
|
264
264
|
// trim already processed chunks if we are above threshold
|
|
265
|
-
if (this._bufferOffset > WRITE_BUFFER_LENGTH_THRESHOLD) {
|
|
265
|
+
if (this._bufferOffset > Constants.WRITE_BUFFER_LENGTH_THRESHOLD) {
|
|
266
266
|
this._writeBuffer = this._writeBuffer.slice(this._bufferOffset);
|
|
267
267
|
this._callbacks = this._callbacks.slice(this._bufferOffset);
|
|
268
268
|
this._bufferOffset = 0;
|
|
@@ -4,10 +4,16 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { IParams, ParamsArray } from 'common/parser/Types';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
const enum Constants {
|
|
8
|
+
/**
|
|
9
|
+
* Max value supported for a single param/subparam (clamped to positive int32 range)
|
|
10
|
+
*/
|
|
11
|
+
MAX_VALUE = 0x7FFFFFFF,
|
|
12
|
+
/**
|
|
13
|
+
* Max allowed subparams for a single sequence (hardcoded limitation)
|
|
14
|
+
*/
|
|
15
|
+
MAX_SUBPARAMS = 256
|
|
16
|
+
}
|
|
11
17
|
|
|
12
18
|
/**
|
|
13
19
|
* Params storage class.
|
|
@@ -70,7 +76,7 @@ export class Params implements IParams {
|
|
|
70
76
|
* @param maxSubParamsLength max length of storable sub parameters
|
|
71
77
|
*/
|
|
72
78
|
constructor(public maxLength: number = 32, public maxSubParamsLength: number = 32) {
|
|
73
|
-
if (maxSubParamsLength > MAX_SUBPARAMS) {
|
|
79
|
+
if (maxSubParamsLength > Constants.MAX_SUBPARAMS) {
|
|
74
80
|
throw new Error('maxSubParamsLength must not be greater than 256');
|
|
75
81
|
}
|
|
76
82
|
this.params = new Int32Array(maxLength);
|
|
@@ -159,7 +165,7 @@ export class Params implements IParams {
|
|
|
159
165
|
throw new Error('values lesser than -1 are not allowed');
|
|
160
166
|
}
|
|
161
167
|
this._subParamsIdx[this.length] = this._subParamsLength << 8 | this._subParamsLength;
|
|
162
|
-
this.params[this.length++] = value > MAX_VALUE ? MAX_VALUE : value;
|
|
168
|
+
this.params[this.length++] = value > Constants.MAX_VALUE ? Constants.MAX_VALUE : value;
|
|
163
169
|
}
|
|
164
170
|
|
|
165
171
|
/**
|
|
@@ -181,7 +187,7 @@ export class Params implements IParams {
|
|
|
181
187
|
if (value < -1) {
|
|
182
188
|
throw new Error('values lesser than -1 are not allowed');
|
|
183
189
|
}
|
|
184
|
-
this._subParams[this._subParamsLength++] = value > MAX_VALUE ? MAX_VALUE : value;
|
|
190
|
+
this._subParams[this._subParamsLength++] = value > Constants.MAX_VALUE ? Constants.MAX_VALUE : value;
|
|
185
191
|
this._subParamsIdx[this.length - 1]++;
|
|
186
192
|
}
|
|
187
193
|
|
|
@@ -237,6 +243,6 @@ export class Params implements IParams {
|
|
|
237
243
|
|
|
238
244
|
const store = this._digitIsSub ? this._subParams : this.params;
|
|
239
245
|
const cur = store[length - 1];
|
|
240
|
-
store[length - 1] = ~cur ? Math.min(cur * 10 + value, MAX_VALUE) : value;
|
|
246
|
+
store[length - 1] = ~cur ? Math.min(cur * 10 + value, Constants.MAX_VALUE) : value;
|
|
241
247
|
}
|
|
242
248
|
}
|
|
@@ -10,8 +10,10 @@ import { IBuffer, IBufferSet } from 'common/buffer/Types';
|
|
|
10
10
|
import { IBufferService, ILogService, IOptionsService, type IBufferResizeEvent } from 'common/services/Services';
|
|
11
11
|
import { Emitter } from 'common/Event';
|
|
12
12
|
|
|
13
|
-
export const
|
|
14
|
-
|
|
13
|
+
export const enum BufferServiceConstants {
|
|
14
|
+
MINIMUM_COLS = 2, // Less than 2 can mess with wide chars
|
|
15
|
+
MINIMUM_ROWS = 1
|
|
16
|
+
}
|
|
15
17
|
|
|
16
18
|
export class BufferService extends Disposable implements IBufferService {
|
|
17
19
|
public serviceBrand: any;
|
|
@@ -37,8 +39,8 @@ export class BufferService extends Disposable implements IBufferService {
|
|
|
37
39
|
@ILogService logService: ILogService
|
|
38
40
|
) {
|
|
39
41
|
super();
|
|
40
|
-
this.cols = Math.max(optionsService.rawOptions.cols || 0, MINIMUM_COLS);
|
|
41
|
-
this.rows = Math.max(optionsService.rawOptions.rows || 0, MINIMUM_ROWS);
|
|
42
|
+
this.cols = Math.max(optionsService.rawOptions.cols || 0, BufferServiceConstants.MINIMUM_COLS);
|
|
43
|
+
this.rows = Math.max(optionsService.rawOptions.rows || 0, BufferServiceConstants.MINIMUM_ROWS);
|
|
42
44
|
this.buffers = this._register(new BufferSet(optionsService, this, logService));
|
|
43
45
|
this._register(this.buffers.onBufferActivate(e => {
|
|
44
46
|
this._onScroll.fire(e.activeBuffer.ydisp);
|
|
@@ -11,13 +11,15 @@
|
|
|
11
11
|
|
|
12
12
|
import { IServiceIdentifier } from 'common/services/Services';
|
|
13
13
|
|
|
14
|
-
const
|
|
15
|
-
|
|
14
|
+
const enum Constants {
|
|
15
|
+
DI_TARGET = 'di$target',
|
|
16
|
+
DI_DEPENDENCIES = 'di$dependencies'
|
|
17
|
+
}
|
|
16
18
|
|
|
17
19
|
export const serviceRegistry: Map<string, IServiceIdentifier<any>> = new Map();
|
|
18
20
|
|
|
19
21
|
export function getServiceDependencies(ctor: any): { id: IServiceIdentifier<any>, index: number, optional: boolean }[] {
|
|
20
|
-
return ctor[DI_DEPENDENCIES] || [];
|
|
22
|
+
return ctor[Constants.DI_DEPENDENCIES] || [];
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
export function createDecorator<T>(id: string): IServiceIdentifier<T> {
|
|
@@ -40,10 +42,10 @@ export function createDecorator<T>(id: string): IServiceIdentifier<T> {
|
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
function storeServiceDependency(id: Function, target: Function, index: number): void {
|
|
43
|
-
if ((target as any)[DI_TARGET] === target) {
|
|
44
|
-
(target as any)[DI_DEPENDENCIES].push({ id, index });
|
|
45
|
+
if ((target as any)[Constants.DI_TARGET] === target) {
|
|
46
|
+
(target as any)[Constants.DI_DEPENDENCIES].push({ id, index });
|
|
45
47
|
} else {
|
|
46
|
-
(target as any)[DI_DEPENDENCIES] = [{ id, index }];
|
|
47
|
-
(target as any)[DI_TARGET] = target;
|
|
48
|
+
(target as any)[Constants.DI_DEPENDENCIES] = [{ id, index }];
|
|
49
|
+
(target as any)[Constants.DI_TARGET] = target;
|
|
48
50
|
}
|
|
49
51
|
}
|