@tuidom/terminal-backend 0.10.0 → 0.11.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.
|
@@ -3,6 +3,8 @@ 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";
|
|
5
5
|
import { Grid } from "@tuidom/core/rendering/grid";
|
|
6
|
+
/** OSC 0 — icon name and window title at once; BEL is the terminator everyone understands. */
|
|
7
|
+
export declare function windowTitleSequence(title: string): string;
|
|
6
8
|
/**
|
|
7
9
|
* Real terminal backend: reads from process.stdin, writes to process.stdout.
|
|
8
10
|
* Handles alternate screen, raw mode, cursor visibility, signal cleanup.
|
|
@@ -29,6 +31,8 @@ export declare class NodeTerminalBackend implements ITerminalBackend {
|
|
|
29
31
|
private lastEmittedSize;
|
|
30
32
|
private resizePending;
|
|
31
33
|
private cleanupHandlers;
|
|
34
|
+
/** The title stack got a push from {@link setWindowTitle}; teardown owes it a pop. */
|
|
35
|
+
private titlePushed;
|
|
32
36
|
private readonly isTmux;
|
|
33
37
|
private readonly isGnuScreen;
|
|
34
38
|
private readonly inputParser;
|
|
@@ -67,6 +71,14 @@ export declare class NodeTerminalBackend implements ITerminalBackend {
|
|
|
67
71
|
* TMUX passthrough is applied automatically when running inside TMUX.
|
|
68
72
|
*/
|
|
69
73
|
writeOscSequence(sequence: string): void;
|
|
74
|
+
/**
|
|
75
|
+
* Set the terminal window title (OSC 0). Written directly, never through tmux
|
|
76
|
+
* passthrough: tmux understands OSC 0/2 itself and keeps it as the pane title
|
|
77
|
+
* (`#{pane_title}`, `#T`), from where `set-titles` / `automatic-rename-format` carry it
|
|
78
|
+
* to the outer window and the tmux window name. The first call saves the current title
|
|
79
|
+
* on the terminal's title stack; {@link teardown} restores it.
|
|
80
|
+
*/
|
|
81
|
+
setWindowTitle(title: string): void;
|
|
70
82
|
onInput(callback: (event: KeyPressEvent) => void): void;
|
|
71
83
|
onMouse(callback: (event: MouseToken) => void): void;
|
|
72
84
|
onPaste(callback: (text: string) => void): void;
|
|
@@ -38,6 +38,19 @@ const MODIFY_OTHER_KEYS_DISABLE = "\x1b[>4;0m";
|
|
|
38
38
|
*/
|
|
39
39
|
const BRACKETED_PASTE_ENABLE = "\x1b[?2004h";
|
|
40
40
|
const BRACKETED_PASTE_DISABLE = "\x1b[?2004l";
|
|
41
|
+
/**
|
|
42
|
+
* Window-title stack (XTWINOPS): `CSI 22 ; 0 t` saves the icon and window titles,
|
|
43
|
+
* `CSI 23 ; 0 t` restores them — the same push/pop vim does around its own title, so the
|
|
44
|
+
* shell's title comes back on exit. tmux keeps the stack per pane; terminals without it
|
|
45
|
+
* ignore the sequence.
|
|
46
|
+
*/
|
|
47
|
+
const TITLE_PUSH = "\x1b[22;0t";
|
|
48
|
+
const TITLE_POP = "\x1b[23;0t";
|
|
49
|
+
/** OSC 0 — icon name and window title at once; BEL is the terminator everyone understands. */
|
|
50
|
+
export function windowTitleSequence(title) {
|
|
51
|
+
// A control character inside the title would cut the sequence short.
|
|
52
|
+
return `\x1b]0;${title.replace(/[\x00-\x1f\x7f]/g, " ")}\x07`;
|
|
53
|
+
}
|
|
41
54
|
/**
|
|
42
55
|
* Keyboard-protocol probe: query current Kitty flags (`CSI ? u`) immediately followed by
|
|
43
56
|
* Primary Device Attributes (`CSI c`). Only Kitty-capable terminals answer the first; every
|
|
@@ -138,6 +151,8 @@ export class NodeTerminalBackend {
|
|
|
138
151
|
lastEmittedSize = null;
|
|
139
152
|
resizePending = false;
|
|
140
153
|
cleanupHandlers = [];
|
|
154
|
+
/** The title stack got a push from {@link setWindowTitle}; teardown owes it a pop. */
|
|
155
|
+
titlePushed = false;
|
|
141
156
|
isTmux;
|
|
142
157
|
isGnuScreen;
|
|
143
158
|
inputParser = new KeyInputParser();
|
|
@@ -187,6 +202,20 @@ export class NodeTerminalBackend {
|
|
|
187
202
|
writeOscSequence(sequence) {
|
|
188
203
|
this.writePassthrough(sequence);
|
|
189
204
|
}
|
|
205
|
+
/**
|
|
206
|
+
* Set the terminal window title (OSC 0). Written directly, never through tmux
|
|
207
|
+
* passthrough: tmux understands OSC 0/2 itself and keeps it as the pane title
|
|
208
|
+
* (`#{pane_title}`, `#T`), from where `set-titles` / `automatic-rename-format` carry it
|
|
209
|
+
* to the outer window and the tmux window name. The first call saves the current title
|
|
210
|
+
* on the terminal's title stack; {@link teardown} restores it.
|
|
211
|
+
*/
|
|
212
|
+
setWindowTitle(title) {
|
|
213
|
+
if (!this.titlePushed) {
|
|
214
|
+
this.writeDirect(TITLE_PUSH);
|
|
215
|
+
this.titlePushed = true;
|
|
216
|
+
}
|
|
217
|
+
this.writeDirect(windowTitleSequence(title));
|
|
218
|
+
}
|
|
190
219
|
onInput(callback) {
|
|
191
220
|
this.inputCallbacks.push(callback);
|
|
192
221
|
}
|
|
@@ -460,6 +489,11 @@ export class NodeTerminalBackend {
|
|
|
460
489
|
this.stdout.write("\x1b[?25h");
|
|
461
490
|
// Restore normal screen buffer
|
|
462
491
|
this.stdout.write("\x1b[?1049l");
|
|
492
|
+
// Restore the title saved by the first setWindowTitle — direct, like the title itself
|
|
493
|
+
if (this.titlePushed) {
|
|
494
|
+
this.writeDirect(TITLE_POP);
|
|
495
|
+
this.titlePushed = false;
|
|
496
|
+
}
|
|
463
497
|
// Remove stdin listener
|
|
464
498
|
if (this.onDataHandler) {
|
|
465
499
|
this.stdin.removeListener("data", this.onDataHandler);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tuidom/terminal-backend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.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.11.1"
|
|
32
32
|
}
|
|
33
33
|
}
|