@xterm/xterm 6.1.0-beta.2 → 6.1.0-beta.200

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 (158) 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 +36 -24
  8. package/src/browser/AccessibilityManager.ts +6 -3
  9. package/src/browser/Clipboard.ts +6 -3
  10. package/src/browser/CoreBrowserTerminal.ts +147 -318
  11. package/src/browser/Dom.ts +178 -0
  12. package/src/browser/Linkifier.ts +11 -11
  13. package/src/browser/OscLinkProvider.ts +4 -2
  14. package/src/browser/RenderDebouncer.ts +2 -2
  15. package/src/browser/TimeBasedDebouncer.ts +2 -2
  16. package/src/browser/Types.ts +12 -11
  17. package/src/browser/Viewport.ts +55 -20
  18. package/src/browser/decorations/BufferDecorationRenderer.ts +1 -1
  19. package/src/browser/decorations/OverviewRulerRenderer.ts +33 -17
  20. package/src/browser/input/CompositionHelper.ts +44 -8
  21. package/src/browser/public/Terminal.ts +25 -28
  22. package/src/browser/renderer/dom/DomRenderer.ts +205 -41
  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 +485 -0
  40. package/src/browser/scrollable/verticalScrollbar.ts +143 -0
  41. package/src/browser/scrollable/widget.ts +23 -0
  42. package/src/browser/services/CharSizeService.ts +2 -2
  43. package/src/browser/services/CoreBrowserService.ts +7 -5
  44. package/src/browser/services/KeyboardService.ts +67 -0
  45. package/src/browser/services/LinkProviderService.ts +1 -1
  46. package/src/browser/services/MouseCoordsService.ts +47 -0
  47. package/src/browser/services/MouseService.ts +518 -25
  48. package/src/browser/services/RenderService.ts +22 -16
  49. package/src/browser/services/SelectionService.ts +16 -8
  50. package/src/browser/services/Services.ts +40 -17
  51. package/src/browser/services/ThemeService.ts +2 -2
  52. package/src/common/Async.ts +105 -0
  53. package/src/common/CircularList.ts +2 -2
  54. package/src/common/Color.ts +8 -0
  55. package/src/common/CoreTerminal.ts +29 -21
  56. package/src/common/Event.ts +118 -0
  57. package/src/common/InputHandler.ts +256 -36
  58. package/src/common/Lifecycle.ts +113 -0
  59. package/src/common/Platform.ts +13 -3
  60. package/src/common/SortedList.ts +7 -3
  61. package/src/common/TaskQueue.ts +14 -5
  62. package/src/common/Types.ts +36 -16
  63. package/src/common/Version.ts +9 -0
  64. package/src/common/buffer/Buffer.ts +22 -16
  65. package/src/common/buffer/BufferLine.ts +4 -5
  66. package/src/common/buffer/BufferSet.ts +7 -6
  67. package/src/common/buffer/CellData.ts +57 -0
  68. package/src/common/buffer/Marker.ts +2 -2
  69. package/src/common/buffer/Types.ts +6 -2
  70. package/src/common/data/Charsets.ts +1 -1
  71. package/src/common/data/EscapeSequences.ts +71 -70
  72. package/src/common/input/Keyboard.ts +14 -7
  73. package/src/common/input/KittyKeyboard.ts +519 -0
  74. package/src/common/input/Win32InputMode.ts +297 -0
  75. package/src/common/input/WriteBuffer.ts +34 -2
  76. package/src/common/input/XParseColor.ts +2 -2
  77. package/src/common/parser/ApcParser.ts +245 -0
  78. package/src/common/parser/Constants.ts +22 -4
  79. package/src/common/parser/DcsParser.ts +5 -5
  80. package/src/common/parser/EscapeSequenceParser.ts +155 -43
  81. package/src/common/parser/OscParser.ts +5 -5
  82. package/src/common/parser/Types.ts +34 -1
  83. package/src/common/public/BufferLineApiView.ts +2 -2
  84. package/src/common/public/BufferNamespaceApi.ts +2 -2
  85. package/src/common/public/ParserApi.ts +3 -0
  86. package/src/common/services/BufferService.ts +8 -5
  87. package/src/common/services/CharsetService.ts +4 -0
  88. package/src/common/services/CoreService.ts +18 -4
  89. package/src/common/services/DecorationService.ts +24 -8
  90. package/src/common/services/LogService.ts +1 -31
  91. package/src/common/services/{CoreMouseService.ts → MouseStateService.ts} +21 -132
  92. package/src/common/services/OptionsService.ts +13 -7
  93. package/src/common/services/Services.ts +47 -44
  94. package/src/common/services/UnicodeService.ts +1 -1
  95. package/typings/xterm.d.ts +320 -45
  96. package/src/common/TypedArrayUtils.ts +0 -17
  97. package/src/vs/base/browser/browser.ts +0 -141
  98. package/src/vs/base/browser/canIUse.ts +0 -49
  99. package/src/vs/base/browser/dom.ts +0 -2369
  100. package/src/vs/base/browser/fastDomNode.ts +0 -316
  101. package/src/vs/base/browser/globalPointerMoveMonitor.ts +0 -112
  102. package/src/vs/base/browser/iframe.ts +0 -135
  103. package/src/vs/base/browser/keyboardEvent.ts +0 -213
  104. package/src/vs/base/browser/mouseEvent.ts +0 -229
  105. package/src/vs/base/browser/touch.ts +0 -372
  106. package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +0 -303
  107. package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +0 -114
  108. package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +0 -720
  109. package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +0 -165
  110. package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +0 -114
  111. package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +0 -243
  112. package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +0 -118
  113. package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +0 -116
  114. package/src/vs/base/browser/ui/widget.ts +0 -57
  115. package/src/vs/base/browser/window.ts +0 -14
  116. package/src/vs/base/common/arrays.ts +0 -887
  117. package/src/vs/base/common/arraysFind.ts +0 -202
  118. package/src/vs/base/common/assert.ts +0 -71
  119. package/src/vs/base/common/async.ts +0 -1992
  120. package/src/vs/base/common/cancellation.ts +0 -148
  121. package/src/vs/base/common/charCode.ts +0 -450
  122. package/src/vs/base/common/collections.ts +0 -140
  123. package/src/vs/base/common/decorators.ts +0 -130
  124. package/src/vs/base/common/equals.ts +0 -146
  125. package/src/vs/base/common/errors.ts +0 -303
  126. package/src/vs/base/common/event.ts +0 -1778
  127. package/src/vs/base/common/functional.ts +0 -32
  128. package/src/vs/base/common/hash.ts +0 -316
  129. package/src/vs/base/common/iterator.ts +0 -159
  130. package/src/vs/base/common/keyCodes.ts +0 -526
  131. package/src/vs/base/common/keybindings.ts +0 -284
  132. package/src/vs/base/common/lazy.ts +0 -47
  133. package/src/vs/base/common/lifecycle.ts +0 -801
  134. package/src/vs/base/common/linkedList.ts +0 -142
  135. package/src/vs/base/common/map.ts +0 -202
  136. package/src/vs/base/common/numbers.ts +0 -98
  137. package/src/vs/base/common/observable.ts +0 -76
  138. package/src/vs/base/common/observableInternal/api.ts +0 -31
  139. package/src/vs/base/common/observableInternal/autorun.ts +0 -281
  140. package/src/vs/base/common/observableInternal/base.ts +0 -489
  141. package/src/vs/base/common/observableInternal/debugName.ts +0 -145
  142. package/src/vs/base/common/observableInternal/derived.ts +0 -428
  143. package/src/vs/base/common/observableInternal/lazyObservableValue.ts +0 -146
  144. package/src/vs/base/common/observableInternal/logging.ts +0 -328
  145. package/src/vs/base/common/observableInternal/promise.ts +0 -209
  146. package/src/vs/base/common/observableInternal/utils.ts +0 -610
  147. package/src/vs/base/common/platform.ts +0 -281
  148. package/src/vs/base/common/scrollable.ts +0 -522
  149. package/src/vs/base/common/sequence.ts +0 -34
  150. package/src/vs/base/common/stopwatch.ts +0 -43
  151. package/src/vs/base/common/strings.ts +0 -557
  152. package/src/vs/base/common/symbols.ts +0 -9
  153. package/src/vs/base/common/uint.ts +0 -59
  154. package/src/vs/patches/nls.ts +0 -90
  155. package/src/vs/typings/base-common.d.ts +0 -20
  156. package/src/vs/typings/require.d.ts +0 -42
  157. package/src/vs/typings/vscode-globals-nls.d.ts +0 -36
  158. package/src/vs/typings/vscode-globals-product.d.ts +0 -33
@@ -3,13 +3,14 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IOscHandler, IHandlerCollection, CsiHandlerType, OscFallbackHandlerType, IOscParser, EscHandlerType, IDcsParser, DcsFallbackHandlerType, IFunctionIdentifier, ExecuteFallbackHandlerType, CsiFallbackHandlerType, EscFallbackHandlerType, PrintHandlerType, PrintFallbackHandlerType, ExecuteHandlerType, IParserStackState, ParserStackType, ResumableHandlersType } from 'common/parser/Types';
6
+ import { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IOscHandler, IHandlerCollection, CsiHandlerType, OscFallbackHandlerType, IOscParser, EscHandlerType, IDcsParser, DcsFallbackHandlerType, IFunctionIdentifier, ExecuteFallbackHandlerType, CsiFallbackHandlerType, EscFallbackHandlerType, PrintHandlerType, PrintFallbackHandlerType, ExecuteHandlerType, IParserStackState, ParserStackType, ResumableHandlersType, IApcHandler, IApcParser, ApcFallbackHandlerType } from 'common/parser/Types';
7
7
  import { ParserState, ParserAction } from 'common/parser/Constants';
8
- import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
8
+ import { Disposable, toDisposable } from 'common/Lifecycle';
9
9
  import { IDisposable } from 'common/Types';
10
10
  import { Params } from 'common/parser/Params';
11
11
  import { OscParser } from 'common/parser/OscParser';
12
12
  import { DcsParser } from 'common/parser/DcsParser';
13
+ import { ApcParser } from 'common/parser/ApcParser';
13
14
 
14
15
  /**
15
16
  * Table values are generated like this:
@@ -17,8 +18,8 @@ import { DcsParser } from 'common/parser/DcsParser';
17
18
  * value: action << TableValue.TRANSITION_ACTION_SHIFT | nextState
18
19
  */
19
20
  const enum TableAccess {
20
- TRANSITION_ACTION_SHIFT = 4,
21
- TRANSITION_STATE_MASK = 15,
21
+ TRANSITION_ACTION_SHIFT = 8,
22
+ TRANSITION_STATE_MASK = 255,
22
23
  INDEX_STATE_SHIFT = 8
23
24
  }
24
25
 
@@ -26,10 +27,10 @@ const enum TableAccess {
26
27
  * Transition table for EscapeSequenceParser.
27
28
  */
28
29
  export class TransitionTable {
29
- public table: Uint8Array;
30
+ public table: Uint16Array;
30
31
 
31
32
  constructor(length: number) {
32
- this.table = new Uint8Array(length);
33
+ this.table = new Uint16Array(length);
33
34
  }
34
35
 
35
36
  /**
@@ -89,22 +90,22 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
89
90
  EXECUTABLES.push(0x19);
90
91
  EXECUTABLES.push.apply(EXECUTABLES, r(0x1c, 0x20));
91
92
 
92
- const states: number[] = r(ParserState.GROUND, ParserState.DCS_PASSTHROUGH + 1);
93
- let state: any;
93
+ const states: number[] = r(ParserState.GROUND, ParserState.STATE_LENGTH);
94
94
 
95
95
  // set default transition
96
96
  table.setDefault(ParserAction.ERROR, ParserState.GROUND);
97
97
  // printables
98
98
  table.addMany(PRINTABLES, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);
99
99
  // global anywhere rules
100
- for (state in states) {
100
+ for (const state of states) {
101
101
  table.addMany([0x18, 0x1a, 0x99, 0x9a], state, ParserAction.EXECUTE, ParserState.GROUND);
102
102
  table.addMany(r(0x80, 0x90), state, ParserAction.EXECUTE, ParserState.GROUND);
103
103
  table.addMany(r(0x90, 0x98), state, ParserAction.EXECUTE, ParserState.GROUND);
104
104
  table.add(0x9c, state, ParserAction.IGNORE, ParserState.GROUND); // ST as terminator
105
105
  table.add(0x1b, state, ParserAction.CLEAR, ParserState.ESCAPE); // ESC
106
106
  table.add(0x9d, state, ParserAction.OSC_START, ParserState.OSC_STRING); // OSC
107
- table.addMany([0x98, 0x9e, 0x9f], state, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
107
+ table.addMany([0x98, 0x9e], state, ParserAction.IGNORE, ParserState.SOS_PM_STRING); // SOS, PM
108
+ table.add(0x9f, state, ParserAction.APC_START, ParserState.APC_STRING); // APC
108
109
  table.add(0x9b, state, ParserAction.CLEAR, ParserState.CSI_ENTRY); // CSI
109
110
  table.add(0x90, state, ParserAction.CLEAR, ParserState.DCS_ENTRY); // DCS
110
111
  }
@@ -128,12 +129,18 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
128
129
  table.add(0x7f, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);
129
130
  table.addMany([0x9c, 0x1b, 0x18, 0x1a, 0x07], ParserState.OSC_STRING, ParserAction.OSC_END, ParserState.GROUND);
130
131
  table.addMany(r(0x1c, 0x20), ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);
131
- // sos/pm/apc does nothing
132
- table.addMany([0x58, 0x5e, 0x5f], ParserState.ESCAPE, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
133
- table.addMany(PRINTABLES, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
134
- table.addMany(EXECUTABLES, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
135
- table.add(0x9c, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.GROUND);
136
- table.add(0x7f, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
132
+ // sos/pm
133
+ table.addMany([0x58, 0x5e], ParserState.ESCAPE, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
134
+ table.addMany(PRINTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
135
+ table.addMany(EXECUTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
136
+ table.add(0x9c, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.GROUND);
137
+ table.add(0x7f, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
138
+ // apc
139
+ table.add(0x5f, ParserState.ESCAPE, ParserAction.APC_START, ParserState.APC_STRING);
140
+ table.addMany(PRINTABLES, ParserState.APC_STRING, ParserAction.APC_PUT, ParserState.APC_STRING);
141
+ table.addMany(EXECUTABLES, ParserState.APC_STRING, ParserAction.IGNORE, ParserState.APC_STRING);
142
+ table.add(0x7f, ParserState.APC_STRING, ParserAction.IGNORE, ParserState.APC_STRING);
143
+ table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.APC_STRING, ParserAction.APC_END, ParserState.GROUND);
137
144
  // csi entries
138
145
  table.add(0x5b, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.CSI_ENTRY);
139
146
  table.addMany(r(0x40, 0x7f), ParserState.CSI_ENTRY, ParserAction.CSI_DISPATCH, ParserState.GROUND);
@@ -193,6 +200,7 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
193
200
  table.add(NON_ASCII_PRINTABLE, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);
194
201
  table.add(NON_ASCII_PRINTABLE, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
195
202
  table.add(NON_ASCII_PRINTABLE, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);
203
+ table.add(NON_ASCII_PRINTABLE, ParserState.APC_STRING, ParserAction.APC_PUT, ParserState.APC_STRING);
196
204
  return table;
197
205
  })();
198
206
 
@@ -243,6 +251,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
243
251
  protected _escHandlers: IHandlerCollection<EscHandlerType>;
244
252
  protected readonly _oscParser: IOscParser;
245
253
  protected readonly _dcsParser: IDcsParser;
254
+ protected readonly _apcParser: IApcParser;
246
255
  protected _errorHandler: (state: IParsingState) => IParsingState;
247
256
 
248
257
  // fallback handlers
@@ -290,6 +299,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
290
299
  }));
291
300
  this._oscParser = this._register(new OscParser());
292
301
  this._dcsParser = this._register(new DcsParser());
302
+ this._apcParser = this._register(new ApcParser());
293
303
  this._errorHandler = this._errorHandlerFb;
294
304
 
295
305
  // swallow 7bit ST (ESC+\)
@@ -351,9 +361,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
351
361
 
352
362
  public registerEscHandler(id: IFunctionIdentifier, handler: EscHandlerType): IDisposable {
353
363
  const ident = this._identifier(id, [0x30, 0x7e]);
354
- if (this._escHandlers[ident] === undefined) {
355
- this._escHandlers[ident] = [];
356
- }
364
+ this._escHandlers[ident] ??= [];
357
365
  const handlerList = this._escHandlers[ident];
358
366
  handlerList.push(handler);
359
367
  return {
@@ -384,9 +392,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
384
392
 
385
393
  public registerCsiHandler(id: IFunctionIdentifier, handler: CsiHandlerType): IDisposable {
386
394
  const ident = this._identifier(id);
387
- if (this._csiHandlers[ident] === undefined) {
388
- this._csiHandlers[ident] = [];
389
- }
395
+ this._csiHandlers[ident] ??= [];
390
396
  const handlerList = this._csiHandlers[ident];
391
397
  handlerList.push(handler);
392
398
  return {
@@ -425,6 +431,16 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
425
431
  this._oscParser.setHandlerFallback(handler);
426
432
  }
427
433
 
434
+ public registerApcHandler(ident: number, handler: IApcHandler): IDisposable {
435
+ return this._apcParser.registerHandler(ident, handler);
436
+ }
437
+ public clearApcHandler(ident: number): void {
438
+ this._apcParser.clearHandler(ident);
439
+ }
440
+ public setApcHandlerFallback(handler: ApcFallbackHandlerType): void {
441
+ this._apcParser.setHandlerFallback(handler);
442
+ }
443
+
428
444
  public setErrorHandler(callback: (state: IParsingState) => IParsingState): void {
429
445
  this._errorHandler = callback;
430
446
  }
@@ -445,6 +461,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
445
461
  this.currentState = this.initialState;
446
462
  this._oscParser.reset();
447
463
  this._dcsParser.reset();
464
+ this._apcParser.reset();
448
465
  this._params.reset();
449
466
  this._params.addParam(0); // ZDM
450
467
  this._collect = 0;
@@ -489,6 +506,10 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
489
506
  * - OSC_STRING:OSC_PUT
490
507
  * - DCS_PASSTHROUGH:DCS_PUT
491
508
  *
509
+ * Additionally the following fast paths exist before the table lookup:
510
+ * - EXE bytes < 0x18 in non-payload states (avoids table lookup entirely)
511
+ * - 7-bit CSI sequences without intermediates (ESC [ params final)
512
+ *
492
513
  * Note on asynchronous handler support:
493
514
  * Any handler returning a promise will be treated as asynchronous.
494
515
  * To keep the in-band blocking working for async handlers, `parse` pauses execution,
@@ -606,6 +627,17 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
606
627
  this._params.addParam(0); // ZDM
607
628
  this._collect = 0;
608
629
  break;
630
+ case ParserStackType.APC:
631
+ code = data[this._parseStack.chunkPos];
632
+ handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a, promiseResult);
633
+ if (handlerResult) {
634
+ return handlerResult;
635
+ }
636
+ if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;
637
+ this._params.reset();
638
+ this._params.addParam(0); // ZDM
639
+ this._collect = 0;
640
+ break;
609
641
  }
610
642
  // cleanup before continuing with the main sync loop
611
643
  this._parseStack.state = ParserStackType.NONE;
@@ -621,34 +653,89 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
621
653
  for (let i = start; i < length; ++i) {
622
654
  code = data[i];
623
655
 
656
+ // EXE fast-path: common control bytes (0x00-0x17) in non-payload states
657
+ if (code < 0x18 && this.currentState <= ParserState.CSI_IGNORE) {
658
+ if (this._executeHandlers[code]) this._executeHandlers[code]();
659
+ else this._executeHandlerFb(code);
660
+ this.precedingJoinState = 0;
661
+ continue;
662
+ }
663
+
664
+ // CSI fast-path: collapse ESC [ into a single entry, parse params+final in a tight loop
665
+ if (code === 0x1b
666
+ && this.currentState < ParserState.OSC_STRING
667
+ && i + 2 < length && data[i + 1] === 0x5b
668
+ ) {
669
+ this._params.reset();
670
+ this._params.addParam(0); // ZDM
671
+ this._collect = 0;
672
+ let k = i + 2;
673
+ let ch = data[k];
674
+ if (ch >= 0x3c && ch <= 0x3f) {
675
+ this._collect = ch;
676
+ k++;
677
+ }
678
+ let csiDone = false;
679
+ for (; k < length; k++) {
680
+ ch = data[k];
681
+ if (ch >= 0x30 && ch <= 0x39) {
682
+ this._params.addDigit(ch - 48);
683
+ } else if (ch === 0x3b) {
684
+ this._params.addParam(0);
685
+ } else if (ch === 0x3a) {
686
+ this._params.addSubParam(-1);
687
+ } else if (ch >= 0x40 && ch <= 0x7e) {
688
+ const handlers = this._csiHandlers[this._collect << 8 | ch];
689
+ let j = handlers ? handlers.length - 1 : -1;
690
+ for (; j >= 0; j--) {
691
+ handlerResult = handlers[j](this._params);
692
+ if (handlerResult === true) {
693
+ break;
694
+ } else if (handlerResult instanceof Promise) {
695
+ transition = ParserAction.CSI_DISPATCH << TableAccess.TRANSITION_ACTION_SHIFT | ParserState.GROUND;
696
+ this._preserveStack(ParserStackType.CSI, handlers, j, transition, k);
697
+ return handlerResult;
698
+ }
699
+ }
700
+ if (j < 0) {
701
+ this._csiHandlerFb(this._collect << 8 | ch, this._params);
702
+ }
703
+ this.precedingJoinState = 0;
704
+ i = k;
705
+ this.currentState = ParserState.GROUND;
706
+ csiDone = true;
707
+ break;
708
+ } else {
709
+ break;
710
+ }
711
+ }
712
+ if (!csiDone) {
713
+ i = k - 1;
714
+ this.currentState = ParserState.CSI_PARAM;
715
+ }
716
+ continue;
717
+ }
718
+
624
719
  // normal transition & action lookup
625
720
  transition = this._transitions.table[this.currentState << TableAccess.INDEX_STATE_SHIFT | (code < 0xa0 ? code : NON_ASCII_PRINTABLE)];
626
721
  switch (transition >> TableAccess.TRANSITION_ACTION_SHIFT) {
627
722
  case ParserAction.PRINT:
628
- // read ahead with loop unrolling
629
723
  // Note: 0x20 (SP) is included, 0x7F (DEL) is excluded
630
- for (let j = i + 1; ; ++j) {
631
- if (j >= length || (code = data[j]) < 0x20 || (code > 0x7e && code < NON_ASCII_PRINTABLE)) {
632
- this._printHandler(data, i, j);
633
- i = j - 1;
634
- break;
635
- }
636
- if (++j >= length || (code = data[j]) < 0x20 || (code > 0x7e && code < NON_ASCII_PRINTABLE)) {
637
- this._printHandler(data, i, j);
638
- i = j - 1;
639
- break;
640
- }
641
- if (++j >= length || (code = data[j]) < 0x20 || (code > 0x7e && code < NON_ASCII_PRINTABLE)) {
642
- this._printHandler(data, i, j);
643
- i = j - 1;
644
- break;
645
- }
646
- if (++j >= length || (code = data[j]) < 0x20 || (code > 0x7e && code < NON_ASCII_PRINTABLE)) {
647
- this._printHandler(data, i, j);
648
- i = j - 1;
649
- break;
724
+ let c = i;
725
+ const l4 = length - 4;
726
+ while (c < l4
727
+ && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)
728
+ && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)
729
+ && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)
730
+ && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)
731
+ ) {}
732
+ if (c >= l4) {
733
+ while (c < length && data[c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)) {
734
+ c++;
650
735
  }
651
736
  }
737
+ this._printHandler(data, i, c);
738
+ i = c - 1;
652
739
  break;
653
740
  case ParserAction.EXECUTE:
654
741
  if (this._executeHandlers[code]) this._executeHandlers[code]();
@@ -785,6 +872,31 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
785
872
  this._collect = 0;
786
873
  this.precedingJoinState = 0;
787
874
  break;
875
+ case ParserAction.APC_START:
876
+ this._apcParser.start();
877
+ break;
878
+ case ParserAction.APC_PUT:
879
+ // inner loop - exit APC_PUT: 0x18, 0x1a, 0x1b, 0x9c
880
+ for (let j = i + 1; ; ++j) {
881
+ if (j >= length || (code = data[j]) === 0x18 || code === 0x1a || code === 0x1b || code === 0x9c || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {
882
+ this._apcParser.put(data, i, j);
883
+ i = j - 1;
884
+ break;
885
+ }
886
+ }
887
+ break;
888
+ case ParserAction.APC_END:
889
+ handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a);
890
+ if (handlerResult) {
891
+ this._preserveStack(ParserStackType.APC, [], 0, transition, i);
892
+ return handlerResult;
893
+ }
894
+ if (code === 0x1b) transition |= ParserState.ESCAPE;
895
+ this._params.reset();
896
+ this._params.addParam(0); // ZDM
897
+ this._collect = 0;
898
+ this.precedingJoinState = 0;
899
+ break;
788
900
  }
789
901
  this.currentState = transition & TableAccess.TRANSITION_STATE_MASK;
790
902
  }
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { IOscHandler, IHandlerCollection, OscFallbackHandlerType, IOscParser, ISubParserStackState } from 'common/parser/Types';
7
- import { OscState, PAYLOAD_LIMIT } from 'common/parser/Constants';
7
+ import { OscState, ParserConstants } from 'common/parser/Constants';
8
8
  import { utf32ToString } from 'common/input/TextDecoder';
9
9
  import { IDisposable } from 'common/Types';
10
10
 
@@ -23,9 +23,7 @@ export class OscParser implements IOscParser {
23
23
  };
24
24
 
25
25
  public registerHandler(ident: number, handler: IOscHandler): IDisposable {
26
- if (this._handlers[ident] === undefined) {
27
- this._handlers[ident] = [];
28
- }
26
+ this._handlers[ident] ??= [];
29
27
  const handlerList = this._handlers[ident];
30
28
  handlerList.push(handler);
31
29
  return {
@@ -194,6 +192,8 @@ export class OscParser implements IOscParser {
194
192
  * as OSC handlers.
195
193
  */
196
194
  export class OscHandler implements IOscHandler {
195
+ private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;
196
+
197
197
  private _data = '';
198
198
  private _hitLimit: boolean = false;
199
199
 
@@ -209,7 +209,7 @@ export class OscHandler implements IOscHandler {
209
209
  return;
210
210
  }
211
211
  this._data += utf32ToString(data, start, end);
212
- if (this._data.length > PAYLOAD_LIMIT) {
212
+ if (this._data.length > OscHandler._payloadLimit) {
213
213
  this._data = '';
214
214
  this._hitLimit = true;
215
215
  }
@@ -134,6 +134,29 @@ export interface IOscHandler {
134
134
  }
135
135
  export type OscFallbackHandlerType = (ident: number, action: 'START' | 'PUT' | 'END', payload?: any) => void;
136
136
 
137
+ /**
138
+ * APC handler types.
139
+ */
140
+ export interface IApcHandler {
141
+ /**
142
+ * Announces start of this APC command.
143
+ * Prepare needed data structures here.
144
+ */
145
+ start(): void;
146
+ /**
147
+ * Incoming data chunk.
148
+ */
149
+ put(data: Uint32Array, start: number, end: number): void;
150
+ /**
151
+ * End of APC command. `success` indicates whether the
152
+ * command finished normally or got aborted, thus final
153
+ * execution of the command should depend on `success`.
154
+ * To save memory also cleanup data structures here.
155
+ */
156
+ end(success: boolean): boolean | Promise<boolean>;
157
+ }
158
+ export type ApcFallbackHandlerType = (ident: number, action: 'START' | 'PUT' | 'END', payload?: any) => void;
159
+
137
160
  /**
138
161
  * PRINT handler types.
139
162
  */
@@ -196,6 +219,10 @@ export interface IEscapeSequenceParser extends IDisposable {
196
219
  clearOscHandler(ident: number): void;
197
220
  setOscHandlerFallback(handler: OscFallbackHandlerType): void;
198
221
 
222
+ registerApcHandler(ident: number, handler: IApcHandler): IDisposable;
223
+ clearApcHandler(ident: number): void;
224
+ setApcHandlerFallback(handler: ApcFallbackHandlerType): void;
225
+
199
226
  setErrorHandler(handler: (state: IParsingState) => IParsingState): void;
200
227
  clearErrorHandler(): void;
201
228
  }
@@ -223,6 +250,11 @@ export interface IDcsParser extends ISubParser<IDcsHandler, DcsFallbackHandlerTy
223
250
  unhook(success: boolean, promiseResult?: boolean): void | Promise<boolean>;
224
251
  }
225
252
 
253
+ export interface IApcParser extends ISubParser<IApcHandler, ApcFallbackHandlerType> {
254
+ start(): void;
255
+ end(success: boolean, promiseResult?: boolean): void | Promise<boolean>;
256
+ }
257
+
226
258
  /**
227
259
  * Interface to denote a specific ESC, CSI or DCS handler slot.
228
260
  * The values are used to create an integer respresentation during handler
@@ -252,7 +284,8 @@ export const enum ParserStackType {
252
284
  CSI,
253
285
  ESC,
254
286
  OSC,
255
- DCS
287
+ DCS,
288
+ APC
256
289
  }
257
290
 
258
291
  // aggregate of resumable handler lists
@@ -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);
@@ -6,8 +6,8 @@
6
6
  import { IBuffer as IBufferApi, IBufferNamespace as IBufferNamespaceApi } from '@xterm/xterm';
7
7
  import { BufferApiView } from 'common/public/BufferApiView';
8
8
  import { ICoreTerminal } from 'common/Types';
9
- import { Disposable } from 'vs/base/common/lifecycle';
10
- import { Emitter } from 'vs/base/common/event';
9
+ import { Disposable } from 'common/Lifecycle';
10
+ import { Emitter } from 'common/Event';
11
11
 
12
12
  export class BufferNamespaceApi extends Disposable implements IBufferNamespaceApi {
13
13
  private _normal: BufferApiView;
@@ -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(ident: number, callback: (data: string) => boolean | Promise<boolean>): IDisposable {
38
+ return this._core.registerApcHandler(ident, callback);
39
+ }
37
40
  }
@@ -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, IBufferLine } from 'common/Types';
8
8
  import { BufferSet } from 'common/buffer/BufferSet';
9
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';
10
+ import { IBufferService, ILogService, IOptionsService, type IBufferResizeEvent } from 'common/services/Services';
11
+ import { Emitter } from 'common/Event';
12
12
 
13
13
  export const MINIMUM_COLS = 2; // Less than 2 can mess with wide chars
14
14
  export const MINIMUM_ROWS = 1;
@@ -32,11 +32,14 @@ export class BufferService extends Disposable implements IBufferService {
32
32
  /** An IBufferline to clone/copy from for new blank lines */
33
33
  private _cachedBlankLine: IBufferLine | undefined;
34
34
 
35
- constructor(@IOptionsService optionsService: IOptionsService) {
35
+ constructor(
36
+ @IOptionsService optionsService: IOptionsService,
37
+ @ILogService logService: ILogService
38
+ ) {
36
39
  super();
37
40
  this.cols = Math.max(optionsService.rawOptions.cols || 0, MINIMUM_COLS);
38
41
  this.rows = Math.max(optionsService.rawOptions.rows || 0, MINIMUM_ROWS);
39
- this.buffers = this._register(new BufferSet(optionsService, this));
42
+ this.buffers = this._register(new BufferSet(optionsService, this, logService));
40
43
  this._register(this.buffers.onBufferActivate(e => {
41
44
  this._onScroll.fire(e.activeBuffer.ydisp);
42
45
  }));
@@ -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 = [];
@@ -4,10 +4,10 @@
4
4
  */
5
5
 
6
6
  import { clone } from 'common/Clone';
7
- import { Disposable } from 'vs/base/common/lifecycle';
8
- import { IDecPrivateModes, IModes } from 'common/Types';
7
+ import { Disposable } from 'common/Lifecycle';
8
+ import { IDecPrivateModes, IKittyKeyboardState, IModes } from 'common/Types';
9
9
  import { IBufferService, ICoreService, ILogService, IOptionsService } from 'common/services/Services';
10
- import { Emitter } from 'vs/base/common/event';
10
+ import { Emitter } from 'common/Event';
11
11
 
12
12
  const DEFAULT_MODES: IModes = Object.freeze({
13
13
  insertMode: false
@@ -17,22 +17,33 @@ const DEFAULT_DEC_PRIVATE_MODES: IDecPrivateModes = Object.freeze({
17
17
  applicationCursorKeys: false,
18
18
  applicationKeypad: false,
19
19
  bracketedPasteMode: false,
20
+ colorSchemeUpdates: false,
20
21
  cursorBlink: undefined,
21
22
  cursorStyle: undefined,
22
23
  origin: false,
23
24
  reverseWraparound: false,
24
25
  sendFocus: false,
25
26
  synchronizedOutput: false,
27
+ win32InputMode: false,
26
28
  wraparound: true // defaults: xterm - true, vt100 - false
27
29
  });
28
30
 
31
+ const DEFAULT_KITTY_KEYBOARD_STATE = (): IKittyKeyboardState => ({
32
+ flags: 0,
33
+ mainFlags: 0,
34
+ altFlags: 0,
35
+ mainStack: [],
36
+ altStack: []
37
+ });
38
+
29
39
  export class CoreService extends Disposable implements ICoreService {
30
40
  public serviceBrand: any;
31
41
 
32
- public isCursorInitialized: boolean = false;
42
+ public isCursorInitialized: boolean;
33
43
  public isCursorHidden: boolean = false;
34
44
  public modes: IModes;
35
45
  public decPrivateModes: IDecPrivateModes;
46
+ public kittyKeyboard: IKittyKeyboardState;
36
47
 
37
48
  private readonly _onData = this._register(new Emitter<string>());
38
49
  public readonly onData = this._onData.event;
@@ -49,13 +60,16 @@ export class CoreService extends Disposable implements ICoreService {
49
60
  @IOptionsService private readonly _optionsService: IOptionsService
50
61
  ) {
51
62
  super();
63
+ this.isCursorInitialized = _optionsService.rawOptions.showCursorImmediately ?? false;
52
64
  this.modes = clone(DEFAULT_MODES);
53
65
  this.decPrivateModes = clone(DEFAULT_DEC_PRIVATE_MODES);
66
+ this.kittyKeyboard = DEFAULT_KITTY_KEYBOARD_STATE();
54
67
  }
55
68
 
56
69
  public reset(): void {
57
70
  this.modes = clone(DEFAULT_MODES);
58
71
  this.decPrivateModes = clone(DEFAULT_DEC_PRIVATE_MODES);
72
+ this.kittyKeyboard = DEFAULT_KITTY_KEYBOARD_STATE();
59
73
  }
60
74
 
61
75
  public triggerDataEvent(data: string, wasUserInput: boolean = false): void {
@@ -4,16 +4,18 @@
4
4
  */
5
5
 
6
6
  import { css } from 'common/Color';
7
- import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
8
- import { IDecorationService, IInternalDecoration } from 'common/services/Services';
7
+ import { Disposable, DisposableStore, toDisposable } from 'common/Lifecycle';
8
+ import { IDecorationService, IInternalDecoration, ILogService } from 'common/services/Services';
9
9
  import { SortedList } from 'common/SortedList';
10
10
  import { IColor } from 'common/Types';
11
11
  import { IDecoration, IDecorationOptions, IMarker } from '@xterm/xterm';
12
- import { Emitter } from 'vs/base/common/event';
12
+ import { Emitter } from 'common/Event';
13
13
 
14
14
  // Work variables to avoid garbage collection
15
15
  let $xmin = 0;
16
16
  let $xmax = 0;
17
+ let $ymin = 0;
18
+ let $ymax = 0;
17
19
 
18
20
  export class DecorationService extends Disposable implements IDecorationService {
19
21
  public serviceBrand: any;
@@ -23,7 +25,7 @@ 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>;
27
29
 
28
30
  private readonly _onDecorationRegistered = this._register(new Emitter<IInternalDecoration>());
29
31
  public readonly onDecorationRegistered = this._onDecorationRegistered.event;
@@ -32,9 +34,11 @@ export class DecorationService extends Disposable implements IDecorationService
32
34
 
33
35
  public get decorations(): IterableIterator<IInternalDecoration> { return this._decorations.values(); }
34
36
 
35
- constructor() {
37
+ constructor(@ILogService private readonly _logService: ILogService) {
36
38
  super();
37
39
 
40
+ this._decorations = new SortedList(e => e?.marker.line, this._logService);
41
+
38
42
  this._register(toDisposable(() => this.reset()));
39
43
  }
40
44
 
@@ -70,7 +74,14 @@ export class DecorationService extends Disposable implements IDecorationService
70
74
  public *getDecorationsAtCell(x: number, line: number, layer?: 'bottom' | 'top'): IterableIterator<IInternalDecoration> {
71
75
  let xmin = 0;
72
76
  let xmax = 0;
73
- for (const d of this._decorations.getKeyIterator(line)) {
77
+ let ymin = 0;
78
+ let ymax = 0;
79
+ for (const d of this._decorations.values()) {
80
+ ymin = d.marker.line;
81
+ ymax = ymin + (d.options.height ?? 1);
82
+ if (line < ymin || line >= ymax) {
83
+ continue;
84
+ }
74
85
  xmin = d.options.x ?? 0;
75
86
  xmax = xmin + (d.options.width ?? 1);
76
87
  if (x >= xmin && x < xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {
@@ -80,13 +91,18 @@ export class DecorationService extends Disposable implements IDecorationService
80
91
  }
81
92
 
82
93
  public forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void {
83
- this._decorations.forEachByKey(line, d => {
94
+ for (const d of this._decorations.values()) {
95
+ $ymin = d.marker.line;
96
+ $ymax = $ymin + (d.options.height ?? 1);
97
+ if (line < $ymin || line >= $ymax) {
98
+ continue;
99
+ }
84
100
  $xmin = d.options.x ?? 0;
85
101
  $xmax = $xmin + (d.options.width ?? 1);
86
102
  if (x >= $xmin && x < $xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {
87
103
  callback(d);
88
104
  }
89
- });
105
+ }
90
106
  }
91
107
  }
92
108