@xterm/xterm 6.1.0-beta.23 → 6.1.0-beta.230

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.
Files changed (160) hide show
  1. package/README.md +62 -38
  2. package/css/xterm.css +29 -22
  3. package/lib/xterm.js +1 -1
  4. package/lib/xterm.js.map +1 -1
  5. package/lib/xterm.mjs +8 -34
  6. package/lib/xterm.mjs.map +4 -4
  7. package/package.json +25 -22
  8. package/src/browser/AccessibilityManager.ts +11 -6
  9. package/src/browser/Clipboard.ts +6 -3
  10. package/src/browser/CoreBrowserTerminal.ts +147 -318
  11. package/src/browser/Dom.ts +178 -0
  12. package/src/browser/Linkifier.ts +11 -11
  13. package/src/browser/OscLinkProvider.ts +82 -14
  14. package/src/browser/RenderDebouncer.ts +2 -2
  15. package/src/browser/TimeBasedDebouncer.ts +2 -2
  16. package/src/browser/Types.ts +12 -11
  17. package/src/browser/Viewport.ts +55 -20
  18. package/src/browser/decorations/BufferDecorationRenderer.ts +1 -1
  19. package/src/browser/decorations/OverviewRulerRenderer.ts +33 -17
  20. package/src/browser/input/CompositionHelper.ts +44 -8
  21. package/src/browser/public/Terminal.ts +25 -28
  22. package/src/browser/renderer/dom/DomRenderer.ts +242 -76
  23. package/src/browser/renderer/dom/DomRendererRowFactory.ts +19 -13
  24. package/src/browser/renderer/dom/WidthCache.ts +54 -52
  25. package/src/browser/renderer/shared/Constants.ts +7 -0
  26. package/src/browser/renderer/shared/TextBlinkStateManager.ts +97 -0
  27. package/src/browser/renderer/shared/Types.ts +8 -2
  28. package/src/browser/scrollable/abstractScrollbar.ts +300 -0
  29. package/src/browser/scrollable/fastDomNode.ts +126 -0
  30. package/src/browser/scrollable/globalPointerMoveMonitor.ts +90 -0
  31. package/src/browser/scrollable/horizontalScrollbar.ts +85 -0
  32. package/src/browser/scrollable/mouseEvent.ts +292 -0
  33. package/src/browser/scrollable/scrollable.ts +486 -0
  34. package/src/browser/scrollable/scrollableElement.ts +581 -0
  35. package/src/browser/scrollable/scrollableElementOptions.ts +161 -0
  36. package/src/browser/scrollable/scrollbarArrow.ts +110 -0
  37. package/src/browser/scrollable/scrollbarState.ts +246 -0
  38. package/src/browser/scrollable/scrollbarVisibilityController.ts +113 -0
  39. package/src/browser/scrollable/touch.ts +485 -0
  40. package/src/browser/scrollable/verticalScrollbar.ts +143 -0
  41. package/src/browser/scrollable/widget.ts +23 -0
  42. package/src/browser/services/CharSizeService.ts +2 -2
  43. package/src/browser/services/CoreBrowserService.ts +7 -5
  44. package/src/browser/services/KeyboardService.ts +67 -0
  45. package/src/browser/services/LinkProviderService.ts +1 -1
  46. package/src/browser/services/MouseCoordsService.ts +47 -0
  47. package/src/browser/services/MouseService.ts +518 -25
  48. package/src/browser/services/RenderService.ts +28 -16
  49. package/src/browser/services/SelectionService.ts +42 -35
  50. package/src/browser/services/Services.ts +40 -17
  51. package/src/browser/services/ThemeService.ts +2 -2
  52. package/src/common/Async.ts +141 -0
  53. package/src/common/CircularList.ts +2 -2
  54. package/src/common/Color.ts +8 -0
  55. package/src/common/CoreTerminal.ts +31 -21
  56. package/src/common/Event.ts +118 -0
  57. package/src/common/InputHandler.ts +283 -81
  58. package/src/common/Lifecycle.ts +113 -0
  59. package/src/common/Platform.ts +13 -3
  60. package/src/common/SortedList.ts +7 -3
  61. package/src/common/TaskQueue.ts +14 -5
  62. package/src/common/Types.ts +51 -31
  63. package/src/common/Version.ts +9 -0
  64. package/src/common/buffer/Buffer.ts +34 -19
  65. package/src/common/buffer/BufferLine.ts +133 -65
  66. package/src/common/buffer/BufferLineStringCache.ts +69 -0
  67. package/src/common/buffer/BufferSet.ts +11 -6
  68. package/src/common/buffer/CellData.ts +57 -0
  69. package/src/common/buffer/Marker.ts +2 -2
  70. package/src/common/buffer/Types.ts +6 -2
  71. package/src/common/data/EscapeSequences.ts +71 -70
  72. package/src/common/input/Keyboard.ts +14 -7
  73. package/src/common/input/KittyKeyboard.ts +526 -0
  74. package/src/common/input/Win32InputMode.ts +297 -0
  75. package/src/common/input/WriteBuffer.ts +69 -32
  76. package/src/common/input/XParseColor.ts +2 -2
  77. package/src/common/parser/ApcParser.ts +197 -0
  78. package/src/common/parser/Constants.ts +14 -4
  79. package/src/common/parser/DcsParser.ts +5 -5
  80. package/src/common/parser/EscapeSequenceParser.ts +205 -63
  81. package/src/common/parser/OscParser.ts +5 -5
  82. package/src/common/parser/Params.ts +27 -8
  83. package/src/common/parser/Types.ts +36 -2
  84. package/src/common/public/BufferLineApiView.ts +2 -2
  85. package/src/common/public/BufferNamespaceApi.ts +3 -3
  86. package/src/common/public/ParserApi.ts +3 -0
  87. package/src/common/services/BufferService.ts +14 -9
  88. package/src/common/services/CharsetService.ts +4 -0
  89. package/src/common/services/CoreService.ts +18 -4
  90. package/src/common/services/DecorationService.ts +258 -8
  91. package/src/common/services/LogService.ts +1 -31
  92. package/src/common/services/{CoreMouseService.ts → MouseStateService.ts} +21 -132
  93. package/src/common/services/OptionsService.ts +13 -4
  94. package/src/common/services/ServiceRegistry.ts +9 -7
  95. package/src/common/services/Services.ts +49 -40
  96. package/src/common/services/UnicodeService.ts +1 -1
  97. package/typings/xterm.d.ts +318 -34
  98. package/src/common/TypedArrayUtils.ts +0 -17
  99. package/src/vs/base/browser/browser.ts +0 -141
  100. package/src/vs/base/browser/canIUse.ts +0 -49
  101. package/src/vs/base/browser/dom.ts +0 -2369
  102. package/src/vs/base/browser/fastDomNode.ts +0 -316
  103. package/src/vs/base/browser/globalPointerMoveMonitor.ts +0 -112
  104. package/src/vs/base/browser/iframe.ts +0 -135
  105. package/src/vs/base/browser/keyboardEvent.ts +0 -213
  106. package/src/vs/base/browser/mouseEvent.ts +0 -229
  107. package/src/vs/base/browser/touch.ts +0 -372
  108. package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +0 -303
  109. package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +0 -114
  110. package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +0 -720
  111. package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +0 -165
  112. package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +0 -114
  113. package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +0 -243
  114. package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +0 -118
  115. package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +0 -116
  116. package/src/vs/base/browser/ui/widget.ts +0 -57
  117. package/src/vs/base/browser/window.ts +0 -14
  118. package/src/vs/base/common/arrays.ts +0 -887
  119. package/src/vs/base/common/arraysFind.ts +0 -202
  120. package/src/vs/base/common/assert.ts +0 -71
  121. package/src/vs/base/common/async.ts +0 -1992
  122. package/src/vs/base/common/cancellation.ts +0 -148
  123. package/src/vs/base/common/charCode.ts +0 -450
  124. package/src/vs/base/common/collections.ts +0 -140
  125. package/src/vs/base/common/decorators.ts +0 -130
  126. package/src/vs/base/common/equals.ts +0 -146
  127. package/src/vs/base/common/errors.ts +0 -303
  128. package/src/vs/base/common/event.ts +0 -1778
  129. package/src/vs/base/common/functional.ts +0 -32
  130. package/src/vs/base/common/hash.ts +0 -316
  131. package/src/vs/base/common/iterator.ts +0 -159
  132. package/src/vs/base/common/keyCodes.ts +0 -526
  133. package/src/vs/base/common/keybindings.ts +0 -284
  134. package/src/vs/base/common/lazy.ts +0 -47
  135. package/src/vs/base/common/lifecycle.ts +0 -801
  136. package/src/vs/base/common/linkedList.ts +0 -142
  137. package/src/vs/base/common/map.ts +0 -202
  138. package/src/vs/base/common/numbers.ts +0 -98
  139. package/src/vs/base/common/observable.ts +0 -76
  140. package/src/vs/base/common/observableInternal/api.ts +0 -31
  141. package/src/vs/base/common/observableInternal/autorun.ts +0 -281
  142. package/src/vs/base/common/observableInternal/base.ts +0 -489
  143. package/src/vs/base/common/observableInternal/debugName.ts +0 -145
  144. package/src/vs/base/common/observableInternal/derived.ts +0 -428
  145. package/src/vs/base/common/observableInternal/lazyObservableValue.ts +0 -146
  146. package/src/vs/base/common/observableInternal/logging.ts +0 -328
  147. package/src/vs/base/common/observableInternal/promise.ts +0 -209
  148. package/src/vs/base/common/observableInternal/utils.ts +0 -610
  149. package/src/vs/base/common/platform.ts +0 -281
  150. package/src/vs/base/common/scrollable.ts +0 -522
  151. package/src/vs/base/common/sequence.ts +0 -34
  152. package/src/vs/base/common/stopwatch.ts +0 -43
  153. package/src/vs/base/common/strings.ts +0 -557
  154. package/src/vs/base/common/symbols.ts +0 -9
  155. package/src/vs/base/common/uint.ts +0 -59
  156. package/src/vs/patches/nls.ts +0 -90
  157. package/src/vs/typings/base-common.d.ts +0 -20
  158. package/src/vs/typings/require.d.ts +0 -42
  159. package/src/vs/typings/vscode-globals-nls.d.ts +0 -36
  160. package/src/vs/typings/vscode-globals-product.d.ts +0 -33
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.
3
+ * @license MIT
4
+ *
5
+ * Minimal lifecycle utilities for xterm.js core.
6
+ * Simplified from VS Code's lifecycle.ts - no tracking/leak detection.
7
+ */
8
+
9
+ export interface IDisposable {
10
+ dispose(): void;
11
+ }
12
+
13
+ export function toDisposable(fn: () => void): IDisposable {
14
+ return { dispose: fn };
15
+ }
16
+
17
+ export function dispose<T extends IDisposable>(disposable: T): T;
18
+ export function dispose<T extends IDisposable>(disposable: T | undefined): T | undefined;
19
+ export function dispose<T extends IDisposable>(disposables: T[]): T[];
20
+ export function dispose<T extends IDisposable>(arg: T | T[] | undefined): T | T[] | undefined {
21
+ if (!arg) {
22
+ return arg;
23
+ }
24
+ if (Array.isArray(arg)) {
25
+ for (const d of arg) {
26
+ d.dispose();
27
+ }
28
+ return [];
29
+ }
30
+ arg.dispose();
31
+ return arg;
32
+ }
33
+
34
+ export function combinedDisposable(...disposables: IDisposable[]): IDisposable {
35
+ return toDisposable(() => dispose(disposables));
36
+ }
37
+
38
+ export class DisposableStore implements IDisposable {
39
+ private readonly _disposables = new Set<IDisposable>();
40
+ private _isDisposed = false;
41
+
42
+ public get isDisposed(): boolean {
43
+ return this._isDisposed;
44
+ }
45
+
46
+ public add<T extends IDisposable>(o: T): T {
47
+ if (this._isDisposed) {
48
+ o.dispose();
49
+ } else {
50
+ this._disposables.add(o);
51
+ }
52
+ return o;
53
+ }
54
+
55
+ public dispose(): void {
56
+ if (this._isDisposed) {
57
+ return;
58
+ }
59
+ this._isDisposed = true;
60
+ for (const d of this._disposables) {
61
+ d.dispose();
62
+ }
63
+ this._disposables.clear();
64
+ }
65
+
66
+ public clear(): void {
67
+ for (const d of this._disposables) {
68
+ d.dispose();
69
+ }
70
+ this._disposables.clear();
71
+ }
72
+ }
73
+
74
+ export abstract class Disposable implements IDisposable {
75
+ public static readonly None: IDisposable = Object.freeze({ dispose() { } });
76
+
77
+ protected readonly _store = new DisposableStore();
78
+
79
+ public dispose(): void {
80
+ this._store.dispose();
81
+ }
82
+
83
+ protected _register<T extends IDisposable>(o: T): T {
84
+ return this._store.add(o);
85
+ }
86
+ }
87
+
88
+ export class MutableDisposable<T extends IDisposable> implements IDisposable {
89
+ private _value: T | undefined;
90
+ private _isDisposed = false;
91
+
92
+ public get value(): T | undefined {
93
+ return this._isDisposed ? undefined : this._value;
94
+ }
95
+
96
+ public set value(value: T | undefined) {
97
+ if (this._isDisposed || value === this._value) {
98
+ return;
99
+ }
100
+ this._value?.dispose();
101
+ this._value = value;
102
+ }
103
+
104
+ public clear(): void {
105
+ this.value = undefined;
106
+ }
107
+
108
+ public dispose(): void {
109
+ this._isDisposed = true;
110
+ this._value?.dispose();
111
+ this._value = undefined;
112
+ }
113
+ }
@@ -14,13 +14,25 @@ interface INavigator {
14
14
  declare const navigator: INavigator;
15
15
  declare const process: unknown;
16
16
 
17
- export const isNode = (typeof process !== 'undefined' && 'title' in (process as any)) ? true : false;
17
+ // navigator.userAgent is also checked here because bundling with the process module can cause
18
+ // issues otherwise. Note that navigator exists in Node.js 21+ but the userAgent is
19
+ // "Node.js/<version>".
20
+ export const isNode = (typeof process !== 'undefined' && 'title' in (process as any) && (typeof navigator === 'undefined' || navigator.userAgent.startsWith('Node.js/'))) ? true : false;
18
21
  const userAgent = (isNode) ? 'node' : navigator.userAgent;
19
22
  const platform = (isNode) ? 'node' : navigator.platform;
20
23
 
21
24
  export const isFirefox = userAgent.includes('Firefox');
25
+ export const isChrome = userAgent.includes('Chrome');
22
26
  export const isLegacyEdge = userAgent.includes('Edge');
23
27
  export const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);
28
+
29
+ interface IZoomWindow {
30
+ devicePixelRatio?: number;
31
+ }
32
+
33
+ export function getZoomFactor(_targetWindow: IZoomWindow): number {
34
+ return 1;
35
+ }
24
36
  export function getSafariVersion(): number {
25
37
  if (!isSafari) {
26
38
  return 0;
@@ -36,8 +48,6 @@ export function getSafariVersion(): number {
36
48
  // and ISO third level shifts.
37
49
  // http://stackoverflow.com/q/19877924/577598
38
50
  export const isMac = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'].includes(platform);
39
- export const isIpad = platform === 'iPad';
40
- export const isIphone = platform === 'iPhone';
41
51
  export const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].includes(platform);
42
52
  export const isLinux = platform.indexOf('Linux') >= 0;
43
53
  // Note that when this is true, isLinux will also be true.
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import { IdleTaskQueue } from 'common/TaskQueue';
7
+ import type { ILogService } from 'common/services/Services';
7
8
 
8
9
  // Work variables to avoid garbage collection.
9
10
  let i = 0;
@@ -18,16 +19,19 @@ export class SortedList<T> {
18
19
  private _array: T[] = [];
19
20
 
20
21
  private readonly _insertedValues: T[] = [];
21
- private readonly _flushInsertedTask = new IdleTaskQueue();
22
+ private readonly _flushInsertedTask: InstanceType<typeof IdleTaskQueue>;
22
23
  private _isFlushingInserted = false;
23
24
 
24
25
  private readonly _deletedIndices: number[] = [];
25
- private readonly _flushDeletedTask = new IdleTaskQueue();
26
+ private readonly _flushDeletedTask: InstanceType<typeof IdleTaskQueue>;
26
27
  private _isFlushingDeleted = false;
27
28
 
28
29
  constructor(
29
- private readonly _getKey: (value: T) => number
30
+ private readonly _getKey: (value: T) => number,
31
+ logService: ILogService
30
32
  ) {
33
+ this._flushInsertedTask = new IdleTaskQueue(logService);
34
+ this._flushDeletedTask = new IdleTaskQueue(logService);
31
35
  }
32
36
 
33
37
  public clear(): void {
@@ -3,7 +3,7 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { isNode } from 'common/Platform';
6
+ import type { ILogService } from 'common/services/Services';
7
7
 
8
8
  interface ITaskQueue {
9
9
  /**
@@ -34,6 +34,11 @@ abstract class TaskQueue implements ITaskQueue {
34
34
  private _tasks: (() => boolean | void)[] = [];
35
35
  private _idleCallback?: number;
36
36
  private _i = 0;
37
+ protected readonly _logService: ILogService;
38
+
39
+ constructor(logService: ILogService) {
40
+ this._logService = logService;
41
+ }
37
42
 
38
43
  protected abstract _requestCallback(callback: CallbackWithDeadline): number;
39
44
  protected abstract _cancelCallback(identifier: number): void;
@@ -90,7 +95,7 @@ abstract class TaskQueue implements ITaskQueue {
90
95
  // Warn when the time exceeding the deadline is over 20ms, if this happens in practice the
91
96
  // task should be split into sub-tasks to ensure the UI remains responsive.
92
97
  if (lastDeadlineRemaining - taskDuration < -20) {
93
- console.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(lastDeadlineRemaining - taskDuration))}ms`);
98
+ this._logService.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(lastDeadlineRemaining - taskDuration))}ms`);
94
99
  }
95
100
  this._start();
96
101
  return;
@@ -142,7 +147,7 @@ class IdleTaskQueueInternal extends TaskQueue {
142
147
  * This reverts to a {@link PriorityTaskQueue} if the environment does not support idle callbacks.
143
148
  */
144
149
  // eslint-disable-next-line @typescript-eslint/naming-convention
145
- export const IdleTaskQueue = (!isNode && 'requestIdleCallback' in window) ? IdleTaskQueueInternal : PriorityTaskQueue;
150
+ export const IdleTaskQueue = ('requestIdleCallback' in globalThis) ? IdleTaskQueueInternal : PriorityTaskQueue;
146
151
 
147
152
  /**
148
153
  * An object that tracks a single debounced task that will run on the next idle frame. When called
@@ -151,8 +156,8 @@ export const IdleTaskQueue = (!isNode && 'requestIdleCallback' in window) ? Idle
151
156
  export class DebouncedIdleTask {
152
157
  private _queue: ITaskQueue;
153
158
 
154
- constructor() {
155
- this._queue = new IdleTaskQueue();
159
+ constructor(logService: ILogService) {
160
+ this._queue = new IdleTaskQueue(logService);
156
161
  }
157
162
 
158
163
  public set(task: () => boolean | void): void {
@@ -163,4 +168,8 @@ export class DebouncedIdleTask {
163
168
  public flush(): void {
164
169
  this._queue.flush();
165
170
  }
171
+
172
+ public dispose(): void {
173
+ this._queue.clear();
174
+ }
166
175
  }
@@ -7,12 +7,12 @@ import { IDeleteEvent, IInsertEvent } from 'common/CircularList';
7
7
  import { UnderlineStyle } from 'common/buffer/Constants';
8
8
  import { IBufferSet } from 'common/buffer/Types';
9
9
  import { IParams } from 'common/parser/Types';
10
- import { ICoreMouseService, ICoreService, IOptionsService, IUnicodeService } from 'common/services/Services';
10
+ import { IMouseStateService, ICoreService, IOptionsService, IUnicodeService } from 'common/services/Services';
11
11
  import { IFunctionIdentifier, ITerminalOptions as IPublicTerminalOptions } from '@xterm/xterm';
12
- import type { Emitter, Event } from 'vs/base/common/event';
12
+ import type { Emitter, IEvent } from 'common/Event';
13
13
 
14
14
  export interface ICoreTerminal {
15
- coreMouseService: ICoreMouseService;
15
+ mouseStateService: IMouseStateService;
16
16
  coreService: ICoreService;
17
17
  optionsService: IOptionsService;
18
18
  unicodeService: IUnicodeService;
@@ -22,6 +22,7 @@ export interface ICoreTerminal {
22
22
  registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise<boolean>): IDisposable;
23
23
  registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise<boolean>): IDisposable;
24
24
  registerOscHandler(ident: number, callback: (data: string) => boolean | Promise<boolean>): IDisposable;
25
+ registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise<boolean>): IDisposable;
25
26
  }
26
27
 
27
28
  export interface IDisposable {
@@ -31,7 +32,6 @@ export interface IDisposable {
31
32
  // TODO: The options that are not in the public API should be reviewed
32
33
  export interface ITerminalOptions extends IPublicTerminalOptions {
33
34
  [key: string]: any;
34
- cancelEvents?: boolean;
35
35
  convertEol?: boolean;
36
36
  termName?: string;
37
37
  }
@@ -68,11 +68,11 @@ export interface ICircularList<T> {
68
68
  isFull: boolean;
69
69
 
70
70
  onDeleteEmitter: Emitter<IDeleteEvent>;
71
- onDelete: Event<IDeleteEvent>;
71
+ onDelete: IEvent<IDeleteEvent>;
72
72
  onInsertEmitter: Emitter<IInsertEvent>;
73
- onInsert: Event<IInsertEvent>;
73
+ onInsert: IEvent<IInsertEvent>;
74
74
  onTrimEmitter: Emitter<number>;
75
- onTrim: Event<number>;
75
+ onTrim: IEvent<number>;
76
76
 
77
77
  get(index: number): T | undefined;
78
78
  set(index: number, value: T): void;
@@ -101,13 +101,13 @@ export interface ICharset {
101
101
  [key: string]: string | undefined;
102
102
  }
103
103
 
104
- export type CharData = [number, string, number, number];
104
+ export type CharData = [attr: number, char: string, width: number, code: number];
105
105
 
106
106
  export interface IColor {
107
107
  readonly css: string;
108
108
  readonly rgba: number; // 32-bit int with rgba in each byte
109
109
  }
110
- export type IColorRGB = [number, number, number];
110
+ export type IColorRGB = [red: number, green: number, blue: number];
111
111
 
112
112
  export interface IExtendedAttrs {
113
113
  ext: number;
@@ -258,7 +258,7 @@ export interface IMarker extends IDisposable {
258
258
  readonly id: number;
259
259
  readonly isDisposed: boolean;
260
260
  readonly line: number;
261
- onDispose: Event<void>;
261
+ onDispose: IEvent<void>;
262
262
  }
263
263
  export interface IModes {
264
264
  insertMode: boolean;
@@ -268,15 +268,34 @@ export interface IDecPrivateModes {
268
268
  applicationCursorKeys: boolean;
269
269
  applicationKeypad: boolean;
270
270
  bracketedPasteMode: boolean;
271
+ colorSchemeUpdates: boolean;
271
272
  cursorBlink: boolean | undefined;
272
273
  cursorStyle: CursorStyle | undefined;
273
274
  origin: boolean;
274
275
  reverseWraparound: boolean;
275
276
  sendFocus: boolean;
276
277
  synchronizedOutput: boolean;
278
+ win32InputMode: boolean;
277
279
  wraparound: boolean; // defaults: xterm - true, vt100 - false
278
280
  }
279
281
 
282
+ /**
283
+ * Kitty keyboard protocol state.
284
+ * Maintains per-screen stacks of enhancement flags.
285
+ */
286
+ export interface IKittyKeyboardState {
287
+ /** Current active enhancement flags (for current screen) */
288
+ flags: number;
289
+ /** Saved flags for main screen when alt is active */
290
+ mainFlags: number;
291
+ /** Saved flags for alternate screen when main is active */
292
+ altFlags: number;
293
+ /** Stack of flags for main screen */
294
+ mainStack: number[];
295
+ /** Stack of flags for alternate screen */
296
+ altStack: number[];
297
+ }
298
+
280
299
  export interface IRowRange {
281
300
  start: number;
282
301
  end: number;
@@ -324,7 +343,7 @@ export interface ICoreMouseEvent {
324
343
  * it is not possible to report multiple buttons at once.
325
344
  * Wheel is treated as a button.
326
345
  * There are invalid combinations of buttons and actions possible
327
- * (like move + wheel), those are silently ignored by the CoreMouseService.
346
+ * (like move + wheel), those are silently ignored by the MouseStateService.
328
347
  */
329
348
  button: CoreMouseButton;
330
349
  action: CoreMouseAction;
@@ -341,7 +360,7 @@ export interface ICoreMouseEvent {
341
360
  * CoreMouseEventType
342
361
  * To be reported to the browser component which events a mouse
343
362
  * protocol wants to be catched and forwarded as an ICoreMouseEvent
344
- * to CoreMouseService.
363
+ * to MouseStateService.
345
364
  */
346
365
  export const enum CoreMouseEventType {
347
366
  NONE = 0,
@@ -359,7 +378,7 @@ export const enum CoreMouseEventType {
359
378
 
360
379
  /**
361
380
  * Mouse protocol interface.
362
- * A mouse protocol can be registered and activated at the CoreMouseService.
381
+ * A mouse protocol can be registered and activated at the MouseStateService.
363
382
  * `events` should contain a list of needed events as a hint for the browser component
364
383
  * to install/remove the appropriate event handlers.
365
384
  * `restrict` applies further protocol specific restrictions like not allowed
@@ -372,7 +391,7 @@ export interface ICoreMouseProtocol {
372
391
 
373
392
  /**
374
393
  * CoreMouseEncoding
375
- * The tracking encoding can be registered and activated at the CoreMouseService.
394
+ * The tracking encoding can be registered and activated at the MouseStateService.
376
395
  * If a ICoreMouseEvent passes all procotol restrictions it will be encoded
377
396
  * with the active encoding and sent out.
378
397
  * Note: Returning an empty string will supress sending a mouse report,
@@ -449,7 +468,7 @@ export type IColorEvent = (IColorReportRequest | IColorSetRequest | IColorRestor
449
468
  * Calls the parser and handles actions generated by the parser.
450
469
  */
451
470
  export interface IInputHandler {
452
- onTitleChange: Event<string>;
471
+ onTitleChange: IEvent<string>;
453
472
 
454
473
  parse(data: string | Uint8Array, promiseResult?: boolean): void | Promise<boolean>;
455
474
  print(data: Uint32Array, start: number, end: number): void;
@@ -457,6 +476,7 @@ export interface IInputHandler {
457
476
  registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise<boolean>): IDisposable;
458
477
  registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise<boolean>): IDisposable;
459
478
  registerOscHandler(ident: number, callback: (data: string) => boolean | Promise<boolean>): IDisposable;
479
+ registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise<boolean>): IDisposable;
460
480
 
461
481
  /** C0 BEL */ bell(): boolean;
462
482
  /** C0 LF */ lineFeed(): boolean;
@@ -508,8 +528,8 @@ export interface IInputHandler {
508
528
  /** CSI ' } */ insertColumns(params: IParams): boolean;
509
529
  /** CSI ' ~ */ deleteColumns(params: IParams): boolean;
510
530
 
511
- /** OSC 0
512
- OSC 2 */ setTitle(data: string): boolean;
531
+ /** OSC 0 */
532
+ /** OSC 2 */ setTitle(data: string): boolean;
513
533
  /** OSC 4 */ setOrReportIndexedColor(data: string): boolean;
514
534
  /** OSC 10 */ setOrReportFgColor(data: string): boolean;
515
535
  /** OSC 11 */ setOrReportBgColor(data: string): boolean;
@@ -522,24 +542,24 @@ export interface IInputHandler {
522
542
  /** ESC E */ nextLine(): boolean;
523
543
  /** ESC = */ keypadApplicationMode(): boolean;
524
544
  /** ESC > */ keypadNumericMode(): boolean;
525
- /** ESC % G
526
- ESC % @ */ selectDefaultCharset(): boolean;
527
- /** ESC ( C
528
- ESC ) C
529
- ESC * C
530
- ESC + C
531
- ESC - C
532
- ESC . C
533
- ESC / C */ selectCharset(collectAndFlag: string): boolean;
545
+ /** ESC % G */
546
+ /** ESC % @ */ selectDefaultCharset(): boolean;
547
+ /** ESC ( C */
548
+ /** ESC ) C */
549
+ /** ESC * C */
550
+ /** ESC + C */
551
+ /** ESC - C */
552
+ /** ESC . C */
553
+ /** ESC / C */ selectCharset(collectAndFlag: string): boolean;
534
554
  /** ESC D */ index(): boolean;
535
555
  /** ESC H */ tabSet(): boolean;
536
556
  /** ESC M */ reverseIndex(): boolean;
537
557
  /** ESC c */ fullReset(): boolean;
538
- /** ESC n
539
- ESC o
540
- ESC |
541
- ESC }
542
- ESC ~ */ setgLevel(level: number): boolean;
558
+ /** ESC n */
559
+ /** ESC o */
560
+ /** ESC | */
561
+ /** ESC } */
562
+ /** ESC ~ */ setgLevel(level: number): boolean;
543
563
  /** ESC # 8 */ screenAlignmentPattern(): boolean;
544
564
  }
545
565
 
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright (c) 2025 The xterm.js authors. All rights reserved.
3
+ * @license MIT
4
+ */
5
+
6
+ /**
7
+ * The xterm.js version. This is updated by the publish script from package.json.
8
+ */
9
+ export const XTERM_VERSION = '6.1.0-beta.230';
@@ -4,17 +4,19 @@
4
4
  */
5
5
 
6
6
  import { CircularList, IInsertEvent } from 'common/CircularList';
7
+ import { Disposable, toDisposable } from 'common/Lifecycle';
7
8
  import { IdleTaskQueue } from 'common/TaskQueue';
8
9
  import { IAttributeData, IBufferLine, ICellData, ICharset } from 'common/Types';
9
10
  import { ExtendedAttrs } from 'common/buffer/AttributeData';
10
11
  import { BufferLine, DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine';
12
+ import { BufferLineStringCache } from 'common/buffer/BufferLineStringCache';
11
13
  import { getWrappedLineTrimmedLength, reflowLargerApplyNewLayout, reflowLargerCreateNewLayout, reflowLargerGetLinesToRemove, reflowSmallerGetNewLineLengths } from 'common/buffer/BufferReflow';
12
14
  import { CellData } from 'common/buffer/CellData';
13
15
  import { NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE, WHITESPACE_CELL_WIDTH } from 'common/buffer/Constants';
14
16
  import { Marker } from 'common/buffer/Marker';
15
17
  import { IBuffer } from 'common/buffer/Types';
16
18
  import { DEFAULT_CHARSET } from 'common/data/Charsets';
17
- import { IBufferService, IOptionsService } from 'common/services/Services';
19
+ import { IBufferService, ILogService, IOptionsService } from 'common/services/Services';
18
20
 
19
21
  export const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1
20
22
 
@@ -25,7 +27,7 @@ export const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1
25
27
  * - cursor position
26
28
  * - scroll position
27
29
  */
28
- export class Buffer implements IBuffer {
30
+ export class Buffer extends Disposable implements IBuffer {
29
31
  public lines: CircularList<IBufferLine>;
30
32
  public ydisp: number = 0;
31
33
  public ybase: number = 0;
@@ -38,24 +40,37 @@ export class Buffer implements IBuffer {
38
40
  public savedX: number = 0;
39
41
  public savedCurAttrData = DEFAULT_ATTR_DATA.clone();
40
42
  public savedCharset: ICharset | undefined = DEFAULT_CHARSET;
43
+ public savedCharsets: (ICharset | undefined)[] = [];
44
+ public savedGlevel: number = 0;
45
+ public savedOriginMode: boolean = false;
46
+ public savedWraparoundMode: boolean = true;
41
47
  public markers: Marker[] = [];
42
48
  private _nullCell: ICellData = CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);
43
49
  private _whitespaceCell: ICellData = CellData.fromCharData([0, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_WIDTH, WHITESPACE_CELL_CODE]);
44
50
  private _cols: number;
45
51
  private _rows: number;
46
52
  private _isClearing: boolean = false;
53
+ private _memoryCleanupQueue: InstanceType<typeof IdleTaskQueue>;
54
+ private _memoryCleanupPosition = 0;
55
+ private readonly _stringCache: BufferLineStringCache;
47
56
 
48
57
  constructor(
49
58
  private _hasScrollback: boolean,
50
59
  private _optionsService: IOptionsService,
51
- private _bufferService: IBufferService
60
+ private _bufferService: IBufferService,
61
+ private readonly _logService: ILogService
52
62
  ) {
63
+ super();
53
64
  this._cols = this._bufferService.cols;
54
65
  this._rows = this._bufferService.rows;
55
66
  this.lines = new CircularList<IBufferLine>(this._getCorrectBufferLength(this._rows));
56
67
  this.scrollTop = 0;
57
68
  this.scrollBottom = this._rows - 1;
58
69
  this.setupTabStops();
70
+ this._memoryCleanupQueue = new IdleTaskQueue(this._logService);
71
+ this._register(toDisposable(() => this._memoryCleanupQueue.clear()));
72
+ this._register(toDisposable(() => this.clearAllMarkers()));
73
+ this._stringCache = this._register(new BufferLineStringCache());
59
74
  }
60
75
 
61
76
  public getNullCell(attr?: IAttributeData): ICellData {
@@ -85,7 +100,7 @@ export class Buffer implements IBuffer {
85
100
  }
86
101
 
87
102
  public getBlankLine(attr: IAttributeData, isWrapped?: boolean): IBufferLine {
88
- return new BufferLine(this._bufferService.cols, this.getNullCell(attr), isWrapped);
103
+ return new BufferLine(this._stringCache, this._bufferService.cols, this.getNullCell(attr), isWrapped);
89
104
  }
90
105
 
91
106
  public get hasScrollback(): boolean {
@@ -118,9 +133,7 @@ export class Buffer implements IBuffer {
118
133
  */
119
134
  public fillViewportRows(fillAttr?: IAttributeData): void {
120
135
  if (this.lines.length === 0) {
121
- if (fillAttr === undefined) {
122
- fillAttr = DEFAULT_ATTR_DATA;
123
- }
136
+ fillAttr ??= DEFAULT_ATTR_DATA;
124
137
  let i = this._rows;
125
138
  while (i--) {
126
139
  this.lines.push(this.getBlankLine(fillAttr));
@@ -132,6 +145,7 @@ export class Buffer implements IBuffer {
132
145
  * Clears the buffer to it's initial state, discarding all previous data.
133
146
  */
134
147
  public clear(): void {
148
+ this._stringCache.clear();
135
149
  this.ydisp = 0;
136
150
  this.ybase = 0;
137
151
  this.y = 0;
@@ -150,6 +164,7 @@ export class Buffer implements IBuffer {
150
164
  public resize(newCols: number, newRows: number): void {
151
165
  // store reference to null cell with default attrs
152
166
  const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);
167
+ this._stringCache.clear();
153
168
 
154
169
  // count bufferlines with overly big memory to be cleaned afterwards
155
170
  let dirtyMemoryLines = 0;
@@ -184,7 +199,7 @@ export class Buffer implements IBuffer {
184
199
  if (this._optionsService.rawOptions.windowsPty.backend !== undefined || this._optionsService.rawOptions.windowsPty.buildNumber !== undefined) {
185
200
  // Just add the new missing rows on Windows as conpty reprints the screen with it's
186
201
  // view of the world. Once a line enters scrollback for conpty it remains there
187
- this.lines.push(new BufferLine(newCols, nullCell));
202
+ this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));
188
203
  } else {
189
204
  if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {
190
205
  // There is room above the buffer and there are no empty elements below the line,
@@ -198,7 +213,7 @@ export class Buffer implements IBuffer {
198
213
  } else {
199
214
  // Add a blank line if there is no buffer left at the top to scroll to, or if there
200
215
  // are blank lines after the cursor
201
- this.lines.push(new BufferLine(newCols, nullCell));
216
+ this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));
202
217
  }
203
218
  }
204
219
  }
@@ -260,6 +275,13 @@ export class Buffer implements IBuffer {
260
275
  this._cols = newCols;
261
276
  this._rows = newRows;
262
277
 
278
+ // Ensure the cursor position invariant: ybase + y must be within buffer bounds
279
+ // This can be violated during reflow or when shrinking rows
280
+ if (this.lines.length > 0) {
281
+ const maxY = Math.max(0, this.lines.length - this.ybase - 1);
282
+ this.y = Math.min(this.y, maxY);
283
+ }
284
+
263
285
  this._memoryCleanupQueue.clear();
264
286
  // schedule memory cleanup only, if more than 10% of the lines are affected
265
287
  if (dirtyMemoryLines > 0.1 * this.lines.length) {
@@ -268,9 +290,6 @@ export class Buffer implements IBuffer {
268
290
  }
269
291
  }
270
292
 
271
- private _memoryCleanupQueue = new IdleTaskQueue();
272
- private _memoryCleanupPosition = 0;
273
-
274
293
  private _batchedMemoryCleanup(): boolean {
275
294
  let normalRun = true;
276
295
  if (this._memoryCleanupPosition >= this.lines.length) {
@@ -335,7 +354,7 @@ export class Buffer implements IBuffer {
335
354
  }
336
355
  if (this.lines.length < newRows) {
337
356
  // Add an extra row at the bottom of the viewport
338
- this.lines.push(new BufferLine(newCols, nullCell));
357
+ this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));
339
358
  }
340
359
  } else {
341
360
  if (this.ydisp === this.ybase) {
@@ -578,9 +597,7 @@ export class Buffer implements IBuffer {
578
597
  * @param x The position to move the cursor to the previous tab stop.
579
598
  */
580
599
  public prevStop(x?: number): number {
581
- if (x === null || x === undefined) {
582
- x = this.x;
583
- }
600
+ x ??= this.x;
584
601
  while (!this.tabs[--x] && x > 0);
585
602
  return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;
586
603
  }
@@ -590,9 +607,7 @@ export class Buffer implements IBuffer {
590
607
  * @param x The position to move the cursor one tab stop forward.
591
608
  */
592
609
  public nextStop(x?: number): number {
593
- if (x === null || x === undefined) {
594
- x = this.x;
595
- }
610
+ x ??= this.x;
596
611
  while (!this.tabs[++x] && x < this._cols);
597
612
  return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;
598
613
  }