@xterm/xterm 6.1.0-beta.30 → 6.1.0-beta.301
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 +69 -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 +180 -350
- 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 +4 -3
- 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 +610 -23
- package/src/browser/services/RenderService.ts +33 -21
- package/src/browser/services/SelectionService.ts +73 -55
- 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 +59 -34
- 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;
|
|
@@ -78,7 +93,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
78
93
|
*/
|
|
79
94
|
protected _onScrollApi?: Emitter<number>;
|
|
80
95
|
protected _onScroll = this._register(new Emitter<IScrollEvent>());
|
|
81
|
-
public get onScroll():
|
|
96
|
+
public get onScroll(): IEvent<number> {
|
|
82
97
|
if (!this._onScrollApi) {
|
|
83
98
|
this._onScrollApi = this._register(new Emitter<number>());
|
|
84
99
|
this._onScroll.event(ev => {
|
|
@@ -107,15 +122,16 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
107
122
|
this._instantiationService = new InstantiationService();
|
|
108
123
|
this.optionsService = this._register(new OptionsService(options));
|
|
109
124
|
this._instantiationService.setService(IOptionsService, this.optionsService);
|
|
110
|
-
this._bufferService = this._register(this._instantiationService.createInstance(BufferService));
|
|
111
|
-
this._instantiationService.setService(IBufferService, this._bufferService);
|
|
112
125
|
this._logService = this._register(this._instantiationService.createInstance(LogService));
|
|
113
126
|
this._instantiationService.setService(ILogService, this._logService);
|
|
127
|
+
this._bufferService = this._register(this._instantiationService.createInstance(BufferService));
|
|
128
|
+
this._instantiationService.setService(IBufferService, this._bufferService);
|
|
114
129
|
this.coreService = this._register(this._instantiationService.createInstance(CoreService));
|
|
115
130
|
this._instantiationService.setService(ICoreService, this.coreService);
|
|
116
|
-
this.
|
|
117
|
-
this._instantiationService.setService(
|
|
131
|
+
this.mouseStateService = this._register(this._instantiationService.createInstance(MouseStateService));
|
|
132
|
+
this._instantiationService.setService(IMouseStateService, this.mouseStateService);
|
|
118
133
|
this.unicodeService = this._register(this._instantiationService.createInstance(UnicodeService));
|
|
134
|
+
this.unicodeService.register(new UnicodeV6());
|
|
119
135
|
this._instantiationService.setService(IUnicodeService, this.unicodeService);
|
|
120
136
|
this._charsetService = this._instantiationService.createInstance(CharsetService);
|
|
121
137
|
this._instantiationService.setService(ICharsetService, this._charsetService);
|
|
@@ -124,13 +140,13 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
124
140
|
|
|
125
141
|
|
|
126
142
|
// Register input handler and handle/forward events
|
|
127
|
-
this._inputHandler = this._register(new InputHandler(this._bufferService, this._charsetService, this.coreService, this._logService, this.optionsService, this._oscLinkService, this.
|
|
128
|
-
this._register(
|
|
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));
|
|
129
145
|
|
|
130
146
|
// Setup listeners
|
|
131
|
-
this._register(
|
|
132
|
-
this._register(
|
|
133
|
-
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));
|
|
134
150
|
this._register(this.coreService.onRequestScrollToBottom(() => this.scrollToBottom(true)));
|
|
135
151
|
this._register(this.coreService.onUserInput(() => this._writeBuffer.handleUserInput()));
|
|
136
152
|
this._register(this.optionsService.onMultipleOptionChange(['windowsPty'], () => this._handleWindowsPtyOptionChange()));
|
|
@@ -140,7 +156,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
140
156
|
}));
|
|
141
157
|
// Setup WriteBuffer
|
|
142
158
|
this._writeBuffer = this._register(new WriteBuffer((data, promiseResult) => this._inputHandler.parse(data, promiseResult)));
|
|
143
|
-
this._register(
|
|
159
|
+
this._register(EventUtils.forward(this._writeBuffer.onWriteParsed, this._onWriteParsed));
|
|
144
160
|
}
|
|
145
161
|
|
|
146
162
|
public write(data: string | Uint8Array, callback?: () => void): void {
|
|
@@ -173,8 +189,12 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
173
189
|
return;
|
|
174
190
|
}
|
|
175
191
|
|
|
176
|
-
x = Math.max(x, MINIMUM_COLS);
|
|
177
|
-
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();
|
|
178
198
|
|
|
179
199
|
this._bufferService.resize(x, y);
|
|
180
200
|
}
|
|
@@ -238,6 +258,11 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
238
258
|
return this._inputHandler.registerOscHandler(ident, callback);
|
|
239
259
|
}
|
|
240
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
|
+
|
|
241
266
|
protected _setup(): void {
|
|
242
267
|
this._handleWindowsPtyOptionChange();
|
|
243
268
|
}
|
|
@@ -247,14 +272,14 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
247
272
|
this._bufferService.reset();
|
|
248
273
|
this._charsetService.reset();
|
|
249
274
|
this.coreService.reset();
|
|
250
|
-
this.
|
|
275
|
+
this.mouseStateService.reset();
|
|
251
276
|
}
|
|
252
277
|
|
|
253
278
|
|
|
254
279
|
private _handleWindowsPtyOptionChange(): void {
|
|
255
280
|
let value = false;
|
|
256
281
|
const windowsPty = this.optionsService.rawOptions.windowsPty;
|
|
257
|
-
if (windowsPty && windowsPty.
|
|
282
|
+
if (windowsPty && windowsPty.backend !== undefined && windowsPty.buildNumber !== undefined) {
|
|
258
283
|
value = !!(windowsPty.backend === 'conpty' && windowsPty.buildNumber < 21376);
|
|
259
284
|
}
|
|
260
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
|
+
}
|