diff options
Diffstat (limited to 'runtime/js')
-rw-r--r-- | runtime/js/41_prompt.js | 107 |
1 files changed, 62 insertions, 45 deletions
diff --git a/runtime/js/41_prompt.js b/runtime/js/41_prompt.js index e665aae07..d73f9d26b 100644 --- a/runtime/js/41_prompt.js +++ b/runtime/js/41_prompt.js @@ -1,78 +1,95 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. import { core, primordials } from "ext:core/mod.js"; +const ops = core.ops; import { isatty } from "ext:runtime/40_tty.js"; import { stdin } from "ext:deno_io/12_io.js"; -const { ArrayPrototypePush, StringPrototypeCharCodeAt, Uint8Array } = - primordials; -const LF = StringPrototypeCharCodeAt("\n", 0); -const CR = StringPrototypeCharCodeAt("\r", 0); +import { getNoColor } from "ext:deno_console/01_console.js"; +const { Uint8Array, StringFromCodePoint } = primordials; + +const ESC = "\x1b"; +const CTRL_C = "\x03"; +const CTRL_D = "\x04"; + +const bold = ansi(1, 22); +const italic = ansi(3, 23); +const yellow = ansi(33, 0); +function ansi(start, end) { + return (str) => getNoColor() ? str : `\x1b[${start}m${str}\x1b[${end}m`; +} function alert(message = "Alert") { if (!isatty(stdin.rid)) { return; } - core.print(`${message} [Enter] `, false); + core.print( + `${yellow(bold(`${message}`))} [${italic("Press any key to continue")}] `, + ); + + try { + stdin.setRaw(true); + stdin.readSync(new Uint8Array(1024)); + } finally { + stdin.setRaw(false); + } - readLineFromStdinSync(); + core.print("\n"); } -function confirm(message = "Confirm") { +function prompt(message = "Prompt", defaultValue = "") { if (!isatty(stdin.rid)) { - return false; + return null; } - core.print(`${message} [y/N] `, false); - - const answer = readLineFromStdinSync(); - - return answer === "Y" || answer === "y"; + return ops.op_read_line_prompt( + `${message} `, + `${defaultValue}`, + ); } -function prompt(message = "Prompt", defaultValue) { - defaultValue ??= null; +const inputMap = new primordials.Map([ + ["Y", true], + ["y", true], + ["\r", true], + ["\n", true], + ["\r\n", true], + ["N", false], + ["n", false], + [ESC, false], + [CTRL_C, false], + [CTRL_D, false], +]); +function confirm(message = "Confirm") { if (!isatty(stdin.rid)) { - return null; + return false; } - if (defaultValue) { - message += ` [${defaultValue}]`; - } + core.print(`${yellow(bold(`${message}`))} [${italic("Y/n")}] `); - message += " "; + let val = false; + try { + stdin.setRaw(true); - // output in one shot to make the tests more reliable - core.print(message, false); + while (true) { + const b = new Uint8Array(1024); + stdin.readSync(b); + let byteString = ""; - return readLineFromStdinSync() || defaultValue; -} + let i = 0; + while (b[i]) byteString += StringFromCodePoint(b[i++]); -function readLineFromStdinSync() { - const c = new Uint8Array(1); - const buf = []; - - while (true) { - const n = stdin.readSync(c); - if (n === null || n === 0) { - break; - } - if (c[0] === CR) { - const n = stdin.readSync(c); - if (c[0] === LF) { - break; - } - ArrayPrototypePush(buf, CR); - if (n === null || n === 0) { + if (inputMap.has(byteString)) { + val = inputMap.get(byteString); break; } } - if (c[0] === LF) { - break; - } - ArrayPrototypePush(buf, c[0]); + } finally { + stdin.setRaw(false); } - return core.decode(new Uint8Array(buf)); + + core.print(`${val ? "y" : "n"}\n`); + return val; } export { alert, confirm, prompt }; |