import { Cursor } from "./cursor.ts"; import { colorize } from "./style.ts"; import { TerminalBlock, TerminalLayout } from "./TerminalLayout.ts"; export async function cliPrompt( message: string, block?: TerminalBlock, ): Promise { const encoder = new TextEncoder(); const input: string[] = []; await Deno.stdin.setRaw(true); let cursorVisible = true; if (!block) { cursorVisible = Cursor["visible"]; Cursor.show(); } let range: [number, number] = [0, 1]; if (block) { range = block.setLines([message + " "]); } else { Deno.stdout.writeSync(encoder.encode(message + " ")); } const buf = new Uint8Array(1); while (true) { const n = await Deno.stdin.read(buf); if (n === null) break; const byte = buf[0]; if (byte === 3) { // Ctrl+C Deno.stdin.setRaw(false); block?.["layout"]?.clearAll(); block?.clear(); Deno.exit(130); } if (byte === 13) { // Enter break; } else if (byte === 127 || byte === 8) { // Backspace input.pop(); } else if (byte >= 32 && byte <= 126) { // Printable chars input.push(String.fromCharCode(byte)); } const line = message + " " + input.join(""); if (block) { range = block.setLines([line], range); } else { Deno.stdout.writeSync(encoder.encode("\r\x1b[K" + line)); } } await Deno.stdin.setRaw(false); if (!block && !cursorVisible) { Cursor.hide(); } Deno.stdout.writeSync(encoder.encode("\n")); return input.join(""); } export function cliConfirm(message: string, block?: TerminalBlock) { return cliPrompt(message + " (y/n)", block).then((v) => v.toLowerCase() === "y" ); } export function cliAlert(message: string, block?: TerminalBlock) { return cliPrompt( message + colorize(" Press Enter to continue", "gray"), block, ).then((v) => { return v; }); } export function cliLog(message: string, block?: TerminalBlock) { if (!block) { console.log(message); } else { block.setLines(message.split("\n")); } } if (import.meta.main) { const layout = new TerminalLayout(); const title = new TerminalBlock(); const block = new TerminalBlock(); block.setPreserveHistory(true); title.setLines(["Hello, World!"]); title.setFixedHeight(1); layout.register("title", title); layout.register("block", block); Deno.addSignalListener("SIGINT", () => { layout.clearAll(); // console.clear(); Deno.exit(0); }); const name = await cliPrompt("Enter your name:", block); cliLog(`Hello, ${name}!`, block); const single = await cliConfirm("Are you single?", block); cliLog(single ? "Do you want to go out with me?" : "Okay", block); const loopingConvo = [ "No response?", "I guess that's okay", "Maybe I'll see you next week?", "Wow, really not going to say anything to me?", "Well, if that's how you feel", ]; let convo = 0; setInterval(() => { cliLog(loopingConvo[convo % loopingConvo.length], block); convo++; }, 2000); // setTimeout(async () => { // await cliAlert("Well, if that's that...", block); // Deno.exit(0); // }, 10000); }