mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 15:49:44 -05:00
fix(web): use rustyline for prompt (#21893)
Workaround until https://github.com/kkawakam/rustyline/pull/759
This commit is contained in:
parent
d8f86c8b9c
commit
9268df5f34
8 changed files with 56 additions and 24 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1655,6 +1655,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"regex",
|
||||
"ring",
|
||||
"rustyline",
|
||||
"serde",
|
||||
"signal-hook-registry",
|
||||
"termcolor",
|
||||
|
@ -5035,6 +5036,7 @@ dependencies = [
|
|||
"cfg-if",
|
||||
"clipboard-win",
|
||||
"fd-lock",
|
||||
"home",
|
||||
"libc",
|
||||
"log",
|
||||
"memchr",
|
||||
|
|
|
@ -138,6 +138,7 @@ rustls = "0.21.8"
|
|||
rustls-pemfile = "1.0.0"
|
||||
rustls-tokio-stream = "=0.2.17"
|
||||
rustls-webpki = "0.101.4"
|
||||
rustyline = "=13.0.0"
|
||||
webpki-roots = "0.25.2"
|
||||
scopeguard = "1.2.0"
|
||||
saffron = "=0.1.0"
|
||||
|
|
|
@ -117,7 +117,7 @@ quick-junit = "^0.3.5"
|
|||
rand = { workspace = true, features = ["small_rng"] }
|
||||
regex.workspace = true
|
||||
ring.workspace = true
|
||||
rustyline = { version = "=13.0.0", default-features = false, features = ["custom-bindings", "with-file-history"] }
|
||||
rustyline.workspace = true
|
||||
rustyline-derive = "=0.7.0"
|
||||
serde.workspace = true
|
||||
serde_repr.workspace = true
|
||||
|
|
|
@ -2823,12 +2823,10 @@ mod permissions {
|
|||
.new_command()
|
||||
.args_vec(["run", "--quiet", "--unstable", "run/066_prompt.ts"])
|
||||
.with_pty(|mut console| {
|
||||
console.expect("What is your name? [Jane Doe] ");
|
||||
console.write_line_raw("John Doe");
|
||||
console.expect("Your name is John Doe.");
|
||||
console.expect("What is your name? [Jane Doe] ");
|
||||
console.expect("What is your name? Jane Doe");
|
||||
console.write_line_raw("");
|
||||
console.expect("Your name is Jane Doe.");
|
||||
|
||||
console.expect("Prompt ");
|
||||
console.write_line_raw("foo");
|
||||
console.expect("Your input is foo.");
|
||||
|
@ -2852,9 +2850,6 @@ mod permissions {
|
|||
console.expect("Alert [Enter] ");
|
||||
console.write_line("");
|
||||
console.expect("The end of test");
|
||||
console.expect("What is EOF? ");
|
||||
console.write_line("");
|
||||
console.expect("Your answer is null");
|
||||
});
|
||||
}
|
||||
|
||||
|
|
4
cli/tests/testdata/run/066_prompt.ts
vendored
4
cli/tests/testdata/run/066_prompt.ts
vendored
|
@ -1,5 +1,3 @@
|
|||
const name0 = prompt("What is your name?", "Jane Doe"); // Answer John Doe
|
||||
console.log(`Your name is ${name0}.`);
|
||||
const name1 = prompt("What is your name?", "Jane Doe"); // Answer with default
|
||||
console.log(`Your name is ${name1}.`);
|
||||
const input = prompt(); // Answer foo
|
||||
|
@ -17,5 +15,3 @@ console.log(`Your answer is ${JSON.stringify(windows)}`);
|
|||
alert("Hi");
|
||||
alert();
|
||||
console.log("The end of test");
|
||||
const eof = prompt("What is EOF?");
|
||||
console.log(`Your answer is ${JSON.stringify(eof)}`);
|
||||
|
|
|
@ -112,6 +112,7 @@ notify.workspace = true
|
|||
once_cell.workspace = true
|
||||
regex.workspace = true
|
||||
ring.workspace = true
|
||||
rustyline = { workspace = true, features = ["custom-bindings"] }
|
||||
serde.workspace = true
|
||||
signal-hook-registry = "1.4.0"
|
||||
termcolor = "1.1.3"
|
||||
|
|
|
@ -9,6 +9,8 @@ const {
|
|||
import { isatty } from "ext:runtime/40_tty.js";
|
||||
import { stdin } from "ext:deno_io/12_io.js";
|
||||
|
||||
const ops = core.ops;
|
||||
|
||||
const LF = StringPrototypeCharCodeAt("\n", 0);
|
||||
const CR = StringPrototypeCharCodeAt("\r", 0);
|
||||
|
||||
|
@ -35,22 +37,16 @@ function confirm(message = "Confirm") {
|
|||
}
|
||||
|
||||
function prompt(message = "Prompt", defaultValue) {
|
||||
defaultValue ??= null;
|
||||
defaultValue ??= "";
|
||||
|
||||
if (!isatty(stdin.rid)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (defaultValue) {
|
||||
message += ` [${defaultValue}]`;
|
||||
}
|
||||
|
||||
message += " ";
|
||||
|
||||
// output in one shot to make the tests more reliable
|
||||
core.print(message, false);
|
||||
|
||||
return readLineFromStdinSync() || defaultValue;
|
||||
return ops.op_read_line_prompt(
|
||||
`${message} `,
|
||||
`${defaultValue}`,
|
||||
);
|
||||
}
|
||||
|
||||
function readLineFromStdinSync() {
|
||||
|
|
|
@ -5,6 +5,13 @@ use std::io::Error;
|
|||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::OpState;
|
||||
use rustyline::config::Configurer;
|
||||
use rustyline::error::ReadlineError;
|
||||
use rustyline::Cmd;
|
||||
use rustyline::Editor;
|
||||
use rustyline::KeyCode;
|
||||
use rustyline::KeyEvent;
|
||||
use rustyline::Modifiers;
|
||||
|
||||
#[cfg(unix)]
|
||||
use deno_core::ResourceId;
|
||||
|
@ -43,7 +50,12 @@ use winapi::um::wincon;
|
|||
|
||||
deno_core::extension!(
|
||||
deno_tty,
|
||||
ops = [op_stdin_set_raw, op_isatty, op_console_size],
|
||||
ops = [
|
||||
op_stdin_set_raw,
|
||||
op_isatty,
|
||||
op_console_size,
|
||||
op_read_line_prompt
|
||||
],
|
||||
state = |state| {
|
||||
#[cfg(unix)]
|
||||
state.put(TtyModeStore::default());
|
||||
|
@ -320,3 +332,32 @@ mod tests {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[op2]
|
||||
#[string]
|
||||
pub fn op_read_line_prompt(
|
||||
#[string] prompt_text: &str,
|
||||
#[string] default_value: &str,
|
||||
) -> Result<Option<String>, AnyError> {
|
||||
let mut editor = Editor::<(), rustyline::history::DefaultHistory>::new()
|
||||
.expect("Failed to create editor.");
|
||||
|
||||
editor.set_keyseq_timeout(1);
|
||||
editor
|
||||
.bind_sequence(KeyEvent(KeyCode::Esc, Modifiers::empty()), Cmd::Interrupt);
|
||||
|
||||
let read_result =
|
||||
editor.readline_with_initial(prompt_text, (default_value, ""));
|
||||
match read_result {
|
||||
Ok(line) => Ok(Some(line)),
|
||||
Err(ReadlineError::Interrupted) => {
|
||||
// SAFETY: Disable raw mode and raise SIGINT.
|
||||
unsafe {
|
||||
libc::raise(libc::SIGINT);
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
Err(ReadlineError::Eof) => Ok(None),
|
||||
Err(err) => Err(err.into()),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue