Spaces:
Sleeping
Sleeping
File size: 2,627 Bytes
aab0173 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | import "@xterm/xterm/css/xterm.css";
const THEME = {
background: "#10141c",
foreground: "#d6deeb",
cursor: "#f7c948",
cursorAccent: "#10141c",
selectionBackground: "#334155",
black: "#111827",
red: "#f87171",
green: "#34d399",
yellow: "#facc15",
blue: "#60a5fa",
magenta: "#c084fc",
cyan: "#22d3ee",
white: "#f8fafc",
brightBlack: "#475569",
brightRed: "#fca5a5",
brightGreen: "#86efac",
brightYellow: "#fde68a",
brightBlue: "#93c5fd",
brightMagenta: "#d8b4fe",
brightCyan: "#67e8f9",
brightWhite: "#ffffff",
};
function normalizeNewlines(text) {
return String(text).replace(/\r?\n/g, "\r\n");
}
function withTimeout(promise, ms, label) {
return Promise.race([
promise,
new Promise((_, reject) => {
setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);
}),
]);
}
export async function createWebTerminal(container) {
let terminal;
let fitAddon;
let engine = "ghostty-web";
try {
const ghostty = await withTimeout(import("ghostty-web"), 3000, "ghostty-web import");
await withTimeout(ghostty.init(), 3000, "ghostty-web init");
terminal = new ghostty.Terminal({
cursorBlink: true,
fontFamily: "JetBrains Mono, SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace",
fontSize: 14,
rows: 30,
cols: 100,
scrollback: 5000,
theme: THEME,
});
fitAddon = new ghostty.FitAddon();
terminal.loadAddon(fitAddon);
} catch (error) {
const [{ Terminal }, { FitAddon }] = await Promise.all([import("@xterm/xterm"), import("@xterm/addon-fit")]);
engine = "xterm";
terminal = new Terminal({
cursorBlink: true,
fontFamily: "JetBrains Mono, SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace",
fontSize: 14,
rows: 30,
cols: 100,
scrollback: 5000,
theme: THEME,
});
fitAddon = new FitAddon();
terminal.loadAddon(fitAddon);
console.warn("ghostty-web failed, using xterm fallback", error);
}
terminal.open(container);
fitAddon.fit();
terminal.focus();
const resizeObserver = new ResizeObserver(() => fitAddon.fit());
resizeObserver.observe(container);
return {
engine,
raw: terminal,
onData: (handler) => terminal.onData(handler),
write: (text) => terminal.write(normalizeNewlines(text)),
writeln: (text = "") => terminal.write(`${normalizeNewlines(text)}\r\n`),
clear: () => terminal.clear(),
focus: () => terminal.focus(),
fit: () => fitAddon.fit(),
dispose: () => {
resizeObserver.disconnect();
terminal.dispose();
},
};
}
|