@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,8 +3,8 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { IDisposable } from 'common/Types';
7
- import { ParserState } from 'common/parser/Constants';
6
+ import { IDisposable } from '../Types';
7
+ import { ParserState } from './Constants';
8
8
 
9
9
 
10
10
  /** sequence params serialized to js arrays */
@@ -32,6 +32,7 @@ export interface IParams {
32
32
  clone(): IParams;
33
33
  toArray(): ParamsArray;
34
34
  reset(): void;
35
+ resetZdm(): void;
35
36
  addParam(value: number): void;
36
37
  addSubParam(value: number): void;
37
38
  hasSubParams(idx: number): boolean;
@@ -107,7 +108,7 @@ export type EscFallbackHandlerType = (identifier: number) => void;
107
108
  /**
108
109
  * EXECUTE handler types.
109
110
  */
110
- export type ExecuteHandlerType = () => boolean;
111
+ export type ExecuteHandlerType = (ident?: number) => boolean;
111
112
  export type ExecuteFallbackHandlerType = (ident: number) => void;
112
113
 
113
114
  /**
@@ -134,6 +135,29 @@ export interface IOscHandler {
134
135
  }
135
136
  export type OscFallbackHandlerType = (ident: number, action: 'START' | 'PUT' | 'END', payload?: any) => void;
136
137
 
138
+ /**
139
+ * APC handler types.
140
+ */
141
+ export interface IApcHandler {
142
+ /**
143
+ * Announces start of this APC command.
144
+ * Prepare needed data structures here.
145
+ */
146
+ start(): void;
147
+ /**
148
+ * Incoming data chunk.
149
+ */
150
+ put(data: Uint32Array, start: number, end: number): void;
151
+ /**
152
+ * End of APC command. `success` indicates whether the
153
+ * command finished normally or got aborted, thus final
154
+ * execution of the command should depend on `success`.
155
+ * To save memory also cleanup data structures here.
156
+ */
157
+ end(success: boolean): boolean | Promise<boolean>;
158
+ }
159
+ export type ApcFallbackHandlerType = (ident: number, action: 'START' | 'PUT' | 'END', payload?: any) => void;
160
+
137
161
  /**
138
162
  * PRINT handler types.
139
163
  */
@@ -196,6 +220,10 @@ export interface IEscapeSequenceParser extends IDisposable {
196
220
  clearOscHandler(ident: number): void;
197
221
  setOscHandlerFallback(handler: OscFallbackHandlerType): void;
198
222
 
223
+ registerApcHandler(id: IFunctionIdentifier, handler: IApcHandler): IDisposable;
224
+ clearApcHandler(id: IFunctionIdentifier): void;
225
+ setApcHandlerFallback(handler: ApcFallbackHandlerType): void;
226
+
199
227
  setErrorHandler(handler: (state: IParsingState) => IParsingState): void;
200
228
  clearErrorHandler(): void;
201
229
  }
@@ -223,6 +251,11 @@ export interface IDcsParser extends ISubParser<IDcsHandler, DcsFallbackHandlerTy
223
251
  unhook(success: boolean, promiseResult?: boolean): void | Promise<boolean>;
224
252
  }
225
253
 
254
+ export interface IApcParser extends ISubParser<IApcHandler, ApcFallbackHandlerType> {
255
+ start(ident: number): void;
256
+ end(success: boolean, promiseResult?: boolean): void | Promise<boolean>;
257
+ }
258
+
226
259
  /**
227
260
  * Interface to denote a specific ESC, CSI or DCS handler slot.
228
261
  * The values are used to create an integer respresentation during handler
@@ -252,7 +285,8 @@ export const enum ParserStackType {
252
285
  CSI,
253
286
  ESC,
254
287
  OSC,
255
- DCS
288
+ DCS,
289
+ APC
256
290
  }
257
291
 
258
292
  // aggregate of resumable handler lists
@@ -4,9 +4,9 @@
4
4
  */
5
5
 
6
6
  import { IBuffer as IBufferApi, IBufferLine as IBufferLineApi, IBufferCell as IBufferCellApi } from '@xterm/xterm';
7
- import { IBuffer } from 'common/buffer/Types';
8
- import { BufferLineApiView } from 'common/public/BufferLineApiView';
9
- import { CellData } from 'common/buffer/CellData';
7
+ import { IBuffer } from '../buffer/Types';
8
+ import { BufferLineApiView } from './BufferLineApiView';
9
+ import { CellData } from '../buffer/CellData';
10
10
 
11
11
  export class BufferApiView implements IBufferApi {
12
12
  constructor(
@@ -3,8 +3,8 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { CellData } from 'common/buffer/CellData';
7
- import { IBufferLine, ICellData } from 'common/Types';
6
+ import { CellData } from '../buffer/CellData';
7
+ import { IBufferLine, ICellData } from '../Types';
8
8
  import { IBufferCell as IBufferCellApi, IBufferLine as IBufferLineApi } from '@xterm/xterm';
9
9
 
10
10
  export class BufferLineApiView implements IBufferLineApi {
@@ -18,10 +18,10 @@ export class BufferLineApiView implements IBufferLineApi {
18
18
  }
19
19
 
20
20
  if (cell) {
21
- this._line.loadCell(x, cell as ICellData);
21
+ this._line.loadCell(x, cell as unknown as ICellData);
22
22
  return cell;
23
23
  }
24
- return this._line.loadCell(x, new CellData());
24
+ return this._line.loadCell(x, new CellData()) as unknown as IBufferCellApi;
25
25
  }
26
26
  public translateToString(trimRight?: boolean, startColumn?: number, endColumn?: number): string {
27
27
  return this._line.translateToString(trimRight, startColumn, endColumn);
@@ -4,10 +4,10 @@
4
4
  */
5
5
 
6
6
  import { IBuffer as IBufferApi, IBufferNamespace as IBufferNamespaceApi } from '@xterm/xterm';
7
- import { BufferApiView } from 'common/public/BufferApiView';
8
- import { ICoreTerminal } from 'common/Types';
9
- import { Disposable } from 'vs/base/common/lifecycle';
10
- import { Emitter } from 'vs/base/common/event';
7
+ import { BufferApiView } from './BufferApiView';
8
+ import { ICoreTerminal } from '../Types';
9
+ import { Disposable } from '../Lifecycle';
10
+ import { Emitter } from '../Event';
11
11
 
12
12
  export class BufferNamespaceApi extends Disposable implements IBufferNamespaceApi {
13
13
  private _normal: BufferApiView;
@@ -20,7 +20,7 @@ export class BufferNamespaceApi extends Disposable implements IBufferNamespaceAp
20
20
  super();
21
21
  this._normal = new BufferApiView(this._core.buffers.normal, 'normal');
22
22
  this._alternate = new BufferApiView(this._core.buffers.alt, 'alternate');
23
- this._core.buffers.onBufferActivate(() => this._onBufferChange.fire(this.active));
23
+ this._register(this._core.buffers.onBufferActivate(() => this._onBufferChange.fire(this.active)));
24
24
  }
25
25
  public get active(): IBufferApi {
26
26
  if (this._core.buffers.active === this._core.buffers.normal) { return this.normal; }
@@ -3,9 +3,9 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { IParams } from 'common/parser/Types';
6
+ import { IParams } from '../parser/Types';
7
7
  import { IDisposable, IFunctionIdentifier, IParser } from '@xterm/xterm';
8
- import { ICoreTerminal } from 'common/Types';
8
+ import { ICoreTerminal } from '../Types';
9
9
 
10
10
  export class ParserApi implements IParser {
11
11
  constructor(private _core: ICoreTerminal) { }
@@ -34,4 +34,7 @@ export class ParserApi implements IParser {
34
34
  public addOscHandler(ident: number, callback: (data: string) => boolean | Promise<boolean>): IDisposable {
35
35
  return this.registerOscHandler(ident, callback);
36
36
  }
37
+ public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise<boolean>): IDisposable {
38
+ return this._core.registerApcHandler(id, callback);
39
+ }
37
40
  }
@@ -3,7 +3,7 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { ICoreTerminal } from 'common/Types';
6
+ import { ICoreTerminal } from '../Types';
7
7
  import { IUnicodeHandling, IUnicodeVersionProvider } from '@xterm/xterm';
8
8
 
9
9
  export class UnicodeApi implements IUnicodeHandling {
@@ -3,15 +3,17 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { Disposable } from 'vs/base/common/lifecycle';
7
- import { IAttributeData, IBufferLine } from 'common/Types';
8
- import { BufferSet } from 'common/buffer/BufferSet';
9
- import { IBuffer, IBufferSet } from 'common/buffer/Types';
10
- import { IBufferService, IOptionsService, type IBufferResizeEvent } from 'common/services/Services';
11
- import { Emitter } from 'vs/base/common/event';
12
-
13
- export const MINIMUM_COLS = 2; // Less than 2 can mess with wide chars
14
- export const MINIMUM_ROWS = 1;
6
+ import { Disposable } from '../Lifecycle';
7
+ import { IAttributeData, IBufferLine } from '../Types';
8
+ import { BufferSet } from '../buffer/BufferSet';
9
+ import { IBuffer, IBufferSet } from '../buffer/Types';
10
+ import { IBufferService, ILogService, IOptionsService, type IBufferResizeEvent } from './Services';
11
+ import { Emitter } from '../Event';
12
+
13
+ export const enum BufferServiceConstants {
14
+ MINIMUM_COLS = 2, // Less than 2 can mess with wide chars
15
+ MINIMUM_ROWS = 1
16
+ }
15
17
 
16
18
  export class BufferService extends Disposable implements IBufferService {
17
19
  public serviceBrand: any;
@@ -32,11 +34,14 @@ export class BufferService extends Disposable implements IBufferService {
32
34
  /** An IBufferline to clone/copy from for new blank lines */
33
35
  private _cachedBlankLine: IBufferLine | undefined;
34
36
 
35
- constructor(@IOptionsService optionsService: IOptionsService) {
37
+ constructor(
38
+ @IOptionsService optionsService: IOptionsService,
39
+ @ILogService logService: ILogService
40
+ ) {
36
41
  super();
37
- this.cols = Math.max(optionsService.rawOptions.cols || 0, MINIMUM_COLS);
38
- this.rows = Math.max(optionsService.rawOptions.rows || 0, MINIMUM_ROWS);
39
- this.buffers = this._register(new BufferSet(optionsService, this));
42
+ this.cols = Math.max(optionsService.rawOptions.cols || 0, BufferServiceConstants.MINIMUM_COLS);
43
+ this.rows = Math.max(optionsService.rawOptions.rows || 0, BufferServiceConstants.MINIMUM_ROWS);
44
+ this.buffers = this._register(new BufferSet(optionsService, this, logService));
40
45
  this._register(this.buffers.onBufferActivate(e => {
41
46
  this._onScroll.fire(e.activeBuffer.ydisp);
42
47
  }));
@@ -3,8 +3,8 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { ICharsetService } from 'common/services/Services';
7
- import { ICharset } from 'common/Types';
6
+ import { ICharsetService } from './Services';
7
+ import { ICharset } from '../Types';
8
8
 
9
9
  export class CharsetService implements ICharsetService {
10
10
  public serviceBrand: any;
@@ -14,6 +14,10 @@ export class CharsetService implements ICharsetService {
14
14
 
15
15
  private _charsets: (ICharset | undefined)[] = [];
16
16
 
17
+ public get charsets(): (ICharset | undefined)[] {
18
+ return this._charsets;
19
+ }
20
+
17
21
  public reset(): void {
18
22
  this.charset = undefined;
19
23
  this._charsets = [];
@@ -3,11 +3,10 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { clone } from 'common/Clone';
7
- import { Disposable } from 'vs/base/common/lifecycle';
8
- import { IDecPrivateModes, IModes } from 'common/Types';
9
- import { IBufferService, ICoreService, ILogService, IOptionsService } from 'common/services/Services';
10
- import { Emitter } from 'vs/base/common/event';
6
+ import { Disposable } from '../Lifecycle';
7
+ import { IDecPrivateModes, IKittyKeyboardState, IModes } from '../Types';
8
+ import { IBufferService, ICoreService, ILogService, IOptionsService } from './Services';
9
+ import { Emitter } from '../Event';
11
10
 
12
11
  const DEFAULT_MODES: IModes = Object.freeze({
13
12
  insertMode: false
@@ -17,22 +16,33 @@ const DEFAULT_DEC_PRIVATE_MODES: IDecPrivateModes = Object.freeze({
17
16
  applicationCursorKeys: false,
18
17
  applicationKeypad: false,
19
18
  bracketedPasteMode: false,
19
+ colorSchemeUpdates: false,
20
20
  cursorBlink: undefined,
21
21
  cursorStyle: undefined,
22
22
  origin: false,
23
23
  reverseWraparound: false,
24
24
  sendFocus: false,
25
25
  synchronizedOutput: false,
26
+ win32InputMode: false,
26
27
  wraparound: true // defaults: xterm - true, vt100 - false
27
28
  });
28
29
 
30
+ const DEFAULT_KITTY_KEYBOARD_STATE = (): IKittyKeyboardState => ({
31
+ flags: 0,
32
+ mainFlags: 0,
33
+ altFlags: 0,
34
+ mainStack: [],
35
+ altStack: []
36
+ });
37
+
29
38
  export class CoreService extends Disposable implements ICoreService {
30
39
  public serviceBrand: any;
31
40
 
32
- public isCursorInitialized: boolean = false;
41
+ public isCursorInitialized: boolean;
33
42
  public isCursorHidden: boolean = false;
34
43
  public modes: IModes;
35
44
  public decPrivateModes: IDecPrivateModes;
45
+ public kittyKeyboard: IKittyKeyboardState;
36
46
 
37
47
  private readonly _onData = this._register(new Emitter<string>());
38
48
  public readonly onData = this._onData.event;
@@ -49,13 +59,16 @@ export class CoreService extends Disposable implements ICoreService {
49
59
  @IOptionsService private readonly _optionsService: IOptionsService
50
60
  ) {
51
61
  super();
52
- this.modes = clone(DEFAULT_MODES);
53
- this.decPrivateModes = clone(DEFAULT_DEC_PRIVATE_MODES);
62
+ this.isCursorInitialized = _optionsService.rawOptions.showCursorImmediately ?? false;
63
+ this.modes = structuredClone(DEFAULT_MODES);
64
+ this.decPrivateModes = structuredClone(DEFAULT_DEC_PRIVATE_MODES);
65
+ this.kittyKeyboard = DEFAULT_KITTY_KEYBOARD_STATE();
54
66
  }
55
67
 
56
68
  public reset(): void {
57
- this.modes = clone(DEFAULT_MODES);
58
- this.decPrivateModes = clone(DEFAULT_DEC_PRIVATE_MODES);
69
+ this.modes = structuredClone(DEFAULT_MODES);
70
+ this.decPrivateModes = structuredClone(DEFAULT_DEC_PRIVATE_MODES);
71
+ this.kittyKeyboard = DEFAULT_KITTY_KEYBOARD_STATE();
59
72
  }
60
73
 
61
74
  public triggerDataEvent(data: string, wasUserInput: boolean = false): void {
@@ -3,13 +3,15 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { css } from 'common/Color';
7
- import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
8
- import { IDecorationService, IInternalDecoration } from 'common/services/Services';
9
- import { SortedList } from 'common/SortedList';
10
- import { IColor } from 'common/Types';
6
+ import type { IDeleteEvent, IInsertEvent } from '../CircularList';
7
+ import { MicrotaskTimer } from '../Async';
8
+ import { css } from '../Color';
9
+ import { Disposable, DisposableStore, MutableDisposable, toDisposable } from '../Lifecycle';
10
+ import { IBufferService, IDecorationService, IInternalDecoration, ILogService } from './Services';
11
+ import { SortedList } from '../SortedList';
12
+ import { IColor, ICircularList } from '../Types';
11
13
  import { IDecoration, IDecorationOptions, IMarker } from '@xterm/xterm';
12
- import { Emitter } from 'vs/base/common/event';
14
+ import { Emitter } from '../Event';
13
15
 
14
16
  // Work variables to avoid garbage collection
15
17
  let $xmin = 0;
@@ -23,7 +25,9 @@ export class DecorationService extends Disposable implements IDecorationService
23
25
  * while marker line values do change, they should all change by the same amount so this should
24
26
  * never become out of order.
25
27
  */
26
- private readonly _decorations: SortedList<IInternalDecoration> = new SortedList(e => e?.marker.line);
28
+ private readonly _decorations: SortedList<IInternalDecoration>;
29
+
30
+ private readonly _lineCache = this._register(new DecorationLineCache());
27
31
 
28
32
  private readonly _onDecorationRegistered = this._register(new Emitter<IInternalDecoration>());
29
33
  public readonly onDecorationRegistered = this._onDecorationRegistered.event;
@@ -32,10 +36,19 @@ export class DecorationService extends Disposable implements IDecorationService
32
36
 
33
37
  public get decorations(): IterableIterator<IInternalDecoration> { return this._decorations.values(); }
34
38
 
35
- constructor() {
39
+ constructor(
40
+ @ILogService private readonly _logService: ILogService,
41
+ @IBufferService private readonly _bufferService: IBufferService
42
+ ) {
36
43
  super();
37
44
 
45
+ this._decorations = new SortedList(e => e?.marker.line, this._logService);
46
+
38
47
  this._register(toDisposable(() => this.reset()));
48
+ this._register(this._bufferService.buffers.onBufferActivate(() => {
49
+ this._lineCache.attachToBufferLines(this._bufferService.buffer.lines);
50
+ }));
51
+ this._lineCache.attachToBufferLines(this._bufferService.buffer.lines);
39
52
  }
40
53
 
41
54
  public registerDecoration(options: IDecorationOptions): IDecoration | undefined {
@@ -49,12 +62,14 @@ export class DecorationService extends Disposable implements IDecorationService
49
62
  listener.dispose();
50
63
  if (decoration) {
51
64
  if (this._decorations.delete(decoration)) {
65
+ this._lineCache.remove(decoration);
52
66
  this._onDecorationRemoved.fire(decoration);
53
67
  }
54
68
  markerDispose.dispose();
55
69
  }
56
70
  });
57
71
  this._decorations.insert(decoration);
72
+ this._lineCache.add(decoration);
58
73
  this._onDecorationRegistered.fire(decoration);
59
74
  }
60
75
  return decoration;
@@ -65,35 +80,264 @@ export class DecorationService extends Disposable implements IDecorationService
65
80
  d.dispose();
66
81
  }
67
82
  this._decorations.clear();
83
+ this._lineCache.clear();
68
84
  }
69
85
 
70
86
  public *getDecorationsAtCell(x: number, line: number, layer?: 'bottom' | 'top'): IterableIterator<IInternalDecoration> {
71
- let xmin = 0;
72
- let xmax = 0;
73
- for (const d of this._decorations.getKeyIterator(line)) {
74
- xmin = d.options.x ?? 0;
75
- xmax = xmin + (d.options.width ?? 1);
76
- if (x >= xmin && x < xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {
87
+ const bucket = this._lineCache.getDecorationsOnLine(line);
88
+ if (!bucket) {
89
+ return;
90
+ }
91
+ for (const d of bucket) {
92
+ $xmin = d.options.x ?? 0;
93
+ $xmax = $xmin + (d.options.width ?? 1);
94
+ if (x >= $xmin && x < $xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {
77
95
  yield d;
78
96
  }
79
97
  }
80
98
  }
81
99
 
82
100
  public forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void {
83
- this._decorations.forEachByKey(line, d => {
101
+ const bucket = this._lineCache.getDecorationsOnLine(line);
102
+ if (!bucket) {
103
+ return;
104
+ }
105
+ for (const d of bucket) {
84
106
  $xmin = d.options.x ?? 0;
85
107
  $xmax = $xmin + (d.options.width ?? 1);
86
108
  if (x >= $xmin && x < $xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {
87
109
  callback(d);
88
110
  }
111
+ }
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Per-logical-line index of decorations for fast cell lookup.
117
+ *
118
+ * Keys are marker.line coordinates (logical buffer lines), not CircularList ring slots.
119
+ * Multi-line decorations appear in every line bucket they span. The index is kept aligned
120
+ * with marker.line updates via buffer line trim/insert/delete events.
121
+ */
122
+ export class DecorationLineCache extends Disposable {
123
+ private readonly _decorationsByLine: Map<number, IInternalDecoration[]> = new Map();
124
+ private readonly _decorations = new Set<IInternalDecoration>();
125
+ private readonly _bufferLineListeners = this._register(new MutableDisposable<DisposableStore>());
126
+ private readonly _lineIndexSyncTimer = this._register(new MicrotaskTimer());
127
+ private _lineIndexSyncCallbacks: (() => void)[] = [];
128
+
129
+ public clear(): void {
130
+ this._lineIndexSyncCallbacks.length = 0;
131
+ this._lineIndexSyncTimer.cancel();
132
+ this._decorationsByLine.clear();
133
+ this._decorations.clear();
134
+ }
135
+
136
+ public add(decoration: IInternalDecoration): void {
137
+ this._decorations.add(decoration);
138
+ this._addToLineBuckets(decoration);
139
+ }
140
+
141
+ public remove(decoration: IInternalDecoration): void {
142
+ this._decorations.delete(decoration);
143
+ this._removeFromLineBuckets(decoration);
144
+ }
145
+
146
+ public getDecorationsOnLine(line: number): ReadonlyArray<IInternalDecoration> | undefined {
147
+ return this._decorationsByLine.get(line);
148
+ }
149
+
150
+ public attachToBufferLines(lines: ICircularList<unknown>): void {
151
+ const store = new DisposableStore();
152
+ this._bufferLineListeners.value = store;
153
+ store.add(lines.onTrim(amount => this._handleBufferLinesTrim(amount)));
154
+ store.add(lines.onInsert(event => this._handleBufferLinesInsert(event)));
155
+ store.add(lines.onDelete(event => this._handleBufferLinesDelete(event)));
156
+ }
157
+
158
+ private _getDecorationHeight(decoration: IInternalDecoration): number {
159
+ return decoration.options.height ?? 1;
160
+ }
161
+
162
+ private _addToLineBuckets(decoration: IInternalDecoration): void {
163
+ const start = decoration.marker.line;
164
+ if (start < 0) {
165
+ return;
166
+ }
167
+ decoration._indexedStartLine = start;
168
+ const height = this._getDecorationHeight(decoration);
169
+ for (let line = start; line < start + height; line++) {
170
+ let bucket = this._decorationsByLine.get(line);
171
+ if (!bucket) {
172
+ bucket = [];
173
+ this._decorationsByLine.set(line, bucket);
174
+ }
175
+ bucket.push(decoration);
176
+ }
177
+ }
178
+
179
+ private _removeFromLineBuckets(decoration: IInternalDecoration): void {
180
+ const start = decoration._indexedStartLine;
181
+ const height = this._getDecorationHeight(decoration);
182
+ for (let line = start; line < start + height; line++) {
183
+ const bucket = this._decorationsByLine.get(line);
184
+ if (!bucket) {
185
+ continue;
186
+ }
187
+ const index = bucket.indexOf(decoration);
188
+ if (index !== -1) {
189
+ bucket.splice(index, 1);
190
+ }
191
+ if (bucket.length === 0) {
192
+ this._decorationsByLine.delete(line);
193
+ }
194
+ }
195
+ }
196
+
197
+ private _reindexDecoration(decoration: IInternalDecoration): void {
198
+ this._removeFromLineBuckets(decoration);
199
+ if (!decoration.marker.isDisposed && decoration.marker.line >= 0) {
200
+ this._addToLineBuckets(decoration);
201
+ }
202
+ }
203
+
204
+ /** Re-index after marker line updates (buffer listeners may run before markers). */
205
+ private _scheduleLineIndexSync(callback: () => void): void {
206
+ this._lineIndexSyncCallbacks.push(callback);
207
+ this._lineIndexSyncTimer.set(() => {
208
+ const callbacks = this._lineIndexSyncCallbacks;
209
+ this._lineIndexSyncCallbacks = [];
210
+ for (const cb of callbacks) {
211
+ cb();
212
+ }
89
213
  });
90
214
  }
215
+
216
+ private _handleBufferLinesTrim(amount: number): void {
217
+ if (amount <= 0) {
218
+ return;
219
+ }
220
+ const newMap = new Map<number, IInternalDecoration[]>();
221
+ for (const [line, bucket] of this._decorationsByLine) {
222
+ const newLine = line - amount;
223
+ if (newLine < 0) {
224
+ continue;
225
+ }
226
+ this._mergeLineBucket(newMap, newLine, bucket);
227
+ }
228
+ this._decorationsByLine.clear();
229
+ for (const [line, bucket] of newMap) {
230
+ this._decorationsByLine.set(line, bucket);
231
+ }
232
+ for (const d of this._decorations) {
233
+ if (!d.marker.isDisposed) {
234
+ d._indexedStartLine -= amount;
235
+ }
236
+ }
237
+ }
238
+
239
+ private _handleBufferLinesInsert(event: IInsertEvent): void {
240
+ this._scheduleLineIndexSync(() => this._applyBufferLinesInsert(event));
241
+ }
242
+
243
+ private _handleBufferLinesDelete(event: IDeleteEvent): void {
244
+ this._scheduleLineIndexSync(() => this._applyBufferLinesDelete(event));
245
+ }
246
+
247
+ private _mergeLineBucket(newMap: Map<number, IInternalDecoration[]>, line: number, bucket: IInternalDecoration[]): void {
248
+ const existing = newMap.get(line);
249
+ if (existing) {
250
+ for (let i = 0, len = bucket.length; i < len; i++) {
251
+ existing.push(bucket[i]);
252
+ }
253
+ } else {
254
+ newMap.set(line, bucket.slice());
255
+ }
256
+ }
257
+
258
+ /**
259
+ * Shift indexed line keys and sync start lines. O(unique indexed lines), not O(decoration count).
260
+ * Decorations that span the insert point are re-indexed individually (rare vs single-line hits).
261
+ */
262
+ private _applyBufferLinesInsert(event: IInsertEvent): void {
263
+ const { index, amount } = event;
264
+ const spanCrossers: IInternalDecoration[] = [];
265
+ for (const d of this._decorations) {
266
+ if (d.marker.isDisposed) {
267
+ continue;
268
+ }
269
+ const start = d._indexedStartLine;
270
+ if (start < index && start + this._getDecorationHeight(d) > index) {
271
+ spanCrossers.push(d);
272
+ this._removeFromLineBuckets(d);
273
+ }
274
+ }
275
+ const newMap = new Map<number, IInternalDecoration[]>();
276
+ for (const [line, bucket] of this._decorationsByLine) {
277
+ const newLine = line >= index ? line + amount : line;
278
+ this._mergeLineBucket(newMap, newLine, bucket);
279
+ }
280
+ this._decorationsByLine.clear();
281
+ for (const [line, bucket] of newMap) {
282
+ this._decorationsByLine.set(line, bucket);
283
+ }
284
+ for (const d of this._decorations) {
285
+ if (d.marker.isDisposed) {
286
+ continue;
287
+ }
288
+ if (d._indexedStartLine >= index) {
289
+ d._indexedStartLine = d.marker.line;
290
+ }
291
+ }
292
+ for (const d of spanCrossers) {
293
+ this._addToLineBuckets(d);
294
+ }
295
+ }
296
+
297
+ /**
298
+ * Drop deleted line keys, shift keys below, sync start lines. Full re-index only when a
299
+ * multi-line decoration spans across the deleted range but survives.
300
+ */
301
+ private _applyBufferLinesDelete(event: IDeleteEvent): void {
302
+ const deleteEnd = event.index + event.amount;
303
+ const newMap = new Map<number, IInternalDecoration[]>();
304
+ for (const [line, bucket] of this._decorationsByLine) {
305
+ if (line >= event.index && line < deleteEnd) {
306
+ continue;
307
+ }
308
+ const newLine = line >= deleteEnd ? line - event.amount : line;
309
+ this._mergeLineBucket(newMap, newLine, bucket);
310
+ }
311
+ this._decorationsByLine.clear();
312
+ for (const [line, bucket] of newMap) {
313
+ this._decorationsByLine.set(line, bucket);
314
+ }
315
+ const toReindex: IInternalDecoration[] = [];
316
+ for (const d of this._decorations) {
317
+ if (d.marker.isDisposed) {
318
+ continue;
319
+ }
320
+ const start = d._indexedStartLine;
321
+ const height = this._getDecorationHeight(d);
322
+ if (start >= deleteEnd) {
323
+ d._indexedStartLine = d.marker.line;
324
+ } else if (start < event.index && start + height > deleteEnd) {
325
+ toReindex.push(d);
326
+ }
327
+ }
328
+ for (const d of toReindex) {
329
+ this._reindexDecoration(d);
330
+ }
331
+ }
91
332
  }
92
333
 
93
334
  class Decoration extends DisposableStore implements IInternalDecoration {
94
335
  public readonly marker: IMarker;
95
336
  public element: HTMLElement | undefined;
96
337
 
338
+ /** Start line used for line-index removal when marker.line is cleared on dispose. */
339
+ public _indexedStartLine: number;
340
+
97
341
  public readonly onRenderEmitter = this.add(new Emitter<HTMLElement>());
98
342
  public readonly onRender = this.onRenderEmitter.event;
99
343
  private readonly _onDispose = this.add(new Emitter<void>());
@@ -128,6 +372,7 @@ class Decoration extends DisposableStore implements IInternalDecoration {
128
372
  ) {
129
373
  super();
130
374
  this.marker = options.marker;
375
+ this._indexedStartLine = options.marker.line;
131
376
  if (this.options.overviewRulerOptions && !this.options.overviewRulerOptions.position) {
132
377
  this.options.overviewRulerOptions.position = 'full';
133
378
  }