@xterm/xterm 6.1.0-beta.28 → 6.1.0-beta.281
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/README.md +62 -38
- package/css/xterm.css +29 -22
- package/lib/xterm.js +1 -1
- package/lib/xterm.js.map +1 -1
- package/lib/xterm.mjs +8 -34
- package/lib/xterm.mjs.map +4 -4
- package/package.json +56 -45
- package/src/browser/AccessibilityManager.ts +18 -13
- package/src/browser/Clipboard.ts +8 -5
- package/src/browser/ColorContrastCache.ts +3 -3
- package/src/browser/CoreBrowserTerminal.ts +179 -348
- package/src/browser/Dom.ts +178 -0
- package/src/browser/Linkifier.ts +14 -14
- package/src/browser/OscLinkProvider.ts +86 -18
- package/src/browser/RenderDebouncer.ts +7 -9
- package/src/browser/TimeBasedDebouncer.ts +12 -5
- package/src/browser/Types.ts +16 -14
- package/src/browser/Viewport.ts +58 -23
- package/src/browser/decorations/BufferDecorationRenderer.ts +3 -3
- package/src/browser/decorations/ColorZoneStore.ts +1 -1
- package/src/browser/decorations/OverviewRulerRenderer.ts +36 -20
- package/src/browser/input/CompositionHelper.ts +47 -11
- package/src/browser/input/Mouse.ts +5 -9
- package/src/browser/input/MoveToCell.ts +3 -3
- package/src/browser/public/Terminal.ts +33 -36
- package/src/browser/renderer/dom/DomRenderer.ts +265 -89
- package/src/browser/renderer/dom/DomRendererRowFactory.ts +34 -27
- package/src/browser/renderer/dom/WidthCache.ts +57 -55
- package/src/browser/renderer/shared/Constants.ts +7 -0
- package/src/browser/renderer/shared/RendererUtils.ts +1 -1
- package/src/browser/renderer/shared/SelectionRenderModel.ts +2 -2
- package/src/browser/renderer/shared/TextBlinkStateManager.ts +97 -0
- package/src/browser/renderer/shared/Types.ts +10 -4
- package/src/browser/scrollable/abstractScrollbar.ts +300 -0
- package/src/browser/scrollable/fastDomNode.ts +126 -0
- package/src/browser/scrollable/globalPointerMoveMonitor.ts +90 -0
- package/src/browser/scrollable/horizontalScrollbar.ts +85 -0
- package/src/browser/scrollable/mouseEvent.ts +292 -0
- package/src/browser/scrollable/scrollable.ts +486 -0
- package/src/browser/scrollable/scrollableElement.ts +581 -0
- package/src/browser/scrollable/scrollableElementOptions.ts +161 -0
- package/src/browser/scrollable/scrollbarArrow.ts +110 -0
- package/src/browser/scrollable/scrollbarState.ts +246 -0
- package/src/browser/scrollable/scrollbarVisibilityController.ts +113 -0
- package/src/browser/scrollable/touch.ts +485 -0
- package/src/browser/scrollable/verticalScrollbar.ts +143 -0
- package/src/browser/scrollable/widget.ts +23 -0
- package/src/browser/selection/SelectionModel.ts +1 -1
- package/src/browser/services/CharSizeService.ts +4 -4
- package/src/browser/services/CharacterJoinerService.ts +13 -11
- package/src/browser/services/CoreBrowserService.ts +7 -5
- package/src/browser/services/KeyboardService.ts +67 -0
- package/src/browser/services/LinkProviderService.ts +3 -3
- package/src/browser/services/MouseCoordsService.ts +47 -0
- package/src/browser/services/MouseService.ts +619 -23
- package/src/browser/services/RenderService.ts +33 -21
- package/src/browser/services/SelectionService.ts +72 -54
- package/src/browser/services/Services.ts +44 -21
- package/src/browser/services/ThemeService.ts +9 -9
- package/src/common/Async.ts +141 -0
- package/src/common/CircularList.ts +24 -3
- package/src/common/Color.ts +13 -5
- package/src/common/CoreTerminal.ts +61 -35
- package/src/common/Event.ts +118 -0
- package/src/common/InputHandler.ts +286 -105
- package/src/common/Lifecycle.ts +113 -0
- package/src/common/Platform.ts +15 -5
- package/src/common/SortedList.ts +8 -4
- package/src/common/StringBuilder.ts +67 -0
- package/src/common/TaskQueue.ts +17 -8
- package/src/common/Types.ts +68 -206
- package/src/common/Version.ts +1 -1
- package/src/common/WindowsMode.ts +2 -2
- package/src/common/buffer/AttributeData.ts +3 -2
- package/src/common/buffer/Buffer.ts +47 -32
- package/src/common/buffer/BufferLine.ts +175 -100
- package/src/common/buffer/BufferLineStringCache.ts +69 -0
- package/src/common/buffer/BufferReflow.ts +7 -4
- package/src/common/buffer/BufferSet.ts +13 -9
- package/src/common/buffer/CellData.ts +61 -4
- package/src/common/buffer/Constants.ts +13 -13
- package/src/common/buffer/Marker.ts +4 -4
- package/src/common/buffer/Types.ts +153 -3
- package/src/common/data/Charsets.ts +4 -7
- package/src/common/data/EscapeSequences.ts +71 -70
- package/src/common/input/Keyboard.ts +17 -10
- package/src/common/input/KittyKeyboard.ts +526 -0
- package/src/common/input/TextDecoder.ts +3 -3
- package/src/common/input/UnicodeV6.ts +3 -2
- package/src/common/input/Win32InputMode.ts +297 -0
- package/src/common/input/WriteBuffer.ts +108 -39
- package/src/common/input/XParseColor.ts +2 -2
- package/src/common/parser/ApcParser.ts +196 -0
- package/src/common/parser/Constants.ts +14 -4
- package/src/common/parser/DcsParser.ts +15 -16
- package/src/common/parser/EscapeSequenceParser.ts +214 -72
- package/src/common/parser/OscParser.ts +14 -15
- package/src/common/parser/Params.ts +31 -12
- package/src/common/parser/Types.ts +40 -30
- package/src/common/public/BufferApiView.ts +3 -3
- package/src/common/public/BufferLineApiView.ts +4 -4
- package/src/common/public/BufferNamespaceApi.ts +5 -5
- package/src/common/public/ParserApi.ts +5 -2
- package/src/common/public/UnicodeApi.ts +1 -1
- package/src/common/services/BufferService.ts +17 -13
- package/src/common/services/CharsetService.ts +6 -2
- package/src/common/services/CoreService.ts +23 -10
- package/src/common/services/DecorationService.ts +260 -15
- package/src/common/services/InstantiationService.ts +2 -2
- package/src/common/services/LogService.ts +2 -32
- package/src/common/services/{CoreMouseService.ts → MouseStateService.ts} +22 -133
- package/src/common/services/OptionsService.ts +17 -7
- package/src/common/services/OscLinkService.ts +3 -2
- package/src/common/services/ServiceRegistry.ts +14 -8
- package/src/common/services/Services.ts +54 -50
- package/src/common/services/UnicodeService.ts +6 -11
- package/typings/xterm.d.ts +329 -34
- package/src/common/Clone.ts +0 -23
- package/src/common/TypedArrayUtils.ts +0 -17
- package/src/vs/base/browser/browser.ts +0 -141
- package/src/vs/base/browser/canIUse.ts +0 -49
- package/src/vs/base/browser/dom.ts +0 -2369
- package/src/vs/base/browser/fastDomNode.ts +0 -316
- package/src/vs/base/browser/globalPointerMoveMonitor.ts +0 -112
- package/src/vs/base/browser/iframe.ts +0 -135
- package/src/vs/base/browser/keyboardEvent.ts +0 -213
- package/src/vs/base/browser/mouseEvent.ts +0 -229
- package/src/vs/base/browser/touch.ts +0 -372
- package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +0 -303
- package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +0 -114
- package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +0 -720
- package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +0 -165
- package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +0 -114
- package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +0 -243
- package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +0 -118
- package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +0 -116
- package/src/vs/base/browser/ui/widget.ts +0 -57
- package/src/vs/base/browser/window.ts +0 -14
- package/src/vs/base/common/arrays.ts +0 -887
- package/src/vs/base/common/arraysFind.ts +0 -202
- package/src/vs/base/common/assert.ts +0 -71
- package/src/vs/base/common/async.ts +0 -1992
- package/src/vs/base/common/cancellation.ts +0 -148
- package/src/vs/base/common/charCode.ts +0 -450
- package/src/vs/base/common/collections.ts +0 -140
- package/src/vs/base/common/decorators.ts +0 -130
- package/src/vs/base/common/equals.ts +0 -146
- package/src/vs/base/common/errors.ts +0 -303
- package/src/vs/base/common/event.ts +0 -1778
- package/src/vs/base/common/functional.ts +0 -32
- package/src/vs/base/common/hash.ts +0 -316
- package/src/vs/base/common/iterator.ts +0 -159
- package/src/vs/base/common/keyCodes.ts +0 -526
- package/src/vs/base/common/keybindings.ts +0 -284
- package/src/vs/base/common/lazy.ts +0 -47
- package/src/vs/base/common/lifecycle.ts +0 -801
- package/src/vs/base/common/linkedList.ts +0 -142
- package/src/vs/base/common/map.ts +0 -202
- package/src/vs/base/common/numbers.ts +0 -98
- package/src/vs/base/common/observable.ts +0 -76
- package/src/vs/base/common/observableInternal/api.ts +0 -31
- package/src/vs/base/common/observableInternal/autorun.ts +0 -281
- package/src/vs/base/common/observableInternal/base.ts +0 -489
- package/src/vs/base/common/observableInternal/debugName.ts +0 -145
- package/src/vs/base/common/observableInternal/derived.ts +0 -428
- package/src/vs/base/common/observableInternal/lazyObservableValue.ts +0 -146
- package/src/vs/base/common/observableInternal/logging.ts +0 -328
- package/src/vs/base/common/observableInternal/promise.ts +0 -209
- package/src/vs/base/common/observableInternal/utils.ts +0 -610
- package/src/vs/base/common/platform.ts +0 -281
- package/src/vs/base/common/scrollable.ts +0 -522
- package/src/vs/base/common/sequence.ts +0 -34
- package/src/vs/base/common/stopwatch.ts +0 -43
- package/src/vs/base/common/strings.ts +0 -557
- package/src/vs/base/common/symbols.ts +0 -9
- package/src/vs/base/common/uint.ts +0 -59
- package/src/vs/patches/nls.ts +0 -90
- package/src/vs/typings/base-common.d.ts +0 -20
- package/src/vs/typings/require.d.ts +0 -42
- package/src/vs/typings/vscode-globals-nls.d.ts +0 -36
- package/src/vs/typings/vscode-globals-product.d.ts +0 -33
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 The xterm.js authors. All rights reserved.
|
|
3
|
+
* @license MIT
|
|
4
|
+
*
|
|
5
|
+
* Minimal async helpers for xterm.js core.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { DisposableStore, IDisposable, toDisposable } from './Lifecycle';
|
|
9
|
+
|
|
10
|
+
export function timeout(millis: number): Promise<void> {
|
|
11
|
+
return new Promise(resolve => setTimeout(resolve, millis));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Creates a timeout that can be disposed using its returned value.
|
|
16
|
+
* @param handler The timeout handler.
|
|
17
|
+
* @param timeout An optional timeout in milliseconds.
|
|
18
|
+
* @param store An optional {@link DisposableStore} that will have the timeout disposable managed
|
|
19
|
+
* automatically.
|
|
20
|
+
*/
|
|
21
|
+
export function disposableTimeout(handler: () => void, timeout = 0, store?: DisposableStore): IDisposable {
|
|
22
|
+
const timer = setTimeout(() => {
|
|
23
|
+
handler();
|
|
24
|
+
if (store) {
|
|
25
|
+
disposable.dispose();
|
|
26
|
+
}
|
|
27
|
+
}, timeout);
|
|
28
|
+
const disposable = toDisposable(() => {
|
|
29
|
+
clearTimeout(timer);
|
|
30
|
+
});
|
|
31
|
+
store?.add(disposable);
|
|
32
|
+
return disposable;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class TimeoutTimer implements IDisposable {
|
|
36
|
+
private _token: any = -1;
|
|
37
|
+
private _isDisposed = false;
|
|
38
|
+
|
|
39
|
+
public dispose(): void {
|
|
40
|
+
this.cancel();
|
|
41
|
+
this._isDisposed = true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public cancel(): void {
|
|
45
|
+
if (this._token !== -1) {
|
|
46
|
+
clearTimeout(this._token);
|
|
47
|
+
this._token = -1;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public cancelAndSet(runner: () => void, timeout: number): void {
|
|
52
|
+
if (this._isDisposed) {
|
|
53
|
+
throw new Error('Calling cancelAndSet on a disposed TimeoutTimer');
|
|
54
|
+
}
|
|
55
|
+
this.cancel();
|
|
56
|
+
this._token = setTimeout(() => {
|
|
57
|
+
this._token = -1;
|
|
58
|
+
runner();
|
|
59
|
+
}, timeout);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public setIfNotSet(runner: () => void, timeout: number): void {
|
|
63
|
+
if (this._isDisposed) {
|
|
64
|
+
throw new Error('Calling setIfNotSet on a disposed TimeoutTimer');
|
|
65
|
+
}
|
|
66
|
+
if (this._token !== -1) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
this._token = setTimeout(() => {
|
|
70
|
+
this._token = -1;
|
|
71
|
+
runner();
|
|
72
|
+
}, timeout);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Schedules a single runner on the microtask queue. Unlike {@link TimeoutTimer}, a scheduled
|
|
78
|
+
* microtask cannot be unqueued; {@link cancel} prevents the runner from executing if it has not
|
|
79
|
+
* run yet.
|
|
80
|
+
*/
|
|
81
|
+
export class MicrotaskTimer implements IDisposable {
|
|
82
|
+
private _isScheduled = false;
|
|
83
|
+
private _isDisposed = false;
|
|
84
|
+
|
|
85
|
+
public dispose(): void {
|
|
86
|
+
this.cancel();
|
|
87
|
+
this._isDisposed = true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public cancel(): void {
|
|
91
|
+
this._isScheduled = false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public set(runner: () => void): void {
|
|
95
|
+
if (this._isDisposed) {
|
|
96
|
+
throw new Error('Calling set on a disposed MicrotaskTimer');
|
|
97
|
+
}
|
|
98
|
+
if (this._isScheduled) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
this._isScheduled = true;
|
|
102
|
+
queueMicrotask(() => {
|
|
103
|
+
if (!this._isScheduled) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
this._isScheduled = false;
|
|
107
|
+
runner();
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export class IntervalTimer implements IDisposable {
|
|
113
|
+
private _disposable: IDisposable | undefined;
|
|
114
|
+
private _isDisposed = false;
|
|
115
|
+
|
|
116
|
+
public cancel(): void {
|
|
117
|
+
this._disposable?.dispose();
|
|
118
|
+
this._disposable = undefined;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public cancelAndSet(runner: () => void, interval: number, context: Window | typeof globalThis = globalThis): void {
|
|
122
|
+
if (this._isDisposed) {
|
|
123
|
+
throw new Error('Calling cancelAndSet on a disposed IntervalTimer');
|
|
124
|
+
}
|
|
125
|
+
this.cancel();
|
|
126
|
+
const handle = context.setInterval(() => {
|
|
127
|
+
runner();
|
|
128
|
+
}, interval);
|
|
129
|
+
this._disposable = {
|
|
130
|
+
dispose: () => {
|
|
131
|
+
context.clearInterval(handle as any);
|
|
132
|
+
this._disposable = undefined;
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public dispose(): void {
|
|
138
|
+
this.cancel();
|
|
139
|
+
this._isDisposed = true;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
* @license MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { Emitter } from 'vs/base/common/event';
|
|
6
|
+
import { Disposable } from './Lifecycle';
|
|
7
|
+
import { Emitter, type IEvent } from './Event';
|
|
9
8
|
|
|
10
9
|
export interface IInsertEvent {
|
|
11
10
|
index: number;
|
|
@@ -17,6 +16,28 @@ export interface IDeleteEvent {
|
|
|
17
16
|
amount: number;
|
|
18
17
|
}
|
|
19
18
|
|
|
19
|
+
export interface ICircularList<T> {
|
|
20
|
+
length: number;
|
|
21
|
+
maxLength: number;
|
|
22
|
+
isFull: boolean;
|
|
23
|
+
|
|
24
|
+
onDeleteEmitter: Emitter<IDeleteEvent>;
|
|
25
|
+
onDelete: IEvent<IDeleteEvent>;
|
|
26
|
+
onInsertEmitter: Emitter<IInsertEvent>;
|
|
27
|
+
onInsert: IEvent<IInsertEvent>;
|
|
28
|
+
onTrimEmitter: Emitter<number>;
|
|
29
|
+
onTrim: IEvent<number>;
|
|
30
|
+
|
|
31
|
+
get(index: number): T | undefined;
|
|
32
|
+
set(index: number, value: T): void;
|
|
33
|
+
push(value: T): void;
|
|
34
|
+
recycle(): T;
|
|
35
|
+
pop(): T | undefined;
|
|
36
|
+
splice(start: number, deleteCount: number, ...items: T[]): void;
|
|
37
|
+
trimStart(count: number): void;
|
|
38
|
+
shiftElements(start: number, count: number, offset: number): void;
|
|
39
|
+
}
|
|
40
|
+
|
|
20
41
|
/**
|
|
21
42
|
* Represents a circular list; a list with a maximum size that wraps around when push is called,
|
|
22
43
|
* overriding values at the start of the list.
|
package/src/common/Color.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @license MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { IColor, IColorRGB } from '
|
|
6
|
+
import { IColor, IColorRGB } from './Types';
|
|
7
7
|
|
|
8
8
|
let $r = 0;
|
|
9
9
|
let $g = 0;
|
|
@@ -177,13 +177,21 @@ export namespace css {
|
|
|
177
177
|
// Formats: rgb() or rgba()
|
|
178
178
|
const rgbaMatch = css.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);
|
|
179
179
|
if (rgbaMatch) {
|
|
180
|
-
$r = parseInt(rgbaMatch[1]);
|
|
181
|
-
$g = parseInt(rgbaMatch[2]);
|
|
182
|
-
$b = parseInt(rgbaMatch[3]);
|
|
180
|
+
$r = parseInt(rgbaMatch[1], 10);
|
|
181
|
+
$g = parseInt(rgbaMatch[2], 10);
|
|
182
|
+
$b = parseInt(rgbaMatch[3], 10);
|
|
183
183
|
$a = Math.round((rgbaMatch[5] === undefined ? 1 : parseFloat(rgbaMatch[5])) * 0xFF);
|
|
184
184
|
return channels.toColor($r, $g, $b, $a);
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
+
// Handle the "transparent" keyword
|
|
188
|
+
if (css === 'transparent') {
|
|
189
|
+
return {
|
|
190
|
+
css: 'transparent',
|
|
191
|
+
rgba: 0x00000000
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
187
195
|
// Validate the context is available for canvas-based color parsing
|
|
188
196
|
if (!$ctx || !$litmusColor) {
|
|
189
197
|
throw new Error('css.toColor: Unsupported css format');
|
|
@@ -365,7 +373,7 @@ export function toPaddedHex(c: number): string {
|
|
|
365
373
|
/**
|
|
366
374
|
* Gets the contrast ratio between two relative luminance values.
|
|
367
375
|
* @param l1 The first relative luminance.
|
|
368
|
-
* @param l2 The
|
|
376
|
+
* @param l2 The second relative luminance.
|
|
369
377
|
* @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef
|
|
370
378
|
*/
|
|
371
379
|
export function contrastRatio(l1: number, l2: number): number {
|
|
@@ -21,28 +21,43 @@
|
|
|
21
21
|
* http://linux.die.net/man/7/urxvt
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
import { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService,
|
|
25
|
-
import { InstantiationService } from '
|
|
26
|
-
import { LogService } from '
|
|
27
|
-
import { BufferService,
|
|
28
|
-
import { OptionsService } from '
|
|
29
|
-
import { IDisposable,
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
24
|
+
import { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, IMouseStateService, IUnicodeService, LogLevelEnum, IOscLinkService } from './services/Services';
|
|
25
|
+
import { InstantiationService } from './services/InstantiationService';
|
|
26
|
+
import { LogService } from './services/LogService';
|
|
27
|
+
import { BufferService, BufferServiceConstants } from './services/BufferService';
|
|
28
|
+
import { OptionsService } from './services/OptionsService';
|
|
29
|
+
import { IDisposable, IScrollEvent, ITerminalOptions, IParams } from './Types';
|
|
30
|
+
import { IAttributeData, IBufferSet } from './buffer/Types';
|
|
31
|
+
import { CoreService } from './services/CoreService';
|
|
32
|
+
import { MouseStateService } from './services/MouseStateService';
|
|
33
|
+
import { UnicodeV6 } from './input/UnicodeV6';
|
|
34
|
+
import { UnicodeService } from './services/UnicodeService';
|
|
35
|
+
import { CharsetService } from './services/CharsetService';
|
|
36
|
+
import { updateWindowsModeWrappedState } from './WindowsMode';
|
|
37
|
+
import { IFunctionIdentifier } from './parser/Types';
|
|
38
|
+
import { InputHandler } from './InputHandler';
|
|
39
|
+
import { WriteBuffer } from './input/WriteBuffer';
|
|
40
|
+
import { OscLinkService } from './services/OscLinkService';
|
|
41
|
+
import { Emitter, EventUtils, type IEvent } from './Event';
|
|
42
|
+
import { Disposable, MutableDisposable, toDisposable } from './Lifecycle';
|
|
42
43
|
|
|
43
44
|
// Only trigger this warning a single time per session
|
|
44
45
|
let hasWriteSyncWarnHappened = false;
|
|
45
46
|
|
|
47
|
+
export interface ICoreTerminal {
|
|
48
|
+
mouseStateService: IMouseStateService;
|
|
49
|
+
coreService: ICoreService;
|
|
50
|
+
optionsService: IOptionsService;
|
|
51
|
+
unicodeService: IUnicodeService;
|
|
52
|
+
buffers: IBufferSet;
|
|
53
|
+
options: Required<ITerminalOptions>;
|
|
54
|
+
registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise<boolean>): IDisposable;
|
|
55
|
+
registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise<boolean>): IDisposable;
|
|
56
|
+
registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise<boolean>): IDisposable;
|
|
57
|
+
registerOscHandler(ident: number, callback: (data: string) => boolean | Promise<boolean>): IDisposable;
|
|
58
|
+
registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise<boolean>): IDisposable;
|
|
59
|
+
}
|
|
60
|
+
|
|
46
61
|
export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
47
62
|
protected readonly _instantiationService: IInstantiationService;
|
|
48
63
|
protected readonly _bufferService: IBufferService;
|
|
@@ -50,7 +65,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
50
65
|
protected readonly _charsetService: ICharsetService;
|
|
51
66
|
protected readonly _oscLinkService: IOscLinkService;
|
|
52
67
|
|
|
53
|
-
public readonly
|
|
68
|
+
public readonly mouseStateService: IMouseStateService;
|
|
54
69
|
public readonly coreService: ICoreService;
|
|
55
70
|
public readonly unicodeService: IUnicodeService;
|
|
56
71
|
public readonly optionsService: IOptionsService;
|
|
@@ -65,6 +80,8 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
65
80
|
public readonly onData = this._onData.event;
|
|
66
81
|
protected _onLineFeed = this._register(new Emitter<void>());
|
|
67
82
|
public readonly onLineFeed = this._onLineFeed.event;
|
|
83
|
+
protected readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());
|
|
84
|
+
public readonly onRender = this._onRender.event;
|
|
68
85
|
private readonly _onResize = this._register(new Emitter<{ cols: number, rows: number }>());
|
|
69
86
|
public readonly onResize = this._onResize.event;
|
|
70
87
|
protected readonly _onWriteParsed = this._register(new Emitter<void>());
|
|
@@ -76,7 +93,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
76
93
|
*/
|
|
77
94
|
protected _onScrollApi?: Emitter<number>;
|
|
78
95
|
protected _onScroll = this._register(new Emitter<IScrollEvent>());
|
|
79
|
-
public get onScroll():
|
|
96
|
+
public get onScroll(): IEvent<number> {
|
|
80
97
|
if (!this._onScrollApi) {
|
|
81
98
|
this._onScrollApi = this._register(new Emitter<number>());
|
|
82
99
|
this._onScroll.event(ev => {
|
|
@@ -105,15 +122,16 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
105
122
|
this._instantiationService = new InstantiationService();
|
|
106
123
|
this.optionsService = this._register(new OptionsService(options));
|
|
107
124
|
this._instantiationService.setService(IOptionsService, this.optionsService);
|
|
108
|
-
this._bufferService = this._register(this._instantiationService.createInstance(BufferService));
|
|
109
|
-
this._instantiationService.setService(IBufferService, this._bufferService);
|
|
110
125
|
this._logService = this._register(this._instantiationService.createInstance(LogService));
|
|
111
126
|
this._instantiationService.setService(ILogService, this._logService);
|
|
127
|
+
this._bufferService = this._register(this._instantiationService.createInstance(BufferService));
|
|
128
|
+
this._instantiationService.setService(IBufferService, this._bufferService);
|
|
112
129
|
this.coreService = this._register(this._instantiationService.createInstance(CoreService));
|
|
113
130
|
this._instantiationService.setService(ICoreService, this.coreService);
|
|
114
|
-
this.
|
|
115
|
-
this._instantiationService.setService(
|
|
131
|
+
this.mouseStateService = this._register(this._instantiationService.createInstance(MouseStateService));
|
|
132
|
+
this._instantiationService.setService(IMouseStateService, this.mouseStateService);
|
|
116
133
|
this.unicodeService = this._register(this._instantiationService.createInstance(UnicodeService));
|
|
134
|
+
this.unicodeService.register(new UnicodeV6());
|
|
117
135
|
this._instantiationService.setService(IUnicodeService, this.unicodeService);
|
|
118
136
|
this._charsetService = this._instantiationService.createInstance(CharsetService);
|
|
119
137
|
this._instantiationService.setService(ICharsetService, this._charsetService);
|
|
@@ -122,14 +140,13 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
122
140
|
|
|
123
141
|
|
|
124
142
|
// Register input handler and handle/forward events
|
|
125
|
-
this._inputHandler = this._register(new InputHandler(this._bufferService, this._charsetService, this.coreService, this._logService, this.optionsService, this._oscLinkService, this.
|
|
126
|
-
this._register(
|
|
127
|
-
this._register(this._inputHandler);
|
|
143
|
+
this._inputHandler = this._register(new InputHandler(this._bufferService, this._charsetService, this.coreService, this._logService, this.optionsService, this._oscLinkService, this.mouseStateService, this.unicodeService));
|
|
144
|
+
this._register(EventUtils.forward(this._inputHandler.onLineFeed, this._onLineFeed));
|
|
128
145
|
|
|
129
146
|
// Setup listeners
|
|
130
|
-
this._register(
|
|
131
|
-
this._register(
|
|
132
|
-
this._register(
|
|
147
|
+
this._register(EventUtils.forward(this._bufferService.onResize, this._onResize));
|
|
148
|
+
this._register(EventUtils.forward(this.coreService.onData, this._onData));
|
|
149
|
+
this._register(EventUtils.forward(this.coreService.onBinary, this._onBinary));
|
|
133
150
|
this._register(this.coreService.onRequestScrollToBottom(() => this.scrollToBottom(true)));
|
|
134
151
|
this._register(this.coreService.onUserInput(() => this._writeBuffer.handleUserInput()));
|
|
135
152
|
this._register(this.optionsService.onMultipleOptionChange(['windowsPty'], () => this._handleWindowsPtyOptionChange()));
|
|
@@ -139,7 +156,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
139
156
|
}));
|
|
140
157
|
// Setup WriteBuffer
|
|
141
158
|
this._writeBuffer = this._register(new WriteBuffer((data, promiseResult) => this._inputHandler.parse(data, promiseResult)));
|
|
142
|
-
this._register(
|
|
159
|
+
this._register(EventUtils.forward(this._writeBuffer.onWriteParsed, this._onWriteParsed));
|
|
143
160
|
}
|
|
144
161
|
|
|
145
162
|
public write(data: string | Uint8Array, callback?: () => void): void {
|
|
@@ -172,8 +189,12 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
172
189
|
return;
|
|
173
190
|
}
|
|
174
191
|
|
|
175
|
-
x = Math.max(x, MINIMUM_COLS);
|
|
176
|
-
y = Math.max(y, MINIMUM_ROWS);
|
|
192
|
+
x = Math.max(x, BufferServiceConstants.MINIMUM_COLS);
|
|
193
|
+
y = Math.max(y, BufferServiceConstants.MINIMUM_ROWS);
|
|
194
|
+
|
|
195
|
+
// Flush pending writes before resize to avoid race conditions where async
|
|
196
|
+
// writes are processed with incorrect dimensions
|
|
197
|
+
this._writeBuffer.flushSync();
|
|
177
198
|
|
|
178
199
|
this._bufferService.resize(x, y);
|
|
179
200
|
}
|
|
@@ -237,6 +258,11 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
237
258
|
return this._inputHandler.registerOscHandler(ident, callback);
|
|
238
259
|
}
|
|
239
260
|
|
|
261
|
+
/** Add handler for APC escape sequence. See xterm.d.ts for details. */
|
|
262
|
+
public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise<boolean>): IDisposable {
|
|
263
|
+
return this._inputHandler.registerApcHandler(id, callback);
|
|
264
|
+
}
|
|
265
|
+
|
|
240
266
|
protected _setup(): void {
|
|
241
267
|
this._handleWindowsPtyOptionChange();
|
|
242
268
|
}
|
|
@@ -246,14 +272,14 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
246
272
|
this._bufferService.reset();
|
|
247
273
|
this._charsetService.reset();
|
|
248
274
|
this.coreService.reset();
|
|
249
|
-
this.
|
|
275
|
+
this.mouseStateService.reset();
|
|
250
276
|
}
|
|
251
277
|
|
|
252
278
|
|
|
253
279
|
private _handleWindowsPtyOptionChange(): void {
|
|
254
280
|
let value = false;
|
|
255
281
|
const windowsPty = this.optionsService.rawOptions.windowsPty;
|
|
256
|
-
if (windowsPty && windowsPty.
|
|
282
|
+
if (windowsPty && windowsPty.backend !== undefined && windowsPty.buildNumber !== undefined) {
|
|
257
283
|
value = !!(windowsPty.backend === 'conpty' && windowsPty.buildNumber < 21376);
|
|
258
284
|
}
|
|
259
285
|
if (value) {
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.
|
|
3
|
+
* @license MIT
|
|
4
|
+
*
|
|
5
|
+
* Minimal event utilities for xterm.js core.
|
|
6
|
+
* Simplified from VS Code's event.ts - no leak detection/profiling.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { IDisposable, DisposableStore, toDisposable } from './Lifecycle';
|
|
10
|
+
|
|
11
|
+
export interface IEvent<T> {
|
|
12
|
+
(listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore): IDisposable;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class Emitter<T> {
|
|
16
|
+
private _listeners: { fn: (e: T) => any, thisArgs: any }[] = [];
|
|
17
|
+
private _disposed = false;
|
|
18
|
+
private _event: IEvent<T> | undefined;
|
|
19
|
+
|
|
20
|
+
public get event(): IEvent<T> {
|
|
21
|
+
if (this._event) {
|
|
22
|
+
return this._event;
|
|
23
|
+
}
|
|
24
|
+
this._event = (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {
|
|
25
|
+
if (this._disposed) {
|
|
26
|
+
return toDisposable(() => {});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const entry = { fn: listener, thisArgs };
|
|
30
|
+
this._listeners.push(entry);
|
|
31
|
+
|
|
32
|
+
const result = toDisposable(() => {
|
|
33
|
+
const idx = this._listeners.indexOf(entry);
|
|
34
|
+
if (idx !== -1) {
|
|
35
|
+
this._listeners.splice(idx, 1);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
if (disposables) {
|
|
40
|
+
if (Array.isArray(disposables)) {
|
|
41
|
+
disposables.push(result);
|
|
42
|
+
} else {
|
|
43
|
+
disposables.add(result);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return result;
|
|
48
|
+
};
|
|
49
|
+
return this._event;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public fire(event: T): void {
|
|
53
|
+
if (this._disposed) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
switch (this._listeners.length) {
|
|
57
|
+
case 0: return;
|
|
58
|
+
case 1: {
|
|
59
|
+
const { fn, thisArgs } = this._listeners[0];
|
|
60
|
+
fn.call(thisArgs, event);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
default: {
|
|
64
|
+
// Snapshot listeners to allow modifications during iteration (2+ listeners)
|
|
65
|
+
const listeners = this._listeners.slice();
|
|
66
|
+
for (const { fn, thisArgs } of listeners) {
|
|
67
|
+
fn.call(thisArgs, event);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public dispose(): void {
|
|
74
|
+
if (this._disposed) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
this._disposed = true;
|
|
78
|
+
this._listeners.length = 0;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export namespace EventUtils {
|
|
83
|
+
export function forward<T>(from: IEvent<T>, to: Emitter<T>): IDisposable {
|
|
84
|
+
return from(e => to.fire(e));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function map<I, O>(event: IEvent<I>, map: (i: I) => O): IEvent<O> {
|
|
88
|
+
return (listener: (e: O) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {
|
|
89
|
+
return event(i => listener.call(thisArgs, map(i)), undefined, disposables);
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function any<T>(...events: IEvent<T>[]): IEvent<T>;
|
|
94
|
+
export function any(...events: IEvent<any>[]): IEvent<void>;
|
|
95
|
+
export function any<T>(...events: IEvent<T>[]): IEvent<T> {
|
|
96
|
+
return (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {
|
|
97
|
+
const store = new DisposableStore();
|
|
98
|
+
for (const event of events) {
|
|
99
|
+
store.add(event(e => listener.call(thisArgs, e)));
|
|
100
|
+
}
|
|
101
|
+
if (disposables) {
|
|
102
|
+
if (Array.isArray(disposables)) {
|
|
103
|
+
disposables.push(store);
|
|
104
|
+
} else {
|
|
105
|
+
disposables.add(store);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return store;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function runAndSubscribe<T>(event: IEvent<T>, handler: (e: T) => void, initial: T): IDisposable;
|
|
113
|
+
export function runAndSubscribe<T>(event: IEvent<T>, handler: (e: T | undefined) => void): IDisposable;
|
|
114
|
+
export function runAndSubscribe<T>(event: IEvent<T>, handler: (e: T | undefined) => void, initial?: T): IDisposable {
|
|
115
|
+
handler(initial);
|
|
116
|
+
return event(e => handler(e));
|
|
117
|
+
}
|
|
118
|
+
}
|