poly-weaver 0.10.6 → 0.11.0
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/README.md +16 -24
- package/dist/agents/runner.d.ts.map +1 -1
- package/dist/agents/runner.js +6 -1
- package/dist/agents/runner.js.map +1 -1
- package/dist/ansi.d.ts +23 -4
- package/dist/ansi.d.ts.map +1 -1
- package/dist/ansi.js +28 -5
- package/dist/ansi.js.map +1 -1
- package/dist/dump/hotkey.d.ts +0 -3
- package/dist/dump/hotkey.d.ts.map +1 -1
- package/dist/dump/hotkey.js +0 -3
- package/dist/dump/hotkey.js.map +1 -1
- package/dist/offscreen/controller.d.ts +4 -1
- package/dist/offscreen/controller.d.ts.map +1 -1
- package/dist/offscreen/controller.js +48 -3
- package/dist/offscreen/controller.js.map +1 -1
- package/dist/offscreen/fork-launch.d.ts +1 -0
- package/dist/offscreen/fork-launch.d.ts.map +1 -1
- package/dist/offscreen/fork-launch.js +4 -0
- package/dist/offscreen/fork-launch.js.map +1 -1
- package/dist/offscreen/fork.d.ts +6 -1
- package/dist/offscreen/fork.d.ts.map +1 -1
- package/dist/offscreen/fork.js +26 -3
- package/dist/offscreen/fork.js.map +1 -1
- package/dist/offscreen/surface.d.ts.map +1 -1
- package/dist/offscreen/surface.js +6 -2
- package/dist/offscreen/surface.js.map +1 -1
- package/dist/providers/claude/strategy.d.ts +6 -0
- package/dist/providers/claude/strategy.d.ts.map +1 -1
- package/dist/providers/claude/strategy.js +2 -0
- package/dist/providers/claude/strategy.js.map +1 -1
- package/dist/providers/codex/strategy.d.ts +1 -0
- package/dist/providers/codex/strategy.d.ts.map +1 -1
- package/dist/providers/codex/strategy.js +7 -1
- package/dist/providers/codex/strategy.js.map +1 -1
- package/dist/providers/types.d.ts +2 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/session/process-start-time.d.ts.map +1 -1
- package/dist/session/process-start-time.js.map +1 -1
- package/dist/status-bar.d.ts +7 -0
- package/dist/status-bar.d.ts.map +1 -1
- package/dist/status-bar.js +34 -6
- package/dist/status-bar.js.map +1 -1
- package/dist/terminal/host-input-mode.d.ts +4 -0
- package/dist/terminal/host-input-mode.d.ts.map +1 -0
- package/dist/terminal/host-input-mode.js +33 -0
- package/dist/terminal/host-input-mode.js.map +1 -0
- package/dist/terminal/host.d.ts +41 -16
- package/dist/terminal/host.d.ts.map +1 -1
- package/dist/terminal/host.js +197 -64
- package/dist/terminal/host.js.map +1 -1
- package/dist/terminal/input-router.d.ts +18 -3
- package/dist/terminal/input-router.d.ts.map +1 -1
- package/dist/terminal/input-router.js +35 -6
- package/dist/terminal/input-router.js.map +1 -1
- package/dist/terminal/key-event-source.d.ts +6 -15
- package/dist/terminal/key-event-source.d.ts.map +1 -1
- package/dist/terminal/key-event-source.js +3 -22
- package/dist/terminal/key-event-source.js.map +1 -1
- package/dist/terminal/key-to-bytes.d.ts +2 -0
- package/dist/terminal/key-to-bytes.d.ts.map +1 -1
- package/dist/terminal/key-to-bytes.js +89 -13
- package/dist/terminal/key-to-bytes.js.map +1 -1
- package/dist/terminal/kitty-negotiator.d.ts +9 -0
- package/dist/terminal/kitty-negotiator.d.ts.map +1 -0
- package/dist/terminal/kitty-negotiator.js +76 -0
- package/dist/terminal/kitty-negotiator.js.map +1 -0
- package/dist/terminal/koffi-loader.d.ts +1 -5
- package/dist/terminal/koffi-loader.d.ts.map +1 -1
- package/dist/terminal/koffi-loader.js.map +1 -1
- package/dist/terminal/mouse-mode-tracker.d.ts +36 -0
- package/dist/terminal/mouse-mode-tracker.d.ts.map +1 -0
- package/dist/terminal/mouse-mode-tracker.js +245 -0
- package/dist/terminal/mouse-mode-tracker.js.map +1 -0
- package/dist/terminal/osc52.d.ts +16 -0
- package/dist/terminal/osc52.d.ts.map +1 -0
- package/dist/terminal/osc52.js +18 -0
- package/dist/terminal/osc52.js.map +1 -0
- package/dist/terminal/render.d.ts +14 -14
- package/dist/terminal/render.d.ts.map +1 -1
- package/dist/terminal/render.js +20 -28
- package/dist/terminal/render.js.map +1 -1
- package/dist/terminal/stdin-byte-source.d.ts +4 -5
- package/dist/terminal/stdin-byte-source.d.ts.map +1 -1
- package/dist/terminal/stdin-byte-source.js +11 -13
- package/dist/terminal/stdin-byte-source.js.map +1 -1
- package/dist/terminal/virtual-terminal.d.ts +9 -1
- package/dist/terminal/virtual-terminal.d.ts.map +1 -1
- package/dist/terminal/virtual-terminal.js +33 -1
- package/dist/terminal/virtual-terminal.js.map +1 -1
- package/dist/terminal-input.d.ts +13 -12
- package/dist/terminal-input.d.ts.map +1 -1
- package/dist/terminal-input.js +82 -108
- package/dist/terminal-input.js.map +1 -1
- package/dist/text-editing/emacs-input.d.ts +1 -6
- package/dist/text-editing/emacs-input.d.ts.map +1 -1
- package/dist/text-editing/emacs-input.js +15 -6
- package/dist/text-editing/emacs-input.js.map +1 -1
- package/dist/text-editing/readline-ops.d.ts.map +1 -1
- package/dist/text-editing/readline-ops.js +11 -2
- package/dist/text-editing/readline-ops.js.map +1 -1
- package/package.json +4 -1
- package/dist/terminal/win32-console-mode.d.ts +0 -23
- package/dist/terminal/win32-console-mode.d.ts.map +0 -1
- package/dist/terminal/win32-console-mode.js +0 -67
- package/dist/terminal/win32-console-mode.js.map +0 -1
- package/dist/terminal/win32-console-source.d.ts +0 -26
- package/dist/terminal/win32-console-source.d.ts.map +0 -1
- package/dist/terminal/win32-console-source.js +0 -277
- package/dist/terminal/win32-console-source.js.map +0 -1
- package/dist/terminal/win32-key-translator.d.ts +0 -26
- package/dist/terminal/win32-key-translator.d.ts.map +0 -1
- package/dist/terminal/win32-key-translator.js +0 -109
- package/dist/terminal/win32-key-translator.js.map +0 -1
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { type TerminalKey } from "../terminal-input.js";
|
|
2
2
|
import type { KeyEventSource, ResizeSize } from "./key-event-source.js";
|
|
3
3
|
/**
|
|
4
|
-
* Default `KeyEventSource
|
|
5
|
-
*
|
|
6
|
-
* its injected stdin.
|
|
4
|
+
* Default `KeyEventSource`. Owns raw-mode on its injected stdin and
|
|
5
|
+
* optional VT input-mode negotiation on its injected stdout.
|
|
7
6
|
*
|
|
8
7
|
* Internally drives a `TerminalKeyParser`; consumers only see the
|
|
9
8
|
* structured `TerminalKey[]` stream — the byte-level parser is no
|
|
@@ -11,13 +10,13 @@ import type { KeyEventSource, ResizeSize } from "./key-event-source.js";
|
|
|
11
10
|
*/
|
|
12
11
|
export declare class StdinByteSource implements KeyEventSource {
|
|
13
12
|
private readonly stdin;
|
|
13
|
+
private readonly out;
|
|
14
14
|
private readonly parser;
|
|
15
15
|
private readonly subscribers;
|
|
16
16
|
private dataListener;
|
|
17
|
-
private vtInputGuard;
|
|
18
17
|
private prevRawMode;
|
|
19
18
|
private started;
|
|
20
|
-
constructor(stdin: NodeJS.ReadStream);
|
|
19
|
+
constructor(stdin: NodeJS.ReadStream, out?: NodeJS.WritableStream);
|
|
21
20
|
start(): void;
|
|
22
21
|
stop(): void;
|
|
23
22
|
onEvents(cb: (events: TerminalKey[]) => void): () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdin-byte-source.d.ts","sourceRoot":"","sources":["../../src/terminal/stdin-byte-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"stdin-byte-source.d.ts","sourceRoot":"","sources":["../../src/terminal/stdin-byte-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExE;;;;;;;GAOG;AACH,qBAAa,eAAgB,YAAW,cAAc;IAQlD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG;IARtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8C;IAC1E,OAAO,CAAC,YAAY,CAAwC;IAC5D,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAS;gBAGL,KAAK,EAAE,MAAM,CAAC,UAAU,EACxB,GAAG,GAAE,MAAM,CAAC,cAA+B;IAM9D,KAAK,IAAI,IAAI;IAkBb,IAAI,IAAI,IAAI;IAiBZ,QAAQ,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,IAAI,GAAG,MAAM,IAAI;IAKzD,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI;IAOrD,OAAO,CAAC,MAAM;CAcf"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { TerminalKeyParser, } from "../terminal-input.js";
|
|
2
|
-
import {
|
|
2
|
+
import { disableHostInputModes, enableHostInputModes } from "./host-input-mode.js";
|
|
3
3
|
/**
|
|
4
|
-
* Default `KeyEventSource
|
|
5
|
-
*
|
|
6
|
-
* its injected stdin.
|
|
4
|
+
* Default `KeyEventSource`. Owns raw-mode on its injected stdin and
|
|
5
|
+
* optional VT input-mode negotiation on its injected stdout.
|
|
7
6
|
*
|
|
8
7
|
* Internally drives a `TerminalKeyParser`; consumers only see the
|
|
9
8
|
* structured `TerminalKey[]` stream — the byte-level parser is no
|
|
@@ -11,14 +10,15 @@ import { enableVtInputOnStdin, } from "./win32-console-mode.js";
|
|
|
11
10
|
*/
|
|
12
11
|
export class StdinByteSource {
|
|
13
12
|
stdin;
|
|
13
|
+
out;
|
|
14
14
|
parser;
|
|
15
15
|
subscribers = new Set();
|
|
16
16
|
dataListener;
|
|
17
|
-
vtInputGuard = null;
|
|
18
17
|
prevRawMode = false;
|
|
19
18
|
started = false;
|
|
20
|
-
constructor(stdin) {
|
|
19
|
+
constructor(stdin, out = process.stdout) {
|
|
21
20
|
this.stdin = stdin;
|
|
21
|
+
this.out = out;
|
|
22
22
|
this.parser = new TerminalKeyParser();
|
|
23
23
|
this.parser.onDeferredKeys((keys) => this.fanOut(keys));
|
|
24
24
|
}
|
|
@@ -29,7 +29,7 @@ export class StdinByteSource {
|
|
|
29
29
|
if (this.stdin.isTTY) {
|
|
30
30
|
this.prevRawMode = this.stdin.isRaw === true;
|
|
31
31
|
this.stdin.setRawMode(true);
|
|
32
|
-
this.
|
|
32
|
+
enableHostInputModes(this.out);
|
|
33
33
|
this.stdin.resume();
|
|
34
34
|
}
|
|
35
35
|
this.dataListener = (chunk) => {
|
|
@@ -48,9 +48,8 @@ export class StdinByteSource {
|
|
|
48
48
|
this.dataListener = undefined;
|
|
49
49
|
}
|
|
50
50
|
this.parser.cancelPendingEscape();
|
|
51
|
-
this.vtInputGuard?.restore();
|
|
52
|
-
this.vtInputGuard = null;
|
|
53
51
|
if (this.stdin.isTTY) {
|
|
52
|
+
disableHostInputModes(this.out);
|
|
54
53
|
try {
|
|
55
54
|
this.stdin.setRawMode(this.prevRawMode);
|
|
56
55
|
}
|
|
@@ -62,10 +61,9 @@ export class StdinByteSource {
|
|
|
62
61
|
return () => { this.subscribers.delete(cb); };
|
|
63
62
|
}
|
|
64
63
|
onResize(_cb) {
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
// signal separately, so this source has nothing to deliver here.
|
|
64
|
+
// libuv refreshes stdout.columns/stdout.rows and fires the stdout
|
|
65
|
+
// "resize" event. The host listens for that signal separately, so
|
|
66
|
+
// this source has nothing to deliver here.
|
|
69
67
|
return () => { };
|
|
70
68
|
}
|
|
71
69
|
fanOut(events) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdin-byte-source.js","sourceRoot":"","sources":["../../src/terminal/stdin-byte-source.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,GAElB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,
|
|
1
|
+
{"version":3,"file":"stdin-byte-source.js","sourceRoot":"","sources":["../../src/terminal/stdin-byte-source.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,GAElB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGnF;;;;;;;GAOG;AACH,MAAM,OAAO,eAAe;IAQP;IACA;IARF,MAAM,CAAoB;IAC1B,WAAW,GAAG,IAAI,GAAG,EAAmC,CAAC;IAClE,YAAY,CAAwC;IACpD,WAAW,GAAG,KAAK,CAAC;IACpB,OAAO,GAAG,KAAK,CAAC;IAExB,YACmB,KAAwB,EACxB,MAA6B,OAAO,CAAC,MAAM;QAD3C,UAAK,GAAL,KAAK,CAAmB;QACxB,QAAG,GAAH,GAAG,CAAwC;QAE5D,IAAI,CAAC,MAAM,GAAG,IAAI,iBAAiB,EAAE,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC;YAC7C,IAAI,CAAC,KAAK,CAAC,UAAW,CAAC,IAAI,CAAC,CAAC;YAC7B,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QACtB,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,CAAC,KAAa,EAAE,EAAE;YACpC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAC7C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;gBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7C,CAAC,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI;QACF,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC1B,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QAErB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YACrD,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACrB,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,CAAC;gBACH,IAAI,CAAC,KAAK,CAAC,UAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC3C,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,EAAmC;QAC1C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzB,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,QAAQ,CAAC,GAA+B;QACtC,kEAAkE;QAClE,kEAAkE;QAClE,2CAA2C;QAC3C,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;IAClB,CAAC;IAEO,MAAM,CAAC,MAAqB;QAClC,mEAAmE;QACnE,qEAAqE;QACrE,sEAAsE;QACtE,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC9B,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC9C,IAAI,CAAC;oBAAC,EAAE,CAAC,MAAM,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,2DAA2D,CAAC,CAAC;YAC3F,CAAC;YACD,OAAO;QACT,CAAC;QACD,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAClC,IAAI,CAAC;gBAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,2DAA2D,CAAC,CAAC;QAC3F,CAAC;IACH,CAAC;CACF"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { IBuffer, IBufferCell } from "@xterm/headless";
|
|
2
|
+
export interface VirtualTerminalOptions {
|
|
3
|
+
onOscClipboard?: (data: string) => void;
|
|
4
|
+
}
|
|
2
5
|
/**
|
|
3
6
|
* Wraps `@xterm/headless` so the rest of the host doesn't need to
|
|
4
7
|
* know xterm-specific details. Owns:
|
|
@@ -18,7 +21,8 @@ import type { IBuffer, IBufferCell } from "@xterm/headless";
|
|
|
18
21
|
*/
|
|
19
22
|
export declare class VirtualTerminal {
|
|
20
23
|
private readonly term;
|
|
21
|
-
|
|
24
|
+
private cursorVisibleState;
|
|
25
|
+
constructor(cols: number, rows: number, opts?: VirtualTerminalOptions);
|
|
22
26
|
write(data: string | Uint8Array, callback?: () => void): void;
|
|
23
27
|
resize(cols: number, rows: number): void;
|
|
24
28
|
get cols(): number;
|
|
@@ -31,6 +35,10 @@ export declare class VirtualTerminal {
|
|
|
31
35
|
get cursorY(): number;
|
|
32
36
|
/** True when the alternate buffer is active. */
|
|
33
37
|
get isAlternate(): boolean;
|
|
38
|
+
/** True when the child enabled bracketed paste mode (`CSI ? 2004 h`). */
|
|
39
|
+
get bracketedPaste(): boolean;
|
|
40
|
+
/** True unless the child hid the cursor via DECTCEM (`CSI ?25l`). Default: true. */
|
|
41
|
+
get cursorVisible(): boolean;
|
|
34
42
|
/** Viewport top row index in scrollback coordinates. */
|
|
35
43
|
get viewportY(): number;
|
|
36
44
|
/** Buffer base Y — the row where the live tail begins. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtual-terminal.d.ts","sourceRoot":"","sources":["../../src/terminal/virtual-terminal.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAA6B,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"virtual-terminal.d.ts","sourceRoot":"","sources":["../../src/terminal/virtual-terminal.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAA6B,MAAM,iBAAiB,CAAC;AAKvF,MAAM,WAAW,sBAAsB;IACrC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,kBAAkB,CAAQ;gBAEtB,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,sBAA2B;IAkCzE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI;IAQ7D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIxC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,0DAA0D;IAC1D,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,8CAA8C;IAC9C,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,8CAA8C;IAC9C,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,gDAAgD;IAChD,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,yEAAyE;IACzE,IAAI,cAAc,IAAI,OAAO,CAE5B;IAED,oFAAoF;IACpF,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,wDAAwD;IACxD,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,0DAA0D;IAC1D,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,gFAAgF;IAChF,IAAI,cAAc,IAAI,OAAO,CAE5B;IAED,2DAA2D;IAC3D,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK/B,8DAA8D;IAC9D,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKlC,8EAA8E;IAC9E,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKpC,uDAAuD;IACvD,WAAW,IAAI,IAAI;IAInB,mDAAmD;IACnD,cAAc,IAAI,IAAI;IAItB,oFAAoF;IACpF,OAAO,IAAI,WAAW;IAItB,OAAO,IAAI,IAAI;CAGhB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import xtermHeadless from "@xterm/headless";
|
|
2
|
+
import { parseOsc52 } from "./osc52.js";
|
|
2
3
|
const { Terminal } = xtermHeadless;
|
|
3
4
|
/**
|
|
4
5
|
* Wraps `@xterm/headless` so the rest of the host doesn't need to
|
|
@@ -19,7 +20,8 @@ const { Terminal } = xtermHeadless;
|
|
|
19
20
|
*/
|
|
20
21
|
export class VirtualTerminal {
|
|
21
22
|
term;
|
|
22
|
-
|
|
23
|
+
cursorVisibleState = true;
|
|
24
|
+
constructor(cols, rows, opts = {}) {
|
|
23
25
|
this.term = new Terminal({
|
|
24
26
|
cols: Math.max(1, cols),
|
|
25
27
|
rows: Math.max(1, rows),
|
|
@@ -27,6 +29,28 @@ export class VirtualTerminal {
|
|
|
27
29
|
// Large enough for typical tool output without bloat.
|
|
28
30
|
scrollback: 1000,
|
|
29
31
|
});
|
|
32
|
+
this.term.parser.registerCsiHandler({ prefix: "?", final: "h" }, (params) => {
|
|
33
|
+
if (params.some((p) => p === 25 || (Array.isArray(p) && p[0] === 25))) {
|
|
34
|
+
this.cursorVisibleState = true;
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
});
|
|
38
|
+
this.term.parser.registerCsiHandler({ prefix: "?", final: "l" }, (params) => {
|
|
39
|
+
if (params.some((p) => p === 25 || (Array.isArray(p) && p[0] === 25))) {
|
|
40
|
+
this.cursorVisibleState = false;
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
});
|
|
44
|
+
const onOscClipboard = opts.onOscClipboard;
|
|
45
|
+
if (onOscClipboard) {
|
|
46
|
+
this.term.parser.registerOscHandler(52, (data) => {
|
|
47
|
+
const parsed = parseOsc52(data);
|
|
48
|
+
if (parsed.kind === "set" || parsed.kind === "clear") {
|
|
49
|
+
onOscClipboard(data);
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
30
54
|
}
|
|
31
55
|
write(data, callback) {
|
|
32
56
|
if (callback) {
|
|
@@ -61,6 +85,14 @@ export class VirtualTerminal {
|
|
|
61
85
|
get isAlternate() {
|
|
62
86
|
return this.term.buffer.active.type === "alternate";
|
|
63
87
|
}
|
|
88
|
+
/** True when the child enabled bracketed paste mode (`CSI ? 2004 h`). */
|
|
89
|
+
get bracketedPaste() {
|
|
90
|
+
return this.term.modes.bracketedPasteMode;
|
|
91
|
+
}
|
|
92
|
+
/** True unless the child hid the cursor via DECTCEM (`CSI ?25l`). Default: true. */
|
|
93
|
+
get cursorVisible() {
|
|
94
|
+
return this.cursorVisibleState;
|
|
95
|
+
}
|
|
64
96
|
/** Viewport top row index in scrollback coordinates. */
|
|
65
97
|
get viewportY() {
|
|
66
98
|
return this.buffer.viewportY;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtual-terminal.js","sourceRoot":"","sources":["../../src/terminal/virtual-terminal.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"virtual-terminal.js","sourceRoot":"","sources":["../../src/terminal/virtual-terminal.ts"],"names":[],"mappings":"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"}
|
package/dist/terminal-input.d.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
export type TerminalKey = {
|
|
13
13
|
kind: "printable";
|
|
14
14
|
char: string;
|
|
15
|
-
source: "plain" | "kitty-u"
|
|
15
|
+
source: "plain" | "kitty-u";
|
|
16
16
|
} | {
|
|
17
17
|
kind: "control";
|
|
18
18
|
byte: number;
|
|
@@ -29,6 +29,7 @@ export type TerminalKey = {
|
|
|
29
29
|
} | {
|
|
30
30
|
kind: "arrow";
|
|
31
31
|
direction: "up" | "down" | "left" | "right";
|
|
32
|
+
modifiers?: number;
|
|
32
33
|
} | {
|
|
33
34
|
kind: "page";
|
|
34
35
|
direction: "up" | "down";
|
|
@@ -45,6 +46,9 @@ export type TerminalKey = {
|
|
|
45
46
|
kind: "kitty-key";
|
|
46
47
|
keyCode: number;
|
|
47
48
|
modifiers: number;
|
|
49
|
+
} | {
|
|
50
|
+
kind: "paste";
|
|
51
|
+
content: string;
|
|
48
52
|
} | {
|
|
49
53
|
kind: "raw";
|
|
50
54
|
bytes: Buffer;
|
|
@@ -53,10 +57,13 @@ export declare class TerminalKeyParser {
|
|
|
53
57
|
private readonly escapeTimeoutMs;
|
|
54
58
|
private state;
|
|
55
59
|
private csiParams;
|
|
60
|
+
private legacyMouseBytes;
|
|
56
61
|
private escapeTimer;
|
|
57
62
|
private deferredCallback;
|
|
58
63
|
private utf8Buffer;
|
|
59
64
|
private utf8Expected;
|
|
65
|
+
private pasteBuffer;
|
|
66
|
+
private pasteEndMatch;
|
|
60
67
|
constructor(escapeTimeoutMs?: number);
|
|
61
68
|
onDeferredKeys(cb: (keys: TerminalKey[]) => void): void;
|
|
62
69
|
cancelPendingEscape(): void;
|
|
@@ -64,17 +71,11 @@ export declare class TerminalKeyParser {
|
|
|
64
71
|
private dispatch;
|
|
65
72
|
private handleSs3;
|
|
66
73
|
private handleCsi;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
* This path never returns `unrecognized`. The byte-stream Win32-input-mode
|
|
73
|
-
* frames come from a structured source (Windows Terminal forwarding console
|
|
74
|
-
* input through ConPTY), so every recognized shape we don't act on is a
|
|
75
|
-
* protocol artifact that should be dropped, not forwarded as `raw`.
|
|
76
|
-
*/
|
|
77
|
-
private handleWin32Input;
|
|
74
|
+
private arrow;
|
|
75
|
+
private arrowFromModifiers;
|
|
76
|
+
private consumePasteByte;
|
|
77
|
+
private appendPasteByte;
|
|
78
|
+
private flushPaste;
|
|
78
79
|
private parseKittyEventType;
|
|
79
80
|
}
|
|
80
81
|
//# sourceMappingURL=terminal-input.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-input.d.ts","sourceRoot":"","sources":["../src/terminal-input.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"terminal-input.d.ts","sourceRoot":"","sources":["../src/terminal-input.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAClF;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,IAAI,GAAG,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GACf;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,IAAI,GAAG,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAkBnC,qBAAa,iBAAiB;IAY1B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAXlC,OAAO,CAAC,KAAK,CAAwE;IACrF,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,WAAW,CAA4C;IAC/D,OAAO,CAAC,gBAAgB,CAA8C;IACtE,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,aAAa,CAAK;gBAGP,eAAe,SAAK;IAGvC,cAAc,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,IAAI,GAAG,IAAI;IAIvD,mBAAmB,IAAI,IAAI;IAO3B,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE;IA2HxC,OAAO,CAAC,QAAQ;IAqBhB,OAAO,CAAC,SAAS;IAejB,OAAO,CAAC,SAAS;IA4IjB,OAAO,CAAC,KAAK;IASb,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,gBAAgB;IAuBxB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,mBAAmB;CAM5B"}
|
package/dist/terminal-input.js
CHANGED
|
@@ -9,8 +9,12 @@
|
|
|
9
9
|
* event types. EmacsInputParser is the shared readline-style mapper for
|
|
10
10
|
* prompt and TUI text-editing surfaces.
|
|
11
11
|
*/
|
|
12
|
+
import { PASTE_END } from "./ansi.js";
|
|
12
13
|
const SUPPRESSED = { tag: "suppressed" };
|
|
13
14
|
const UNRECOGNIZED = { tag: "unrecognized" };
|
|
15
|
+
const START_PASTE = { tag: "start-paste" };
|
|
16
|
+
const PASTE_END_BYTES = Buffer.from(PASTE_END, "ascii");
|
|
17
|
+
const MAX_PASTE_BYTES = 4 * 1024 * 1024;
|
|
14
18
|
function keys(...k) {
|
|
15
19
|
return { tag: "keys", keys: k };
|
|
16
20
|
}
|
|
@@ -18,10 +22,13 @@ export class TerminalKeyParser {
|
|
|
18
22
|
escapeTimeoutMs;
|
|
19
23
|
state = "normal";
|
|
20
24
|
csiParams = "";
|
|
25
|
+
legacyMouseBytes = [];
|
|
21
26
|
escapeTimer;
|
|
22
27
|
deferredCallback;
|
|
23
28
|
utf8Buffer = [];
|
|
24
29
|
utf8Expected = 0;
|
|
30
|
+
pasteBuffer = null;
|
|
31
|
+
pasteEndMatch = 0;
|
|
25
32
|
constructor(escapeTimeoutMs = 50) {
|
|
26
33
|
this.escapeTimeoutMs = escapeTimeoutMs;
|
|
27
34
|
}
|
|
@@ -37,6 +44,10 @@ export class TerminalKeyParser {
|
|
|
37
44
|
parseChunk(chunk) {
|
|
38
45
|
const out = [];
|
|
39
46
|
for (const byte of chunk) {
|
|
47
|
+
if (this.pasteBuffer !== null) {
|
|
48
|
+
this.consumePasteByte(byte, out);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
40
51
|
switch (this.state) {
|
|
41
52
|
case "normal":
|
|
42
53
|
if (byte === 0x1b) {
|
|
@@ -85,6 +96,11 @@ export class TerminalKeyParser {
|
|
|
85
96
|
case "csi": {
|
|
86
97
|
if (byte >= 0x40 && byte <= 0x7e) {
|
|
87
98
|
const params = this.csiParams;
|
|
99
|
+
if (params === "" && byte === 0x4d) {
|
|
100
|
+
this.state = "legacy-mouse";
|
|
101
|
+
this.legacyMouseBytes = [0x1b, 0x5b, byte];
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
88
104
|
const result = this.handleCsi(params, String.fromCharCode(byte));
|
|
89
105
|
this.state = "normal";
|
|
90
106
|
this.dispatch(out, result, () => {
|
|
@@ -103,6 +119,14 @@ export class TerminalKeyParser {
|
|
|
103
119
|
}
|
|
104
120
|
break;
|
|
105
121
|
}
|
|
122
|
+
case "legacy-mouse":
|
|
123
|
+
this.legacyMouseBytes.push(byte);
|
|
124
|
+
if (this.legacyMouseBytes.length === 6) {
|
|
125
|
+
out.push({ kind: "raw", bytes: Buffer.from(this.legacyMouseBytes) });
|
|
126
|
+
this.legacyMouseBytes = [];
|
|
127
|
+
this.state = "normal";
|
|
128
|
+
}
|
|
129
|
+
break;
|
|
106
130
|
case "ss3": {
|
|
107
131
|
const result = this.handleSs3(byte);
|
|
108
132
|
this.state = "normal";
|
|
@@ -147,6 +171,10 @@ export class TerminalKeyParser {
|
|
|
147
171
|
for (const k of result.keys)
|
|
148
172
|
out.push(k);
|
|
149
173
|
return;
|
|
174
|
+
case "start-paste":
|
|
175
|
+
this.pasteBuffer = [];
|
|
176
|
+
this.pasteEndMatch = 0;
|
|
177
|
+
return;
|
|
150
178
|
case "suppressed":
|
|
151
179
|
return;
|
|
152
180
|
case "unrecognized":
|
|
@@ -171,13 +199,13 @@ export class TerminalKeyParser {
|
|
|
171
199
|
handleCsi(params, finalByte) {
|
|
172
200
|
// Standard arrow keys: CSI A/B/C/D (with optional params like "1;1")
|
|
173
201
|
if (finalByte === "A")
|
|
174
|
-
return keys(
|
|
202
|
+
return keys(this.arrow("up", params));
|
|
175
203
|
if (finalByte === "B")
|
|
176
|
-
return keys(
|
|
204
|
+
return keys(this.arrow("down", params));
|
|
177
205
|
if (finalByte === "C")
|
|
178
|
-
return keys(
|
|
206
|
+
return keys(this.arrow("right", params));
|
|
179
207
|
if (finalByte === "D")
|
|
180
|
-
return keys(
|
|
208
|
+
return keys(this.arrow("left", params));
|
|
181
209
|
// CSI Z: standard Shift+Tab — normalize to Kitty protocol representation
|
|
182
210
|
if (finalByte === "Z")
|
|
183
211
|
return keys({ kind: "kitty-key", keyCode: 9, modifiers: 2 });
|
|
@@ -187,6 +215,8 @@ export class TerminalKeyParser {
|
|
|
187
215
|
const code = parseInt(parts[0] ?? "", 10) || 0;
|
|
188
216
|
const modifiers = parseInt(parts[1] ?? "1", 10) || 1;
|
|
189
217
|
switch (code) {
|
|
218
|
+
case 200:
|
|
219
|
+
return START_PASTE;
|
|
190
220
|
case 3:
|
|
191
221
|
return keys({ kind: "delete", ctrl: ((modifiers - 1) & 0x04) !== 0 });
|
|
192
222
|
case 5: return keys({ kind: "page", direction: "up" });
|
|
@@ -206,7 +236,8 @@ export class TerminalKeyParser {
|
|
|
206
236
|
// Wheel events: Cb=64 (up) / Cb=65 (down) — surface as `wheel`
|
|
207
237
|
// only when x/y are usable 1-based coordinates.
|
|
208
238
|
// Non-wheel SGR mouse (clicks, motion, releases) → `unrecognized` so
|
|
209
|
-
//
|
|
239
|
+
// routing boundaries can decide whether to forward or drop the raw frame
|
|
240
|
+
// based on the current input owner.
|
|
210
241
|
if (params.startsWith("<") && (finalByte === "M" || finalByte === "m")) {
|
|
211
242
|
const parts = params.slice(1).split(";");
|
|
212
243
|
const cb = parseInteger(parts[0]);
|
|
@@ -224,14 +255,10 @@ export class TerminalKeyParser {
|
|
|
224
255
|
}
|
|
225
256
|
return UNRECOGNIZED;
|
|
226
257
|
}
|
|
227
|
-
if (finalByte !== "u"
|
|
258
|
+
if (finalByte !== "u") {
|
|
228
259
|
return UNRECOGNIZED;
|
|
229
260
|
}
|
|
230
261
|
const parts = params.split(";");
|
|
231
|
-
// Win32-input-mode: CSI Vk;Sc;Uc;Kd;Cs;Rc _ (6 fields, finalByte '_')
|
|
232
|
-
if (finalByte === "_" && parts.length === 6) {
|
|
233
|
-
return this.handleWin32Input(parts);
|
|
234
|
-
}
|
|
235
262
|
const keyCode = parseInt(parts[0]?.split(":")[0] ?? "", 10) || 0;
|
|
236
263
|
const modifiers = parseInt(parts[1]?.split(":")[0] ?? "1", 10) || 1;
|
|
237
264
|
const eventType = this.parseKittyEventType(parts[1]);
|
|
@@ -284,28 +311,13 @@ export class TerminalKeyParser {
|
|
|
284
311
|
case 57348: // Delete
|
|
285
312
|
return keys({ kind: "delete", ctrl: ((modifiers - 1) & 0x04) !== 0 });
|
|
286
313
|
case 57350: // Left
|
|
287
|
-
return keys(
|
|
314
|
+
return keys(this.arrowFromModifiers("left", modifiers));
|
|
288
315
|
case 57351: // Right
|
|
289
|
-
return keys(
|
|
316
|
+
return keys(this.arrowFromModifiers("right", modifiers));
|
|
290
317
|
case 57352: // Up
|
|
291
|
-
return keys(
|
|
318
|
+
return keys(this.arrowFromModifiers("up", modifiers));
|
|
292
319
|
case 57353: // Down
|
|
293
|
-
return keys(
|
|
294
|
-
}
|
|
295
|
-
// Kitty text event (_): extract codepoints
|
|
296
|
-
if (finalByte === "_" && parts.length >= 3) {
|
|
297
|
-
const cps = parts[2]
|
|
298
|
-
.split(":")
|
|
299
|
-
.map(Number)
|
|
300
|
-
.filter((cp) => cp >= 32);
|
|
301
|
-
return {
|
|
302
|
-
tag: "keys",
|
|
303
|
-
keys: cps.map((cp) => ({
|
|
304
|
-
kind: "printable",
|
|
305
|
-
char: String.fromCodePoint(cp),
|
|
306
|
-
source: "kitty-text",
|
|
307
|
-
})),
|
|
308
|
-
};
|
|
320
|
+
return keys(this.arrowFromModifiers("down", modifiers));
|
|
309
321
|
}
|
|
310
322
|
// Printable keycodes via 'u'
|
|
311
323
|
if (keyCode >= 32 && keyCode < 127) {
|
|
@@ -314,89 +326,51 @@ export class TerminalKeyParser {
|
|
|
314
326
|
}
|
|
315
327
|
return UNRECOGNIZED;
|
|
316
328
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
// Modifier-only keys (Ctrl=17, Shift=16, Alt=18) — ignore
|
|
335
|
-
const vk = parseInt(parts[0], 10) || 0;
|
|
336
|
-
if (vk === 16 || vk === 17 || vk === 18)
|
|
337
|
-
return SUPPRESSED;
|
|
338
|
-
// Navigation keys (VK_PRIOR=33, VK_NEXT=34, VK_END=35, VK_HOME=36)
|
|
339
|
-
if (vk === 33)
|
|
340
|
-
return keys({ kind: "page", direction: "up" });
|
|
341
|
-
if (vk === 34)
|
|
342
|
-
return keys({ kind: "page", direction: "down" });
|
|
343
|
-
if (vk === 35)
|
|
344
|
-
return keys({ kind: "end" });
|
|
345
|
-
if (vk === 36)
|
|
346
|
-
return keys({ kind: "home" });
|
|
347
|
-
// Arrow keys (VK_LEFT=37, VK_UP=38, VK_RIGHT=39, VK_DOWN=40)
|
|
348
|
-
if (vk >= 37 && vk <= 40) {
|
|
349
|
-
const dir = ["left", "up", "right", "down"][vk - 37];
|
|
350
|
-
return keys({ kind: "arrow", direction: dir });
|
|
351
|
-
}
|
|
352
|
-
const ctrl = (cs & 0x000c) !== 0; // LEFT_CTRL(0x08) | RIGHT_CTRL(0x04)
|
|
353
|
-
const alt = (cs & 0x0003) !== 0; // LEFT_ALT(0x02) | RIGHT_ALT(0x01)
|
|
354
|
-
const shift = (cs & 0x0010) !== 0;
|
|
355
|
-
if (vk === 46)
|
|
356
|
-
return keys({ kind: "delete", ctrl }); // VK_DELETE
|
|
357
|
-
if (uc === 10 && !shift) {
|
|
358
|
-
return keys({ kind: "control", byte: 0x0a });
|
|
359
|
-
}
|
|
360
|
-
// Enter
|
|
361
|
-
if (uc === 13 || uc === 10) {
|
|
362
|
-
if (uc === 13 && (ctrl || shift)) {
|
|
363
|
-
const modifiers = 1 + (shift ? 1 : 0) + (ctrl ? 4 : 0);
|
|
364
|
-
return keys({ kind: "kitty-key", keyCode: 13, modifiers });
|
|
329
|
+
arrow(direction, params) {
|
|
330
|
+
const parts = params.split(";");
|
|
331
|
+
const modifiers = parseInt(parts[1] ?? "1", 10) || 1;
|
|
332
|
+
return this.arrowFromModifiers(direction, modifiers);
|
|
333
|
+
}
|
|
334
|
+
arrowFromModifiers(direction, modifiers) {
|
|
335
|
+
if (modifiers > 1)
|
|
336
|
+
return { kind: "arrow", direction, modifiers };
|
|
337
|
+
return { kind: "arrow", direction };
|
|
338
|
+
}
|
|
339
|
+
consumePasteByte(byte, out) {
|
|
340
|
+
if (this.pasteBuffer === null)
|
|
341
|
+
return;
|
|
342
|
+
if (byte === PASTE_END_BYTES[this.pasteEndMatch]) {
|
|
343
|
+
this.pasteEndMatch++;
|
|
344
|
+
if (this.pasteEndMatch === PASTE_END_BYTES.length) {
|
|
345
|
+
this.flushPaste(this.pasteBuffer, out);
|
|
365
346
|
}
|
|
366
|
-
return
|
|
367
|
-
}
|
|
368
|
-
// Backspace (VK_BACK=8)
|
|
369
|
-
if (vk === 8)
|
|
370
|
-
return keys({ kind: "backspace" });
|
|
371
|
-
// Escape (VK_ESCAPE=27)
|
|
372
|
-
if (vk === 27)
|
|
373
|
-
return keys({ kind: "escape" });
|
|
374
|
-
// Tab (VK_TAB=9)
|
|
375
|
-
if (vk === 9) {
|
|
376
|
-
return keys({ kind: "kitty-key", keyCode: 9, modifiers: shift ? 2 : 1 });
|
|
347
|
+
return;
|
|
377
348
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
349
|
+
if (this.pasteEndMatch > 0) {
|
|
350
|
+
// The buffered prefix was not the paste terminator after all — flush
|
|
351
|
+
// those bytes back into the paste content, then re-process `byte`.
|
|
352
|
+
const matched = this.pasteEndMatch;
|
|
353
|
+
this.pasteEndMatch = 0;
|
|
354
|
+
for (let i = 0; i < matched; i++)
|
|
355
|
+
this.appendPasteByte(PASTE_END_BYTES[i], out);
|
|
356
|
+
this.consumePasteByte(byte, out);
|
|
357
|
+
return;
|
|
381
358
|
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
const modifiers = 1 + (shift ? 1 : 0) + 2 + (ctrl ? 4 : 0);
|
|
391
|
-
return keys({ kind: "kitty-key", keyCode, modifiers });
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
// Printable characters
|
|
395
|
-
if (uc >= 32) {
|
|
396
|
-
const ch = String.fromCharCode(uc);
|
|
397
|
-
return keys({ kind: "printable", char: ch, source: "plain" });
|
|
359
|
+
this.appendPasteByte(byte, out);
|
|
360
|
+
}
|
|
361
|
+
appendPasteByte(byte, out) {
|
|
362
|
+
if (this.pasteBuffer === null)
|
|
363
|
+
return;
|
|
364
|
+
this.pasteBuffer.push(byte);
|
|
365
|
+
if (this.pasteBuffer.length > MAX_PASTE_BYTES) {
|
|
366
|
+
this.flushPaste(this.pasteBuffer, out);
|
|
398
367
|
}
|
|
399
|
-
|
|
368
|
+
}
|
|
369
|
+
flushPaste(buffer, out) {
|
|
370
|
+
this.pasteBuffer = null;
|
|
371
|
+
this.pasteEndMatch = 0;
|
|
372
|
+
this.state = "normal";
|
|
373
|
+
out.push({ kind: "paste", content: Buffer.from(buffer).toString("utf8") });
|
|
400
374
|
}
|
|
401
375
|
parseKittyEventType(modsAndEvent) {
|
|
402
376
|
if (!modsAndEvent)
|