@xterm/xterm 6.1.0-beta.28 → 6.1.0-beta.280

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 (181) 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 -45
  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 +179 -348
  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 +7 -9
  16. package/src/browser/TimeBasedDebouncer.ts +12 -5
  17. package/src/browser/Types.ts +16 -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/Mouse.ts +5 -9
  24. package/src/browser/input/MoveToCell.ts +3 -3
  25. package/src/browser/public/Terminal.ts +33 -36
  26. package/src/browser/renderer/dom/DomRenderer.ts +265 -89
  27. package/src/browser/renderer/dom/DomRendererRowFactory.ts +34 -27
  28. package/src/browser/renderer/dom/WidthCache.ts +57 -55
  29. package/src/browser/renderer/shared/Constants.ts +7 -0
  30. package/src/browser/renderer/shared/RendererUtils.ts +1 -1
  31. package/src/browser/renderer/shared/SelectionRenderModel.ts +2 -2
  32. package/src/browser/renderer/shared/TextBlinkStateManager.ts +97 -0
  33. package/src/browser/renderer/shared/Types.ts +10 -4
  34. package/src/browser/scrollable/abstractScrollbar.ts +300 -0
  35. package/src/browser/scrollable/fastDomNode.ts +126 -0
  36. package/src/browser/scrollable/globalPointerMoveMonitor.ts +90 -0
  37. package/src/browser/scrollable/horizontalScrollbar.ts +85 -0
  38. package/src/browser/scrollable/mouseEvent.ts +292 -0
  39. package/src/browser/scrollable/scrollable.ts +486 -0
  40. package/src/browser/scrollable/scrollableElement.ts +581 -0
  41. package/src/browser/scrollable/scrollableElementOptions.ts +161 -0
  42. package/src/browser/scrollable/scrollbarArrow.ts +110 -0
  43. package/src/browser/scrollable/scrollbarState.ts +246 -0
  44. package/src/browser/scrollable/scrollbarVisibilityController.ts +113 -0
  45. package/src/browser/scrollable/touch.ts +485 -0
  46. package/src/browser/scrollable/verticalScrollbar.ts +143 -0
  47. package/src/browser/scrollable/widget.ts +23 -0
  48. package/src/browser/selection/SelectionModel.ts +1 -1
  49. package/src/browser/services/CharSizeService.ts +4 -4
  50. package/src/browser/services/CharacterJoinerService.ts +13 -11
  51. package/src/browser/services/CoreBrowserService.ts +7 -5
  52. package/src/browser/services/KeyboardService.ts +67 -0
  53. package/src/browser/services/LinkProviderService.ts +3 -3
  54. package/src/browser/services/MouseCoordsService.ts +47 -0
  55. package/src/browser/services/MouseService.ts +619 -23
  56. package/src/browser/services/RenderService.ts +33 -21
  57. package/src/browser/services/SelectionService.ts +72 -54
  58. package/src/browser/services/Services.ts +44 -21
  59. package/src/browser/services/ThemeService.ts +9 -9
  60. package/src/common/Async.ts +141 -0
  61. package/src/common/CircularList.ts +24 -3
  62. package/src/common/Color.ts +13 -5
  63. package/src/common/CoreTerminal.ts +61 -35
  64. package/src/common/Event.ts +118 -0
  65. package/src/common/InputHandler.ts +286 -105
  66. package/src/common/Lifecycle.ts +113 -0
  67. package/src/common/Platform.ts +15 -5
  68. package/src/common/SortedList.ts +8 -4
  69. package/src/common/StringBuilder.ts +67 -0
  70. package/src/common/TaskQueue.ts +17 -8
  71. package/src/common/Types.ts +68 -206
  72. package/src/common/Version.ts +1 -1
  73. package/src/common/WindowsMode.ts +2 -2
  74. package/src/common/buffer/AttributeData.ts +3 -2
  75. package/src/common/buffer/Buffer.ts +47 -32
  76. package/src/common/buffer/BufferLine.ts +175 -100
  77. package/src/common/buffer/BufferLineStringCache.ts +69 -0
  78. package/src/common/buffer/BufferReflow.ts +7 -4
  79. package/src/common/buffer/BufferSet.ts +13 -9
  80. package/src/common/buffer/CellData.ts +61 -4
  81. package/src/common/buffer/Constants.ts +13 -13
  82. package/src/common/buffer/Marker.ts +4 -4
  83. package/src/common/buffer/Types.ts +153 -3
  84. package/src/common/data/Charsets.ts +4 -7
  85. package/src/common/data/EscapeSequences.ts +71 -70
  86. package/src/common/input/Keyboard.ts +17 -10
  87. package/src/common/input/KittyKeyboard.ts +526 -0
  88. package/src/common/input/TextDecoder.ts +3 -3
  89. package/src/common/input/UnicodeV6.ts +3 -2
  90. package/src/common/input/Win32InputMode.ts +297 -0
  91. package/src/common/input/WriteBuffer.ts +108 -39
  92. package/src/common/input/XParseColor.ts +2 -2
  93. package/src/common/parser/ApcParser.ts +196 -0
  94. package/src/common/parser/Constants.ts +14 -4
  95. package/src/common/parser/DcsParser.ts +15 -16
  96. package/src/common/parser/EscapeSequenceParser.ts +214 -72
  97. package/src/common/parser/OscParser.ts +14 -15
  98. package/src/common/parser/Params.ts +31 -12
  99. package/src/common/parser/Types.ts +40 -30
  100. package/src/common/public/BufferApiView.ts +3 -3
  101. package/src/common/public/BufferLineApiView.ts +4 -4
  102. package/src/common/public/BufferNamespaceApi.ts +5 -5
  103. package/src/common/public/ParserApi.ts +5 -2
  104. package/src/common/public/UnicodeApi.ts +1 -1
  105. package/src/common/services/BufferService.ts +17 -13
  106. package/src/common/services/CharsetService.ts +6 -2
  107. package/src/common/services/CoreService.ts +23 -10
  108. package/src/common/services/DecorationService.ts +260 -15
  109. package/src/common/services/InstantiationService.ts +2 -2
  110. package/src/common/services/LogService.ts +2 -32
  111. package/src/common/services/{CoreMouseService.ts → MouseStateService.ts} +22 -133
  112. package/src/common/services/OptionsService.ts +17 -7
  113. package/src/common/services/OscLinkService.ts +3 -2
  114. package/src/common/services/ServiceRegistry.ts +14 -8
  115. package/src/common/services/Services.ts +54 -50
  116. package/src/common/services/UnicodeService.ts +6 -11
  117. package/typings/xterm.d.ts +329 -34
  118. package/src/common/Clone.ts +0 -23
  119. package/src/common/TypedArrayUtils.ts +0 -17
  120. package/src/vs/base/browser/browser.ts +0 -141
  121. package/src/vs/base/browser/canIUse.ts +0 -49
  122. package/src/vs/base/browser/dom.ts +0 -2369
  123. package/src/vs/base/browser/fastDomNode.ts +0 -316
  124. package/src/vs/base/browser/globalPointerMoveMonitor.ts +0 -112
  125. package/src/vs/base/browser/iframe.ts +0 -135
  126. package/src/vs/base/browser/keyboardEvent.ts +0 -213
  127. package/src/vs/base/browser/mouseEvent.ts +0 -229
  128. package/src/vs/base/browser/touch.ts +0 -372
  129. package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +0 -303
  130. package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +0 -114
  131. package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +0 -720
  132. package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +0 -165
  133. package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +0 -114
  134. package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +0 -243
  135. package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +0 -118
  136. package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +0 -116
  137. package/src/vs/base/browser/ui/widget.ts +0 -57
  138. package/src/vs/base/browser/window.ts +0 -14
  139. package/src/vs/base/common/arrays.ts +0 -887
  140. package/src/vs/base/common/arraysFind.ts +0 -202
  141. package/src/vs/base/common/assert.ts +0 -71
  142. package/src/vs/base/common/async.ts +0 -1992
  143. package/src/vs/base/common/cancellation.ts +0 -148
  144. package/src/vs/base/common/charCode.ts +0 -450
  145. package/src/vs/base/common/collections.ts +0 -140
  146. package/src/vs/base/common/decorators.ts +0 -130
  147. package/src/vs/base/common/equals.ts +0 -146
  148. package/src/vs/base/common/errors.ts +0 -303
  149. package/src/vs/base/common/event.ts +0 -1778
  150. package/src/vs/base/common/functional.ts +0 -32
  151. package/src/vs/base/common/hash.ts +0 -316
  152. package/src/vs/base/common/iterator.ts +0 -159
  153. package/src/vs/base/common/keyCodes.ts +0 -526
  154. package/src/vs/base/common/keybindings.ts +0 -284
  155. package/src/vs/base/common/lazy.ts +0 -47
  156. package/src/vs/base/common/lifecycle.ts +0 -801
  157. package/src/vs/base/common/linkedList.ts +0 -142
  158. package/src/vs/base/common/map.ts +0 -202
  159. package/src/vs/base/common/numbers.ts +0 -98
  160. package/src/vs/base/common/observable.ts +0 -76
  161. package/src/vs/base/common/observableInternal/api.ts +0 -31
  162. package/src/vs/base/common/observableInternal/autorun.ts +0 -281
  163. package/src/vs/base/common/observableInternal/base.ts +0 -489
  164. package/src/vs/base/common/observableInternal/debugName.ts +0 -145
  165. package/src/vs/base/common/observableInternal/derived.ts +0 -428
  166. package/src/vs/base/common/observableInternal/lazyObservableValue.ts +0 -146
  167. package/src/vs/base/common/observableInternal/logging.ts +0 -328
  168. package/src/vs/base/common/observableInternal/promise.ts +0 -209
  169. package/src/vs/base/common/observableInternal/utils.ts +0 -610
  170. package/src/vs/base/common/platform.ts +0 -281
  171. package/src/vs/base/common/scrollable.ts +0 -522
  172. package/src/vs/base/common/sequence.ts +0 -34
  173. package/src/vs/base/common/stopwatch.ts +0 -43
  174. package/src/vs/base/common/strings.ts +0 -557
  175. package/src/vs/base/common/symbols.ts +0 -9
  176. package/src/vs/base/common/uint.ts +0 -59
  177. package/src/vs/patches/nls.ts +0 -90
  178. package/src/vs/typings/base-common.d.ts +0 -20
  179. package/src/vs/typings/require.d.ts +0 -42
  180. package/src/vs/typings/vscode-globals-nls.d.ts +0 -36
  181. package/src/vs/typings/vscode-globals-product.d.ts +0 -33
@@ -3,13 +3,32 @@
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';
7
- import { ParserState, ParserAction } from 'common/parser/Constants';
8
- import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
9
- import { IDisposable } from 'common/Types';
10
- import { Params } from 'common/parser/Params';
11
- import { OscParser } from 'common/parser/OscParser';
12
- import { DcsParser } from 'common/parser/DcsParser';
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 './Types';
7
+ import { ParserState, ParserAction } from './Constants';
8
+ import { Disposable, toDisposable } from '../Lifecycle';
9
+ import { IDisposable } from '../Types';
10
+ import { Params } from './Params';
11
+ import { OscParser } from './OscParser';
12
+ import { DcsParser } from './DcsParser';
13
+ import { ApcParser } from './ApcParser';
14
+
15
+ /**
16
+ * VT commands done by the parser
17
+ */
18
+ // @vt: #Y ESC CSI "Control Sequence Introducer" "ESC [" "Start of a CSI sequence."
19
+ // @vt: #Y ESC OSC "Operating System Command" "ESC ]" "Start of an OSC sequence."
20
+ // @vt: #Y ESC DCS "Device Control String" "ESC P" "Start of a DCS sequence."
21
+ // @vt: #Y ESC ST "String Terminator" "ESC \\" "Terminator used for string type sequences."
22
+ // @vt: #Y ESC PM "Privacy Message" "ESC ^" "Start of a privacy message."
23
+ // @vt: #Y ESC APC "Application Program Command" "ESC _" "Start of an APC sequence."
24
+ // @vt: #Y C1 CSI "Control Sequence Introducer" "\x9B" "Start of a CSI sequence."
25
+ // @vt: #Y C1 OSC "Operating System Command" "\x9D" "Start of an OSC sequence."
26
+ // @vt: #Y C1 DCS "Device Control String" "\x90" "Start of a DCS sequence."
27
+ // @vt: #Y C1 ST "String Terminator" "\x9C" "Terminator used for string type sequences."
28
+ // @vt: #Y C1 PM "Privacy Message" "\x9E" "Start of a privacy message."
29
+ // @vt: #Y C1 APC "Application Program Command" "\x9F" "Start of an APC sequence."
30
+ // @vt: #Y C0 NUL "Null" "\0, \x00" "NUL is ignored."
31
+ // @vt: #Y C0 ESC "Escape" "\e, \x1B" "Start of a sequence. Cancels any other sequence."
13
32
 
14
33
  /**
15
34
  * Table values are generated like this:
@@ -17,8 +36,8 @@ import { DcsParser } from 'common/parser/DcsParser';
17
36
  * value: action << TableValue.TRANSITION_ACTION_SHIFT | nextState
18
37
  */
19
38
  const enum TableAccess {
20
- TRANSITION_ACTION_SHIFT = 4,
21
- TRANSITION_STATE_MASK = 15,
39
+ TRANSITION_ACTION_SHIFT = 8,
40
+ TRANSITION_STATE_MASK = 255,
22
41
  INDEX_STATE_SHIFT = 8
23
42
  }
24
43
 
@@ -26,10 +45,10 @@ const enum TableAccess {
26
45
  * Transition table for EscapeSequenceParser.
27
46
  */
28
47
  export class TransitionTable {
29
- public table: Uint8Array;
48
+ public table: Uint16Array;
30
49
 
31
50
  constructor(length: number) {
32
- this.table = new Uint8Array(length);
51
+ this.table = new Uint16Array(length);
33
52
  }
34
53
 
35
54
  /**
@@ -76,7 +95,9 @@ const NON_ASCII_PRINTABLE = 0xA0;
76
95
  * Taken from https://vt100.net/emu/dec_ansi_parser.
77
96
  */
78
97
  export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
79
- const table: TransitionTable = new TransitionTable(4095);
98
+ // table size:
99
+ // (ParserState.STATE_LENGTH - 1) << TableAccess.INDEX_STATE_SHIFT | NON_ASCII_PRINTABLE + 1
100
+ const table: TransitionTable = new TransitionTable(4257);
80
101
 
81
102
  // range macro for byte
82
103
  const BYTE_VALUES = 256;
@@ -89,22 +110,22 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
89
110
  EXECUTABLES.push(0x19);
90
111
  EXECUTABLES.push.apply(EXECUTABLES, r(0x1c, 0x20));
91
112
 
92
- const states: number[] = r(ParserState.GROUND, ParserState.DCS_PASSTHROUGH + 1);
93
- let state: any;
113
+ const states: number[] = r(ParserState.GROUND, ParserState.STATE_LENGTH);
94
114
 
95
115
  // set default transition
96
116
  table.setDefault(ParserAction.ERROR, ParserState.GROUND);
97
117
  // printables
98
118
  table.addMany(PRINTABLES, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);
99
119
  // global anywhere rules
100
- for (state in states) {
120
+ for (const state of states) {
101
121
  table.addMany([0x18, 0x1a, 0x99, 0x9a], state, ParserAction.EXECUTE, ParserState.GROUND);
102
122
  table.addMany(r(0x80, 0x90), state, ParserAction.EXECUTE, ParserState.GROUND);
103
123
  table.addMany(r(0x90, 0x98), state, ParserAction.EXECUTE, ParserState.GROUND);
104
124
  table.add(0x9c, state, ParserAction.IGNORE, ParserState.GROUND); // ST as terminator
105
125
  table.add(0x1b, state, ParserAction.CLEAR, ParserState.ESCAPE); // ESC
106
126
  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);
127
+ table.addMany([0x98, 0x9e], state, ParserAction.IGNORE, ParserState.SOS_PM_STRING); // SOS, PM
128
+ table.add(0x9f, state, ParserAction.CLEAR, ParserState.APC_ENTRY); // APC
108
129
  table.add(0x9b, state, ParserAction.CLEAR, ParserState.CSI_ENTRY); // CSI
109
130
  table.add(0x90, state, ParserAction.CLEAR, ParserState.DCS_ENTRY); // DCS
110
131
  }
@@ -128,12 +149,27 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
128
149
  table.add(0x7f, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);
129
150
  table.addMany([0x9c, 0x1b, 0x18, 0x1a, 0x07], ParserState.OSC_STRING, ParserAction.OSC_END, ParserState.GROUND);
130
151
  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);
152
+ // sos/pm
153
+ table.addMany([0x58, 0x5e], ParserState.ESCAPE, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
154
+ table.addMany(PRINTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
155
+ table.addMany(EXECUTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
156
+ table.add(0x9c, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.GROUND);
157
+ table.add(0x7f, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
158
+ // apc
159
+ table.add(0x5f, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.APC_ENTRY);
160
+ table.addMany(EXECUTABLES, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);
161
+ table.add(0x7f, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);
162
+ table.addMany(r(0x20, 0x30), ParserState.APC_ENTRY, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);
163
+ table.addMany(r(0x30, 0x7f), ParserState.APC_ENTRY, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);
164
+ table.addMany(r(0x30, 0x7f), ParserState.APC_INTERMEDIATE, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);
165
+ table.addMany(EXECUTABLES, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);
166
+ table.addMany(r(0x20, 0x30), ParserState.APC_INTERMEDIATE, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);
167
+ table.add(0x7f, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);
168
+ table.addMany(PRINTABLES, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);
169
+ table.addMany(EXECUTABLES, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);
170
+ table.addMany(r(0x08, 0x0e), ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);
171
+ table.add(0x7f, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);
172
+ table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.APC_PASSTHROUGH, ParserAction.APC_END, ParserState.GROUND);
137
173
  // csi entries
138
174
  table.add(0x5b, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.CSI_ENTRY);
139
175
  table.addMany(r(0x40, 0x7f), ParserState.CSI_ENTRY, ParserAction.CSI_DISPATCH, ParserState.GROUND);
@@ -162,22 +198,18 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
162
198
  table.add(0x50, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.DCS_ENTRY);
163
199
  table.addMany(EXECUTABLES, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);
164
200
  table.add(0x7f, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);
165
- table.addMany(r(0x1c, 0x20), ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);
166
201
  table.addMany(r(0x20, 0x30), ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);
167
202
  table.addMany(r(0x30, 0x3c), ParserState.DCS_ENTRY, ParserAction.PARAM, ParserState.DCS_PARAM);
168
203
  table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_PARAM);
169
204
  table.addMany(EXECUTABLES, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
170
205
  table.addMany(r(0x20, 0x80), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
171
- table.addMany(r(0x1c, 0x20), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
172
206
  table.addMany(EXECUTABLES, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);
173
207
  table.add(0x7f, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);
174
- table.addMany(r(0x1c, 0x20), ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);
175
208
  table.addMany(r(0x30, 0x3c), ParserState.DCS_PARAM, ParserAction.PARAM, ParserState.DCS_PARAM);
176
209
  table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_IGNORE);
177
210
  table.addMany(r(0x20, 0x30), ParserState.DCS_PARAM, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);
178
211
  table.addMany(EXECUTABLES, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);
179
212
  table.add(0x7f, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);
180
- table.addMany(r(0x1c, 0x20), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);
181
213
  table.addMany(r(0x20, 0x30), ParserState.DCS_INTERMEDIATE, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);
182
214
  table.addMany(r(0x30, 0x40), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
183
215
  table.addMany(r(0x40, 0x7f), ParserState.DCS_INTERMEDIATE, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);
@@ -193,6 +225,7 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
193
225
  table.add(NON_ASCII_PRINTABLE, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);
194
226
  table.add(NON_ASCII_PRINTABLE, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
195
227
  table.add(NON_ASCII_PRINTABLE, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);
228
+ table.add(NON_ASCII_PRINTABLE, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);
196
229
  return table;
197
230
  })();
198
231
 
@@ -210,7 +243,7 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
210
243
  *
211
244
  * This parser is currently hardcoded to operate in ZDM (Zero Default Mode)
212
245
  * as suggested by the original parser, thus empty parameters are set to 0.
213
- * This this is not in line with the latest ECMA-48 specification
246
+ * This is not in line with the latest ECMA-48 specification
214
247
  * (ZDM was part of the early specs and got completely removed later on).
215
248
  *
216
249
  * Other than the original parser from vt100.net this parser supports
@@ -239,10 +272,13 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
239
272
  // handler lookup containers
240
273
  protected _printHandler: PrintHandlerType;
241
274
  protected _executeHandlers: { [flag: number]: ExecuteHandlerType };
275
+ // fast path for EXE bytes < 0x18
276
+ protected _executeHandlersArr: (ExecuteHandlerType | undefined)[];
242
277
  protected _csiHandlers: IHandlerCollection<CsiHandlerType>;
243
278
  protected _escHandlers: IHandlerCollection<EscHandlerType>;
244
279
  protected readonly _oscParser: IOscParser;
245
280
  protected readonly _dcsParser: IDcsParser;
281
+ protected readonly _apcParser: IApcParser;
246
282
  protected _errorHandler: (state: IParsingState) => IParsingState;
247
283
 
248
284
  // fallback handlers
@@ -281,15 +317,18 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
281
317
  this._errorHandlerFb = (state: IParsingState): IParsingState => state;
282
318
  this._printHandler = this._printHandlerFb;
283
319
  this._executeHandlers = Object.create(null);
320
+ this._executeHandlersArr = new Array(0x18).fill(undefined);
284
321
  this._csiHandlers = Object.create(null);
285
322
  this._escHandlers = Object.create(null);
286
323
  this._register(toDisposable(() => {
287
324
  this._csiHandlers = Object.create(null);
288
325
  this._executeHandlers = Object.create(null);
326
+ this._executeHandlersArr = new Array(0x18).fill(undefined);
289
327
  this._escHandlers = Object.create(null);
290
328
  }));
291
329
  this._oscParser = this._register(new OscParser());
292
330
  this._dcsParser = this._register(new DcsParser());
331
+ this._apcParser = this._register(new ApcParser());
293
332
  this._errorHandler = this._errorHandlerFb;
294
333
 
295
334
  // swallow 7bit ST (ESC+\)
@@ -303,7 +342,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
303
342
  throw new Error('only one byte as prefix supported');
304
343
  }
305
344
  res = id.prefix.charCodeAt(0);
306
- if (res && 0x3c > res || res > 0x3f) {
345
+ if (res < 0x3c || res > 0x3f) {
307
346
  throw new Error('prefix must be in range 0x3c .. 0x3f');
308
347
  }
309
348
  }
@@ -351,9 +390,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
351
390
 
352
391
  public registerEscHandler(id: IFunctionIdentifier, handler: EscHandlerType): IDisposable {
353
392
  const ident = this._identifier(id, [0x30, 0x7e]);
354
- if (this._escHandlers[ident] === undefined) {
355
- this._escHandlers[ident] = [];
356
- }
393
+ this._escHandlers[ident] ??= [];
357
394
  const handlerList = this._escHandlers[ident];
358
395
  handlerList.push(handler);
359
396
  return {
@@ -373,10 +410,14 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
373
410
  }
374
411
 
375
412
  public setExecuteHandler(flag: string, handler: ExecuteHandlerType): void {
376
- this._executeHandlers[flag.charCodeAt(0)] = handler;
413
+ const code = flag.charCodeAt(0);
414
+ this._executeHandlers[code] = handler;
415
+ if (code < 0x18) this._executeHandlersArr[code] = handler;
377
416
  }
378
417
  public clearExecuteHandler(flag: string): void {
379
- if (this._executeHandlers[flag.charCodeAt(0)]) delete this._executeHandlers[flag.charCodeAt(0)];
418
+ const code = flag.charCodeAt(0);
419
+ if (this._executeHandlers[code]) delete this._executeHandlers[code];
420
+ if (code < 0x18) this._executeHandlersArr[code] = undefined;
380
421
  }
381
422
  public setExecuteHandlerFallback(handler: ExecuteFallbackHandlerType): void {
382
423
  this._executeHandlerFb = handler;
@@ -384,9 +425,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
384
425
 
385
426
  public registerCsiHandler(id: IFunctionIdentifier, handler: CsiHandlerType): IDisposable {
386
427
  const ident = this._identifier(id);
387
- if (this._csiHandlers[ident] === undefined) {
388
- this._csiHandlers[ident] = [];
389
- }
428
+ this._csiHandlers[ident] ??= [];
390
429
  const handlerList = this._csiHandlers[ident];
391
430
  handlerList.push(handler);
392
431
  return {
@@ -425,6 +464,18 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
425
464
  this._oscParser.setHandlerFallback(handler);
426
465
  }
427
466
 
467
+ public registerApcHandler(id: IFunctionIdentifier, handler: IApcHandler): IDisposable {
468
+ id.prefix = undefined; // APC does not support prefix byte
469
+ return this._apcParser.registerHandler(this._identifier(id, [0x30, 0x7e]), handler);
470
+ }
471
+ public clearApcHandler(id: IFunctionIdentifier): void {
472
+ id.prefix = undefined; // APC does not support prefix byte
473
+ this._apcParser.clearHandler(this._identifier(id, [0x30, 0x7e]));
474
+ }
475
+ public setApcHandlerFallback(handler: ApcFallbackHandlerType): void {
476
+ this._apcParser.setHandlerFallback(handler);
477
+ }
478
+
428
479
  public setErrorHandler(callback: (state: IParsingState) => IParsingState): void {
429
480
  this._errorHandler = callback;
430
481
  }
@@ -445,8 +496,8 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
445
496
  this.currentState = this.initialState;
446
497
  this._oscParser.reset();
447
498
  this._dcsParser.reset();
448
- this._params.reset();
449
- this._params.addParam(0); // ZDM
499
+ this._apcParser.reset();
500
+ this._params.resetZdm();
450
501
  this._collect = 0;
451
502
  this.precedingJoinState = 0;
452
503
  // abort pending continuation from async handler
@@ -489,6 +540,10 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
489
540
  * - OSC_STRING:OSC_PUT
490
541
  * - DCS_PASSTHROUGH:DCS_PUT
491
542
  *
543
+ * Additionally the following fast paths exist before the table lookup:
544
+ * - EXE bytes < 0x18 in non-payload states (avoids table lookup entirely)
545
+ * - 7-bit CSI sequences without intermediates (ESC [ params final)
546
+ *
492
547
  * Note on asynchronous handler support:
493
548
  * Any handler returning a promise will be treated as asynchronous.
494
549
  * To keep the in-band blocking working for async handlers, `parse` pauses execution,
@@ -517,8 +572,8 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
517
572
  * ```
518
573
  */
519
574
  public parse(data: Uint32Array, length: number, promiseResult?: boolean): void | Promise<boolean> {
520
- let code = 0;
521
- let transition = 0;
575
+ let code: number;
576
+ let transition: number;
522
577
  let start = 0;
523
578
  let handlerResult: void | boolean | Promise<boolean>;
524
579
 
@@ -591,8 +646,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
591
646
  return handlerResult;
592
647
  }
593
648
  if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;
594
- this._params.reset();
595
- this._params.addParam(0); // ZDM
649
+ this._params.resetZdm();
596
650
  this._collect = 0;
597
651
  break;
598
652
  case ParserStackType.OSC:
@@ -602,8 +656,17 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
602
656
  return handlerResult;
603
657
  }
604
658
  if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;
605
- this._params.reset();
606
- this._params.addParam(0); // ZDM
659
+ this._params.resetZdm();
660
+ this._collect = 0;
661
+ break;
662
+ case ParserStackType.APC:
663
+ code = data[this._parseStack.chunkPos];
664
+ handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a, promiseResult);
665
+ if (handlerResult) {
666
+ return handlerResult;
667
+ }
668
+ if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;
669
+ this._params.resetZdm();
607
670
  this._collect = 0;
608
671
  break;
609
672
  }
@@ -621,34 +684,90 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
621
684
  for (let i = start; i < length; ++i) {
622
685
  code = data[i];
623
686
 
687
+ // EXE fast-path: common control bytes (0x00-0x17) in non-payload states
688
+ if (code < 0x18 && this.currentState <= ParserState.CSI_IGNORE) {
689
+ (this._executeHandlersArr[code] ?? this._executeHandlerFb)(code);
690
+ this.precedingJoinState = 0;
691
+ continue;
692
+ }
693
+
694
+ // CSI fast-path: collapse ESC [ into a single entry, parse params+final in a tight loop
695
+ if (code === 0x1b
696
+ && this.currentState < ParserState.OSC_STRING
697
+ && i + 2 < length && data[i + 1] === 0x5b
698
+ ) {
699
+ this._params.resetZdm();
700
+ this._collect = 0;
701
+ let k = i + 2;
702
+ let ch = data[k];
703
+ if (ch >= 0x3c && ch <= 0x3f) {
704
+ this._collect = ch;
705
+ k++;
706
+ }
707
+ let csiDone = false;
708
+ for (; k < length; k++) {
709
+ ch = data[k];
710
+ if (ch >= 0x30 && ch <= 0x39) {
711
+ this._params.addDigit(ch - 48);
712
+ } else if (ch === 0x3b) {
713
+ this._params.addParam(0);
714
+ } else if (ch === 0x3a) {
715
+ this._params.addSubParam(-1);
716
+ } else if (ch >= 0x40 && ch <= 0x7e) {
717
+ const handlers = this._csiHandlers[this._collect << 8 | ch];
718
+ let j = handlers ? handlers.length - 1 : -1;
719
+ for (; j >= 0; j--) {
720
+ handlerResult = handlers[j](this._params);
721
+ if (handlerResult === true) {
722
+ break;
723
+ } else if (handlerResult instanceof Promise) {
724
+ transition = ParserAction.CSI_DISPATCH << TableAccess.TRANSITION_ACTION_SHIFT | ParserState.GROUND;
725
+ this._preserveStack(ParserStackType.CSI, handlers, j, transition, k);
726
+ return handlerResult;
727
+ }
728
+ }
729
+ if (j < 0) {
730
+ this._csiHandlerFb(this._collect << 8 | ch, this._params);
731
+ }
732
+ this.precedingJoinState = 0;
733
+ i = k;
734
+ this.currentState = ParserState.GROUND;
735
+ csiDone = true;
736
+ break;
737
+ } else {
738
+ break;
739
+ }
740
+ }
741
+ if (!csiDone) {
742
+ i = k - 1;
743
+ this.currentState = ParserState.CSI_PARAM;
744
+ }
745
+ continue;
746
+ }
747
+
624
748
  // normal transition & action lookup
625
- transition = this._transitions.table[this.currentState << TableAccess.INDEX_STATE_SHIFT | (code < 0xa0 ? code : NON_ASCII_PRINTABLE)];
749
+ transition = this._transitions.table[
750
+ this.currentState << TableAccess.INDEX_STATE_SHIFT |
751
+ (code < NON_ASCII_PRINTABLE ? code : NON_ASCII_PRINTABLE)
752
+ ];
626
753
  switch (transition >> TableAccess.TRANSITION_ACTION_SHIFT) {
627
754
  case ParserAction.PRINT:
628
- // read ahead with loop unrolling
629
755
  // 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;
756
+ let c = i;
757
+ const l4 = length - 4;
758
+ while (c < l4
759
+ && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)
760
+ && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)
761
+ && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)
762
+ && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)
763
+ ) {}
764
+ if (c >= l4) {
765
+ while (c < length && data[c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)) {
766
+ c++;
650
767
  }
651
768
  }
769
+ this._printHandler(data, i, c);
770
+ i = c - 1;
652
771
  break;
653
772
  case ParserAction.EXECUTE:
654
773
  if (this._executeHandlers[code]) this._executeHandlers[code]();
@@ -730,8 +849,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
730
849
  this.precedingJoinState = 0;
731
850
  break;
732
851
  case ParserAction.CLEAR:
733
- this._params.reset();
734
- this._params.addParam(0); // ZDM
852
+ this._params.resetZdm();
735
853
  this._collect = 0;
736
854
  break;
737
855
  case ParserAction.DCS_HOOK:
@@ -755,8 +873,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
755
873
  return handlerResult;
756
874
  }
757
875
  if (code === 0x1b) transition |= ParserState.ESCAPE;
758
- this._params.reset();
759
- this._params.addParam(0); // ZDM
876
+ this._params.resetZdm();
760
877
  this._collect = 0;
761
878
  this.precedingJoinState = 0;
762
879
  break;
@@ -780,8 +897,33 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
780
897
  return handlerResult;
781
898
  }
782
899
  if (code === 0x1b) transition |= ParserState.ESCAPE;
783
- this._params.reset();
784
- this._params.addParam(0); // ZDM
900
+ this._params.resetZdm();
901
+ this._collect = 0;
902
+ this.precedingJoinState = 0;
903
+ break;
904
+ case ParserAction.APC_START:
905
+ this._apcParser.start(this._collect << 8 | code);
906
+ break;
907
+ case ParserAction.APC_PUT:
908
+ // inner loop - exit APC_PUT: 0x18, 0x1a, 0x1b, 0x9c
909
+ // allowed: 00/08 .. 00/13, 02/00 .. 07/14 + NON_ASCII_PRINTABLE
910
+ for (let j = i + 1; ; ++j) {
911
+ if (j < length && (
912
+ (data[j] >= 0x20 && data[j] < 0x7f) || (data[j] >= 0x08 && data[j] < 0x0e) || data[j] >= NON_ASCII_PRINTABLE
913
+ )) continue;
914
+ this._apcParser.put(data, i, j);
915
+ i = j - 1;
916
+ break;
917
+ }
918
+ break;
919
+ case ParserAction.APC_END:
920
+ handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a);
921
+ if (handlerResult) {
922
+ this._preserveStack(ParserStackType.APC, [], 0, transition, i);
923
+ return handlerResult;
924
+ }
925
+ if (code === 0x1b) transition |= ParserState.ESCAPE;
926
+ this._params.resetZdm();
785
927
  this._collect = 0;
786
928
  this.precedingJoinState = 0;
787
929
  break;
@@ -3,10 +3,11 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { IOscHandler, IHandlerCollection, OscFallbackHandlerType, IOscParser, ISubParserStackState } from 'common/parser/Types';
7
- import { OscState, PAYLOAD_LIMIT } from 'common/parser/Constants';
8
- import { utf32ToString } from 'common/input/TextDecoder';
9
- import { IDisposable } from 'common/Types';
6
+ import { IOscHandler, IHandlerCollection, OscFallbackHandlerType, IOscParser, ISubParserStackState } from './Types';
7
+ import { OscState, ParserConstants } from './Constants';
8
+ import { utf32ToString } from '../input/TextDecoder';
9
+ import { IDisposable } from '../Types';
10
+ import { LimitedStringBuilder } from '../StringBuilder';
10
11
 
11
12
  const EMPTY_HANDLERS: IOscHandler[] = [];
12
13
 
@@ -23,9 +24,7 @@ export class OscParser implements IOscParser {
23
24
  };
24
25
 
25
26
  public registerHandler(ident: number, handler: IOscHandler): IDisposable {
26
- if (this._handlers[ident] === undefined) {
27
- this._handlers[ident] = [];
28
- }
27
+ this._handlers[ident] ??= [];
29
28
  const handlerList = this._handlers[ident];
30
29
  handlerList.push(handler);
31
30
  return {
@@ -194,13 +193,15 @@ export class OscParser implements IOscParser {
194
193
  * as OSC handlers.
195
194
  */
196
195
  export class OscHandler implements IOscHandler {
197
- private _data = '';
196
+ private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;
197
+
198
+ private _data = new LimitedStringBuilder(OscHandler._payloadLimit);
198
199
  private _hitLimit: boolean = false;
199
200
 
200
201
  constructor(private _handler: (data: string) => boolean | Promise<boolean>) { }
201
202
 
202
203
  public start(): void {
203
- this._data = '';
204
+ this._data.reset();
204
205
  this._hitLimit = false;
205
206
  }
206
207
 
@@ -208,9 +209,7 @@ export class OscHandler implements IOscHandler {
208
209
  if (this._hitLimit) {
209
210
  return;
210
211
  }
211
- this._data += utf32ToString(data, start, end);
212
- if (this._data.length > PAYLOAD_LIMIT) {
213
- this._data = '';
212
+ if (this._data.append(utf32ToString(data, start, end))) {
214
213
  this._hitLimit = true;
215
214
  }
216
215
  }
@@ -220,18 +219,18 @@ export class OscHandler implements IOscHandler {
220
219
  if (this._hitLimit) {
221
220
  ret = false;
222
221
  } else if (success) {
223
- ret = this._handler(this._data);
222
+ ret = this._handler(this._data.toString());
224
223
  if (ret instanceof Promise) {
225
224
  // need to hold data until `ret` got resolved
226
225
  // dont care for errors, data will be freed anyway on next start
227
226
  return ret.then(res => {
228
- this._data = '';
227
+ this._data.reset();
229
228
  this._hitLimit = false;
230
229
  return res;
231
230
  });
232
231
  }
233
232
  }
234
- this._data = '';
233
+ this._data.reset();
235
234
  this._hitLimit = false;
236
235
  return ret;
237
236
  }