fix: terminal size sync — resize message handler + xterm-256color default-terminal
This commit is contained in:
parent
b64aaab40a
commit
fcfe729d23
|
|
@ -22,6 +22,7 @@ import { readChunks } from "../../buffer/reader.js";
|
|||
import type { StateEvent } from "../../pi/events.js";
|
||||
import { SequenceCounter } from "../../sequence.js";
|
||||
import { ControlClient } from "../../tmux/control.js";
|
||||
import { resizeSession } from "../../tmux/manager.js";
|
||||
import { capturePane } from "../../tmux/snapshot.js";
|
||||
import type { WsClient, WsServer } from "../types.js";
|
||||
|
||||
|
|
@ -155,6 +156,12 @@ function handleStreamConnection(
|
|||
if (ws.readyState !== 1) break;
|
||||
sendBinary(ws, buildBinaryFrame(chunk.seq, chunk.data));
|
||||
}
|
||||
} else if (m.type === "resize") {
|
||||
// IC-1 extension: client reports its actual terminal dimensions.
|
||||
// Resize the tmux window so line-wrapping matches what the client sees.
|
||||
const cols = typeof m.cols === "number" ? m.cols : 80;
|
||||
const rows = typeof m.rows === "number" ? m.rows : 24;
|
||||
resizeSession(sessionId, cols, rows).catch(() => {});
|
||||
} else if (m.type === "snapshot-request") {
|
||||
capturePane({ session: sessionId })
|
||||
.then((text) => {
|
||||
|
|
|
|||
|
|
@ -60,6 +60,15 @@ export async function spawnSession(opts: {
|
|||
await checkTmuxVersion();
|
||||
const { name, width = 120, height = 40, command = "" } = opts;
|
||||
|
||||
// Set default-terminal globally so programs inside tmux get xterm-256color
|
||||
// and emit the escape sequences that SwiftTerm / xterm-compatible clients expect.
|
||||
await execFileAsync("tmux", [
|
||||
"set-option",
|
||||
"-g",
|
||||
"default-terminal",
|
||||
"xterm-256color",
|
||||
]).catch(() => {}); // best-effort; older tmux may not support all options
|
||||
|
||||
const args = [
|
||||
"new-session",
|
||||
"-d",
|
||||
|
|
@ -76,6 +85,28 @@ export async function spawnSession(opts: {
|
|||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize an existing session's window.
|
||||
* Safe to call at any time; silently ignores unknown sessions.
|
||||
*/
|
||||
export async function resizeSession(
|
||||
name: string,
|
||||
cols: number,
|
||||
rows: number,
|
||||
): Promise<void> {
|
||||
const c = Math.max(1, Math.min(Math.round(cols), 500));
|
||||
const r = Math.max(1, Math.min(Math.round(rows), 200));
|
||||
await execFileAsync("tmux", [
|
||||
"resize-window",
|
||||
"-t",
|
||||
name,
|
||||
"-x",
|
||||
String(c),
|
||||
"-y",
|
||||
String(r),
|
||||
]).catch(() => {}); // session may not exist yet; ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* List all tmux sessions with metadata.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue