@gjsify/readline 0.3.12 → 0.3.14

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/esm/index.js CHANGED
@@ -1,631 +1,654 @@
1
1
  import { EventEmitter } from "node:events";
2
2
  import { StringDecoder } from "node:string_decoder";
3
+
4
+ //#region src/index.ts
3
5
  const LINE_END = /\r\n|\r|\n/;
4
- class Interface extends EventEmitter {
5
- terminal;
6
- line = "";
7
- cursor = 0;
8
- _input;
9
- _output;
10
- get input() {
11
- return this._input;
12
- }
13
- get output() {
14
- return this._output;
15
- }
16
- _prompt;
17
- _closed = false;
18
- _paused = false;
19
- history;
20
- _historySize;
21
- _crlfDelay;
22
- _lineBuffer = "";
23
- _questionCallback = null;
24
- // Per-listener refs so close() removes only our listeners, not the keypress
25
- // parser's 'data' listener — which must survive across sequential prompts.
26
- _boundOnData = null;
27
- _boundOnEnd = null;
28
- _boundOnError = null;
29
- _boundOnKeypress = null;
30
- constructor(input, output) {
31
- super();
32
- let opts;
33
- if (input && typeof input === "object" && !("read" in input && typeof input.read === "function")) {
34
- opts = input;
35
- } else {
36
- opts = { input, output };
37
- }
38
- this._input = opts.input || null;
39
- this._output = opts.output || null;
40
- this._prompt = opts.prompt || "> ";
41
- this.terminal = opts.terminal ?? this._output !== null;
42
- this._historySize = opts.historySize ?? 30;
43
- this.history = [];
44
- this._crlfDelay = opts.crlfDelay ?? 100;
45
- if (this._input) {
46
- this._boundOnData = (chunk) => this._onData(chunk);
47
- this._boundOnEnd = () => this._onEnd();
48
- this._boundOnError = (err) => this.emit("error", err);
49
- this._input.on("data", this._boundOnData);
50
- this._input.on("end", this._boundOnEnd);
51
- this._input.on("error", this._boundOnError);
52
- if ("setEncoding" in this._input && typeof this._input.setEncoding === "function") {
53
- this._input.setEncoding("utf8");
54
- }
55
- if (this.terminal) {
56
- emitKeypressEvents(this._input, this);
57
- if ("setRawMode" in this._input && typeof this._input.setRawMode === "function") {
58
- if (!this._input.isRaw) this._input.setRawMode(true);
59
- }
60
- if ("resume" in this._input && typeof this._input.resume === "function") {
61
- this._input.resume();
62
- }
63
- this._boundOnKeypress = (str, key) => {
64
- if (!key) return;
65
- if (key.name === "backspace" || key.name === "delete") {
66
- if (this.cursor > 0) {
67
- this.line = this.line.slice(0, this.cursor - 1) + this.line.slice(this.cursor);
68
- this.cursor--;
69
- }
70
- } else if (str && str.length === 1 && !key.ctrl && !key.meta && key.name !== "return" && key.name !== "enter" && key.name !== "escape") {
71
- this.line = this.line.slice(0, this.cursor) + str + this.line.slice(this.cursor);
72
- this.cursor++;
73
- }
74
- };
75
- this._input.on("keypress", this._boundOnKeypress);
76
- }
77
- }
78
- }
79
- _onData(chunk) {
80
- if (this._closed || this._paused) return;
81
- const str = typeof chunk === "string" ? chunk : chunk.toString("utf8");
82
- this._lineBuffer += str;
83
- let m;
84
- while ((m = LINE_END.exec(this._lineBuffer)) !== null) {
85
- const line = this._lineBuffer.substring(0, m.index);
86
- this._lineBuffer = this._lineBuffer.substring(m.index + m[0].length);
87
- this._onLine(line);
88
- }
89
- }
90
- _onLine(line) {
91
- if (line.length > 0 && this._historySize > 0) {
92
- if (this.history.length === 0 || this.history[0] !== line) {
93
- this.history.unshift(line);
94
- if (this.history.length > this._historySize) this.history.pop();
95
- }
96
- }
97
- if (this._questionCallback) {
98
- const cb = this._questionCallback;
99
- this._questionCallback = null;
100
- cb(line);
101
- }
102
- this.emit("line", line);
103
- }
104
- _onEnd() {
105
- if (this._lineBuffer.length > 0) {
106
- this._onLine(this._lineBuffer);
107
- this._lineBuffer = "";
108
- }
109
- this.close();
110
- }
111
- setPrompt(prompt) {
112
- this._prompt = prompt;
113
- }
114
- getPrompt() {
115
- return this._prompt;
116
- }
117
- prompt(_preserveCursor) {
118
- if (this._closed) throw new Error("readline was closed");
119
- this._output?.write(this._prompt);
120
- }
121
- question(query, optionsOrCallback, callback) {
122
- if (this._closed) throw new Error("readline was closed");
123
- const cb = typeof optionsOrCallback === "function" ? optionsOrCallback : callback;
124
- this._questionCallback = cb;
125
- this._output?.write(query);
126
- }
127
- clearLine(_dir, callback) {
128
- this.line = "";
129
- this.cursor = 0;
130
- if (callback) callback();
131
- return true;
132
- }
133
- write(data, key) {
134
- if (this._closed) return;
135
- if (key) {
136
- if (this._input) this._input.emit("keypress", data ?? "", key);
137
- return;
138
- }
139
- if (data !== null && data !== void 0) {
140
- const str = typeof data === "string" ? data : data.toString("utf8");
141
- if (str) {
142
- this.line = this.line.slice(0, this.cursor) + str + this.line.slice(this.cursor);
143
- this.cursor += str.length;
144
- }
145
- this._output?.write(data);
146
- }
147
- }
148
- close() {
149
- if (this._closed) return;
150
- this._closed = true;
151
- if (this._input) {
152
- if (this._boundOnData) this._input.removeListener("data", this._boundOnData);
153
- if (this._boundOnEnd) this._input.removeListener("end", this._boundOnEnd);
154
- if (this._boundOnError) this._input.removeListener("error", this._boundOnError);
155
- if (this._boundOnKeypress) this._input.removeListener("keypress", this._boundOnKeypress);
156
- this._boundOnData = null;
157
- this._boundOnEnd = null;
158
- this._boundOnError = null;
159
- this._boundOnKeypress = null;
160
- if (this.terminal && this._input.isRaw && "setRawMode" in this._input && typeof this._input.setRawMode === "function") {
161
- this._input.setRawMode(false);
162
- }
163
- if ("pause" in this._input && typeof this._input.pause === "function") {
164
- this._input.pause();
165
- }
166
- }
167
- this.emit("close");
168
- }
169
- pause() {
170
- if (this._closed) return this;
171
- this._paused = true;
172
- if (this._input && "pause" in this._input && typeof this._input.pause === "function") {
173
- this._input.pause();
174
- }
175
- this.emit("pause");
176
- return this;
177
- }
178
- resume() {
179
- if (this._closed) return this;
180
- this._paused = false;
181
- if (this._input && "resume" in this._input && typeof this._input.resume === "function") {
182
- this._input.resume();
183
- }
184
- this.emit("resume");
185
- return this;
186
- }
187
- getCursorPos() {
188
- const columns = this._output?.columns ?? 80;
189
- const len = this._prompt.length + this.cursor;
190
- return { rows: Math.floor(len / columns), cols: len % columns };
191
- }
192
- [Symbol.asyncIterator]() {
193
- const lines = [];
194
- let resolve = null;
195
- let done = false;
196
- const onLine = (line) => {
197
- if (resolve) {
198
- const r = resolve;
199
- resolve = null;
200
- r({ value: line, done: false });
201
- } else {
202
- lines.push(line);
203
- }
204
- };
205
- const onClose = () => {
206
- done = true;
207
- if (resolve) {
208
- const r = resolve;
209
- resolve = null;
210
- r({ value: void 0, done: true });
211
- }
212
- };
213
- this.on("line", onLine);
214
- this.on("close", onClose);
215
- return {
216
- next: () => {
217
- if (lines.length > 0) return Promise.resolve({ value: lines.shift(), done: false });
218
- if (done) return Promise.resolve({ value: void 0, done: true });
219
- return new Promise((r) => {
220
- resolve = r;
221
- });
222
- },
223
- return: () => {
224
- done = true;
225
- this.removeListener("line", onLine);
226
- this.removeListener("close", onClose);
227
- return Promise.resolve({ value: void 0, done: true });
228
- },
229
- [Symbol.asyncIterator]() {
230
- return this;
231
- }
232
- };
233
- }
234
- }
6
+ var Interface = class extends EventEmitter {
7
+ terminal;
8
+ line = "";
9
+ cursor = 0;
10
+ _input;
11
+ _output;
12
+ get input() {
13
+ return this._input;
14
+ }
15
+ get output() {
16
+ return this._output;
17
+ }
18
+ _prompt;
19
+ _closed = false;
20
+ _paused = false;
21
+ history;
22
+ _historySize;
23
+ _crlfDelay;
24
+ _lineBuffer = "";
25
+ _questionCallback = null;
26
+ _boundOnData = null;
27
+ _boundOnEnd = null;
28
+ _boundOnError = null;
29
+ _boundOnKeypress = null;
30
+ constructor(input, output) {
31
+ super();
32
+ let opts;
33
+ if (input && typeof input === "object" && !("read" in input && typeof input.read === "function")) {
34
+ opts = input;
35
+ } else {
36
+ opts = {
37
+ input,
38
+ output
39
+ };
40
+ }
41
+ this._input = opts.input || null;
42
+ this._output = opts.output || null;
43
+ this._prompt = opts.prompt || "> ";
44
+ this.terminal = opts.terminal ?? this._output !== null;
45
+ this._historySize = opts.historySize ?? 30;
46
+ this.history = [];
47
+ this._crlfDelay = opts.crlfDelay ?? 100;
48
+ if (this._input) {
49
+ this._boundOnData = (chunk) => this._onData(chunk);
50
+ this._boundOnEnd = () => this._onEnd();
51
+ this._boundOnError = (err) => this.emit("error", err);
52
+ this._input.on("data", this._boundOnData);
53
+ this._input.on("end", this._boundOnEnd);
54
+ this._input.on("error", this._boundOnError);
55
+ if ("setEncoding" in this._input && typeof this._input.setEncoding === "function") {
56
+ this._input.setEncoding("utf8");
57
+ }
58
+ if (this.terminal) {
59
+ emitKeypressEvents(this._input, this);
60
+ if ("setRawMode" in this._input && typeof this._input.setRawMode === "function") {
61
+ if (!this._input.isRaw) this._input.setRawMode(true);
62
+ }
63
+ if ("resume" in this._input && typeof this._input.resume === "function") {
64
+ this._input.resume();
65
+ }
66
+ this._boundOnKeypress = (str, key) => {
67
+ if (!key) return;
68
+ if (key.name === "backspace" || key.name === "delete") {
69
+ if (this.cursor > 0) {
70
+ this.line = this.line.slice(0, this.cursor - 1) + this.line.slice(this.cursor);
71
+ this.cursor--;
72
+ }
73
+ } else if (str && str.length === 1 && !key.ctrl && !key.meta && key.name !== "return" && key.name !== "enter" && key.name !== "escape") {
74
+ this.line = this.line.slice(0, this.cursor) + str + this.line.slice(this.cursor);
75
+ this.cursor++;
76
+ }
77
+ };
78
+ this._input.on("keypress", this._boundOnKeypress);
79
+ }
80
+ }
81
+ }
82
+ _onData(chunk) {
83
+ if (this._closed || this._paused) return;
84
+ const str = typeof chunk === "string" ? chunk : chunk.toString("utf8");
85
+ this._lineBuffer += str;
86
+ let m;
87
+ while ((m = LINE_END.exec(this._lineBuffer)) !== null) {
88
+ const line = this._lineBuffer.substring(0, m.index);
89
+ this._lineBuffer = this._lineBuffer.substring(m.index + m[0].length);
90
+ this._onLine(line);
91
+ }
92
+ }
93
+ _onLine(line) {
94
+ if (line.length > 0 && this._historySize > 0) {
95
+ if (this.history.length === 0 || this.history[0] !== line) {
96
+ this.history.unshift(line);
97
+ if (this.history.length > this._historySize) this.history.pop();
98
+ }
99
+ }
100
+ if (this._questionCallback) {
101
+ const cb = this._questionCallback;
102
+ this._questionCallback = null;
103
+ cb(line);
104
+ }
105
+ this.emit("line", line);
106
+ }
107
+ _onEnd() {
108
+ if (this._lineBuffer.length > 0) {
109
+ this._onLine(this._lineBuffer);
110
+ this._lineBuffer = "";
111
+ }
112
+ this.close();
113
+ }
114
+ setPrompt(prompt) {
115
+ this._prompt = prompt;
116
+ }
117
+ getPrompt() {
118
+ return this._prompt;
119
+ }
120
+ prompt(_preserveCursor) {
121
+ if (this._closed) throw new Error("readline was closed");
122
+ this._output?.write(this._prompt);
123
+ }
124
+ question(query, optionsOrCallback, callback) {
125
+ if (this._closed) throw new Error("readline was closed");
126
+ const cb = typeof optionsOrCallback === "function" ? optionsOrCallback : callback;
127
+ this._questionCallback = cb;
128
+ this._output?.write(query);
129
+ }
130
+ clearLine(_dir, callback) {
131
+ this.line = "";
132
+ this.cursor = 0;
133
+ if (callback) callback();
134
+ return true;
135
+ }
136
+ write(data, key) {
137
+ if (this._closed) return;
138
+ if (key) {
139
+ if (this._input) this._input.emit("keypress", data ?? "", key);
140
+ return;
141
+ }
142
+ if (data !== null && data !== undefined) {
143
+ const str = typeof data === "string" ? data : data.toString("utf8");
144
+ if (str) {
145
+ this.line = this.line.slice(0, this.cursor) + str + this.line.slice(this.cursor);
146
+ this.cursor += str.length;
147
+ }
148
+ this._output?.write(data);
149
+ }
150
+ }
151
+ close() {
152
+ if (this._closed) return;
153
+ this._closed = true;
154
+ if (this._input) {
155
+ if (this._boundOnData) this._input.removeListener("data", this._boundOnData);
156
+ if (this._boundOnEnd) this._input.removeListener("end", this._boundOnEnd);
157
+ if (this._boundOnError) this._input.removeListener("error", this._boundOnError);
158
+ if (this._boundOnKeypress) this._input.removeListener("keypress", this._boundOnKeypress);
159
+ this._boundOnData = null;
160
+ this._boundOnEnd = null;
161
+ this._boundOnError = null;
162
+ this._boundOnKeypress = null;
163
+ if (this.terminal && this._input.isRaw && "setRawMode" in this._input && typeof this._input.setRawMode === "function") {
164
+ this._input.setRawMode(false);
165
+ }
166
+ if ("pause" in this._input && typeof this._input.pause === "function") {
167
+ this._input.pause();
168
+ }
169
+ }
170
+ this.emit("close");
171
+ }
172
+ pause() {
173
+ if (this._closed) return this;
174
+ this._paused = true;
175
+ if (this._input && "pause" in this._input && typeof this._input.pause === "function") {
176
+ this._input.pause();
177
+ }
178
+ this.emit("pause");
179
+ return this;
180
+ }
181
+ resume() {
182
+ if (this._closed) return this;
183
+ this._paused = false;
184
+ if (this._input && "resume" in this._input && typeof this._input.resume === "function") {
185
+ this._input.resume();
186
+ }
187
+ this.emit("resume");
188
+ return this;
189
+ }
190
+ getCursorPos() {
191
+ const columns = this._output?.columns ?? 80;
192
+ const len = this._prompt.length + this.cursor;
193
+ return {
194
+ rows: Math.floor(len / columns),
195
+ cols: len % columns
196
+ };
197
+ }
198
+ [Symbol.asyncIterator]() {
199
+ const lines = [];
200
+ let resolve = null;
201
+ let done = false;
202
+ const onLine = (line) => {
203
+ if (resolve) {
204
+ const r = resolve;
205
+ resolve = null;
206
+ r({
207
+ value: line,
208
+ done: false
209
+ });
210
+ } else {
211
+ lines.push(line);
212
+ }
213
+ };
214
+ const onClose = () => {
215
+ done = true;
216
+ if (resolve) {
217
+ const r = resolve;
218
+ resolve = null;
219
+ r({
220
+ value: undefined,
221
+ done: true
222
+ });
223
+ }
224
+ };
225
+ this.on("line", onLine);
226
+ this.on("close", onClose);
227
+ return {
228
+ next: () => {
229
+ if (lines.length > 0) return Promise.resolve({
230
+ value: lines.shift(),
231
+ done: false
232
+ });
233
+ if (done) return Promise.resolve({
234
+ value: undefined,
235
+ done: true
236
+ });
237
+ return new Promise((r) => {
238
+ resolve = r;
239
+ });
240
+ },
241
+ return: () => {
242
+ done = true;
243
+ this.removeListener("line", onLine);
244
+ this.removeListener("close", onClose);
245
+ return Promise.resolve({
246
+ value: undefined,
247
+ done: true
248
+ });
249
+ },
250
+ [Symbol.asyncIterator]() {
251
+ return this;
252
+ }
253
+ };
254
+ }
255
+ };
235
256
  function createInterface(input, output, completer, terminal) {
236
- if (typeof input === "object" && input !== null && !("read" in input && typeof input.read === "function")) {
237
- return new Interface(input);
238
- }
239
- return new Interface({ input, output, completer, terminal });
257
+ if (typeof input === "object" && input !== null && !("read" in input && typeof input.read === "function")) {
258
+ return new Interface(input);
259
+ }
260
+ return new Interface({
261
+ input,
262
+ output,
263
+ completer,
264
+ terminal
265
+ });
240
266
  }
241
267
  function clearLine(stream, dir, callback) {
242
- if (!stream || typeof stream.write !== "function") {
243
- if (callback) callback();
244
- return true;
245
- }
246
- const code = dir < 0 ? "\x1B[1K" : dir > 0 ? "\x1B[0K" : "\x1B[2K";
247
- return stream.write(code, callback);
268
+ if (!stream || typeof stream.write !== "function") {
269
+ if (callback) callback();
270
+ return true;
271
+ }
272
+ const code = dir < 0 ? "\x1B[1K" : dir > 0 ? "\x1B[0K" : "\x1B[2K";
273
+ return stream.write(code, callback);
248
274
  }
249
275
  function clearScreenDown(stream, callback) {
250
- if (!stream || typeof stream.write !== "function") {
251
- if (callback) callback();
252
- return true;
253
- }
254
- return stream.write("\x1B[0J", callback);
276
+ if (!stream || typeof stream.write !== "function") {
277
+ if (callback) callback();
278
+ return true;
279
+ }
280
+ return stream.write("\x1B[0J", callback);
255
281
  }
256
282
  function cursorTo(stream, x, y, callback) {
257
- if (!stream || typeof stream.write !== "function") {
258
- if (typeof y === "function") y();
259
- else if (callback) callback();
260
- return true;
261
- }
262
- if (typeof y === "function") {
263
- callback = y;
264
- y = void 0;
265
- }
266
- const code = typeof y === "number" ? `\x1B[${y + 1};${x + 1}H` : `\x1B[${x + 1}G`;
267
- return stream.write(code, callback);
283
+ if (!stream || typeof stream.write !== "function") {
284
+ if (typeof y === "function") y();
285
+ else if (callback) callback();
286
+ return true;
287
+ }
288
+ if (typeof y === "function") {
289
+ callback = y;
290
+ y = undefined;
291
+ }
292
+ const code = typeof y === "number" ? `\x1b[${y + 1};${x + 1}H` : `\x1b[${x + 1}G`;
293
+ return stream.write(code, callback);
268
294
  }
269
295
  function moveCursor(stream, dx, dy, callback) {
270
- if (!stream || typeof stream.write !== "function") {
271
- if (callback) callback();
272
- return true;
273
- }
274
- let code = "";
275
- if (dx > 0) code += `\x1B[${dx}C`;
276
- else if (dx < 0) code += `\x1B[${-dx}D`;
277
- if (dy > 0) code += `\x1B[${dy}B`;
278
- else if (dy < 0) code += `\x1B[${-dy}A`;
279
- if (code) return stream.write(code, callback);
280
- if (callback) callback();
281
- return true;
296
+ if (!stream || typeof stream.write !== "function") {
297
+ if (callback) callback();
298
+ return true;
299
+ }
300
+ let code = "";
301
+ if (dx > 0) code += `\x1b[${dx}C`;
302
+ else if (dx < 0) code += `\x1b[${-dx}D`;
303
+ if (dy > 0) code += `\x1b[${dy}B`;
304
+ else if (dy < 0) code += `\x1b[${-dy}A`;
305
+ if (code) return stream.write(code, callback);
306
+ if (callback) callback();
307
+ return true;
282
308
  }
283
309
  const ESCAPE_CODE_TIMEOUT = 500;
284
310
  function* emitKeys(stream) {
285
- while (true) {
286
- let ch = yield;
287
- let s = ch;
288
- let escaped = false;
289
- const key = { sequence: "", name: void 0, ctrl: false, meta: false, shift: false };
290
- if (ch === "\x1B") {
291
- escaped = true;
292
- s += ch = yield;
293
- if (ch === "\x1B") s += ch = yield;
294
- }
295
- if (escaped && (ch === "O" || ch === "[")) {
296
- let code = ch;
297
- let modifier = 0;
298
- if (ch === "O") {
299
- s += ch = yield;
300
- if (ch >= "0" && ch <= "9") {
301
- modifier = ch.charCodeAt(0) - 1;
302
- s += ch = yield;
303
- }
304
- code += ch;
305
- } else if (ch === "[") {
306
- s += ch = yield;
307
- if (ch === "[") {
308
- code += ch;
309
- s += ch = yield;
310
- }
311
- const cmdStart = s.length - 1;
312
- if (ch >= "0" && ch <= "9") {
313
- s += ch = yield;
314
- if (ch >= "0" && ch <= "9") {
315
- s += ch = yield;
316
- if (ch >= "0" && ch <= "9") s += ch = yield;
317
- }
318
- }
319
- if (ch === ";") {
320
- s += ch = yield;
321
- if (ch >= "0" && ch <= "9") s += yield;
322
- }
323
- const cmd = s.slice(cmdStart);
324
- let match;
325
- if (match = /^(?:(\d\d?)(?:;(\d))?([~^$])|(\d{3}~))$/.exec(cmd)) {
326
- if (match[4]) {
327
- code += match[4];
328
- } else {
329
- code += match[1] + match[3];
330
- modifier = (parseInt(match[2] ?? "1", 10) || 1) - 1;
331
- }
332
- } else if (match = /^((\d;)?(\d))?([A-Za-z])$/.exec(cmd)) {
333
- code += match[4];
334
- modifier = (parseInt(match[3] ?? "1", 10) || 1) - 1;
335
- } else {
336
- code += cmd;
337
- }
338
- }
339
- key.ctrl = !!(modifier & 4);
340
- key.meta = !!(modifier & 10);
341
- key.shift = !!(modifier & 1);
342
- key.code = code;
343
- switch (code) {
344
- case "[P":
345
- case "OP":
346
- case "[11~":
347
- case "[[A":
348
- key.name = "f1";
349
- break;
350
- case "[Q":
351
- case "OQ":
352
- case "[12~":
353
- case "[[B":
354
- key.name = "f2";
355
- break;
356
- case "[R":
357
- case "OR":
358
- case "[13~":
359
- case "[[C":
360
- key.name = "f3";
361
- break;
362
- case "[S":
363
- case "OS":
364
- case "[14~":
365
- case "[[D":
366
- key.name = "f4";
367
- break;
368
- case "[15~":
369
- case "[[E":
370
- key.name = "f5";
371
- break;
372
- case "[17~":
373
- key.name = "f6";
374
- break;
375
- case "[18~":
376
- key.name = "f7";
377
- break;
378
- case "[19~":
379
- key.name = "f8";
380
- break;
381
- case "[20~":
382
- key.name = "f9";
383
- break;
384
- case "[21~":
385
- key.name = "f10";
386
- break;
387
- case "[23~":
388
- key.name = "f11";
389
- break;
390
- case "[24~":
391
- key.name = "f12";
392
- break;
393
- case "[200~":
394
- key.name = "paste-start";
395
- break;
396
- case "[201~":
397
- key.name = "paste-end";
398
- break;
399
- case "[A":
400
- case "OA":
401
- key.name = "up";
402
- break;
403
- case "[B":
404
- case "OB":
405
- key.name = "down";
406
- break;
407
- case "[C":
408
- case "OC":
409
- key.name = "right";
410
- break;
411
- case "[D":
412
- case "OD":
413
- key.name = "left";
414
- break;
415
- case "[E":
416
- case "OE":
417
- key.name = "clear";
418
- break;
419
- case "[F":
420
- case "OF":
421
- key.name = "end";
422
- break;
423
- case "[H":
424
- case "OH":
425
- key.name = "home";
426
- break;
427
- case "[1~":
428
- key.name = "home";
429
- break;
430
- case "[2~":
431
- key.name = "insert";
432
- break;
433
- case "[3~":
434
- key.name = "delete";
435
- break;
436
- case "[4~":
437
- key.name = "end";
438
- break;
439
- case "[5~":
440
- case "[[5~":
441
- key.name = "pageup";
442
- break;
443
- case "[6~":
444
- case "[[6~":
445
- key.name = "pagedown";
446
- break;
447
- case "[7~":
448
- key.name = "home";
449
- break;
450
- case "[8~":
451
- key.name = "end";
452
- break;
453
- case "[a":
454
- key.name = "up";
455
- key.shift = true;
456
- break;
457
- case "[b":
458
- key.name = "down";
459
- key.shift = true;
460
- break;
461
- case "[c":
462
- key.name = "right";
463
- key.shift = true;
464
- break;
465
- case "[d":
466
- key.name = "left";
467
- key.shift = true;
468
- break;
469
- case "[2$":
470
- key.name = "insert";
471
- key.shift = true;
472
- break;
473
- case "[3$":
474
- key.name = "delete";
475
- key.shift = true;
476
- break;
477
- case "[5$":
478
- key.name = "pageup";
479
- key.shift = true;
480
- break;
481
- case "[6$":
482
- key.name = "pagedown";
483
- key.shift = true;
484
- break;
485
- case "[7$":
486
- key.name = "home";
487
- key.shift = true;
488
- break;
489
- case "[8$":
490
- key.name = "end";
491
- key.shift = true;
492
- break;
493
- case "Oa":
494
- key.name = "up";
495
- key.ctrl = true;
496
- break;
497
- case "Ob":
498
- key.name = "down";
499
- key.ctrl = true;
500
- break;
501
- case "Oc":
502
- key.name = "right";
503
- key.ctrl = true;
504
- break;
505
- case "Od":
506
- key.name = "left";
507
- key.ctrl = true;
508
- break;
509
- case "[2^":
510
- key.name = "insert";
511
- key.ctrl = true;
512
- break;
513
- case "[3^":
514
- key.name = "delete";
515
- key.ctrl = true;
516
- break;
517
- case "[5^":
518
- key.name = "pageup";
519
- key.ctrl = true;
520
- break;
521
- case "[6^":
522
- key.name = "pagedown";
523
- key.ctrl = true;
524
- break;
525
- case "[7^":
526
- key.name = "home";
527
- key.ctrl = true;
528
- break;
529
- case "[8^":
530
- key.name = "end";
531
- key.ctrl = true;
532
- break;
533
- case "[Z":
534
- key.name = "tab";
535
- key.shift = true;
536
- break;
537
- default:
538
- key.name = "undefined";
539
- break;
540
- }
541
- } else if (ch === "\r") {
542
- key.name = "return";
543
- key.meta = escaped;
544
- } else if (ch === "\n") {
545
- key.name = "enter";
546
- key.meta = escaped;
547
- } else if (ch === " ") {
548
- key.name = "tab";
549
- key.meta = escaped;
550
- } else if (ch === "\b" || ch === "\x7F") {
551
- key.name = "backspace";
552
- key.meta = escaped;
553
- } else if (ch === "\x1B") {
554
- key.name = "escape";
555
- key.meta = escaped;
556
- } else if (ch === " ") {
557
- key.name = "space";
558
- key.meta = escaped;
559
- } else if (!escaped && ch <= "") {
560
- key.name = String.fromCharCode(ch.charCodeAt(0) + "a".charCodeAt(0) - 1);
561
- key.ctrl = true;
562
- } else if (/^[0-9A-Za-z]$/.test(ch)) {
563
- key.name = ch.toLowerCase();
564
- key.shift = /^[A-Z]$/.test(ch);
565
- key.meta = escaped;
566
- } else if (escaped) {
567
- key.name = ch.length ? void 0 : "escape";
568
- key.meta = true;
569
- }
570
- key.sequence = s;
571
- if (s.length !== 0 && (key.name !== void 0 || escaped)) {
572
- stream.emit("keypress", escaped ? void 0 : s, key);
573
- } else if (s.length === 1) {
574
- stream.emit("keypress", s, key);
575
- }
576
- }
311
+ while (true) {
312
+ let ch = yield;
313
+ let s = ch;
314
+ let escaped = false;
315
+ const key = {
316
+ sequence: "",
317
+ name: undefined,
318
+ ctrl: false,
319
+ meta: false,
320
+ shift: false
321
+ };
322
+ if (ch === "\x1B") {
323
+ escaped = true;
324
+ s += ch = yield;
325
+ if (ch === "\x1B") s += ch = yield;
326
+ }
327
+ if (escaped && (ch === "O" || ch === "[")) {
328
+ let code = ch;
329
+ let modifier = 0;
330
+ if (ch === "O") {
331
+ s += ch = yield;
332
+ if (ch >= "0" && ch <= "9") {
333
+ modifier = ch.charCodeAt(0) - 1;
334
+ s += ch = yield;
335
+ }
336
+ code += ch;
337
+ } else if (ch === "[") {
338
+ s += ch = yield;
339
+ if (ch === "[") {
340
+ code += ch;
341
+ s += ch = yield;
342
+ }
343
+ const cmdStart = s.length - 1;
344
+ if (ch >= "0" && ch <= "9") {
345
+ s += ch = yield;
346
+ if (ch >= "0" && ch <= "9") {
347
+ s += ch = yield;
348
+ if (ch >= "0" && ch <= "9") s += ch = yield;
349
+ }
350
+ }
351
+ if (ch === ";") {
352
+ s += ch = yield;
353
+ if (ch >= "0" && ch <= "9") s += yield;
354
+ }
355
+ const cmd = s.slice(cmdStart);
356
+ let match;
357
+ if (match = /^(?:(\d\d?)(?:;(\d))?([~^$])|(\d{3}~))$/.exec(cmd)) {
358
+ if (match[4]) {
359
+ code += match[4];
360
+ } else {
361
+ code += match[1] + match[3];
362
+ modifier = (parseInt(match[2] ?? "1", 10) || 1) - 1;
363
+ }
364
+ } else if (match = /^((\d;)?(\d))?([A-Za-z])$/.exec(cmd)) {
365
+ code += match[4];
366
+ modifier = (parseInt(match[3] ?? "1", 10) || 1) - 1;
367
+ } else {
368
+ code += cmd;
369
+ }
370
+ }
371
+ key.ctrl = !!(modifier & 4);
372
+ key.meta = !!(modifier & 10);
373
+ key.shift = !!(modifier & 1);
374
+ key.code = code;
375
+ switch (code) {
376
+ case "[P":
377
+ case "OP":
378
+ case "[11~":
379
+ case "[[A":
380
+ key.name = "f1";
381
+ break;
382
+ case "[Q":
383
+ case "OQ":
384
+ case "[12~":
385
+ case "[[B":
386
+ key.name = "f2";
387
+ break;
388
+ case "[R":
389
+ case "OR":
390
+ case "[13~":
391
+ case "[[C":
392
+ key.name = "f3";
393
+ break;
394
+ case "[S":
395
+ case "OS":
396
+ case "[14~":
397
+ case "[[D":
398
+ key.name = "f4";
399
+ break;
400
+ case "[15~":
401
+ case "[[E":
402
+ key.name = "f5";
403
+ break;
404
+ case "[17~":
405
+ key.name = "f6";
406
+ break;
407
+ case "[18~":
408
+ key.name = "f7";
409
+ break;
410
+ case "[19~":
411
+ key.name = "f8";
412
+ break;
413
+ case "[20~":
414
+ key.name = "f9";
415
+ break;
416
+ case "[21~":
417
+ key.name = "f10";
418
+ break;
419
+ case "[23~":
420
+ key.name = "f11";
421
+ break;
422
+ case "[24~":
423
+ key.name = "f12";
424
+ break;
425
+ case "[200~":
426
+ key.name = "paste-start";
427
+ break;
428
+ case "[201~":
429
+ key.name = "paste-end";
430
+ break;
431
+ case "[A":
432
+ case "OA":
433
+ key.name = "up";
434
+ break;
435
+ case "[B":
436
+ case "OB":
437
+ key.name = "down";
438
+ break;
439
+ case "[C":
440
+ case "OC":
441
+ key.name = "right";
442
+ break;
443
+ case "[D":
444
+ case "OD":
445
+ key.name = "left";
446
+ break;
447
+ case "[E":
448
+ case "OE":
449
+ key.name = "clear";
450
+ break;
451
+ case "[F":
452
+ case "OF":
453
+ key.name = "end";
454
+ break;
455
+ case "[H":
456
+ case "OH":
457
+ key.name = "home";
458
+ break;
459
+ case "[1~":
460
+ key.name = "home";
461
+ break;
462
+ case "[2~":
463
+ key.name = "insert";
464
+ break;
465
+ case "[3~":
466
+ key.name = "delete";
467
+ break;
468
+ case "[4~":
469
+ key.name = "end";
470
+ break;
471
+ case "[5~":
472
+ case "[[5~":
473
+ key.name = "pageup";
474
+ break;
475
+ case "[6~":
476
+ case "[[6~":
477
+ key.name = "pagedown";
478
+ break;
479
+ case "[7~":
480
+ key.name = "home";
481
+ break;
482
+ case "[8~":
483
+ key.name = "end";
484
+ break;
485
+ case "[a":
486
+ key.name = "up";
487
+ key.shift = true;
488
+ break;
489
+ case "[b":
490
+ key.name = "down";
491
+ key.shift = true;
492
+ break;
493
+ case "[c":
494
+ key.name = "right";
495
+ key.shift = true;
496
+ break;
497
+ case "[d":
498
+ key.name = "left";
499
+ key.shift = true;
500
+ break;
501
+ case "[2$":
502
+ key.name = "insert";
503
+ key.shift = true;
504
+ break;
505
+ case "[3$":
506
+ key.name = "delete";
507
+ key.shift = true;
508
+ break;
509
+ case "[5$":
510
+ key.name = "pageup";
511
+ key.shift = true;
512
+ break;
513
+ case "[6$":
514
+ key.name = "pagedown";
515
+ key.shift = true;
516
+ break;
517
+ case "[7$":
518
+ key.name = "home";
519
+ key.shift = true;
520
+ break;
521
+ case "[8$":
522
+ key.name = "end";
523
+ key.shift = true;
524
+ break;
525
+ case "Oa":
526
+ key.name = "up";
527
+ key.ctrl = true;
528
+ break;
529
+ case "Ob":
530
+ key.name = "down";
531
+ key.ctrl = true;
532
+ break;
533
+ case "Oc":
534
+ key.name = "right";
535
+ key.ctrl = true;
536
+ break;
537
+ case "Od":
538
+ key.name = "left";
539
+ key.ctrl = true;
540
+ break;
541
+ case "[2^":
542
+ key.name = "insert";
543
+ key.ctrl = true;
544
+ break;
545
+ case "[3^":
546
+ key.name = "delete";
547
+ key.ctrl = true;
548
+ break;
549
+ case "[5^":
550
+ key.name = "pageup";
551
+ key.ctrl = true;
552
+ break;
553
+ case "[6^":
554
+ key.name = "pagedown";
555
+ key.ctrl = true;
556
+ break;
557
+ case "[7^":
558
+ key.name = "home";
559
+ key.ctrl = true;
560
+ break;
561
+ case "[8^":
562
+ key.name = "end";
563
+ key.ctrl = true;
564
+ break;
565
+ case "[Z":
566
+ key.name = "tab";
567
+ key.shift = true;
568
+ break;
569
+ default:
570
+ key.name = "undefined";
571
+ break;
572
+ }
573
+ } else if (ch === "\r") {
574
+ key.name = "return";
575
+ key.meta = escaped;
576
+ } else if (ch === "\n") {
577
+ key.name = "enter";
578
+ key.meta = escaped;
579
+ } else if (ch === " ") {
580
+ key.name = "tab";
581
+ key.meta = escaped;
582
+ } else if (ch === "\b" || ch === "") {
583
+ key.name = "backspace";
584
+ key.meta = escaped;
585
+ } else if (ch === "\x1B") {
586
+ key.name = "escape";
587
+ key.meta = escaped;
588
+ } else if (ch === " ") {
589
+ key.name = "space";
590
+ key.meta = escaped;
591
+ } else if (!escaped && ch <= "") {
592
+ key.name = String.fromCharCode(ch.charCodeAt(0) + "a".charCodeAt(0) - 1);
593
+ key.ctrl = true;
594
+ } else if (/^[0-9A-Za-z]$/.test(ch)) {
595
+ key.name = ch.toLowerCase();
596
+ key.shift = /^[A-Z]$/.test(ch);
597
+ key.meta = escaped;
598
+ } else if (escaped) {
599
+ key.name = ch.length ? undefined : "escape";
600
+ key.meta = true;
601
+ }
602
+ key.sequence = s;
603
+ if (s.length !== 0 && (key.name !== undefined || escaped)) {
604
+ stream.emit("keypress", escaped ? undefined : s, key);
605
+ } else if (s.length === 1) {
606
+ stream.emit("keypress", s, key);
607
+ }
608
+ }
577
609
  }
578
- const _KEYPRESS_DECODER = /* @__PURE__ */ Symbol("keypress-decoder");
579
- const _ESCAPE_DECODER = /* @__PURE__ */ Symbol("escape-decoder");
610
+ const _KEYPRESS_DECODER = Symbol("keypress-decoder");
611
+ const _ESCAPE_DECODER = Symbol("escape-decoder");
580
612
  function emitKeypressEvents(stream, iface = {}) {
581
- if (stream[_KEYPRESS_DECODER]) return;
582
- stream[_KEYPRESS_DECODER] = new StringDecoder("utf8");
583
- stream[_ESCAPE_DECODER] = emitKeys(stream);
584
- stream[_ESCAPE_DECODER].next();
585
- const escTimeout = iface.escapeCodeTimeout ?? ESCAPE_CODE_TIMEOUT;
586
- let timeoutId;
587
- const triggerEscape = () => stream[_ESCAPE_DECODER].next("");
588
- function onData(input) {
589
- if (stream.listenerCount("keypress") > 0) {
590
- const str = stream[_KEYPRESS_DECODER].write(
591
- typeof input === "string" ? Buffer.from(input) : input
592
- );
593
- if (str) {
594
- clearTimeout(timeoutId);
595
- for (const ch of str) {
596
- try {
597
- stream[_ESCAPE_DECODER].next(ch);
598
- if (ch === "\x1B") timeoutId = setTimeout(triggerEscape, escTimeout);
599
- } catch {
600
- stream[_ESCAPE_DECODER] = emitKeys(stream);
601
- stream[_ESCAPE_DECODER].next();
602
- }
603
- }
604
- }
605
- } else {
606
- stream.removeListener("data", onData);
607
- delete stream[_KEYPRESS_DECODER];
608
- delete stream[_ESCAPE_DECODER];
609
- }
610
- }
611
- stream.on("data", onData);
613
+ if (stream[_KEYPRESS_DECODER]) return;
614
+ stream[_KEYPRESS_DECODER] = new StringDecoder("utf8");
615
+ stream[_ESCAPE_DECODER] = emitKeys(stream);
616
+ stream[_ESCAPE_DECODER].next();
617
+ const escTimeout = iface.escapeCodeTimeout ?? ESCAPE_CODE_TIMEOUT;
618
+ let timeoutId;
619
+ const triggerEscape = () => stream[_ESCAPE_DECODER].next("");
620
+ function onData(input) {
621
+ if (stream.listenerCount("keypress") > 0) {
622
+ const str = stream[_KEYPRESS_DECODER].write(typeof input === "string" ? Buffer.from(input) : input);
623
+ if (str) {
624
+ clearTimeout(timeoutId);
625
+ for (const ch of str) {
626
+ try {
627
+ stream[_ESCAPE_DECODER].next(ch);
628
+ if (ch === "\x1B") timeoutId = setTimeout(triggerEscape, escTimeout);
629
+ } catch {
630
+ stream[_ESCAPE_DECODER] = emitKeys(stream);
631
+ stream[_ESCAPE_DECODER].next();
632
+ }
633
+ }
634
+ }
635
+ } else {
636
+ stream.removeListener("data", onData);
637
+ delete stream[_KEYPRESS_DECODER];
638
+ delete stream[_ESCAPE_DECODER];
639
+ }
640
+ }
641
+ stream.on("data", onData);
612
642
  }
613
- var index_default = {
614
- Interface,
615
- createInterface,
616
- clearLine,
617
- clearScreenDown,
618
- cursorTo,
619
- moveCursor,
620
- emitKeypressEvents
621
- };
622
- export {
623
- Interface,
624
- clearLine,
625
- clearScreenDown,
626
- createInterface,
627
- cursorTo,
628
- index_default as default,
629
- emitKeypressEvents,
630
- moveCursor
643
+ var src_default = {
644
+ Interface,
645
+ createInterface,
646
+ clearLine,
647
+ clearScreenDown,
648
+ cursorTo,
649
+ moveCursor,
650
+ emitKeypressEvents
631
651
  };
652
+
653
+ //#endregion
654
+ export { Interface, clearLine, clearScreenDown, createInterface, cursorTo, src_default as default, emitKeypressEvents, moveCursor };