@xterm/xterm 6.1.0-beta.18 → 6.1.0-beta.181

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 (156) hide show
  1. package/README.md +60 -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 -14
  8. package/src/browser/AccessibilityManager.ts +6 -3
  9. package/src/browser/Clipboard.ts +6 -3
  10. package/src/browser/CoreBrowserTerminal.ts +142 -62
  11. package/src/browser/Dom.ts +178 -0
  12. package/src/browser/Linkifier.ts +3 -3
  13. package/src/browser/OscLinkProvider.ts +3 -1
  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 +40 -17
  18. package/src/browser/decorations/BufferDecorationRenderer.ts +1 -1
  19. package/src/browser/decorations/OverviewRulerRenderer.ts +15 -16
  20. package/src/browser/input/CompositionHelper.ts +16 -1
  21. package/src/browser/public/Terminal.ts +24 -27
  22. package/src/browser/renderer/dom/DomRenderer.ts +128 -8
  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 +579 -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 +481 -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/MouseService.ts +2 -1
  47. package/src/browser/services/RenderService.ts +22 -15
  48. package/src/browser/services/SelectionService.ts +12 -4
  49. package/src/browser/services/Services.ts +24 -15
  50. package/src/browser/services/ThemeService.ts +2 -2
  51. package/src/common/Async.ts +105 -0
  52. package/src/common/CircularList.ts +2 -2
  53. package/src/common/Color.ts +8 -0
  54. package/src/common/CoreTerminal.ts +21 -11
  55. package/src/common/Event.ts +118 -0
  56. package/src/common/InputHandler.ts +244 -24
  57. package/src/common/Lifecycle.ts +113 -0
  58. package/src/common/Platform.ts +13 -3
  59. package/src/common/SortedList.ts +7 -3
  60. package/src/common/TaskQueue.ts +9 -3
  61. package/src/common/Types.ts +29 -9
  62. package/src/common/Version.ts +9 -0
  63. package/src/common/buffer/Buffer.ts +20 -14
  64. package/src/common/buffer/BufferLine.ts +4 -5
  65. package/src/common/buffer/BufferSet.ts +7 -6
  66. package/src/common/buffer/CellData.ts +57 -0
  67. package/src/common/buffer/Marker.ts +2 -2
  68. package/src/common/buffer/Types.ts +6 -2
  69. package/src/common/data/EscapeSequences.ts +71 -70
  70. package/src/common/input/Keyboard.ts +14 -7
  71. package/src/common/input/KittyKeyboard.ts +496 -0
  72. package/src/common/input/Win32InputMode.ts +297 -0
  73. package/src/common/input/WriteBuffer.ts +34 -2
  74. package/src/common/input/XParseColor.ts +2 -2
  75. package/src/common/parser/ApcParser.ts +245 -0
  76. package/src/common/parser/Constants.ts +22 -4
  77. package/src/common/parser/DcsParser.ts +5 -5
  78. package/src/common/parser/EscapeSequenceParser.ts +75 -22
  79. package/src/common/parser/OscParser.ts +5 -5
  80. package/src/common/parser/Types.ts +34 -1
  81. package/src/common/public/BufferLineApiView.ts +2 -2
  82. package/src/common/public/BufferNamespaceApi.ts +2 -2
  83. package/src/common/public/ParserApi.ts +3 -0
  84. package/src/common/services/BufferService.ts +8 -5
  85. package/src/common/services/CharsetService.ts +4 -0
  86. package/src/common/services/CoreMouseService.ts +2 -2
  87. package/src/common/services/CoreService.ts +18 -4
  88. package/src/common/services/DecorationService.ts +24 -8
  89. package/src/common/services/LogService.ts +1 -31
  90. package/src/common/services/OptionsService.ts +13 -4
  91. package/src/common/services/Services.ts +39 -16
  92. package/src/common/services/UnicodeService.ts +1 -1
  93. package/typings/xterm.d.ts +319 -35
  94. package/src/common/TypedArrayUtils.ts +0 -17
  95. package/src/vs/base/browser/browser.ts +0 -141
  96. package/src/vs/base/browser/canIUse.ts +0 -49
  97. package/src/vs/base/browser/dom.ts +0 -2369
  98. package/src/vs/base/browser/fastDomNode.ts +0 -316
  99. package/src/vs/base/browser/globalPointerMoveMonitor.ts +0 -112
  100. package/src/vs/base/browser/iframe.ts +0 -135
  101. package/src/vs/base/browser/keyboardEvent.ts +0 -213
  102. package/src/vs/base/browser/mouseEvent.ts +0 -229
  103. package/src/vs/base/browser/touch.ts +0 -372
  104. package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +0 -303
  105. package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +0 -114
  106. package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +0 -720
  107. package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +0 -165
  108. package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +0 -114
  109. package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +0 -243
  110. package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +0 -118
  111. package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +0 -116
  112. package/src/vs/base/browser/ui/widget.ts +0 -57
  113. package/src/vs/base/browser/window.ts +0 -14
  114. package/src/vs/base/common/arrays.ts +0 -887
  115. package/src/vs/base/common/arraysFind.ts +0 -202
  116. package/src/vs/base/common/assert.ts +0 -71
  117. package/src/vs/base/common/async.ts +0 -1992
  118. package/src/vs/base/common/cancellation.ts +0 -148
  119. package/src/vs/base/common/charCode.ts +0 -450
  120. package/src/vs/base/common/collections.ts +0 -140
  121. package/src/vs/base/common/decorators.ts +0 -130
  122. package/src/vs/base/common/equals.ts +0 -146
  123. package/src/vs/base/common/errors.ts +0 -303
  124. package/src/vs/base/common/event.ts +0 -1778
  125. package/src/vs/base/common/functional.ts +0 -32
  126. package/src/vs/base/common/hash.ts +0 -316
  127. package/src/vs/base/common/iterator.ts +0 -159
  128. package/src/vs/base/common/keyCodes.ts +0 -526
  129. package/src/vs/base/common/keybindings.ts +0 -284
  130. package/src/vs/base/common/lazy.ts +0 -47
  131. package/src/vs/base/common/lifecycle.ts +0 -801
  132. package/src/vs/base/common/linkedList.ts +0 -142
  133. package/src/vs/base/common/map.ts +0 -202
  134. package/src/vs/base/common/numbers.ts +0 -98
  135. package/src/vs/base/common/observable.ts +0 -76
  136. package/src/vs/base/common/observableInternal/api.ts +0 -31
  137. package/src/vs/base/common/observableInternal/autorun.ts +0 -281
  138. package/src/vs/base/common/observableInternal/base.ts +0 -489
  139. package/src/vs/base/common/observableInternal/debugName.ts +0 -145
  140. package/src/vs/base/common/observableInternal/derived.ts +0 -428
  141. package/src/vs/base/common/observableInternal/lazyObservableValue.ts +0 -146
  142. package/src/vs/base/common/observableInternal/logging.ts +0 -328
  143. package/src/vs/base/common/observableInternal/promise.ts +0 -209
  144. package/src/vs/base/common/observableInternal/utils.ts +0 -610
  145. package/src/vs/base/common/platform.ts +0 -281
  146. package/src/vs/base/common/scrollable.ts +0 -522
  147. package/src/vs/base/common/sequence.ts +0 -34
  148. package/src/vs/base/common/stopwatch.ts +0 -43
  149. package/src/vs/base/common/strings.ts +0 -557
  150. package/src/vs/base/common/symbols.ts +0 -9
  151. package/src/vs/base/common/uint.ts +0 -59
  152. package/src/vs/patches/nls.ts +0 -90
  153. package/src/vs/typings/base-common.d.ts +0 -20
  154. package/src/vs/typings/require.d.ts +0 -42
  155. package/src/vs/typings/vscode-globals-nls.d.ts +0 -36
  156. 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 {
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import { isNode } from 'common/Platform';
7
+ import type { ILogService } from 'common/services/Services';
7
8
 
8
9
  interface ITaskQueue {
9
10
  /**
@@ -34,6 +35,11 @@ abstract class TaskQueue implements ITaskQueue {
34
35
  private _tasks: (() => boolean | void)[] = [];
35
36
  private _idleCallback?: number;
36
37
  private _i = 0;
38
+ protected readonly _logService: ILogService;
39
+
40
+ constructor(logService: ILogService) {
41
+ this._logService = logService;
42
+ }
37
43
 
38
44
  protected abstract _requestCallback(callback: CallbackWithDeadline): number;
39
45
  protected abstract _cancelCallback(identifier: number): void;
@@ -90,7 +96,7 @@ abstract class TaskQueue implements ITaskQueue {
90
96
  // Warn when the time exceeding the deadline is over 20ms, if this happens in practice the
91
97
  // task should be split into sub-tasks to ensure the UI remains responsive.
92
98
  if (lastDeadlineRemaining - taskDuration < -20) {
93
- console.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(lastDeadlineRemaining - taskDuration))}ms`);
99
+ this._logService.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(lastDeadlineRemaining - taskDuration))}ms`);
94
100
  }
95
101
  this._start();
96
102
  return;
@@ -151,8 +157,8 @@ export const IdleTaskQueue = (!isNode && 'requestIdleCallback' in window) ? Idle
151
157
  export class DebouncedIdleTask {
152
158
  private _queue: ITaskQueue;
153
159
 
154
- constructor() {
155
- this._queue = new IdleTaskQueue();
160
+ constructor(logService: ILogService) {
161
+ this._queue = new IdleTaskQueue(logService);
156
162
  }
157
163
 
158
164
  public set(task: () => boolean | void): void {
@@ -9,7 +9,7 @@ import { IBufferSet } from 'common/buffer/Types';
9
9
  import { IParams } from 'common/parser/Types';
10
10
  import { ICoreMouseService, 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
15
  coreMouseService: ICoreMouseService;
@@ -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(ident: number, 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;
@@ -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(ident: number, callback: (data: string) => boolean | Promise<boolean>): IDisposable;
460
480
 
461
481
  /** C0 BEL */ bell(): boolean;
462
482
  /** C0 LF */ lineFeed(): boolean;
@@ -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.181';
@@ -14,7 +14,7 @@ import { NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR,
14
14
  import { Marker } from 'common/buffer/Marker';
15
15
  import { IBuffer } from 'common/buffer/Types';
16
16
  import { DEFAULT_CHARSET } from 'common/data/Charsets';
17
- import { IBufferService, IOptionsService } from 'common/services/Services';
17
+ import { IBufferService, ILogService, IOptionsService } from 'common/services/Services';
18
18
 
19
19
  export const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1
20
20
 
@@ -38,17 +38,24 @@ export class Buffer implements IBuffer {
38
38
  public savedX: number = 0;
39
39
  public savedCurAttrData = DEFAULT_ATTR_DATA.clone();
40
40
  public savedCharset: ICharset | undefined = DEFAULT_CHARSET;
41
+ public savedCharsets: (ICharset | undefined)[] = [];
42
+ public savedGlevel: number = 0;
43
+ public savedOriginMode: boolean = false;
44
+ public savedWraparoundMode: boolean = true;
41
45
  public markers: Marker[] = [];
42
46
  private _nullCell: ICellData = CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);
43
47
  private _whitespaceCell: ICellData = CellData.fromCharData([0, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_WIDTH, WHITESPACE_CELL_CODE]);
44
48
  private _cols: number;
45
49
  private _rows: number;
46
50
  private _isClearing: boolean = false;
51
+ private _memoryCleanupQueue: InstanceType<typeof IdleTaskQueue>;
52
+ private _memoryCleanupPosition = 0;
47
53
 
48
54
  constructor(
49
55
  private _hasScrollback: boolean,
50
56
  private _optionsService: IOptionsService,
51
- private _bufferService: IBufferService
57
+ private _bufferService: IBufferService,
58
+ private readonly _logService: ILogService
52
59
  ) {
53
60
  this._cols = this._bufferService.cols;
54
61
  this._rows = this._bufferService.rows;
@@ -56,6 +63,7 @@ export class Buffer implements IBuffer {
56
63
  this.scrollTop = 0;
57
64
  this.scrollBottom = this._rows - 1;
58
65
  this.setupTabStops();
66
+ this._memoryCleanupQueue = new IdleTaskQueue(this._logService);
59
67
  }
60
68
 
61
69
  public getNullCell(attr?: IAttributeData): ICellData {
@@ -118,9 +126,7 @@ export class Buffer implements IBuffer {
118
126
  */
119
127
  public fillViewportRows(fillAttr?: IAttributeData): void {
120
128
  if (this.lines.length === 0) {
121
- if (fillAttr === undefined) {
122
- fillAttr = DEFAULT_ATTR_DATA;
123
- }
129
+ fillAttr ??= DEFAULT_ATTR_DATA;
124
130
  let i = this._rows;
125
131
  while (i--) {
126
132
  this.lines.push(this.getBlankLine(fillAttr));
@@ -260,6 +266,13 @@ export class Buffer implements IBuffer {
260
266
  this._cols = newCols;
261
267
  this._rows = newRows;
262
268
 
269
+ // Ensure the cursor position invariant: ybase + y must be within buffer bounds
270
+ // This can be violated during reflow or when shrinking rows
271
+ if (this.lines.length > 0) {
272
+ const maxY = Math.max(0, this.lines.length - this.ybase - 1);
273
+ this.y = Math.min(this.y, maxY);
274
+ }
275
+
263
276
  this._memoryCleanupQueue.clear();
264
277
  // schedule memory cleanup only, if more than 10% of the lines are affected
265
278
  if (dirtyMemoryLines > 0.1 * this.lines.length) {
@@ -268,9 +281,6 @@ export class Buffer implements IBuffer {
268
281
  }
269
282
  }
270
283
 
271
- private _memoryCleanupQueue = new IdleTaskQueue();
272
- private _memoryCleanupPosition = 0;
273
-
274
284
  private _batchedMemoryCleanup(): boolean {
275
285
  let normalRun = true;
276
286
  if (this._memoryCleanupPosition >= this.lines.length) {
@@ -578,9 +588,7 @@ export class Buffer implements IBuffer {
578
588
  * @param x The position to move the cursor to the previous tab stop.
579
589
  */
580
590
  public prevStop(x?: number): number {
581
- if (x === null || x === undefined) {
582
- x = this.x;
583
- }
591
+ x ??= this.x;
584
592
  while (!this.tabs[--x] && x > 0);
585
593
  return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;
586
594
  }
@@ -590,9 +598,7 @@ export class Buffer implements IBuffer {
590
598
  * @param x The position to move the cursor one tab stop forward.
591
599
  */
592
600
  public nextStop(x?: number): number {
593
- if (x === null || x === undefined) {
594
- x = this.x;
595
- }
601
+ x ??= this.x;
596
602
  while (!this.tabs[++x] && x < this._cols);
597
603
  return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;
598
604
  }
@@ -39,6 +39,7 @@ export const DEFAULT_ATTR_DATA = Object.freeze(new AttributeData());
39
39
 
40
40
  // Work variables to avoid garbage collection
41
41
  let $startIndex = 0;
42
+ const $workCell = new CellData();
42
43
 
43
44
  /** Factor when to cleanup underlying array buffer after shrinking. */
44
45
  const CLEANUP_THRESHOLD = 2;
@@ -66,7 +67,7 @@ export class BufferLine implements IBufferLine {
66
67
 
67
68
  constructor(cols: number, fillCellData?: ICellData, public isWrapped: boolean = false) {
68
69
  this._data = new Uint32Array(cols * CELL_SIZE);
69
- const cell = fillCellData || CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);
70
+ const cell = fillCellData ?? CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);
70
71
  for (let i = 0; i < cols; ++i) {
71
72
  this.setCell(i, cell);
72
73
  }
@@ -262,9 +263,8 @@ export class BufferLine implements IBufferLine {
262
263
  }
263
264
 
264
265
  if (n < this.length - pos) {
265
- const cell = new CellData();
266
266
  for (let i = this.length - pos - n - 1; i >= 0; --i) {
267
- this.setCell(pos + n + i, this.loadCell(pos + i, cell));
267
+ this.setCell(pos + n + i, this.loadCell(pos + i, $workCell));
268
268
  }
269
269
  for (let i = 0; i < n; ++i) {
270
270
  this.setCell(pos + i, fillCellData);
@@ -284,9 +284,8 @@ export class BufferLine implements IBufferLine {
284
284
  public deleteCells(pos: number, n: number, fillCellData: ICellData): void {
285
285
  pos %= this.length;
286
286
  if (n < this.length - pos) {
287
- const cell = new CellData();
288
287
  for (let i = 0; i < this.length - pos - n; ++i) {
289
- this.setCell(pos + i, this.loadCell(pos + n + i, cell));
288
+ this.setCell(pos + i, this.loadCell(pos + n + i, $workCell));
290
289
  }
291
290
  for (let i = this.length - n; i < this.length; ++i) {
292
291
  this.setCell(i, fillCellData);
@@ -3,12 +3,12 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { Disposable } from 'vs/base/common/lifecycle';
6
+ import { Disposable } from 'common/Lifecycle';
7
7
  import { IAttributeData } from 'common/Types';
8
8
  import { Buffer } from 'common/buffer/Buffer';
9
9
  import { IBuffer, IBufferSet } from 'common/buffer/Types';
10
- import { IBufferService, IOptionsService } from 'common/services/Services';
11
- import { Emitter } from 'vs/base/common/event';
10
+ import { IBufferService, ILogService, IOptionsService } from 'common/services/Services';
11
+ import { Emitter } from 'common/Event';
12
12
 
13
13
  /**
14
14
  * The BufferSet represents the set of two buffers used by xterm terminals (normal and alt) and
@@ -27,7 +27,8 @@ export class BufferSet extends Disposable implements IBufferSet {
27
27
  */
28
28
  constructor(
29
29
  private readonly _optionsService: IOptionsService,
30
- private readonly _bufferService: IBufferService
30
+ private readonly _bufferService: IBufferService,
31
+ private readonly _logService: ILogService
31
32
  ) {
32
33
  super();
33
34
  this.reset();
@@ -36,12 +37,12 @@ export class BufferSet extends Disposable implements IBufferSet {
36
37
  }
37
38
 
38
39
  public reset(): void {
39
- this._normal = new Buffer(true, this._optionsService, this._bufferService);
40
+ this._normal = new Buffer(true, this._optionsService, this._bufferService, this._logService);
40
41
  this._normal.fillViewportRows();
41
42
 
42
43
  // The alt buffer should never have scrollback.
43
44
  // See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
44
- this._alt = new Buffer(false, this._optionsService, this._bufferService);
45
+ this._alt = new Buffer(false, this._optionsService, this._bufferService, this._logService);
45
46
  this._activeBuffer = this._normal;
46
47
  this._onBufferActivate.fire({
47
48
  activeBuffer: this._normal,
@@ -7,6 +7,7 @@ import { CharData, ICellData, IExtendedAttrs } from 'common/Types';
7
7
  import { stringFromCodePoint } from 'common/input/TextDecoder';
8
8
  import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_ATTR_INDEX, Content } from 'common/buffer/Constants';
9
9
  import { AttributeData, ExtendedAttrs } from 'common/buffer/AttributeData';
10
+ import type { IBufferCell as IBufferCellApi } from '@xterm/xterm';
10
11
 
11
12
  /**
12
13
  * CellData - represents a single Cell in the terminal buffer.
@@ -91,4 +92,60 @@ export class CellData extends AttributeData implements ICellData {
91
92
  public getAsCharData(): CharData {
92
93
  return [this.fg, this.getChars(), this.getWidth(), this.getCode()];
93
94
  }
95
+
96
+ public attributesEquals(other: IBufferCellApi): boolean {
97
+ if (this.getFgColorMode() !== other.getFgColorMode() || this.getFgColor() !== other.getFgColor()) {
98
+ return false;
99
+ }
100
+ if (this.getBgColorMode() !== other.getBgColorMode() || this.getBgColor() !== other.getBgColor()) {
101
+ return false;
102
+ }
103
+ if (this.isInverse() !== other.isInverse()) {
104
+ return false;
105
+ }
106
+ if (this.isBold() !== other.isBold()) {
107
+ return false;
108
+ }
109
+ if (this.isUnderline() !== other.isUnderline()) {
110
+ return false;
111
+ }
112
+ if (this.isUnderline()) {
113
+ if (this.getUnderlineStyle() !== other.getUnderlineStyle()) {
114
+ return false;
115
+ }
116
+ const thisDefault = this.isUnderlineColorDefault();
117
+ const otherDefault = other.isUnderlineColorDefault();
118
+ if (!(thisDefault && otherDefault)) {
119
+ if (thisDefault !== otherDefault) {
120
+ return false;
121
+ }
122
+ if (this.getUnderlineColor() !== other.getUnderlineColor()) {
123
+ return false;
124
+ }
125
+ if (this.getUnderlineColorMode() !== other.getUnderlineColorMode()) {
126
+ return false;
127
+ }
128
+ }
129
+ }
130
+ if (this.isOverline() !== other.isOverline()) {
131
+ return false;
132
+ }
133
+ if (this.isBlink() !== other.isBlink()) {
134
+ return false;
135
+ }
136
+ if (this.isInvisible() !== other.isInvisible()) {
137
+ return false;
138
+ }
139
+ if (this.isItalic() !== other.isItalic()) {
140
+ return false;
141
+ }
142
+ if (this.isDim() !== other.isDim()) {
143
+ return false;
144
+ }
145
+ if (this.isStrikethrough() !== other.isStrikethrough()) {
146
+ return false;
147
+ }
148
+ return true;
149
+ }
150
+
94
151
  }
@@ -4,8 +4,8 @@
4
4
  */
5
5
 
6
6
  import { IDisposable, IMarker } from 'common/Types';
7
- import { Emitter } from 'vs/base/common/event';
8
- import { dispose } from 'vs/base/common/lifecycle';
7
+ import { Emitter } from 'common/Event';
8
+ import { dispose } from 'common/Lifecycle';
9
9
 
10
10
  export class Marker implements IMarker {
11
11
  private static _nextId = 1;
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { IAttributeData, ICircularList, IBufferLine, ICellData, IMarker, ICharset, IDisposable } from 'common/Types';
7
- import type { Event } from 'vs/base/common/event';
7
+ import type { IEvent } from 'common/Event';
8
8
 
9
9
  // BufferIndex denotes a position in the buffer: [rowIndex, colIndex]
10
10
  export type BufferIndex = [number, number];
@@ -22,6 +22,10 @@ export interface IBuffer {
22
22
  savedY: number;
23
23
  savedX: number;
24
24
  savedCharset: ICharset | undefined;
25
+ savedCharsets: (ICharset | undefined)[];
26
+ savedGlevel: number;
27
+ savedOriginMode: boolean;
28
+ savedWraparoundMode: boolean;
25
29
  savedCurAttrData: IAttributeData;
26
30
  isCursorInViewport: boolean;
27
31
  markers: IMarker[];
@@ -42,7 +46,7 @@ export interface IBufferSet extends IDisposable {
42
46
  normal: IBuffer;
43
47
  active: IBuffer;
44
48
 
45
- onBufferActivate: Event<{ activeBuffer: IBuffer, inactiveBuffer: IBuffer }>;
49
+ onBufferActivate: IEvent<{ activeBuffer: IBuffer, inactiveBuffer: IBuffer }>;
46
50
 
47
51
  activateNormalBuffer(): void;
48
52
  activateAltBuffer(fillAttr?: IAttributeData): void;