@xterm/xterm 6.1.0-beta.211 → 6.1.0-beta.212
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.
- package/lib/xterm.js +1 -1
- package/lib/xterm.js.map +1 -1
- package/lib/xterm.mjs +7 -7
- package/lib/xterm.mjs.map +2 -2
- package/package.json +3 -3
- package/src/common/CoreTerminal.ts +2 -2
- package/src/common/InputHandler.ts +5 -21
- package/src/common/Types.ts +2 -2
- package/src/common/Version.ts +1 -1
- package/src/common/parser/ApcParser.ts +43 -91
- package/src/common/parser/Constants.ts +4 -12
- package/src/common/parser/EscapeSequenceParser.ts +55 -23
- package/src/common/parser/Types.ts +3 -3
- package/src/common/public/ParserApi.ts +2 -2
- package/typings/xterm.d.ts +5 -5
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xterm/xterm",
|
|
3
3
|
"description": "Full xterm terminal, in your browser",
|
|
4
|
-
"version": "6.1.0-beta.
|
|
4
|
+
"version": "6.1.0-beta.212",
|
|
5
5
|
"main": "lib/xterm.js",
|
|
6
6
|
"module": "lib/xterm.mjs",
|
|
7
7
|
"style": "css/xterm.css",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"benchmark-baseline": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --baseline out-test/benchmark/*benchmark.js",
|
|
67
67
|
"benchmark-eval": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --eval out-test/benchmark/*benchmark.js",
|
|
68
68
|
"clean": "rm -rf lib out addons/*/lib addons/*/out",
|
|
69
|
-
"vtfeatures": "node bin/extract_vtfeatures.js src
|
|
69
|
+
"vtfeatures": "node bin/extract_vtfeatures.js src/*/*.ts src/*/*/*.ts src/*.ts addons/**/src/*.ts",
|
|
70
70
|
"prepackage": "npm run build",
|
|
71
71
|
"package": "webpack",
|
|
72
72
|
"postpackage": "npm run esbuild-package",
|
|
@@ -119,5 +119,5 @@
|
|
|
119
119
|
"ws": "^8.2.3",
|
|
120
120
|
"xterm-benchmark": "^0.3.1"
|
|
121
121
|
},
|
|
122
|
-
"commit": "
|
|
122
|
+
"commit": "874e767b4022a85d9bd7f8d9780f0812efe49fb6"
|
|
123
123
|
}
|
|
@@ -243,8 +243,8 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
/** Add handler for APC escape sequence. See xterm.d.ts for details. */
|
|
246
|
-
public registerApcHandler(
|
|
247
|
-
return this._inputHandler.registerApcHandler(
|
|
246
|
+
public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise<boolean>): IDisposable {
|
|
247
|
+
return this._inputHandler.registerApcHandler(id, callback);
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
protected _setup(): void {
|
|
@@ -30,28 +30,9 @@ import { XTERM_VERSION } from 'common/Version';
|
|
|
30
30
|
*/
|
|
31
31
|
const GLEVEL: { [key: string]: number } = { '(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2 };
|
|
32
32
|
|
|
33
|
-
/**
|
|
34
|
-
* VT commands done by the parser - FIXME: move this to the parser?
|
|
35
|
-
*/
|
|
36
|
-
// @vt: #Y ESC CSI "Control Sequence Introducer" "ESC [" "Start of a CSI sequence."
|
|
37
|
-
// @vt: #Y ESC OSC "Operating System Command" "ESC ]" "Start of an OSC sequence."
|
|
38
|
-
// @vt: #Y ESC DCS "Device Control String" "ESC P" "Start of a DCS sequence."
|
|
39
|
-
// @vt: #Y ESC ST "String Terminator" "ESC \" "Terminator used for string type sequences."
|
|
40
|
-
// @vt: #Y ESC PM "Privacy Message" "ESC ^" "Start of a privacy message."
|
|
41
|
-
// @vt: #Y ESC APC "Application Program Command" "ESC _" "Start of an APC sequence."
|
|
42
|
-
// @vt: #Y C1 CSI "Control Sequence Introducer" "\x9B" "Start of a CSI sequence."
|
|
43
|
-
// @vt: #Y C1 OSC "Operating System Command" "\x9D" "Start of an OSC sequence."
|
|
44
|
-
// @vt: #Y C1 DCS "Device Control String" "\x90" "Start of a DCS sequence."
|
|
45
|
-
// @vt: #Y C1 ST "String Terminator" "\x9C" "Terminator used for string type sequences."
|
|
46
|
-
// @vt: #Y C1 PM "Privacy Message" "\x9E" "Start of a privacy message."
|
|
47
|
-
// @vt: #Y C1 APC "Application Program Command" "\x9F" "Start of an APC sequence."
|
|
48
|
-
// @vt: #Y C0 NUL "Null" "\0, \x00" "NUL is ignored."
|
|
49
|
-
// @vt: #Y C0 ESC "Escape" "\e, \x1B" "Start of a sequence. Cancels any other sequence."
|
|
50
|
-
|
|
51
33
|
/**
|
|
52
34
|
* Document xterm VT features here that are currently unsupported
|
|
53
35
|
*/
|
|
54
|
-
// @vt: #E[Supported via @xterm/addon-image.] DCS SIXEL "SIXEL Graphics" "DCS Ps ; Ps ; Ps ; q Pt ST" "Draw SIXEL image."
|
|
55
36
|
// @vt: #N DCS DECUDK "User Defined Keys" "DCS Ps ; Ps \| Pt ST" "Definitions for user-defined keys."
|
|
56
37
|
// @vt: #N DCS XTGETTCAP "Request Terminfo String" "DCS + q Pt ST" "Request Terminfo String."
|
|
57
38
|
// @vt: #N DCS XTSETTCAP "Set Terminfo Data" "DCS + p Pt ST" "Set Terminfo Data."
|
|
@@ -211,6 +192,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
|
|
211
192
|
}
|
|
212
193
|
this._logService.debug('Unknown DCS code: ', { identifier: this._parser.identToString(ident), action, payload });
|
|
213
194
|
});
|
|
195
|
+
this._parser.setApcHandlerFallback((ident, action, payload) => {
|
|
196
|
+
this._logService.debug('Unknown APC code: ', { identifier: this._parser.identToString(ident), action, payload });
|
|
197
|
+
});
|
|
214
198
|
|
|
215
199
|
/**
|
|
216
200
|
* print handler
|
|
@@ -729,8 +713,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
|
|
729
713
|
/**
|
|
730
714
|
* Forward registerApcHandler from parser.
|
|
731
715
|
*/
|
|
732
|
-
public registerApcHandler(
|
|
733
|
-
return this._parser.registerApcHandler(
|
|
716
|
+
public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise<boolean>): IDisposable {
|
|
717
|
+
return this._parser.registerApcHandler(id, new ApcHandler(callback));
|
|
734
718
|
}
|
|
735
719
|
|
|
736
720
|
/**
|
package/src/common/Types.ts
CHANGED
|
@@ -22,7 +22,7 @@ export interface ICoreTerminal {
|
|
|
22
22
|
registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise<boolean>): IDisposable;
|
|
23
23
|
registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise<boolean>): IDisposable;
|
|
24
24
|
registerOscHandler(ident: number, callback: (data: string) => boolean | Promise<boolean>): IDisposable;
|
|
25
|
-
registerApcHandler(
|
|
25
|
+
registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise<boolean>): IDisposable;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export interface IDisposable {
|
|
@@ -476,7 +476,7 @@ export interface IInputHandler {
|
|
|
476
476
|
registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise<boolean>): IDisposable;
|
|
477
477
|
registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise<boolean>): IDisposable;
|
|
478
478
|
registerOscHandler(ident: number, callback: (data: string) => boolean | Promise<boolean>): IDisposable;
|
|
479
|
-
registerApcHandler(
|
|
479
|
+
registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise<boolean>): IDisposable;
|
|
480
480
|
|
|
481
481
|
/** C0 BEL */ bell(): boolean;
|
|
482
482
|
/** C0 LF */ lineFeed(): boolean;
|
package/src/common/Version.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { IApcHandler, IHandlerCollection, ApcFallbackHandlerType, IApcParser, ISubParserStackState } from 'common/parser/Types';
|
|
7
|
-
import {
|
|
7
|
+
import { ParserConstants } from 'common/parser/Constants';
|
|
8
8
|
import { utf32ToString } from 'common/input/TextDecoder';
|
|
9
9
|
import { IDisposable } from 'common/Types';
|
|
10
10
|
|
|
@@ -19,10 +19,9 @@ const EMPTY_HANDLERS: IApcHandler[] = [];
|
|
|
19
19
|
* The identifier is the character code of the first byte after ESC _.
|
|
20
20
|
*/
|
|
21
21
|
export class ApcParser implements IApcParser {
|
|
22
|
-
private _state = ApcState.START;
|
|
23
|
-
private _active = EMPTY_HANDLERS;
|
|
24
|
-
private _id = -1;
|
|
25
22
|
private _handlers: IHandlerCollection<IApcHandler> = Object.create(null);
|
|
23
|
+
private _active = EMPTY_HANDLERS;
|
|
24
|
+
private _ident: number = 0;
|
|
26
25
|
private _handlerFb: ApcFallbackHandlerType = () => { };
|
|
27
26
|
private _stack: ISubParserStackState = {
|
|
28
27
|
paused: false,
|
|
@@ -64,22 +63,24 @@ export class ApcParser implements IApcParser {
|
|
|
64
63
|
}
|
|
65
64
|
|
|
66
65
|
public reset(): void {
|
|
67
|
-
// force cleanup handlers
|
|
68
|
-
if (this.
|
|
66
|
+
// force cleanup handlers
|
|
67
|
+
if (this._active.length) {
|
|
69
68
|
for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {
|
|
70
69
|
this._active[j].end(false);
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
72
|
this._stack.paused = false;
|
|
74
73
|
this._active = EMPTY_HANDLERS;
|
|
75
|
-
this.
|
|
76
|
-
this._state = ApcState.START;
|
|
74
|
+
this._ident = 0;
|
|
77
75
|
}
|
|
78
76
|
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
public start(ident: number): void {
|
|
78
|
+
// always reset leftover handlers
|
|
79
|
+
this.reset();
|
|
80
|
+
this._ident = ident;
|
|
81
|
+
this._active = this._handlers[ident] || EMPTY_HANDLERS;
|
|
81
82
|
if (!this._active.length) {
|
|
82
|
-
this._handlerFb(this.
|
|
83
|
+
this._handlerFb(this._ident, 'START');
|
|
83
84
|
} else {
|
|
84
85
|
for (let j = this._active.length - 1; j >= 0; j--) {
|
|
85
86
|
this._active[j].start();
|
|
@@ -87,9 +88,9 @@ export class ApcParser implements IApcParser {
|
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
90
|
|
|
90
|
-
|
|
91
|
+
public put(data: Uint32Array, start: number, end: number): void {
|
|
91
92
|
if (!this._active.length) {
|
|
92
|
-
this._handlerFb(this.
|
|
93
|
+
this._handlerFb(this._ident, 'PUT', utf32ToString(data, start, end));
|
|
93
94
|
} else {
|
|
94
95
|
for (let j = this._active.length - 1; j >= 0; j--) {
|
|
95
96
|
this._active[j].put(data, start, end);
|
|
@@ -97,100 +98,51 @@ export class ApcParser implements IApcParser {
|
|
|
97
98
|
}
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
public start(): void {
|
|
101
|
-
// always reset leftover handlers
|
|
102
|
-
this.reset();
|
|
103
|
-
this._state = ApcState.ID;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Put data to current APC command.
|
|
108
|
-
* For APC, the first character is used as the identifier.
|
|
109
|
-
* Format: ESC _ <identifier><payload> ESC \
|
|
110
|
-
* Example: ESC _ G f=100,a=T;... ESC \ (Kitty graphics, identifier='G')
|
|
111
|
-
*/
|
|
112
|
-
public put(data: Uint32Array, start: number, end: number): void {
|
|
113
|
-
if (this._state === ApcState.ABORT) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
if (this._state === ApcState.ID) {
|
|
117
|
-
// The first character is the identifier
|
|
118
|
-
if (start < end) {
|
|
119
|
-
this._id = data[start++];
|
|
120
|
-
this._state = ApcState.PAYLOAD;
|
|
121
|
-
this._start();
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
if (this._state === ApcState.PAYLOAD && end - start > 0) {
|
|
125
|
-
this._put(data, start, end);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
101
|
/**
|
|
130
102
|
* Indicates end of an APC command.
|
|
131
103
|
* Whether the APC got aborted or finished normally
|
|
132
104
|
* is indicated by `success`.
|
|
133
105
|
*/
|
|
134
106
|
public end(success: boolean, promiseResult: boolean = true): void | Promise<boolean> {
|
|
135
|
-
if (this.
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
this.
|
|
146
|
-
this._state = ApcState.START;
|
|
147
|
-
return;
|
|
107
|
+
if (!this._active.length) {
|
|
108
|
+
this._handlerFb(this._ident, 'END', success);
|
|
109
|
+
} else {
|
|
110
|
+
let handlerResult: boolean | Promise<boolean> = false;
|
|
111
|
+
let j = this._active.length - 1;
|
|
112
|
+
let fallThrough = false;
|
|
113
|
+
if (this._stack.paused) {
|
|
114
|
+
j = this._stack.loopPosition - 1;
|
|
115
|
+
handlerResult = promiseResult;
|
|
116
|
+
fallThrough = this._stack.fallThrough;
|
|
117
|
+
this._stack.paused = false;
|
|
148
118
|
}
|
|
149
|
-
|
|
150
|
-
if (!this._active.length) {
|
|
151
|
-
this._handlerFb(this._id, 'END', success);
|
|
152
|
-
} else {
|
|
153
|
-
let handlerResult: boolean | Promise<boolean> = false;
|
|
154
|
-
let j = this._active.length - 1;
|
|
155
|
-
let fallThrough = false;
|
|
156
|
-
if (this._stack.paused) {
|
|
157
|
-
j = this._stack.loopPosition - 1;
|
|
158
|
-
handlerResult = promiseResult;
|
|
159
|
-
fallThrough = this._stack.fallThrough;
|
|
160
|
-
this._stack.paused = false;
|
|
161
|
-
}
|
|
162
|
-
if (!fallThrough && handlerResult === false) {
|
|
163
|
-
for (; j >= 0; j--) {
|
|
164
|
-
handlerResult = this._active[j].end(success);
|
|
165
|
-
if (handlerResult === true) {
|
|
166
|
-
break;
|
|
167
|
-
} else if (handlerResult instanceof Promise) {
|
|
168
|
-
this._stack.paused = true;
|
|
169
|
-
this._stack.loopPosition = j;
|
|
170
|
-
this._stack.fallThrough = false;
|
|
171
|
-
return handlerResult;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
j--;
|
|
175
|
-
}
|
|
176
|
-
// cleanup left over handlers
|
|
177
|
-
// we always have to call .end for proper cleanup,
|
|
178
|
-
// here we use `success` to indicate whether a handler should execute
|
|
119
|
+
if (!fallThrough && handlerResult === false) {
|
|
179
120
|
for (; j >= 0; j--) {
|
|
180
|
-
handlerResult = this._active[j].end(
|
|
181
|
-
if (handlerResult
|
|
121
|
+
handlerResult = this._active[j].end(success);
|
|
122
|
+
if (handlerResult === true) {
|
|
123
|
+
break;
|
|
124
|
+
} else if (handlerResult instanceof Promise) {
|
|
182
125
|
this._stack.paused = true;
|
|
183
126
|
this._stack.loopPosition = j;
|
|
184
|
-
this._stack.fallThrough =
|
|
127
|
+
this._stack.fallThrough = false;
|
|
185
128
|
return handlerResult;
|
|
186
129
|
}
|
|
187
130
|
}
|
|
131
|
+
j--;
|
|
132
|
+
}
|
|
133
|
+
// cleanup left over handlers (fallThrough for async)
|
|
134
|
+
for (; j >= 0; j--) {
|
|
135
|
+
handlerResult = this._active[j].end(false);
|
|
136
|
+
if (handlerResult instanceof Promise) {
|
|
137
|
+
this._stack.paused = true;
|
|
138
|
+
this._stack.loopPosition = j;
|
|
139
|
+
this._stack.fallThrough = true;
|
|
140
|
+
return handlerResult;
|
|
141
|
+
}
|
|
188
142
|
}
|
|
189
|
-
|
|
190
143
|
}
|
|
191
144
|
this._active = EMPTY_HANDLERS;
|
|
192
|
-
this.
|
|
193
|
-
this._state = ApcState.START;
|
|
145
|
+
this._ident = 0;
|
|
194
146
|
}
|
|
195
147
|
}
|
|
196
148
|
|
|
@@ -21,9 +21,11 @@ export const enum ParserState {
|
|
|
21
21
|
DCS_IGNORE = 11,
|
|
22
22
|
DCS_INTERMEDIATE = 12,
|
|
23
23
|
DCS_PASSTHROUGH = 13,
|
|
24
|
-
|
|
24
|
+
APC_ENTRY = 14,
|
|
25
|
+
APC_INTERMEDIATE = 15,
|
|
26
|
+
APC_PASSTHROUGH = 16,
|
|
25
27
|
// Number of states, meaning LAST_STATE + 1.
|
|
26
|
-
STATE_LENGTH =
|
|
28
|
+
STATE_LENGTH = 17
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
/**
|
|
@@ -60,16 +62,6 @@ export const enum OscState {
|
|
|
60
62
|
ABORT = 3
|
|
61
63
|
}
|
|
62
64
|
|
|
63
|
-
/**
|
|
64
|
-
* Internal states of ApcParser.
|
|
65
|
-
*/
|
|
66
|
-
export const enum ApcState {
|
|
67
|
-
START = 0,
|
|
68
|
-
ID = 1,
|
|
69
|
-
PAYLOAD = 2,
|
|
70
|
-
ABORT = 3
|
|
71
|
-
}
|
|
72
|
-
|
|
73
65
|
// payload limit for OSC and DCS
|
|
74
66
|
export const enum ParserConstants {
|
|
75
67
|
PAYLOAD_LIMIT = 10000000
|
|
@@ -12,6 +12,24 @@ import { OscParser } from 'common/parser/OscParser';
|
|
|
12
12
|
import { DcsParser } from 'common/parser/DcsParser';
|
|
13
13
|
import { ApcParser } from 'common/parser/ApcParser';
|
|
14
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."
|
|
32
|
+
|
|
15
33
|
/**
|
|
16
34
|
* Table values are generated like this:
|
|
17
35
|
* index: currentState << TableValue.INDEX_STATE_SHIFT | charCode
|
|
@@ -77,7 +95,9 @@ const NON_ASCII_PRINTABLE = 0xA0;
|
|
|
77
95
|
* Taken from https://vt100.net/emu/dec_ansi_parser.
|
|
78
96
|
*/
|
|
79
97
|
export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
|
|
80
|
-
|
|
98
|
+
// table size:
|
|
99
|
+
// (ParserState.STATE_LENGTH - 1) << TableAccess.INDEX_STATE_SHIFT | NON_ASCII_PRINTABLE + 1
|
|
100
|
+
const table: TransitionTable = new TransitionTable(4257);
|
|
81
101
|
|
|
82
102
|
// range macro for byte
|
|
83
103
|
const BYTE_VALUES = 256;
|
|
@@ -105,7 +125,7 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
|
|
|
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
127
|
table.addMany([0x98, 0x9e], state, ParserAction.IGNORE, ParserState.SOS_PM_STRING); // SOS, PM
|
|
108
|
-
table.add(0x9f, state, ParserAction.
|
|
128
|
+
table.add(0x9f, state, ParserAction.CLEAR, ParserState.APC_ENTRY); // APC
|
|
109
129
|
table.add(0x9b, state, ParserAction.CLEAR, ParserState.CSI_ENTRY); // CSI
|
|
110
130
|
table.add(0x90, state, ParserAction.CLEAR, ParserState.DCS_ENTRY); // DCS
|
|
111
131
|
}
|
|
@@ -136,11 +156,20 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
|
|
|
136
156
|
table.add(0x9c, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.GROUND);
|
|
137
157
|
table.add(0x7f, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
|
|
138
158
|
// apc
|
|
139
|
-
table.add(0x5f, ParserState.ESCAPE, ParserAction.
|
|
140
|
-
table.addMany(
|
|
141
|
-
table.
|
|
142
|
-
table.
|
|
143
|
-
table.addMany(
|
|
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);
|
|
144
173
|
// csi entries
|
|
145
174
|
table.add(0x5b, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.CSI_ENTRY);
|
|
146
175
|
table.addMany(r(0x40, 0x7f), ParserState.CSI_ENTRY, ParserAction.CSI_DISPATCH, ParserState.GROUND);
|
|
@@ -169,22 +198,18 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
|
|
|
169
198
|
table.add(0x50, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.DCS_ENTRY);
|
|
170
199
|
table.addMany(EXECUTABLES, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);
|
|
171
200
|
table.add(0x7f, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);
|
|
172
|
-
table.addMany(r(0x1c, 0x20), ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);
|
|
173
201
|
table.addMany(r(0x20, 0x30), ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);
|
|
174
202
|
table.addMany(r(0x30, 0x3c), ParserState.DCS_ENTRY, ParserAction.PARAM, ParserState.DCS_PARAM);
|
|
175
203
|
table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_PARAM);
|
|
176
204
|
table.addMany(EXECUTABLES, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
|
|
177
205
|
table.addMany(r(0x20, 0x80), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
|
|
178
|
-
table.addMany(r(0x1c, 0x20), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
|
|
179
206
|
table.addMany(EXECUTABLES, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);
|
|
180
207
|
table.add(0x7f, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);
|
|
181
|
-
table.addMany(r(0x1c, 0x20), ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);
|
|
182
208
|
table.addMany(r(0x30, 0x3c), ParserState.DCS_PARAM, ParserAction.PARAM, ParserState.DCS_PARAM);
|
|
183
209
|
table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_IGNORE);
|
|
184
210
|
table.addMany(r(0x20, 0x30), ParserState.DCS_PARAM, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);
|
|
185
211
|
table.addMany(EXECUTABLES, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);
|
|
186
212
|
table.add(0x7f, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);
|
|
187
|
-
table.addMany(r(0x1c, 0x20), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);
|
|
188
213
|
table.addMany(r(0x20, 0x30), ParserState.DCS_INTERMEDIATE, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);
|
|
189
214
|
table.addMany(r(0x30, 0x40), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
|
|
190
215
|
table.addMany(r(0x40, 0x7f), ParserState.DCS_INTERMEDIATE, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);
|
|
@@ -200,7 +225,7 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
|
|
|
200
225
|
table.add(NON_ASCII_PRINTABLE, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);
|
|
201
226
|
table.add(NON_ASCII_PRINTABLE, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
|
|
202
227
|
table.add(NON_ASCII_PRINTABLE, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);
|
|
203
|
-
table.add(NON_ASCII_PRINTABLE, ParserState.
|
|
228
|
+
table.add(NON_ASCII_PRINTABLE, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);
|
|
204
229
|
return table;
|
|
205
230
|
})();
|
|
206
231
|
|
|
@@ -439,11 +464,13 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
439
464
|
this._oscParser.setHandlerFallback(handler);
|
|
440
465
|
}
|
|
441
466
|
|
|
442
|
-
public registerApcHandler(
|
|
443
|
-
|
|
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);
|
|
444
470
|
}
|
|
445
|
-
public clearApcHandler(
|
|
446
|
-
|
|
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]));
|
|
447
474
|
}
|
|
448
475
|
public setApcHandlerFallback(handler: ApcFallbackHandlerType): void {
|
|
449
476
|
this._apcParser.setHandlerFallback(handler);
|
|
@@ -719,7 +746,10 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
719
746
|
}
|
|
720
747
|
|
|
721
748
|
// normal transition & action lookup
|
|
722
|
-
transition = this._transitions.table[
|
|
749
|
+
transition = this._transitions.table[
|
|
750
|
+
this.currentState << TableAccess.INDEX_STATE_SHIFT |
|
|
751
|
+
(code < NON_ASCII_PRINTABLE ? code : NON_ASCII_PRINTABLE)
|
|
752
|
+
];
|
|
723
753
|
switch (transition >> TableAccess.TRANSITION_ACTION_SHIFT) {
|
|
724
754
|
case ParserAction.PRINT:
|
|
725
755
|
// Note: 0x20 (SP) is included, 0x7F (DEL) is excluded
|
|
@@ -872,16 +902,18 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
872
902
|
this.precedingJoinState = 0;
|
|
873
903
|
break;
|
|
874
904
|
case ParserAction.APC_START:
|
|
875
|
-
this._apcParser.start();
|
|
905
|
+
this._apcParser.start(this._collect << 8 | code);
|
|
876
906
|
break;
|
|
877
907
|
case ParserAction.APC_PUT:
|
|
878
908
|
// inner loop - exit APC_PUT: 0x18, 0x1a, 0x1b, 0x9c
|
|
909
|
+
// allowed: 00/08 .. 00/13, 02/00 .. 07/14 + NON_ASCII_PRINTABLE
|
|
879
910
|
for (let j = i + 1; ; ++j) {
|
|
880
|
-
if (j
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
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;
|
|
885
917
|
}
|
|
886
918
|
break;
|
|
887
919
|
case ParserAction.APC_END:
|
|
@@ -220,8 +220,8 @@ export interface IEscapeSequenceParser extends IDisposable {
|
|
|
220
220
|
clearOscHandler(ident: number): void;
|
|
221
221
|
setOscHandlerFallback(handler: OscFallbackHandlerType): void;
|
|
222
222
|
|
|
223
|
-
registerApcHandler(
|
|
224
|
-
clearApcHandler(
|
|
223
|
+
registerApcHandler(id: IFunctionIdentifier, handler: IApcHandler): IDisposable;
|
|
224
|
+
clearApcHandler(id: IFunctionIdentifier): void;
|
|
225
225
|
setApcHandlerFallback(handler: ApcFallbackHandlerType): void;
|
|
226
226
|
|
|
227
227
|
setErrorHandler(handler: (state: IParsingState) => IParsingState): void;
|
|
@@ -252,7 +252,7 @@ export interface IDcsParser extends ISubParser<IDcsHandler, DcsFallbackHandlerTy
|
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
export interface IApcParser extends ISubParser<IApcHandler, ApcFallbackHandlerType> {
|
|
255
|
-
start(): void;
|
|
255
|
+
start(ident: number): void;
|
|
256
256
|
end(success: boolean, promiseResult?: boolean): void | Promise<boolean>;
|
|
257
257
|
}
|
|
258
258
|
|
|
@@ -34,7 +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(
|
|
38
|
-
return this._core.registerApcHandler(
|
|
37
|
+
public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise<boolean>): IDisposable {
|
|
38
|
+
return this._core.registerApcHandler(id, callback);
|
|
39
39
|
}
|
|
40
40
|
}
|
package/typings/xterm.d.ts
CHANGED
|
@@ -1909,12 +1909,12 @@ declare module '@xterm/xterm' {
|
|
|
1909
1909
|
prefix?: string;
|
|
1910
1910
|
/**
|
|
1911
1911
|
* Optional intermediate bytes, must be in range \x20 .. \x2f.
|
|
1912
|
-
* Usable in CSI, DCS and
|
|
1912
|
+
* Usable in CSI, DCS, ESC and APC.
|
|
1913
1913
|
*/
|
|
1914
1914
|
intermediates?: string;
|
|
1915
1915
|
/**
|
|
1916
1916
|
* Final byte, must be in range \x40 .. \x7e for CSI and DCS,
|
|
1917
|
-
* \x30 .. \x7e for ESC.
|
|
1917
|
+
* \x30 .. \x7e for ESC and APC.
|
|
1918
1918
|
*/
|
|
1919
1919
|
final: string;
|
|
1920
1920
|
}
|
|
@@ -2002,8 +2002,8 @@ declare module '@xterm/xterm' {
|
|
|
2002
2002
|
|
|
2003
2003
|
/**
|
|
2004
2004
|
* Adds a handler for APC escape sequences.
|
|
2005
|
-
* @param
|
|
2006
|
-
*
|
|
2005
|
+
* @param id Specifies the function identifier under which the callback
|
|
2006
|
+
* gets registered, e.g. {final: 'G'} for Kitty graphics protocol.
|
|
2007
2007
|
* @param callback The function to handle the sequence. Note that the
|
|
2008
2008
|
* function will only be called once if the sequence finished successfully.
|
|
2009
2009
|
* There is currently no way to intercept smaller data chunks, data chunks
|
|
@@ -2016,7 +2016,7 @@ declare module '@xterm/xterm' {
|
|
|
2016
2016
|
* handler. The most recently added handler is tried first.
|
|
2017
2017
|
* @returns An IDisposable you can call to remove this handler.
|
|
2018
2018
|
*/
|
|
2019
|
-
registerApcHandler(
|
|
2019
|
+
registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise<boolean>): IDisposable;
|
|
2020
2020
|
}
|
|
2021
2021
|
|
|
2022
2022
|
/**
|