@xterm/xterm 6.1.0-beta.26 → 6.1.0-beta.260

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 (179) 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 +56 -48
  8. package/src/browser/AccessibilityManager.ts +18 -13
  9. package/src/browser/Clipboard.ts +8 -5
  10. package/src/browser/ColorContrastCache.ts +3 -3
  11. package/src/browser/CoreBrowserTerminal.ts +177 -346
  12. package/src/browser/Dom.ts +178 -0
  13. package/src/browser/Linkifier.ts +14 -14
  14. package/src/browser/OscLinkProvider.ts +86 -18
  15. package/src/browser/RenderDebouncer.ts +4 -4
  16. package/src/browser/TimeBasedDebouncer.ts +3 -3
  17. package/src/browser/Types.ts +15 -14
  18. package/src/browser/Viewport.ts +58 -23
  19. package/src/browser/decorations/BufferDecorationRenderer.ts +3 -3
  20. package/src/browser/decorations/ColorZoneStore.ts +1 -1
  21. package/src/browser/decorations/OverviewRulerRenderer.ts +36 -20
  22. package/src/browser/input/CompositionHelper.ts +47 -11
  23. package/src/browser/input/MoveToCell.ts +2 -2
  24. package/src/browser/public/Terminal.ts +33 -36
  25. package/src/browser/renderer/dom/DomRenderer.ts +251 -85
  26. package/src/browser/renderer/dom/DomRendererRowFactory.ts +33 -27
  27. package/src/browser/renderer/dom/WidthCache.ts +57 -55
  28. package/src/browser/renderer/shared/Constants.ts +7 -0
  29. package/src/browser/renderer/shared/RendererUtils.ts +1 -1
  30. package/src/browser/renderer/shared/SelectionRenderModel.ts +2 -2
  31. package/src/browser/renderer/shared/TextBlinkStateManager.ts +97 -0
  32. package/src/browser/renderer/shared/Types.ts +10 -4
  33. package/src/browser/scrollable/abstractScrollbar.ts +300 -0
  34. package/src/browser/scrollable/fastDomNode.ts +126 -0
  35. package/src/browser/scrollable/globalPointerMoveMonitor.ts +90 -0
  36. package/src/browser/scrollable/horizontalScrollbar.ts +85 -0
  37. package/src/browser/scrollable/mouseEvent.ts +292 -0
  38. package/src/browser/scrollable/scrollable.ts +486 -0
  39. package/src/browser/scrollable/scrollableElement.ts +581 -0
  40. package/src/browser/scrollable/scrollableElementOptions.ts +161 -0
  41. package/src/browser/scrollable/scrollbarArrow.ts +110 -0
  42. package/src/browser/scrollable/scrollbarState.ts +246 -0
  43. package/src/browser/scrollable/scrollbarVisibilityController.ts +113 -0
  44. package/src/browser/scrollable/touch.ts +485 -0
  45. package/src/browser/scrollable/verticalScrollbar.ts +143 -0
  46. package/src/browser/scrollable/widget.ts +23 -0
  47. package/src/browser/selection/SelectionModel.ts +1 -1
  48. package/src/browser/services/CharSizeService.ts +4 -4
  49. package/src/browser/services/CharacterJoinerService.ts +7 -7
  50. package/src/browser/services/CoreBrowserService.ts +7 -5
  51. package/src/browser/services/KeyboardService.ts +67 -0
  52. package/src/browser/services/LinkProviderService.ts +3 -3
  53. package/src/browser/services/MouseCoordsService.ts +47 -0
  54. package/src/browser/services/MouseService.ts +619 -23
  55. package/src/browser/services/RenderService.ts +33 -21
  56. package/src/browser/services/SelectionService.ts +72 -54
  57. package/src/browser/services/Services.ts +44 -21
  58. package/src/browser/services/ThemeService.ts +8 -8
  59. package/src/common/Async.ts +141 -0
  60. package/src/common/CircularList.ts +3 -3
  61. package/src/common/Color.ts +9 -1
  62. package/src/common/CoreTerminal.ts +45 -35
  63. package/src/common/Event.ts +118 -0
  64. package/src/common/InputHandler.ts +301 -102
  65. package/src/common/Lifecycle.ts +113 -0
  66. package/src/common/Platform.ts +13 -3
  67. package/src/common/SortedList.ts +8 -4
  68. package/src/common/StringBuilder.ts +67 -0
  69. package/src/common/TaskQueue.ts +16 -7
  70. package/src/common/Types.ts +55 -35
  71. package/src/common/Version.ts +9 -0
  72. package/src/common/WindowsMode.ts +2 -2
  73. package/src/common/buffer/AttributeData.ts +2 -2
  74. package/src/common/buffer/Buffer.ts +45 -30
  75. package/src/common/buffer/BufferLine.ts +145 -73
  76. package/src/common/buffer/BufferLineStringCache.ts +69 -0
  77. package/src/common/buffer/BufferReflow.ts +7 -4
  78. package/src/common/buffer/BufferSet.ts +14 -9
  79. package/src/common/buffer/CellData.ts +61 -4
  80. package/src/common/buffer/Marker.ts +3 -3
  81. package/src/common/buffer/Types.ts +7 -3
  82. package/src/common/data/Charsets.ts +4 -7
  83. package/src/common/data/EscapeSequences.ts +71 -70
  84. package/src/common/input/Keyboard.ts +16 -9
  85. package/src/common/input/KittyKeyboard.ts +526 -0
  86. package/src/common/input/TextDecoder.ts +1 -1
  87. package/src/common/input/UnicodeV6.ts +2 -2
  88. package/src/common/input/Win32InputMode.ts +297 -0
  89. package/src/common/input/WriteBuffer.ts +107 -38
  90. package/src/common/input/XParseColor.ts +2 -2
  91. package/src/common/parser/ApcParser.ts +196 -0
  92. package/src/common/parser/Constants.ts +14 -4
  93. package/src/common/parser/DcsParser.ts +15 -16
  94. package/src/common/parser/EscapeSequenceParser.ts +212 -70
  95. package/src/common/parser/OscParser.ts +14 -15
  96. package/src/common/parser/Params.ts +28 -9
  97. package/src/common/parser/Types.ts +38 -4
  98. package/src/common/public/BufferApiView.ts +3 -3
  99. package/src/common/public/BufferLineApiView.ts +4 -4
  100. package/src/common/public/BufferNamespaceApi.ts +5 -5
  101. package/src/common/public/ParserApi.ts +5 -2
  102. package/src/common/public/UnicodeApi.ts +1 -1
  103. package/src/common/services/BufferService.ts +18 -13
  104. package/src/common/services/CharsetService.ts +6 -2
  105. package/src/common/services/CoreService.ts +23 -10
  106. package/src/common/services/DecorationService.ts +260 -15
  107. package/src/common/services/InstantiationService.ts +2 -2
  108. package/src/common/services/LogService.ts +2 -32
  109. package/src/common/services/{CoreMouseService.ts → MouseStateService.ts} +22 -133
  110. package/src/common/services/OptionsService.ts +17 -7
  111. package/src/common/services/OscLinkService.ts +2 -2
  112. package/src/common/services/ServiceRegistry.ts +10 -8
  113. package/src/common/services/Services.ts +52 -42
  114. package/src/common/services/UnicodeService.ts +3 -3
  115. package/typings/xterm.d.ts +329 -34
  116. package/src/common/Clone.ts +0 -23
  117. package/src/common/TypedArrayUtils.ts +0 -17
  118. package/src/vs/base/browser/browser.ts +0 -141
  119. package/src/vs/base/browser/canIUse.ts +0 -49
  120. package/src/vs/base/browser/dom.ts +0 -2369
  121. package/src/vs/base/browser/fastDomNode.ts +0 -316
  122. package/src/vs/base/browser/globalPointerMoveMonitor.ts +0 -112
  123. package/src/vs/base/browser/iframe.ts +0 -135
  124. package/src/vs/base/browser/keyboardEvent.ts +0 -213
  125. package/src/vs/base/browser/mouseEvent.ts +0 -229
  126. package/src/vs/base/browser/touch.ts +0 -372
  127. package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +0 -303
  128. package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +0 -114
  129. package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +0 -720
  130. package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +0 -165
  131. package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +0 -114
  132. package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +0 -243
  133. package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +0 -118
  134. package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +0 -116
  135. package/src/vs/base/browser/ui/widget.ts +0 -57
  136. package/src/vs/base/browser/window.ts +0 -14
  137. package/src/vs/base/common/arrays.ts +0 -887
  138. package/src/vs/base/common/arraysFind.ts +0 -202
  139. package/src/vs/base/common/assert.ts +0 -71
  140. package/src/vs/base/common/async.ts +0 -1992
  141. package/src/vs/base/common/cancellation.ts +0 -148
  142. package/src/vs/base/common/charCode.ts +0 -450
  143. package/src/vs/base/common/collections.ts +0 -140
  144. package/src/vs/base/common/decorators.ts +0 -130
  145. package/src/vs/base/common/equals.ts +0 -146
  146. package/src/vs/base/common/errors.ts +0 -303
  147. package/src/vs/base/common/event.ts +0 -1778
  148. package/src/vs/base/common/functional.ts +0 -32
  149. package/src/vs/base/common/hash.ts +0 -316
  150. package/src/vs/base/common/iterator.ts +0 -159
  151. package/src/vs/base/common/keyCodes.ts +0 -526
  152. package/src/vs/base/common/keybindings.ts +0 -284
  153. package/src/vs/base/common/lazy.ts +0 -47
  154. package/src/vs/base/common/lifecycle.ts +0 -801
  155. package/src/vs/base/common/linkedList.ts +0 -142
  156. package/src/vs/base/common/map.ts +0 -202
  157. package/src/vs/base/common/numbers.ts +0 -98
  158. package/src/vs/base/common/observable.ts +0 -76
  159. package/src/vs/base/common/observableInternal/api.ts +0 -31
  160. package/src/vs/base/common/observableInternal/autorun.ts +0 -281
  161. package/src/vs/base/common/observableInternal/base.ts +0 -489
  162. package/src/vs/base/common/observableInternal/debugName.ts +0 -145
  163. package/src/vs/base/common/observableInternal/derived.ts +0 -428
  164. package/src/vs/base/common/observableInternal/lazyObservableValue.ts +0 -146
  165. package/src/vs/base/common/observableInternal/logging.ts +0 -328
  166. package/src/vs/base/common/observableInternal/promise.ts +0 -209
  167. package/src/vs/base/common/observableInternal/utils.ts +0 -610
  168. package/src/vs/base/common/platform.ts +0 -281
  169. package/src/vs/base/common/scrollable.ts +0 -522
  170. package/src/vs/base/common/sequence.ts +0 -34
  171. package/src/vs/base/common/stopwatch.ts +0 -43
  172. package/src/vs/base/common/strings.ts +0 -557
  173. package/src/vs/base/common/symbols.ts +0 -9
  174. package/src/vs/base/common/uint.ts +0 -59
  175. package/src/vs/patches/nls.ts +0 -90
  176. package/src/vs/typings/base-common.d.ts +0 -20
  177. package/src/vs/typings/require.d.ts +0 -42
  178. package/src/vs/typings/vscode-globals-nls.d.ts +0 -36
  179. package/src/vs/typings/vscode-globals-product.d.ts +0 -33
@@ -3,9 +3,9 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { ICircularList } from 'common/Types';
7
- import { Disposable } from 'vs/base/common/lifecycle';
8
- import { Emitter } from 'vs/base/common/event';
6
+ import { ICircularList } from './Types';
7
+ import { Disposable } from './Lifecycle';
8
+ import { Emitter } from './Event';
9
9
 
10
10
  export interface IInsertEvent {
11
11
  index: number;
@@ -3,7 +3,7 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { IColor, IColorRGB } from 'common/Types';
6
+ import { IColor, IColorRGB } from './Types';
7
7
 
8
8
  let $r = 0;
9
9
  let $g = 0;
@@ -184,6 +184,14 @@ export namespace css {
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');
@@ -21,24 +21,24 @@
21
21
  * http://linux.die.net/man/7/urxvt
22
22
  */
23
23
 
24
- import { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, ICoreMouseService, IUnicodeService, LogLevelEnum, ITerminalOptions, IOscLinkService } from 'common/services/Services';
25
- import { InstantiationService } from 'common/services/InstantiationService';
26
- import { LogService } from 'common/services/LogService';
27
- import { BufferService, MINIMUM_COLS, MINIMUM_ROWS } from 'common/services/BufferService';
28
- import { OptionsService } from 'common/services/OptionsService';
29
- import { IDisposable, IAttributeData, ICoreTerminal, IScrollEvent } from 'common/Types';
30
- import { CoreService } from 'common/services/CoreService';
31
- import { CoreMouseService } from 'common/services/CoreMouseService';
32
- import { UnicodeService } from 'common/services/UnicodeService';
33
- import { CharsetService } from 'common/services/CharsetService';
34
- import { updateWindowsModeWrappedState } from 'common/WindowsMode';
35
- import { IFunctionIdentifier, IParams } from 'common/parser/Types';
36
- import { IBufferSet } from 'common/buffer/Types';
37
- import { InputHandler } from 'common/InputHandler';
38
- import { WriteBuffer } from 'common/input/WriteBuffer';
39
- import { OscLinkService } from 'common/services/OscLinkService';
40
- import { Emitter, Event } from 'vs/base/common/event';
41
- import { Disposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
24
+ import { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, IMouseStateService, IUnicodeService, LogLevelEnum, ITerminalOptions, 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, IAttributeData, ICoreTerminal, IScrollEvent } from './Types';
30
+ import { CoreService } from './services/CoreService';
31
+ import { MouseStateService } from './services/MouseStateService';
32
+ import { UnicodeService } from './services/UnicodeService';
33
+ import { CharsetService } from './services/CharsetService';
34
+ import { updateWindowsModeWrappedState } from './WindowsMode';
35
+ import { IFunctionIdentifier, IParams } from './parser/Types';
36
+ import { IBufferSet } from './buffer/Types';
37
+ import { InputHandler } from './InputHandler';
38
+ import { WriteBuffer } from './input/WriteBuffer';
39
+ import { OscLinkService } from './services/OscLinkService';
40
+ import { Emitter, EventUtils, type IEvent } from './Event';
41
+ import { Disposable, MutableDisposable, toDisposable } from './Lifecycle';
42
42
 
43
43
  // Only trigger this warning a single time per session
44
44
  let hasWriteSyncWarnHappened = false;
@@ -50,7 +50,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
50
50
  protected readonly _charsetService: ICharsetService;
51
51
  protected readonly _oscLinkService: IOscLinkService;
52
52
 
53
- public readonly coreMouseService: ICoreMouseService;
53
+ public readonly mouseStateService: IMouseStateService;
54
54
  public readonly coreService: ICoreService;
55
55
  public readonly unicodeService: IUnicodeService;
56
56
  public readonly optionsService: IOptionsService;
@@ -65,6 +65,8 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
65
65
  public readonly onData = this._onData.event;
66
66
  protected _onLineFeed = this._register(new Emitter<void>());
67
67
  public readonly onLineFeed = this._onLineFeed.event;
68
+ protected readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());
69
+ public readonly onRender = this._onRender.event;
68
70
  private readonly _onResize = this._register(new Emitter<{ cols: number, rows: number }>());
69
71
  public readonly onResize = this._onResize.event;
70
72
  protected readonly _onWriteParsed = this._register(new Emitter<void>());
@@ -76,7 +78,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
76
78
  */
77
79
  protected _onScrollApi?: Emitter<number>;
78
80
  protected _onScroll = this._register(new Emitter<IScrollEvent>());
79
- public get onScroll(): Event<number> {
81
+ public get onScroll(): IEvent<number> {
80
82
  if (!this._onScrollApi) {
81
83
  this._onScrollApi = this._register(new Emitter<number>());
82
84
  this._onScroll.event(ev => {
@@ -105,14 +107,14 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
105
107
  this._instantiationService = new InstantiationService();
106
108
  this.optionsService = this._register(new OptionsService(options));
107
109
  this._instantiationService.setService(IOptionsService, this.optionsService);
108
- this._bufferService = this._register(this._instantiationService.createInstance(BufferService));
109
- this._instantiationService.setService(IBufferService, this._bufferService);
110
110
  this._logService = this._register(this._instantiationService.createInstance(LogService));
111
111
  this._instantiationService.setService(ILogService, this._logService);
112
+ this._bufferService = this._register(this._instantiationService.createInstance(BufferService));
113
+ this._instantiationService.setService(IBufferService, this._bufferService);
112
114
  this.coreService = this._register(this._instantiationService.createInstance(CoreService));
113
115
  this._instantiationService.setService(ICoreService, this.coreService);
114
- this.coreMouseService = this._register(this._instantiationService.createInstance(CoreMouseService));
115
- this._instantiationService.setService(ICoreMouseService, this.coreMouseService);
116
+ this.mouseStateService = this._register(this._instantiationService.createInstance(MouseStateService));
117
+ this._instantiationService.setService(IMouseStateService, this.mouseStateService);
116
118
  this.unicodeService = this._register(this._instantiationService.createInstance(UnicodeService));
117
119
  this._instantiationService.setService(IUnicodeService, this.unicodeService);
118
120
  this._charsetService = this._instantiationService.createInstance(CharsetService);
@@ -122,14 +124,13 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
122
124
 
123
125
 
124
126
  // Register input handler and handle/forward events
125
- this._inputHandler = this._register(new InputHandler(this._bufferService, this._charsetService, this.coreService, this._logService, this.optionsService, this._oscLinkService, this.coreMouseService, this.unicodeService));
126
- this._register(Event.forward(this._inputHandler.onLineFeed, this._onLineFeed));
127
- this._register(this._inputHandler);
127
+ this._inputHandler = this._register(new InputHandler(this._bufferService, this._charsetService, this.coreService, this._logService, this.optionsService, this._oscLinkService, this.mouseStateService, this.unicodeService));
128
+ this._register(EventUtils.forward(this._inputHandler.onLineFeed, this._onLineFeed));
128
129
 
129
130
  // Setup listeners
130
- this._register(Event.forward(this._bufferService.onResize, this._onResize));
131
- this._register(Event.forward(this.coreService.onData, this._onData));
132
- this._register(Event.forward(this.coreService.onBinary, this._onBinary));
131
+ this._register(EventUtils.forward(this._bufferService.onResize, this._onResize));
132
+ this._register(EventUtils.forward(this.coreService.onData, this._onData));
133
+ this._register(EventUtils.forward(this.coreService.onBinary, this._onBinary));
133
134
  this._register(this.coreService.onRequestScrollToBottom(() => this.scrollToBottom(true)));
134
135
  this._register(this.coreService.onUserInput(() => this._writeBuffer.handleUserInput()));
135
136
  this._register(this.optionsService.onMultipleOptionChange(['windowsPty'], () => this._handleWindowsPtyOptionChange()));
@@ -139,7 +140,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
139
140
  }));
140
141
  // Setup WriteBuffer
141
142
  this._writeBuffer = this._register(new WriteBuffer((data, promiseResult) => this._inputHandler.parse(data, promiseResult)));
142
- this._register(Event.forward(this._writeBuffer.onWriteParsed, this._onWriteParsed));
143
+ this._register(EventUtils.forward(this._writeBuffer.onWriteParsed, this._onWriteParsed));
143
144
  }
144
145
 
145
146
  public write(data: string | Uint8Array, callback?: () => void): void {
@@ -172,8 +173,12 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
172
173
  return;
173
174
  }
174
175
 
175
- x = Math.max(x, MINIMUM_COLS);
176
- y = Math.max(y, MINIMUM_ROWS);
176
+ x = Math.max(x, BufferServiceConstants.MINIMUM_COLS);
177
+ y = Math.max(y, BufferServiceConstants.MINIMUM_ROWS);
178
+
179
+ // Flush pending writes before resize to avoid race conditions where async
180
+ // writes are processed with incorrect dimensions
181
+ this._writeBuffer.flushSync();
177
182
 
178
183
  this._bufferService.resize(x, y);
179
184
  }
@@ -237,6 +242,11 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
237
242
  return this._inputHandler.registerOscHandler(ident, callback);
238
243
  }
239
244
 
245
+ /** Add handler for APC escape sequence. See xterm.d.ts for details. */
246
+ public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise<boolean>): IDisposable {
247
+ return this._inputHandler.registerApcHandler(id, callback);
248
+ }
249
+
240
250
  protected _setup(): void {
241
251
  this._handleWindowsPtyOptionChange();
242
252
  }
@@ -246,14 +256,14 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
246
256
  this._bufferService.reset();
247
257
  this._charsetService.reset();
248
258
  this.coreService.reset();
249
- this.coreMouseService.reset();
259
+ this.mouseStateService.reset();
250
260
  }
251
261
 
252
262
 
253
263
  private _handleWindowsPtyOptionChange(): void {
254
264
  let value = false;
255
265
  const windowsPty = this.optionsService.rawOptions.windowsPty;
256
- if (windowsPty && windowsPty.buildNumber !== undefined && windowsPty.buildNumber !== undefined) {
266
+ if (windowsPty && windowsPty.backend !== undefined && windowsPty.buildNumber !== undefined) {
257
267
  value = !!(windowsPty.backend === 'conpty' && windowsPty.buildNumber < 21376);
258
268
  }
259
269
  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
+ }