@tuidom/terminal-backend 0.16.1 → 0.17.1
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { HostTerminalColors, ITerminalBackend } from "@tuidom/core/backend/iTerminalBackend";
|
|
1
|
+
import type { HostColorScheme, HostTerminalColors, ITerminalBackend } from "@tuidom/core/backend/iTerminalBackend";
|
|
2
2
|
import { Point, Size } from "@tuidom/core/common/geometryPromitives";
|
|
3
3
|
import type { KeyPressEvent } from "@tuidom/core/input/keyEvent";
|
|
4
4
|
import type { MouseToken } from "@tuidom/core/input/rawTerminalToken";
|
|
@@ -18,6 +18,9 @@ export declare class NodeTerminalBackend implements ITerminalBackend {
|
|
|
18
18
|
private resizeCallbacks;
|
|
19
19
|
private oscResponseCallbacks;
|
|
20
20
|
private deviceReportCallbacks;
|
|
21
|
+
private colorSchemeCallbacks;
|
|
22
|
+
/** Mode 2031 is on — teardown owes the terminal its reset. */
|
|
23
|
+
private colorSchemeReportsOn;
|
|
21
24
|
/** DA1-запросов отправлено / ответов получено — чтобы проба ждала именно свой DA1. */
|
|
22
25
|
private da1Sent;
|
|
23
26
|
private da1Received;
|
|
@@ -84,6 +87,8 @@ export declare class NodeTerminalBackend implements ITerminalBackend {
|
|
|
84
87
|
onPaste(callback: (text: string) => void): void;
|
|
85
88
|
onResize(callback: (size: Size) => void): void;
|
|
86
89
|
onOscResponse(callback: (code: number, data: string) => void): void;
|
|
90
|
+
onColorSchemeChange(callback: (scheme: HostColorScheme) => void): void;
|
|
91
|
+
private enableColorSchemeReports;
|
|
87
92
|
probeKeyboardProtocol(onResult: (supported: boolean) => void): void;
|
|
88
93
|
probeTerminalVersion(onResult: (nameAndVersion: string | undefined) => void): void;
|
|
89
94
|
probeHostColors(onResult: (colors: HostTerminalColors) => void): void;
|
|
@@ -46,6 +46,23 @@ const BRACKETED_PASTE_DISABLE = "\x1b[?2004l";
|
|
|
46
46
|
*/
|
|
47
47
|
const TITLE_PUSH = "\x1b[22;0t";
|
|
48
48
|
const TITLE_POP = "\x1b[23;0t";
|
|
49
|
+
/**
|
|
50
|
+
* Color-scheme reports (DEC private mode 2031, the Contour protocol): with the mode on the
|
|
51
|
+
* terminal sends `CSI ? 997 ; 1|2 n` whenever its scheme flips; `CSI ? 996 n` asks for the
|
|
52
|
+
* current one right away. Direct, per-pane: tmux ≥ 3.6 tracks the mode itself and reports
|
|
53
|
+
* the outer terminal's scheme to the panes that asked.
|
|
54
|
+
*/
|
|
55
|
+
const COLOR_SCHEME_REPORTS_ENABLE = "\x1b[?2031h";
|
|
56
|
+
const COLOR_SCHEME_REPORTS_DISABLE = "\x1b[?2031l";
|
|
57
|
+
const COLOR_SCHEME_QUERY = "\x1b[?996n";
|
|
58
|
+
/** `?997;1` → dark, `?997;2` → light; any other value isn't a scheme we know. */
|
|
59
|
+
function parseColorSchemeReport(params) {
|
|
60
|
+
if (params === "?997;1")
|
|
61
|
+
return "dark";
|
|
62
|
+
if (params === "?997;2")
|
|
63
|
+
return "light";
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
49
66
|
/** OSC 0 — icon name and window title at once; BEL is the terminator everyone understands. */
|
|
50
67
|
export function windowTitleSequence(title) {
|
|
51
68
|
// A control character inside the title would cut the sequence short.
|
|
@@ -138,6 +155,9 @@ export class NodeTerminalBackend {
|
|
|
138
155
|
resizeCallbacks = [];
|
|
139
156
|
oscResponseCallbacks = [];
|
|
140
157
|
deviceReportCallbacks = [];
|
|
158
|
+
colorSchemeCallbacks = [];
|
|
159
|
+
/** Mode 2031 is on — teardown owes the terminal its reset. */
|
|
160
|
+
colorSchemeReportsOn = false;
|
|
141
161
|
/** DA1-запросов отправлено / ответов получено — чтобы проба ждала именно свой DA1. */
|
|
142
162
|
da1Sent = 0;
|
|
143
163
|
da1Received = 0;
|
|
@@ -231,6 +251,18 @@ export class NodeTerminalBackend {
|
|
|
231
251
|
onOscResponse(callback) {
|
|
232
252
|
this.oscResponseCallbacks.push(callback);
|
|
233
253
|
}
|
|
254
|
+
onColorSchemeChange(callback) {
|
|
255
|
+
this.colorSchemeCallbacks.push(callback);
|
|
256
|
+
// Before setup the tty is still in cooked mode with ECHO: the reply would land on the screen.
|
|
257
|
+
if (this.onDataHandler !== null)
|
|
258
|
+
this.enableColorSchemeReports();
|
|
259
|
+
}
|
|
260
|
+
enableColorSchemeReports() {
|
|
261
|
+
if (this.colorSchemeReportsOn)
|
|
262
|
+
return;
|
|
263
|
+
this.colorSchemeReportsOn = true;
|
|
264
|
+
this.writeDirect(COLOR_SCHEME_REPORTS_ENABLE + COLOR_SCHEME_QUERY);
|
|
265
|
+
}
|
|
234
266
|
probeKeyboardProtocol(onResult) {
|
|
235
267
|
let supported = false;
|
|
236
268
|
// Direct (not passthrough): the reply must reflect tmux's own Kitty support, per-pane.
|
|
@@ -342,6 +374,12 @@ export class NodeTerminalBackend {
|
|
|
342
374
|
for (const report of result.deviceReports) {
|
|
343
375
|
if (report.report === "da1")
|
|
344
376
|
this.da1Received++;
|
|
377
|
+
if (report.report === "color-scheme") {
|
|
378
|
+
const scheme = parseColorSchemeReport(report.params);
|
|
379
|
+
if (scheme !== undefined)
|
|
380
|
+
for (const cb of this.colorSchemeCallbacks)
|
|
381
|
+
cb(scheme);
|
|
382
|
+
}
|
|
345
383
|
for (const cb of this.deviceReportCallbacks)
|
|
346
384
|
cb(report.report, report.params);
|
|
347
385
|
}
|
|
@@ -442,6 +480,9 @@ export class NodeTerminalBackend {
|
|
|
442
480
|
this.schedulePartialInputFlush();
|
|
443
481
|
};
|
|
444
482
|
this.stdin.on("data", this.onDataHandler);
|
|
483
|
+
// A subscriber from before setup gets its reports now that the tty is raw.
|
|
484
|
+
if (this.colorSchemeCallbacks.length > 0)
|
|
485
|
+
this.enableColorSchemeReports();
|
|
445
486
|
// Listen for terminal resize (throttled + deduplicated)
|
|
446
487
|
this.onResizeHandler = () => {
|
|
447
488
|
if (this.resizeThrottleTimer !== null) {
|
|
@@ -485,6 +526,10 @@ export class NodeTerminalBackend {
|
|
|
485
526
|
this.writeDirect(MOUSE_TRACKING_DISABLE);
|
|
486
527
|
// Disable bracketed paste — direct (matches the per-pane enable in setup)
|
|
487
528
|
this.writeDirect(BRACKETED_PASTE_DISABLE);
|
|
529
|
+
if (this.colorSchemeReportsOn) {
|
|
530
|
+
this.writeDirect(COLOR_SCHEME_REPORTS_DISABLE);
|
|
531
|
+
this.colorSchemeReportsOn = false;
|
|
532
|
+
}
|
|
488
533
|
// Restore cursor
|
|
489
534
|
this.stdout.write("\x1b[?25h");
|
|
490
535
|
// Restore normal screen buffer
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tuidom/terminal-backend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Experimental terminal UI DOM — real terminal backend for Node (tty, ANSI diffing, Kitty protocol). API is unstable.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,6 +28,6 @@
|
|
|
28
28
|
"./*": "./dist/*.js"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@tuidom/core": "0.
|
|
31
|
+
"@tuidom/core": "0.17.1"
|
|
32
32
|
}
|
|
33
33
|
}
|